6.html

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

HTML
596
字号
<a name='L417'>
<a name='L418'><i><font color='green'>//// 复制内存块。</font></i>
<a name='L419'><i><font color='green'>// 从from 地址复制一块数据到to 位置。</font></i>
<a name='L420'><font color='darkred'>#define</font> <a href='../S/6.html#L461' title='Refered from 461 in fs/buffer.c.'>COPYBLK</a>(from,to) \
<a name='L421'><b>__asm__</b>( "cld\n\t" \
<a name='L422'>"rep\n\t" \
<a name='L423'>"movsl\n\t" \
<a name='L424'>:: "c" (<a href='../D/23.html' title='Multiple defined in 2 places.'>BLOCK_SIZE</a>/4), "S" (from), "D" (to) \
<a name='L425'>: "cx", "di", "si")
<a name='L426'>
<a name='L427'><i><font color='green'>/*</font></i>
<a name='L428'><i><font color='green'>* bread_page reads four buffers into memory at the desired address. It's</font></i>
<a name='L429'><i><font color='green'>* a function of its own, as there is some speed to be got by reading them</font></i>
<a name='L430'><i><font color='green'>* all at the same time, not waiting for one to be read, and then another</font></i>
<a name='L431'><i><font color='green'>* etc.</font></i>
<a name='L432'><i><font color='green'>*/</font></i>
<a name='L433'><i><font color='green'>/*</font></i>
<a name='L434'><i><font color='green'>* bread_page 一次读四个缓冲块内容读到内存指定的地址。它是一个完整的函数,</font></i>
<a name='L435'><i><font color='green'>* 因为同时读取四块可以获得速度上的好处,不用等着读一块,再读一块了。</font></i>
<a name='L436'><i><font color='green'>*/</font></i>
<a name='L437'><i><font color='green'>//// 读设备上一个页面(4 个缓冲块)的内容到内存指定的地址。</font></i>
<a name='L438'><b>void</b>
<a name='L439'><a href='../R/391.html' title='Multiple refered from 2 places.'>bread_page</a> (<b>unsigned</b> <b>long</b> address, <b>int</b> dev, <b>int</b> b[4])
<a name='L440'><font color='red'>{</font>
<a name='L441'>  <b>struct</b> buffer_head *bh[4];
<a name='L442'>  <b>int</b> <a href='../D/839.html' title='Multiple defined in 4 places.'>i</a>;
<a name='L443'>
<a name='L444'><i><font color='green'>// 循环执行4 次,读一页内容。</font></i>
<a name='L445'>  <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; <a href='../D/839.html' title='Multiple defined in 4 places.'>i</a>++)
<a name='L446'>    <b>if</b> (b[<a href='../D/839.html' title='Multiple defined in 4 places.'>i</a>])
<a name='L447'>      <font color='red'>{</font>
<a name='L448'><i><font color='green'>// 取高速缓冲中指定设备和块号的缓冲区,如果该缓冲区数据无效则产生读设备请求。</font></i>
<a name='L449'>        <b>if</b> (bh[<a href='../D/839.html' title='Multiple defined in 4 places.'>i</a>] = <a href='../S/6.html#L301' title='Defined at 301 in fs/buffer.c.'>getblk</a> (<a href='../S/7.html#L136' title='Defined at 136 in fs/char_dev.c.'>dev</a>, b[<a href='../D/839.html' title='Multiple defined in 4 places.'>i</a>]))
<a name='L450'>          <b>if</b> (!bh[<a href='../D/839.html' title='Multiple defined in 4 places.'>i</a>]-&gt;b_uptodate)
<a name='L451'>            <a href='../S/57.html#L204' title='Defined at 204 in kernel/blk_drv/ll_rw_blk.c.'>ll_rw_block</a> (<a href='../S/31.html#L42' title='Defined at 42 in include/linux/fs.h.'>READ</a>, bh[<a href='../D/839.html' title='Multiple defined in 4 places.'>i</a>]);
<a name='L452'>      <font color='red'>}</font>
<a name='L453'>    <b>else</b>
<a name='L454'>      bh[<a href='../D/839.html' title='Multiple defined in 4 places.'>i</a>] = <a href='../D/261.html' title='Multiple defined in 12 places.'>NULL</a>;
<a name='L455'><i><font color='green'>// 将4 块缓冲区上的内容顺序复制到指定地址处。</font></i>
<a name='L456'>  <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; <a href='../D/839.html' title='Multiple defined in 4 places.'>i</a>++, address += <a href='../D/23.html' title='Multiple defined in 2 places.'>BLOCK_SIZE</a>)
<a name='L457'>    <b>if</b> (bh[<a href='../D/839.html' title='Multiple defined in 4 places.'>i</a>])
<a name='L458'>      <font color='red'>{</font>
<a name='L459'>        <a href='../S/6.html#L64' title='Defined at 64 in fs/buffer.c.'>wait_on_buffer</a> (bh[<a href='../D/839.html' title='Multiple defined in 4 places.'>i</a>]); <i><font color='green'>// 等待缓冲区解锁(如果已被上锁的话)。</font></i>
<a name='L460'>        <b>if</b> (bh[<a href='../D/839.html' title='Multiple defined in 4 places.'>i</a>]-&gt;b_uptodate)  <i><font color='green'>// 如果该缓冲区中数据有效的话,则复制。</font></i>
<a name='L461'>          <a href='../S/6.html#L420' title='Defined at 420 in fs/buffer.c.'>COPYBLK</a> ((<b>unsigned</b> <b>long</b>) bh[<a href='../D/839.html' title='Multiple defined in 4 places.'>i</a>]-&gt;b_data, address);
<a name='L462'>        <a href='../S/6.html#L377' title='Defined at 377 in fs/buffer.c.'>brelse</a> (bh[<a href='../D/839.html' title='Multiple defined in 4 places.'>i</a>]);         <i><font color='green'>// 释放该缓冲区。</font></i>
<a name='L463'>      <font color='red'>}</font>
<a name='L464'><font color='red'>}</font>
<a name='L465'>
<a name='L466'><i><font color='green'>/*</font></i>
<a name='L467'><i><font color='green'>* Ok, breada can be used as bread, but additionally to mark other</font></i>
<a name='L468'><i><font color='green'>* blocks for reading as well. End the argument list with a negative</font></i>
<a name='L469'><i><font color='green'>* number.</font></i>
<a name='L470'><i><font color='green'>*/</font></i>
<a name='L471'><i><font color='green'>/*</font></i>
<a name='L472'><i><font color='green'>* OK,breada 可以象bread 一样使用,但会另外预读一些块。该函数参数列表</font></i>
<a name='L473'><i><font color='green'>* 需要使用一个负数来表明参数列表的结束。</font></i>
<a name='L474'><i><font color='green'>*/</font></i>
<a name='L475'><i><font color='green'>//// 从指定设备读取指定的一些块。</font></i>
<a name='L476'><i><font color='green'>// 成功时返回第1 块的缓冲区头指针,否则返回NULL。</font></i>
<a name='L477'><b>struct</b> buffer_head *
<a name='L478'><a href='../R/392.html' title='Multiple refered from 5 places.'>breada</a> (<b>int</b> dev, <b>int</b> first, ...)
<a name='L479'><font color='red'>{</font>
<a name='L480'>  <a href='../S/40.html#L4' title='Defined at 4 in include/stdarg.h.'>va_list</a> args;
<a name='L481'>  <b>struct</b> buffer_head *bh, *tmp;
<a name='L482'>
<a name='L483'><i><font color='green'>// 取可变参数表中第1 个参数(块号)。</font></i>
<a name='L484'>  <a href='../D/1107.html' title='Multiple defined in 2 places.'>va_start</a> (args, first);
<a name='L485'><i><font color='green'>// 取高速缓冲中指定设备和块号的缓冲区。如果该缓冲区数据无效,则发出读设备数据块请求。</font></i>
<a name='L486'>  <b>if</b> (!(bh = <a href='../S/6.html#L301' title='Defined at 301 in fs/buffer.c.'>getblk</a> (<a href='../S/7.html#L136' title='Defined at 136 in fs/char_dev.c.'>dev</a>, first)))
<a name='L487'>    <a href='../S/72.html#L24' title='Defined at 24 in kernel/panic.c.'>panic</a> ("bread: getblk returned NULL\n");
<a name='L488'>  <b>if</b> (!bh-&gt;b_uptodate)
<a name='L489'>    <a href='../S/57.html#L204' title='Defined at 204 in kernel/blk_drv/ll_rw_blk.c.'>ll_rw_block</a> (<a href='../S/31.html#L42' title='Defined at 42 in include/linux/fs.h.'>READ</a>, bh);
<a name='L490'><i><font color='green'>// 然后顺序取可变参数表中其它预读块号,并作与上面同样处理,但不引用。</font></i>
<a name='L491'>  <b>while</b> ((first = <a href='../S/40.html#L40' title='Defined at 40 in include/stdarg.h.'>va_arg</a> (args, <b>int</b>)) &gt;= 0)
<a name='L492'>    <font color='red'>{</font>
<a name='L493'>      tmp = <a href='../S/6.html#L301' title='Defined at 301 in fs/buffer.c.'>getblk</a> (<a href='../S/7.html#L136' title='Defined at 136 in fs/char_dev.c.'>dev</a>, first);
<a name='L494'>      <b>if</b> (tmp)
<a name='L495'>        <font color='red'>{</font>
<a name='L496'>          <b>if</b> (!tmp-&gt;b_uptodate)
<a name='L497'>            <a href='../S/57.html#L204' title='Defined at 204 in kernel/blk_drv/ll_rw_blk.c.'>ll_rw_block</a> (<a href='../S/31.html#L44' title='Defined at 44 in include/linux/fs.h.'>READA</a>, bh);
<a name='L498'>          tmp-&gt;b_count--;
<a name='L499'>        <font color='red'>}</font>
<a name='L500'>    <font color='red'>}</font>
<a name='L501'><i><font color='green'>// 可变参数表中所有参数处理完毕。等待第1 个缓冲区解锁(如果已被上锁)。</font></i>
<a name='L502'>  <a href='../S/40.html#L32' title='Defined at 32 in include/stdarg.h.'>va_end</a> (args);
<a name='L503'>  <a href='../S/6.html#L64' title='Defined at 64 in fs/buffer.c.'>wait_on_buffer</a> (bh);
<a name='L504'><i><font color='green'>// 如果缓冲区中数据有效,则返回缓冲区头指针,退出。否则释放该缓冲区,返回NULL,退出。</font></i>
<a name='L505'>  <b>if</b> (bh-&gt;b_uptodate)
<a name='L506'>    <b>return</b> bh;
<a name='L507'>  <a href='../S/6.html#L377' title='Defined at 377 in fs/buffer.c.'>brelse</a> (bh);
<a name='L508'>  <b>return</b> (<a href='../D/261.html' title='Multiple defined in 12 places.'>NULL</a>);
<a name='L509'><font color='red'>}</font>
<a name='L510'>
<a name='L511'><i><font color='green'>//// 缓冲区初始化函数。</font></i>
<a name='L512'><i><font color='green'>// 参数buffer_end 是指定的缓冲区内存的末端。对于系统有16MB 内存,则缓冲区末端设置为4MB。</font></i>
<a name='L513'><i><font color='green'>// 对于系统有8MB 内存,缓冲区末端设置为2MB。</font></i>
<a name='L514'><b>void</b>
<a name='L515'><a href='../R/395.html' title='Multiple refered from 2 places.'>buffer_init</a> (<b>long</b> buffer_end)
<a name='L516'><font color='red'>{</font>
<a name='L517'>  <b>struct</b> buffer_head *h = start_buffer;
<a name='L518'>  <b>void</b> *b;
<a name='L519'>  <b>int</b> <a href='../D/839.html' title='Multiple defined in 4 places.'>i</a>;
<a name='L520'>
<a name='L521'><i><font color='green'>// 如果缓冲区高端等于1Mb,则由于从640KB-1MB 被显示内存和BIOS 占用,因此实际可用缓冲区内存</font></i>
<a name='L522'><i><font color='green'>// 高端应该是640KB。否则内存高端一定大于1MB。</font></i>
<a name='L523'>  <b>if</b> (buffer_end == 1 &lt;&lt; 20)
<a name='L524'>    b = (<b>void</b> *) (640 * 1024);
<a name='L525'>  <b>else</b>
<a name='L526'>    b = (<b>void</b> *) buffer_end;
<a name='L527'><i><font color='green'>// 这段代码用于初始化缓冲区,建立空闲缓冲区环链表,并获取系统中缓冲块的数目。</font></i>
<a name='L528'><i><font color='green'>// 操作的过程是从缓冲区高端开始划分1K 大小的缓冲块,与此同时在缓冲区低端建立描述该缓冲块</font></i>
<a name='L529'><i><font color='green'>// 的结构buffer_head,并将这些buffer_head 组成双向链表。</font></i>
<a name='L530'><i><font color='green'>// h 是指向缓冲头结构的指针,而h+1 是指向内存地址连续的下一个缓冲头地址,也可以说是指向h</font></i>
<a name='L531'><i><font color='green'>// 缓冲头的末端外。为了保证有足够长度的内存来存储一个缓冲头结构,需要b 所指向的内存块</font></i>
<a name='L532'><i><font color='green'>// 地址 &gt;= h 缓冲头的末端,也即要&gt;=h+1。</font></i>
<a name='L533'>  <b>while</b> ((b -= <a href='../D/23.html' title='Multiple defined in 2 places.'>BLOCK_SIZE</a>) &gt;= ((<b>void</b> *) (h + 1)))
<a name='L534'>    <font color='red'>{</font>
<a name='L535'>      h-&gt;b_dev = 0;             <i><font color='green'>// 使用该缓冲区的设备号。</font></i>
<a name='L536'>      h-&gt;b_dirt = 0;            <i><font color='green'>// 脏标志,也即缓冲区修改标志。</font></i>
<a name='L537'>      h-&gt;b_count = 0;           <i><font color='green'>// 该缓冲区引用计数。</font></i>
<a name='L538'>      h-&gt;b_lock = 0;            <i><font color='green'>// 缓冲区锁定标志。</font></i>
<a name='L539'>      h-&gt;b_uptodate = 0;        <i><font color='green'>// 缓冲区更新标志(或称数据有效标志)。</font></i>
<a name='L540'>      h-&gt;b_wait = <a href='../D/261.html' title='Multiple defined in 12 places.'>NULL</a>;         <i><font color='green'>// 指向等待该缓冲区解锁的进程。</font></i>
<a name='L541'>      h-&gt;b_next = <a href='../D/261.html' title='Multiple defined in 12 places.'>NULL</a>;         <i><font color='green'>// 指向具有相同hash 值的下一个缓冲头。</font></i>
<a name='L542'>      h-&gt;b_prev = <a href='../D/261.html' title='Multiple defined in 12 places.'>NULL</a>;         <i><font color='green'>// 指向具有相同hash 值的前一个缓冲头。</font></i>
<a name='L543'>      h-&gt;b_data = (<b>char</b> *) b;   <i><font color='green'>// 指向对应缓冲区数据块(1024 字节)。</font></i>
<a name='L544'>      h-&gt;b_prev_free = h - 1;   <i><font color='green'>// 指向链表中前一项。</font></i>
<a name='L545'>      h-&gt;b_next_free = h + 1;   <i><font color='green'>// 指向链表中下一项。</font></i>
<a name='L546'>      h++;                      <i><font color='green'>// h 指向下一新缓冲头位置。</font></i>
<a name='L547'>      <a href='../S/31.html#L64' title='Defined at 64 in include/linux/fs.h.'>NR_BUFFERS</a>++;             <i><font color='green'>// 缓冲区块数累加。</font></i>
<a name='L548'>      <b>if</b> (b == (<b>void</b> *) 0x100000)       <i><font color='green'>// 如果地址b 递减到等于1MB,则跳过384KB,</font></i>
<a name='L549'>        b = (<b>void</b> *) 0xA0000;   <i><font color='green'>// 让b 指向地址0xA0000(640KB)处。</font></i>
<a name='L550'>    <font color='red'>}</font>
<a name='L551'>  h--;                          <i><font color='green'>// 让h 指向最后一个有效缓冲头。</font></i>
<a name='L552'>  free_list = start_buffer;     <i><font color='green'>// 让空闲链表头指向头一个缓冲区头。</font></i>
<a name='L553'>  free_list-&gt;b_prev_free = h;   <i><font color='green'>// 链表头的b_prev_free 指向前一项(即最后一项)。</font></i>
<a name='L554'>  h-&gt;b_next_free = free_list;   <i><font color='green'>// h 的下一项指针指向第一项,形成一个环链。</font></i>
<a name='L555'><i><font color='green'>// 初始化hash 表(哈希表、散列表),置表中所有的指针为NULL。</font></i>
<a name='L556'>  <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/31.html#L63' title='Defined at 63 in include/linux/fs.h.'>NR_HASH</a>; <a href='../D/839.html' title='Multiple defined in 4 places.'>i</a>++)
<a name='L557'>    hash_table[<a href='../D/839.html' title='Multiple defined in 4 places.'>i</a>] = <a href='../D/261.html' title='Multiple defined in 12 places.'>NULL</a>;
<a name='L558'><font color='red'>}</font>
</pre>
<hr>
<a name='BOTTOM'>
<i><font color='green'>/* [&lt;][&gt;]<a href='#L64'>[^]</a><a href='#L515'>[v]</a><a href='#TOP'>[top]</a>[bottom]<a href='../mains.html'>[index]</a><a href='../help.html'>[help]</a> */</font></i>
</body>
</html>

⌨️ 快捷键说明

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