94.html

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

HTML
668
字号
<a name='L506'>      *(<b>unsigned</b> <b>long</b> *) to_page = to | 7;
<a name='L507'>    <b>else</b>
<a name='L508'>      <a href='../S/94.html#L49' title='Defined at 49 in mm/memory.c.'>oom</a> ();
<a name='L509'><i><font color='green'>// 取对应页表地址??to,页表项地址??to_page。如果对应的页面已经存在,则出错,死机。</font></i>
<a name='L510'>  to &amp;= 0xfffff000;
<a name='L511'>  to_page = to + ((address &gt;&gt; 10) &amp; 0xffc);
<a name='L512'>  <b>if</b> (1 &amp; *(<b>unsigned</b> <b>long</b> *) to_page)
<a name='L513'>    <a href='../S/72.html#L24' title='Defined at 24 in kernel/panic.c.'>panic</a> ("try_to_share: to_page already exists");
<a name='L514'><i><font color='green'>/* share them: write-protect */</font></i>
<a name='L515'><i><font color='green'>/* 对它们进行共享处理:写保护 */</font></i>
<a name='L516'><i><font color='green'>// 对p 进程中页面置写保护标志(置R/W=0 只读)。并且当前进程中的对应页表项指向它。</font></i>
<a name='L517'>  *(<b>unsigned</b> <b>long</b> *) from_page &amp;= ~2;
<a name='L518'>  *(<b>unsigned</b> <b>long</b> *) to_page = *(<b>unsigned</b> <b>long</b> *) from_page;
<a name='L519'><i><font color='green'>// 刷新页变换高速缓冲。</font></i>
<a name='L520'>  <a href='../S/94.html#L59' title='Defined at 59 in mm/memory.c.'>invalidate</a> ();
<a name='L521'><i><font color='green'>// 计算所操作页面的页面号,并将对应页面映射数组项中的引用递增1。</font></i>
<a name='L522'>  phys_addr -= <a href='../S/94.html#L65' title='Defined at 65 in mm/memory.c.'>LOW_MEM</a>;
<a name='L523'>  phys_addr &gt;&gt;= 12;
<a name='L524'>  mem_map[phys_addr]++;
<a name='L525'>  <b>return</b> 1;
<a name='L526'><font color='red'>}</font>
<a name='L527'>
<a name='L528'><i><font color='green'>/*</font></i>
<a name='L529'><i><font color='green'>* share_page() tries to find a process that could share a page with</font></i>
<a name='L530'><i><font color='green'>* the current one. Address is the address of the wanted page relative</font></i>
<a name='L531'><i><font color='green'>* to the current data space.</font></i>
<a name='L532'><i><font color='green'>*</font></i>
<a name='L533'><i><font color='green'>* We first check if it is at all feasible by checking executable-&gt;i_count.</font></i>
<a name='L534'><i><font color='green'>* It should be &gt;1 if there are other tasks sharing this inode.</font></i>
<a name='L535'><i><font color='green'>*/</font></i>
<a name='L536'><i><font color='green'>/*</font></i>
<a name='L537'><i><font color='green'>* share_page()试图找到一个进程,它可以与当前进程共享页面。参数address 是</font></i>
<a name='L538'><i><font color='green'>* 当前数据空间中期望共享的某页面地址。</font></i>
<a name='L539'><i><font color='green'>*</font></i>
<a name='L540'><i><font color='green'>* 首先我们通过检测executable-&gt;i_count 来查证是否可行。如果有其它任务已共享</font></i>
<a name='L541'><i><font color='green'>* 该inode,则它应该大于1。</font></i>
<a name='L542'><i><font color='green'>*/</font></i>
<a name='L543'><i><font color='green'>//// 共享页面。在缺页处理时看看能否共享页面。</font></i>
<a name='L544'><i><font color='green'>// 返回1 - 成功,0 - 失败。</font></i>
<a name='L545'><b>static</b> <b>int</b>
<a name='L546'><a href='../S/94.html#L596' title='Refered from 596 in mm/memory.c.'>share_page</a> (<b>unsigned</b> <b>long</b> address)
<a name='L547'><font color='red'>{</font>
<a name='L548'>  <b>struct</b> task_struct **p;
<a name='L549'>
<a name='L550'><i><font color='green'>// 如果是不可执行的,则返回。excutable 是执行进程的内存i 节点结构。</font></i>
<a name='L551'>  <b>if</b> (!current-&gt;executable)
<a name='L552'>    <b>return</b> 0;
<a name='L553'><i><font color='green'>// 如果只能单独执行(executable-&gt;i_count=1),也退出。</font></i>
<a name='L554'>  <b>if</b> (current-&gt;executable-&gt;i_count &lt; 2)
<a name='L555'>    <b>return</b> 0;
<a name='L556'><i><font color='green'>// 搜索任务数组中所有任务。寻找与当前进程可共享页面的进程,并尝试对指定地址的页面进行共享。</font></i>
<a name='L557'>  <b>for</b> (p = &amp;<a href='../S/36.html#L8' title='Defined at 8 in include/linux/sched.h.'>LAST_TASK</a>; p &gt; &amp;<a href='../S/36.html#L7' title='Defined at 7 in include/linux/sched.h.'>FIRST_TASK</a>; --p)
<a name='L558'>    <font color='red'>{</font>
<a name='L559'>      <b>if</b> (!*p)                  <i><font color='green'>// 如果该任务项空闲,则继续寻找。</font></i>
<a name='L560'>        <b>continue</b>;
<a name='L561'>      <b>if</b> (current == *p)        <i><font color='green'>// 如果就是当前任务,也继续寻找。</font></i>
<a name='L562'>        <b>continue</b>;
<a name='L563'>      <b>if</b> ((*p)-&gt;executable != current-&gt;executable)      <i><font color='green'>// 如果executable 不等,也继续。</font></i>
<a name='L564'>        <b>continue</b>;
<a name='L565'>      <b>if</b> (<a href='../S/94.html#L467' title='Defined at 467 in mm/memory.c.'>try_to_share</a> (address, *p))   <i><font color='green'>// 尝试共享页面。</font></i>
<a name='L566'>        <b>return</b> 1;
<a name='L567'>    <font color='red'>}</font>
<a name='L568'>  <b>return</b> 0;
<a name='L569'><font color='red'>}</font>
<a name='L570'>
<a name='L571'><i><font color='green'>//// 页异常中断处理调用的函数。处理缺页异常情况。在page.s 程序中被调用。</font></i>
<a name='L572'><i><font color='green'>// 参数error_code 是由CPU 自动产生,address 是页面线性地址。</font></i>
<a name='L573'><b>void</b>
<a name='L574'><a href='../S/95.html#L34' title='Refered from 34 in mm/page.s.'>do_no_page</a> (<b>unsigned</b> <b>long</b> error_code, <b>unsigned</b> <b>long</b> address)
<a name='L575'><font color='red'>{</font>
<a name='L576'>  <b>int</b> nr[4];
<a name='L577'>  <b>unsigned</b> <b>long</b> tmp;
<a name='L578'>  <b>unsigned</b> <b>long</b> page;
<a name='L579'>  <b>int</b> block, <a href='../D/839.html' title='Multiple defined in 4 places.'>i</a>;
<a name='L580'>
<a name='L581'>  address &amp;= 0xfffff000;        <i><font color='green'>// 页面地址。</font></i>
<a name='L582'><i><font color='green'>// 首先算出指定线性地址在进程空间中相对于进程基址的偏移长度值。</font></i>
<a name='L583'>  tmp = address - current-&gt;start_code;
<a name='L584'><i><font color='green'>// 若当前进程的executable 空,或者指定地址超出代码+数据长度,则申请一页物理内存,并映射</font></i>
<a name='L585'><i><font color='green'>// 影射到指定的线性地址处。executable 是进程的i 节点结构。该值为0,表明进程刚开始设置,</font></i>
<a name='L586'><i><font color='green'>// 需要内存;而指定的线性地址超出代码加数据长度,表明进程在申请新的内存空间,也需要给予。</font></i>
<a name='L587'><i><font color='green'>// 因此就直接调用get_empty_page()函数,申请一页物理内存并映射到指定线性地址处即可。</font></i>
<a name='L588'><i><font color='green'>// start_code 是进程代码段地址,end_data 是代码加数据长度。对于linux 内核,它的代码段和</font></i>
<a name='L589'><i><font color='green'>// 数据段是起始基址是相同的。</font></i>
<a name='L590'>  <b>if</b> (!current-&gt;executable || tmp &gt;= current-&gt;end_data)
<a name='L591'>    <font color='red'>{</font>
<a name='L592'>      <a href='../S/94.html#L435' title='Defined at 435 in mm/memory.c.'>get_empty_page</a> (address);
<a name='L593'>      <b>return</b>;
<a name='L594'>    <font color='red'>}</font>
<a name='L595'><i><font color='green'>// 如果尝试共享页面成功,则退出。</font></i>
<a name='L596'>  <b>if</b> (<a href='../S/94.html#L546' title='Defined at 546 in mm/memory.c.'>share_page</a> (tmp))
<a name='L597'>    <b>return</b>;
<a name='L598'><i><font color='green'>// 取空闲页面,如果内存不够了,则显示内存不够,终止进程。</font></i>
<a name='L599'>  <b>if</b> (!(page = <a href='../S/94.html#L101' title='Defined at 101 in mm/memory.c.'>get_free_page</a> ()))
<a name='L600'>    <a href='../S/94.html#L49' title='Defined at 49 in mm/memory.c.'>oom</a> ();
<a name='L601'><i><font color='green'>/* remember that 1 block is used for header */</font></i>
<a name='L602'><i><font color='green'>/* 记住,(程序)头要使用1 个数据块 */</font></i>
<a name='L603'><i><font color='green'>// 首先计算缺页所在的数据块项。BLOCK_SIZE = 1024 字节,因此一页内存需要4 个数据块。</font></i>
<a name='L604'>  block = 1 + tmp / <a href='../D/23.html' title='Multiple defined in 2 places.'>BLOCK_SIZE</a>;
<a name='L605'><i><font color='green'>// 根据i 节点信息,取数据块在设备上的对应的逻辑块号。</font></i>
<a name='L606'>  <b>for</b> (<a href='../D/839.html' title='Multiple defined in 4 places.'>i</a> = 0; <a href='../D/839.html' title='Multiple defined in 4 places.'>i</a> &lt; 4; block++, <a href='../D/839.html' title='Multiple defined in 4 places.'>i</a>++)
<a name='L607'>    nr[<a href='../D/839.html' title='Multiple defined in 4 places.'>i</a>] = <a href='../S/12.html#L207' title='Defined at 207 in fs/inode.c.'>bmap</a> (current-&gt;executable, block);
<a name='L608'><i><font color='green'>// 读设备上一个页面的数据(4 个逻辑块)到指定物理地址page 处。</font></i>
<a name='L609'>  <a href='../S/6.html#L439' title='Defined at 439 in fs/buffer.c.'>bread_page</a> (page, current-&gt;executable-&gt;i_dev, nr);
<a name='L610'><i><font color='green'>// 在增加了一页内存后,该页内存的部分可能会超过进程的end_data 位置。下面的循环即是对物理</font></i>
<a name='L611'><i><font color='green'>// 页面超出的部分进行清零处理。</font></i>
<a name='L612'>  <a href='../D/839.html' title='Multiple defined in 4 places.'>i</a> = tmp + 4096 - current-&gt;end_data;
<a name='L613'>  tmp = page + 4096;
<a name='L614'>  <b>while</b> (<a href='../D/839.html' title='Multiple defined in 4 places.'>i</a>-- &gt; 0)
<a name='L615'>    <font color='red'>{</font>
<a name='L616'>      tmp--;
<a name='L617'>      *(<b>char</b> *) tmp = 0;
<a name='L618'>    <font color='red'>}</font>
<a name='L619'><i><font color='green'>// 如果把物理页面映射到指定线性地址的操作成功,就返回。否则就释放内存页,显示内存不够。</font></i>
<a name='L620'>  <b>if</b> (<a href='../S/94.html#L306' title='Defined at 306 in mm/memory.c.'>put_page</a> (page, address))
<a name='L621'>    <b>return</b>;
<a name='L622'>  <a href='../S/94.html#L130' title='Defined at 130 in mm/memory.c.'>free_page</a> (page);
<a name='L623'>  <a href='../S/94.html#L49' title='Defined at 49 in mm/memory.c.'>oom</a> ();
<a name='L624'><font color='red'>}</font>
<a name='L625'>
<a name='L626'><i><font color='green'>//// 物理内存初始化。</font></i>
<a name='L627'><i><font color='green'>// 参数:start_mem - 可用作分页处理的物理内存起始位置(已去除RAMDISK 所占内存空间等)。</font></i>
<a name='L628'><i><font color='green'>// end_mem - 实际物理内存最大地址。</font></i>
<a name='L629'><i><font color='green'>// 在该版的linux 内核中,最多能使用16Mb 的内存,大于16Mb 的内存将不于考虑,弃置不用。</font></i>
<a name='L630'><i><font color='green'>// 0 - 1Mb 内存空间用于内核系统(其实是0-640Kb)。</font></i>
<a name='L631'><b>void</b>
<a name='L632'><a href='../S/52.html#L170' title='Refered from 170 in init/main.c.'>mem_init</a> (<b>long</b> start_mem, <b>long</b> end_mem)
<a name='L633'><font color='red'>{</font>
<a name='L634'>  <b>int</b> <a href='../D/839.html' title='Multiple defined in 4 places.'>i</a>;
<a name='L635'>
<a name='L636'>  HIGH_MEMORY = end_mem;        <i><font color='green'>// 设置内存最高端。</font></i>
<a name='L637'>  <b>for</b> (<a href='../D/839.html' title='Multiple defined in 4 places.'>i</a> = 0; <a href='../D/839.html' title='Multiple defined in 4 places.'>i</a> &lt; <a href='../S/9

⌨️ 快捷键说明

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