74.html
来自「linux 0.11中文版 有注释」· HTML 代码 · 共 632 行 · 第 1/4 页
HTML
632 行
<a name='L278'> <font color='red'>}</font>
<a name='L279'><font color='red'>}</font>
<a name='L280'>
<a name='L281'><i><font color='green'>/*</font></i>
<a name='L282'><i><font color='green'> * OK, here are some floppy things that shouldn't be in the kernel</font></i>
<a name='L283'><i><font color='green'> * proper. They are here because the floppy needs a timer, and this</font></i>
<a name='L284'><i><font color='green'> * was the easiest way of doing it.</font></i>
<a name='L285'><i><font color='green'> */</font></i>
<a name='L286'><i><font color='green'>/*</font></i>
<a name='L287'><i><font color='green'> * 好了,从这里开始是一些有关软盘的子程序,本不应该放在内核的主要部分中的。将它们放在这里</font></i>
<a name='L288'><i><font color='green'> * 是因为软驱需要一个时钟,而放在这里是最方便的办法。</font></i>
<a name='L289'><i><font color='green'> */</font></i>
<a name='L290'><b>static</b> <b>struct</b> task_struct *wait_motor[4] = <font color='red'>{</font> <a href='../D/261.html' title='Multiple defined in 12 places.'>NULL</a>, <a href='../D/261.html' title='Multiple defined in 12 places.'>NULL</a>, <a href='../D/261.html' title='Multiple defined in 12 places.'>NULL</a>, <a href='../D/261.html' title='Multiple defined in 12 places.'>NULL</a> <font color='red'>}</font>;
<a name='L291'><b>static</b> <b>int</b> mon_timer[4] = <font color='red'>{</font> 0, 0, 0, 0 <font color='red'>}</font>;
<a name='L292'><b>static</b> <b>int</b> moff_timer[4] = <font color='red'>{</font> 0, 0, 0, 0 <font color='red'>}</font>;
<a name='L293'><b>unsigned</b> <b>char</b> current_DOR = 0x0C; <i><font color='green'>// 数字输出寄存器(初值:允许DMA 和请求中断、启动FDC)。</font></i>
<a name='L294'>
<a name='L295'><i><font color='green'>// 指定软盘到正常运转状态所需延迟滴答数(时间)。</font></i>
<a name='L296'><i><font color='green'>// nr -- 软驱号(0-3),返回值为滴答数。</font></i>
<a name='L297'><b>int</b>
<a name='L298'><a href='../R/701.html' title='Multiple refered from 3 places.'>ticks_to_floppy_on</a> (<b>unsigned</b> <b>int</b> nr)
<a name='L299'><font color='red'>{</font>
<a name='L300'> <b>extern</b> <b>unsigned</b> <b>char</b> selected; <i><font color='green'>// 当前选中的软盘号(kernel/blk_drv/floppy.c,122)。</font></i>
<a name='L301'> <b>unsigned</b> <b>char</b> mask = 0x10 << nr; <i><font color='green'>// 所选软驱对应数字输出寄存器中启动马达比特位。</font></i>
<a name='L302'>
<a name='L303'> <b>if</b> (nr > 3)
<a name='L304'> <a href='../S/72.html#L24' title='Defined at 24 in kernel/panic.c.'>panic</a> ("floppy_on: nr>3"); <i><font color='green'>// 最多4 个软驱。</font></i>
<a name='L305'> moff_timer[nr] = 10000; <i><font color='green'>/* 100 s = very big :-) */</font></i>
<a name='L306'> <a href='../S/25.html#L15' title='Defined at 15 in include/asm/system.h.'>cli</a> (); <i><font color='green'>/* use floppy_off to turn it off */</font></i>
<a name='L307'> mask |= current_DOR;
<a name='L308'> <i><font color='green'>// 如果不是当前软驱,则首先复位其它软驱的选择位,然后置对应软驱选择位。</font></i>
<a name='L309'> <b>if</b> (!selected)
<a name='L310'> <font color='red'>{</font>
<a name='L311'> mask &= 0xFC;
<a name='L312'> mask |= nr;
<a name='L313'> <font color='red'>}</font>
<a name='L314'> <i><font color='green'>// 如果数字输出寄存器的当前值与要求的值不同,则向FDC 数字输出端口输出新值(mask)。并且如果</font></i>
<a name='L315'> <i><font color='green'>// 要求启动的马达还没有启动,则置相应软驱的马达启动定时器值(HZ/2 = 0.5 秒或50 个滴答)。</font></i>
<a name='L316'> <i><font color='green'>// 此后更新当前数字输出寄存器值current_DOR。</font></i>
<a name='L317'> <b>if</b> (mask != current_DOR)
<a name='L318'> <font color='red'>{</font>
<a name='L319'> <a href='../S/22.html#L3' title='Defined at 3 in include/asm/io.h.'>outb</a> (mask, FD_DOR);
<a name='L320'> <b>if</b> ((mask ^ current_DOR) & 0xf0)
<a name='L321'> mon_timer[nr] = <a href='../S/36.html#L5' title='Defined at 5 in include/linux/sched.h.'>HZ</a> / 2;
<a name='L322'> <b>else</b> <b>if</b> (mon_timer[nr] < 2)
<a name='L323'> mon_timer[nr] = 2;
<a name='L324'> current_DOR = mask;
<a name='L325'> <font color='red'>}</font>
<a name='L326'> <a href='../S/25.html#L14' title='Defined at 14 in include/asm/system.h.'>sti</a> ();
<a name='L327'> <b>return</b> mon_timer[nr];
<a name='L328'><font color='red'>}</font>
<a name='L329'>
<a name='L330'><i><font color='green'>// 等待指定软驱马达启动所需时间。</font></i>
<a name='L331'><b>void</b>
<a name='L332'><a href='../R/460.html' title='Multiple refered from 3 places.'>floppy_on</a> (<b>unsigned</b> <b>int</b> nr)
<a name='L333'><font color='red'>{</font>
<a name='L334'> <a href='../S/25.html#L15' title='Defined at 15 in include/asm/system.h.'>cli</a> (); <i><font color='green'>// 关中断。</font></i>
<a name='L335'> <b>while</b> (<a href='../S/74.html#L298' title='Defined at 298 in kernel/sched.c.'>ticks_to_floppy_on</a> (nr)) <i><font color='green'>// 如果马达启动定时还没到,就一直把当前进程置</font></i>
<a name='L336'> <a href='../S/74.html#L219' title='Defined at 219 in kernel/sched.c.'>sleep_on</a> (nr + wait_motor); <i><font color='green'>// 为不可中断睡眠状态并放入等待马达运行的队列中。</font></i>
<a name='L337'> <a href='../S/25.html#L14' title='Defined at 14 in include/asm/system.h.'>sti</a> (); <i><font color='green'>// 开中断。</font></i>
<a name='L338'><font color='red'>}</font>
<a name='L339'>
<a name='L340'><i><font color='green'>// 置关闭相应软驱马达停转定时器(3 秒)。</font></i>
<a name='L341'><b>void</b>
<a name='L342'><a href='../R/459.html' title='Multiple refered from 4 places.'>floppy_off</a> (<b>unsigned</b> <b>int</b> nr)
<a name='L343'><font color='red'>{</font>
<a name='L344'> moff_timer[nr] = 3 * <a href='../S/36.html#L5' title='Defined at 5 in include/linux/sched.h.'>HZ</a>;
<a name='L345'><font color='red'>}</font>
<a name='L346'>
<a name='L347'><i><font color='green'>// 软盘定时处理子程序。更新马达启动定时值和马达关闭停转计时值。该子程序是在时钟定时</font></i>
<a name='L348'><i><font color='green'>// 中断中被调用,因此每一个滴答(10ms)被调用一次,更新马达开启或停转定时器的值。如果某</font></i>
<a name='L349'><i><font color='green'>// 一个马达停转定时到,则将数字输出寄存器马达启动位复位。</font></i>
<a name='L350'><b>void</b>
<a name='L351'><a href='../S/74.html#L471' title='Refered from 471 in kernel/sched.c.'>do_floppy_timer</a> (<b>void</b>)
<a name='L352'><font color='red'>{</font>
<a name='L353'> <b>int</b> <a href='../D/839.html' title='Multiple defined in 4 places.'>i</a>;
<a name='L354'> <b>unsigned</b> <b>char</b> mask = 0x10;
<a name='L355'>
<a name='L356'> <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>++, mask <<= 1)
<a name='L357'> <font color='red'>{</font>
<a name='L358'> <b>if</b> (!(mask & current_DOR)) <i><font color='green'>// 如果不是DOR 指定的马达则跳过。</font></i>
<a name='L359'> <b>continue</b>;
<a name='L360'> <b>if</b> (mon_timer[<a href='../D/839.html' title='Multiple defined in 4 places.'>i</a>])
<a name='L361'> <font color='red'>{</font>
<a name='L362'> <b>if</b> (!--mon_timer[<a href='../D/839.html' title='Multiple defined in 4 places.'>i</a>])
<a name='L363'> <a href='../S/74.html#L272' title='Defined at 272 in kernel/sched.c.'>wake_up</a> (<a href='../D/839.html' title='Multiple defined in 4 places.'>i</a> + wait_motor); <i><font color='green'>// 如果马达启动定时到则唤醒进程。</font></i>
<a name='L364'> <font color='red'>}</font>
<a name='L365'> <b>else</b> <b>if</b> (!moff_timer[<a href='../D/839.html' title='Multiple defined in 4 places.'>i</a>])
<a name='L366'> <font color='red'>{</font> <i><font color='green'>// 如果马达停转定时到则</font></i>
<a name='L367'> current_DOR &= ~mask; <i><font color='green'>// 复位相应马达启动位,并</font></i>
<a name='L368'> <a href='../S/22.html#L3' title='Defined at 3 in include/asm/io.h.'>outb</a> (current_DOR, FD_DOR); <i><font color='green'>// 更新数字输出寄存器。</font></i>
<a name='L369'> <font color='red'>}</font>
<a name='L370'> <b>else</b>
<a name='L371'> moff_timer[<a href='../D/839.html' title='Multiple defined in 4 places.'>i</a>]--; <i><font color='green'>// 马达停转计时递减。</font></i>
<a name='L372'> <font color='red'>}</font>
<a name='L373'><font color='red'>}</font>
<a name='L374'>
<a name='L375'><font color='darkred'>#define</font> <a href='../R/269.html' title='Multiple refered from 3 places.'>TIME_REQUESTS</a> 64 <i><font color='green'>// 最多可有64 个定时器链表(64 个任务)。</font></i>
<a name='L376'>
<a name='L377'><i><font color='green'>// 定时器链表结构和定时器数组。</font></i>
<a name='L378'><b>static</b> <b>struct</b> timer_list
<a name='L379'><font color='red'>{</font>
<a name='L380'> <b>long</b> jiffies; <i><font color='green'>// 定时滴答数。</font></i>
<a name='L381'> <b>void</b> (*fn) (); <i><font color='green'>// 定时处理程序。</font></i>
<a name='L382'> <b>struct</b> timer_list *next; <i><font color='green'>// 下一个定时器。</font></i>
<a name='L383'><font color='red'>}</font>
<a name='L384'>timer_list[<a href='../S/74.html#L375' title='Defined at 375 in kernel/sched.c.'>TIME_REQUESTS</a>], *next_timer = <a href='../D/261.html' title='Multiple defined in 12 places.'>NULL</a>;
<a name='L385'>
<a name='L386'><i><font color='green'>// 添加定时器。输入参数为指定的定时值(滴答数)和相应的处理程序指针。</font></i>
<a name='L387'><i><font color='green'>// jiffies – 以10 毫秒计的滴答数;*fn()- 定时时间到时执行的函数。</font></i>
<a name='L388'><b>void</b>
<a name='L389'><a href='../R/383.html' title='Multiple refered from 3 places.'>add_timer</a> (<b>long</b> jiffies, <b>void</b> (*fn) (<b>void</b>))
<a name='L390'><font color='red'>{</font>
<a name='L391'> <b>struct</b> timer_list *p;
<a name='L392'>
<a name='L393'> <i><font color='green'>// 如果定时处理程序指针为空,则退出。</font></i>
<a name='L394'> <b>if</b> (!fn)
<a name='L395'> <b>return</b>;
<a name='L396'> <a href='../S/25.html#L15' title='Defined at 15 in include/asm/system.h.'>cli</a> ();
<a name='L397'> <i><font color='green'>// 如果定时值<=0,则立刻调用其处理程序。并且该定时器不加入链表中。</font></i>
<a name='L398'> <b>if</b> (jiffies <= 0)
<a name='L399'> (fn) ();
<a name='L400'> <b>else</b>
<a name='L401'> <font color='red'>{</font>
<a name='L402'> <i><font color='green'>// 从定时器数组中,找一个空闲项。</font></i>
<a name='L403'> <b>for</b> (p = timer_list; p < timer_list + <a href='../S/74.html#L375' title='Defined at 375 in kernel/sched.c.'>TIME_REQUESTS</a>; p++)
<a name='L404'> <b>if</b> (!p->fn)
<a name='L405'> <b>break</b>;
<a name='L406'> <i><font color='green'>// 如果已经用完了定时器数组,则系统崩溃?。</font></i>
<a name='L407'> <b>if</b> (p >= timer_list + <a href='../S/74.html#L375' title='Defined at 375 in kernel/sched.c.'>TIME_REQUESTS</a>)
<a name='L408'> <a href='../S/72.html#L24' title='Defined at 24 in kernel/panic.c.'>panic</a> ("No more time requests free");
<a name='L409'> <i><font color='green'>// 向定时器数据结构填入相应信息。并链入链表头</font></i>
<a name='L410'> p->fn = fn;
<a name='L411'> p->jiffies = jiffies;
<a name='L412'> p->next = next_timer;
<a name='L413'> next_timer = p;
<a name='L414'> <i><font color='green'>// 链表项按定时值从小到大排序。在排序时减去排在前面需要的滴答数,这样在处理定时器时只要</font></i>
<a name='L415'> <i><font color='green'>// 查看链表头的第一项的定时是否到期即可。[[?? 这段程序好象没有考虑周全。如果新插入的定时</font></i>
<a name='L416'> <i><font color='green'>// 器值 < 原来头一个定时器值时,也应该将所有后面的定时值均减去新的第1 个的定时值。]]</font></i>
<a name='L417'> <b>while</b> (p->next && p->next->jiffies < p->jiffies)
<a name='L418'> <font color='red'>{</font>
<a name='L419'> p->jiffies -= p->next->jiffies;
<a name='L420'> fn = p->fn;
<a name='L421'> p->fn = p->next->fn;
<a name='L422'> p->next->fn = fn;
<a name='L423'> jiffies = p->jiffies;
<a name='L424'> p->jiffies = p->next->jiffies;
<a name='L425'> p->next->jiffies = jiffies;
<a name='L426'> p = p->next;
<a name='L427'> <font color='red'>}</font>
<a name='L428'> <font color='red'>}</font>
<a name='L429'> <a href='../S/25.html#L14' title='Defined at 14 in include/asm/system.h.'>sti</a> ();
<a name='L430'><font color='red'>}</font>
<a name='L431'>
<a name='L432'><i><font color='green'>//// 时钟中断C 函数处理程序,在kernel/system_call.s 中的_timer_interrupt(176 行)被调用。</font></i>
<a name='L433'><i><font color='green'>// 参数cpl 是当前特权级0 或3,0 表示内核代码在执行。</font></i>
<a name='L434'><i><font color='green'>// 对于一个进程由于执行时间片用完时,则进行任务切换。并执行一个计时更新工作。</font></i>
<a name='L435'><b>void</b>
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?