94.html

来自「linux 0.11中文版 有注释」· HTML 代码 · 共 668 行 · 第 1/5 页

HTML
668
字号
<html>
<head>
<title>mm/memory.c</title>
<meta name='robots' content='noindex,nofollow'>
<meta name='generator' content='GLOBAL-5.4.1'>
</head>
<body text='#191970' bgcolor='#f5f5dc' vlink='gray'>
<a name='TOP'><h2><a href='../mains.html'>root</a>/<a href='../files/109.html'>mm</a>/memory.c</h2>
<i><font color='green'>/* [&lt;][&gt;]<a href='#L49'>[^]</a><a href='#L648'>[v]</a>[top]<a href='#BOTTOM'>[bottom]</a><a href='../mains.html'>[index]</a><a href='../help.html'>[help]</a> */</font></i>
<hr>
<h2>DEFINITIONS</h2>
This source file includes following definitions.
<ol>
<li><a href='#L49' title='Defined at 49.'>oom</a>
<li><a href='#L101' title='Defined at 101.'>get_free_page</a>
<li><a href='#L130' title='Defined at 130.'>free_page</a>
<li><a href='#L158' title='Defined at 158.'>free_page_tables</a>
<li><a href='#L230' title='Defined at 230.'>copy_page_tables</a>
<li><a href='#L306' title='Defined at 306.'>put_page</a>
<li><a href='#L344' title='Defined at 344.'>un_wp_page</a>
<li><a href='#L388' title='Defined at 388.'>do_wp_page</a>
<li><a href='#L414' title='Defined at 414.'>write_verify</a>
<li><a href='#L435' title='Defined at 435.'>get_empty_page</a>
<li><a href='#L467' title='Defined at 467.'>try_to_share</a>
<li><a href='#L546' title='Defined at 546.'>share_page</a>
<li><a href='#L574' title='Defined at 574.'>do_no_page</a>
<li><a href='#L632' title='Defined at 632.'>mem_init</a>
<li><a href='#L648' title='Defined at 648.'>calc_mem</a>
</ol>
<hr>
<pre>
<a name='L1'><i><font color='green'>/*</font></i>
<a name='L2'><i><font color='green'>* linux/mm/memory.c</font></i>
<a name='L3'><i><font color='green'>*</font></i>
<a name='L4'><i><font color='green'>* (C) 1991 Linus Torvalds</font></i>
<a name='L5'><i><font color='green'>*/</font></i>
<a name='L6'>
<a name='L7'><i><font color='green'>/*</font></i>
<a name='L8'><i><font color='green'>* demand-loading started 01.12.91 - seems it is high on the list of</font></i>
<a name='L9'><i><font color='green'>* things wanted, and it should be easy to implement. - Linus</font></i>
<a name='L10'><i><font color='green'>*/</font></i>
<a name='L11'><i><font color='green'>/*</font></i>
<a name='L12'><i><font color='green'>* 需求加载是从01.12.91 开始编写的 - 在程序编制表中是呼是最重要的程序,</font></i>
<a name='L13'><i><font color='green'>* 并且应该是很容易编制的 - linus</font></i>
<a name='L14'><i><font color='green'>*/</font></i>
<a name='L15'>
<a name='L16'><i><font color='green'>/*</font></i>
<a name='L17'><i><font color='green'>* Ok, demand-loading was easy, shared pages a little bit tricker. Shared</font></i>
<a name='L18'><i><font color='green'>* pages started 02.12.91, seems to work. - Linus.</font></i>
<a name='L19'><i><font color='green'>*</font></i>
<a name='L20'><i><font color='green'>* Tested sharing by executing about 30 /bin/sh: under the old kernel it</font></i>
<a name='L21'><i><font color='green'>* would have taken more than the 6M I have free, but it worked well as</font></i>
<a name='L22'><i><font color='green'>* far as I could see.</font></i>
<a name='L23'><i><font color='green'>*</font></i>
<a name='L24'><i><font color='green'>* Also corrected some "invalidate()"s - I wasn't doing enough of them.</font></i>
<a name='L25'><i><font color='green'>*/</font></i>
<a name='L26'><i><font color='green'>/*</font></i>
<a name='L27'><i><font color='green'>* OK,需求加载是比较容易编写的,而共享页面却需要有点技巧。共享页面程序是</font></i>
<a name='L28'><i><font color='green'>* 02.12.91 开始编写的,好象能够工作 - Linus。</font></i>
<a name='L29'><i><font color='green'>*</font></i>
<a name='L30'><i><font color='green'>* 通过执行大约30 个/bin/sh 对共享操作进行了测试:在老内核当中需要占用多于</font></i>
<a name='L31'><i><font color='green'>* 6M 的内存,而目前却不用。现在看来工作得很好。</font></i>
<a name='L32'><i><font color='green'>*</font></i>
<a name='L33'><i><font color='green'>* 对"invalidate()"函数也进行了修正 - 在这方面我还做的不够。</font></i>
<a name='L34'><i><font color='green'>*/</font></i>
<a name='L35'>
<a name='L36'><font color='darkred'>#include</font> &lt;<a href='39.html'>signal.h</a>&gt;             <i><font color='green'>// 信号头文件。定义信号符号常量,信号结构以及信号操作函数原型。</font></i>
<a name='L37'>
<a name='L38'><font color='darkred'>#include</font> &lt;<a href='25.html'>asm/system.h</a>&gt;         <i><font color='green'>// 系统头文件。定义了设置或修改描述符/中断门等的嵌入式汇编宏。</font></i>
<a name='L39'>
<a name='L40'><font color='darkred'>#include</font> &lt;<a href='36.html'>linux/sched.h</a>&gt;        <i><font color='green'>// 调度程序头文件,定义了任务结构task_struct、初始任务0 的数据,</font></i>
<a name='L41'><i><font color='green'>// 还有一些有关描述符参数设置和获取的嵌入式汇编函数宏语句。</font></i>
<a name='L42'><font color='darkred'>#include</font> &lt;<a href='33.html'>linux/head.h</a>&gt;         <i><font color='green'>// head 头文件,定义了段描述符的简单结构,和几个选择符常量。</font></i>
<a name='L43'><font color='darkred'>#include</font> &lt;<a href='34.html'>linux/kernel.h</a>&gt;       <i><font color='green'>// 内核头文件。含有一些内核常用函数的原形定义。</font></i>
<a name='L44'>
<a name='L45'><b>volatile</b> <b>void</b> <a href='../S/67.html#L139' title='Defined at 139 in kernel/exit.c.'>do_exit</a> (<b>long</b> code);      <i><font color='green'>// 进程退出处理函数,在kernel/exit.c,102 行。</font></i>
<a name='L46'>
<a name='L47'><i><font color='green'>//// 显示内存已用完出错信息,并退出。</font></i>
<a name='L48'><b>static</b> <b>inline</b> <b>volatile</b> <b>void</b>
<a name='L49'><a href='../R/541.html' title='Multiple refered from 5 places.'>oom</a> (<b>void</b>)
<a name='L50'><font color='red'>{</font>
<a name='L51'>  <a href='../S/73.html#L30' title='Defined at 30 in kernel/printk.c.'>printk</a> ("out of memory\n\r");
<a name='L52'>  <a href='../S/67.html#L139' title='Defined at 139 in kernel/exit.c.'>do_exit</a> (<a href='../S/39.html#L24' title='Defined at 24 in include/signal.h.'>SIGSEGV</a>);            <i><font color='green'>// do_exit()应该使用退出代码,这里用了信号值SIGSEGV(11)</font></i>
<a name='L53'><font color='red'>}</font>                               <i><font color='green'>// 相同值的出错码含义是“资源暂时不可用”,正好同义。</font></i>
<a name='L54'>
<a name='L55'><i><font color='green'>// 刷新页变换高速缓冲宏函数。</font></i>
<a name='L56'><i><font color='green'>// 为了提高地址转换的效率,CPU 将最近使用的页表数据存放在芯片中高速缓冲中。在修改过页表</font></i>
<a name='L57'><i><font color='green'>// 信息之后,就需要刷新该缓冲区。这里使用重新加载页目录基址寄存器cr3 的方法来进行刷新。</font></i>
<a name='L58'><i><font color='green'>// 下面eax = 0,是页目录的基址。</font></i>
<a name='L59'><font color='darkred'>#define</font> <a href='../R/508.html' title='Multiple refered from 5 places.'>invalidate</a>() \
<a name='L60'><b>__asm__</b>( "movl %%eax,%%cr3":: "a" (0))
<a name='L61'>
<a name='L62'><i><font color='green'>/* these are not to be changed without changing head.s etc */</font></i>
<a name='L63'><i><font color='green'>/* 下面定义若需要改动,则需要与head.s 等文件中的相关信息一起改变 */</font></i>
<a name='L64'><i><font color='green'>// linux 0.11 内核默认支持的最大内存容量是16M,可以修改这些定义以适合更多的内存。</font></i>
<a name='L65'><font color='darkred'>#define</font> <a href='../R/115.html' title='Multiple refered from 12 places.'>LOW_MEM</a> 0x100000        <i><font color='green'>// 内存低端(1MB)。</font></i>
<a name='L66'><font color='darkred'>#define</font> <a href='../S/94.html#L67' title='Refered from 67 in mm/memory.c.'>PAGING_MEMORY</a> (15*1024*1024)    <i><font color='green'>// 分页内存15MB。主内存区最多15M。</font></i>
<a name='L67'><font color='darkred'>#define</font> <a href='../R/200.html' title='Multiple refered from 5 places.'>PAGING_PAGES</a> (<a href='../S/94.html#L66' title='Defined at 66 in mm/memory.c.'>PAGING_MEMORY</a>&gt;&gt;12)        <i><font color='green'>// 分页后的物理内存页数。</font></i>
<a name='L68'><font color='darkred'>#define</font> <a href='../R/122.html' title='Multiple refered from 3 places.'>MAP_NR</a>(addr) (((addr)-<a href='../S/94.html#L65' title='Defined at 65 in mm/memory.c.'>LOW_MEM</a>)&gt;&gt;12)     <i><font color='green'>// 指定内存地址映射为页号。</font></i>
<a name='L69'><font color='darkred'>#define</font> <a href='../S/94.html#L638' title='Refered from 638 in mm/memory.c.'>USED</a> 100                <i><font color='green'>// 页面被占用标志,参见405 行。</font></i>
<a name='L70'>
<a name='L71'><i><font color='green'>// CODE_SPACE(addr) ((((addr)+0xfff)&amp;~0xfff) &lt; current-&gt;start_code + current-&gt;end_code)。</font></i>
<a name='L72'><i><font color='green'>// 该宏用于判断给定地址是否位于当前进程的代码段中,参见252 行。</font></i>
<a name='L73'><font color='darkred'>#define</font> <a href='../S/94.html#L395' title='Refered from 395 in mm/memory.c.'>CODE_SPACE</a>(addr) ((((addr)+4095)&amp;~4095) &lt; \
<a name='L74'>current-&gt;start_code + current-&gt;end_code)
<a name='L75'>
<a name='L76'><b>static</b> <b>long</b> HIGH_MEMORY = 0;    <i><font color='green'>// 全局变量,存放实际物理内存最高端地址。</font></i>
<a name='L77'>
<a name='L78'><i><font color='green'>// 复制1 页内存(4K 字节)。</font></i>
<a name='L79'><font color='darkred'>#define</font> <a href='../S/94.html#L368' title='Refered from 368 in mm/memory.c.'>copy_page</a>(from,to) \
<a name='L80'><b>__asm__</b>( "cld ; rep ; movsl":: "S" (from), "D" (to), "c" (1024): "cx", "di", "si")
<a name='L81'>
<a name='L82'><i><font color='green'>// 内存映射字节图(1 字节代表1 页内存),每个页面对应的字节用于标志页面当前被引用(占用)次数。</font></i>
<a name='L83'><b>static</b> <b>unsigned</b> <b>char</b> mem_map[<a href='../S/94.html#L67' title='Defined at 67 in mm/memory.c.'>PAGING_PAGES</a>] = <font color='red'>{</font> 0, <font color='red'>}</font>;
<a name='L84'>
<a name='L85'><i><font color='green'>/*</font></i>
<a name='L86'><i><font color='green'>* Get physical address of first (actually last :-) free page, and mark it</font></i>
<a name='L87'><i><font color='green'>* used. If no free pages left, return 0.</font></i>
<a name='L88'><i><font color='green'>*/</font></i>
<a name='L89'><i><font color='green'>/*</font></i>
<a name='L90'><i><font color='green'>* 获取首个(实际上是最后1 个:-)空闲页面,并标记为已使用。如果没有空闲页面,</font></i>
<a name='L91'><i><font color='green'>* 就返回0。</font></i>
<a name='L92'><i><font color='green'>*/</font></i>
<a name='L93'><i><font color='green'>//// 取空闲页面。如果已经没有可用内存了,则返回0。</font></i>
<a name='L94'><i><font color='green'>// 输入:%1(ax=0) - 0;%2(LOW_MEM);%3(cx=PAGING PAGES);%4(edi=mem_map+PAGING_PAGES-1)。</font></i>
<a name='L95'><i><font color='green'>// 输出:返回%0(ax=页面起始地址)。</font></i>
<a name='L96'><i><font color='green'>// 上面%4 寄存器实际指向mem_map[]内存字节图的最后一个字节。本函数从字节图末端开始向前扫描</font></i>
<a name='L97'><i><font color='green'>// 所有页面标志(页面总数为PAGING_PAGES),若有页面空闲(其内存映像字节为0)则返回页面地址。</font></i>
<a name='L98'><i><font color='green'>// 注意!本函数只是指出在主内存区的一页空闲页面,但并没有映射到某个进程的线性地址去。后面</font></i>
<a name='L99'><i><font color='green'>// 的put_page()函数就是用来作映射的。</font></i>
<a name='L100'><b>unsigned</b> <b>long</b>
<a name='L101'><a href='../R/477.html' title='Multiple refered from 12 places.'>get_free_page</a> (<b>void</b>)
<a name='L102'><font color='red'>{</font>
<a name='L103'>  <b>register</b> <b>unsigned</b> <b>long</b> __res <b>asm</b> ("ax");

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?