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> < 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>]->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> < 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>]->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>]->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->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>)) >= 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->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->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->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 << 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'>// 地址 >= h 缓冲头的末端,也即要>=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>) >= ((<b>void</b> *) (h + 1)))
<a name='L534'> <font color='red'>{</font>
<a name='L535'> h->b_dev = 0; <i><font color='green'>// 使用该缓冲区的设备号。</font></i>
<a name='L536'> h->b_dirt = 0; <i><font color='green'>// 脏标志,也即缓冲区修改标志。</font></i>
<a name='L537'> h->b_count = 0; <i><font color='green'>// 该缓冲区引用计数。</font></i>
<a name='L538'> h->b_lock = 0; <i><font color='green'>// 缓冲区锁定标志。</font></i>
<a name='L539'> h->b_uptodate = 0; <i><font color='green'>// 缓冲区更新标志(或称数据有效标志)。</font></i>
<a name='L540'> h->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->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->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->b_data = (<b>char</b> *) b; <i><font color='green'>// 指向对应缓冲区数据块(1024 字节)。</font></i>
<a name='L544'> h->b_prev_free = h - 1; <i><font color='green'>// 指向链表中前一项。</font></i>
<a name='L545'> h->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->b_prev_free = h; <i><font color='green'>// 链表头的b_prev_free 指向前一项(即最后一项)。</font></i>
<a name='L554'> h->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> < <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'>/* [<][>]<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 + -
显示快捷键?