����8-5 linux/kernel/sched.c


  1 /*

  2  *  linux/kernel/sched.c

  3  *

  4  *  (C) 1991  Linus Torvalds

  5  */

  6

  7 /*

  8  * 'sched.c' is the main kernel file. It contains scheduling primitives

  9  * (sleep_on, wakeup, schedule etc) as well as a number of simple system

 10  * call functions (type getpid(), which just extracts a field from

 11  * current-task

 12  */

    /*

     * 'sched.c'����Ҫ���ں��ļ������а����йص��ȵĻ�������(sleep_on��wakeup��schedule��)

     * �Լ�һЩ�򵥵�ϵͳ���ú���������getpid()�����ӵ�ǰ�����л�ȡһ���ֶΣ���

     */

 

    // �����ǵ��ȳ���ͷ�ļ�������������ṹtask_struct����1����ʼ��������ݡ�����һЩ�Ժ�

    // ����ʽ������й��������������úͻ�ȡ��Ƕ��ʽ��ຯ������

 13 #include <linux/sched.h>

 14 #include <linux/kernel.h> // �ں�ͷ�ļ�������һЩ�ں˳��ú�����ԭ�ζ��塣

 15 #include <linux/sys.h>    // ϵͳ����ͷ�ļ�������82��ϵͳ����C��������,��'sys_'��ͷ��

 16 #include <linux/fdreg.h>  // ����ͷ�ļ����������̿�����������һЩ���塣

 17 #include <asm/system.h>   // ϵͳͷ�ļ������������û��޸�������/�ж��ŵȵ�Ƕ��ʽ���ꡣ

 18 #include <asm/io.h>       // ioͷ�ļ�������Ӳ���˿�����/���������䡣

 19 #include <asm/segment.h>  // �β���ͷ�ļ����������йضμĴ���������Ƕ��ʽ��ຯ����

 20

 21 #include <signal.h>       // �ź�ͷ�ļ��������źŷ��ų�����sigaction�ṹ����������ԭ�͡�

 22

    // �ú�ȡ�ź�nr���ź�λͼ�ж�Ӧλ�Ķ�������ֵ���źű��1-32�������ź�5��λͼ��ֵ����

    // 1<<(5-1) = 16 = 00010000b��

 23 #define _S(nr) (1<<((nr)-1))

    // ����SIGKILL��SIGSTOP�ź����������źŶ��ǿ�������(��1011,1111,1110,1111,1111b)��

 24 #define _BLOCKABLE (~(_S(SIGKILL) | _S(SIGSTOP)))

 25

    // �ں˵��Ժ�������ʾ�����nr�Ľ��̺š�����״̬���ں˶�ջ�����ֽ�������Լ����

 26 void show_task(int nr,struct task_struct * p)

 27 {

 28         int i,j = 4096-sizeof(struct task_struct);

 29

 30         printk("%d: pid=%d, state=%d, father=%d, child=%d, ",nr,p->pid,

 31                 p->state, p->p_pptr->pid, p->p_cptr ? p->p_cptr->pid : -1);

 32         i=0;

 33         while (i<j && !((char *)(p+1))[i])  // ���ָ���������ݽṹ�Ժ����0���ֽ�����

 34                 i++;

 35         printk("%d/%d chars free in kstack\n\r",i,j);

 36         printk("   PC=%08X.", *(1019 + (unsigned long *) p));

 37         if (p->p_ysptr || p->p_osptr)

 38                 printk("   Younger sib=%d, older sib=%d\n\r",

 39                         p->p_ysptr ? p->p_ysptr->pid : -1,

 40                         p->p_osptr ? p->p_osptr->pid : -1);

 41         else

 42                 printk("\n\r");

 43 }

 44

    // ��ʾ�������������š����̺š�����״̬���ں˶�ջ�����ֽ�������Լ����

    // NR_TASKS��ϵͳ�����ɵ�������(����)����(64��)��������include/kernel/sched.h ��6�С�

 45 void show_state(void)

 46 {

 47         int i;

 48

 49         printk("\rTask-info:\n\r");

 50         for (i=0;i<NR_TASKS;i++)

 51                 if (task[i])

 52                         show_task(i,task[i]);

 53 }

 54

    // PC��8253��ʱоƬ������ʱ��Ƶ��ԼΪ1.193180MHz��Linux�ں�ϣ����ʱ�������жϵ�Ƶ����

    // 100Hz��Ҳ��ÿ10ms����һ��ʱ���жϡ��������LATCH������8253оƬ�ij�ֵ���μ�438�С�

 55 #define LATCH (1193180/HZ)

 56

 57 extern void mem_use(void);         // [??]û���κεط���������øú�����

 58

 59 extern int timer_interrupt(void);  // ʱ���жϴ�������kernel/system_call.s��176����

 60 extern int system_call(void);      // ϵͳ�����жϴ�������kernel/system_call.s��80����

 61

    // ÿ�����񣨽��̣����ں�̬����ʱ�����Լ����ں�̬��ջ�����ﶨ����������ں�̬��ջ�ṹ��

    // ���ﶨ���������ϣ�����ṹ��Ա��stack�ַ������Ա������Ϊһ����������ݽṹ�����ں�

    // ̬��ջ����ͬһ�ڴ�ҳ�У����ԴӶ�ջ�μĴ���ss���Ի�������ݶ�ѡ�����

 62 union task_union {

 63         struct task_struct task;

 64         char stack[PAGE_SIZE];

 65 };

 66

    // ���ó�ʼ��������ݡ���ʼ������include/kernel/sched.h�У���156�п�ʼ��

 67 static union task_union init_task = {INIT_TASK,};

 68

    // �ӿ�����ʼ����ĵδ���ʱ��ֵȫ�ֱ�����10ms/�δ𣩡�ϵͳʱ���ж�ÿ����һ�μ�һ���δ�

    // ǰ����޶��� volatile��Ӣ�Ľ������׸ı�ġ����ȶ�����˼������޶��ʵĺ������������

    // ָ�����������ݿ��ܻ����ڱ����������޸Ķ��仯��ͨ���ڳ���������һ������ʱ�� ��������

    // �������������ͨ�üĴ����У����� ebx������߷���Ч�ʡ���CPU����ֵ�ŵ� ebx�к�һ��

    // �Ͳ����ٹ��ĸñ�����Ӧ�ڴ�λ���е����ݡ�����ʱ�������������ں˳����һ���жϹ��̣�

    // �޸����ڴ��иñ�����ֵ��ebx�е�ֵ��������֮���¡�Ϊ�˽����������ʹ�����volatile

    // �޶������ô��������øñ���ʱһ��Ҫ��ָ���ڴ�λ����ȡ����ֵ�����T��Ҫ�� gcc��Ҫ��

    // jiffies �����Ż�������Ҳ��ҪŲ��λ�ã�������Ҫ���ڴ���ȡ��ֵ����Ϊʱ���жϴ�������

    // �ȳ�����޸�����ֵ��

 69 unsigned long volatile jiffies=0;

 70 unsigned long startup_time=0;                 // ����ʱ�䡣��1970:0:0:0��ʼ��ʱ��������

    // ������������ۼ���Ҫ������ʱ���������

 71 int jiffies_offset = 0;         /* # clock ticks to add to get "true

 72                                    time".  Should always be less than

 73                                    1 second's worth.  For time fanatics

 74                                    who like to syncronize their machines

 75                                    to WWV :-) */

    /* Ϊ����ʱ�Ӷ���Ҫ���ӵ�ʱ����������Ի�á���ȷʱ�䡱����Щ�����������

     * ���ܺͲ�Ӧ�ó���1�롣��������Ϊ����Щ��ʱ�侫ȷ��Ҫ����̵��ˣ�����ϲ

     * ���Լ��Ļ���ʱ����WWVͬ�� :-)

     */

 76

 77 struct task_struct *current = &(init_task.task);  // ��ǰ����ָ�루��ʼ��ָ������0����

 78 struct task_struct *last_task_used_math = NULL;   // ʹ�ù�Э�����������ָ�롣

 79

    // ��������ָ�����顣��1���ʼ��ָ���ʼ��������0�����������ݽṹ��

 80 struct task_struct * task[NR_TASKS] = {&(init_task.task), };

 81

    // �����û���ջ����1K�����4K�ֽڡ����ں˳�ʼ�����������б������ں�ջ����ʼ�����

    // �Ժ󽫱���������0���û�̬��ջ������������0֮ǰ�����ں�ջ���Ժ���������0��1����

    // ��̬ջ������ṹ�������ö�ջss:esp�����ݶ�ѡ�����ָ�룩����head.s����23�С�

    // ss������Ϊ�ں����ݶ�ѡ�����0x10����ָ��espָ�� user_stack�������һ����档����

    // ��ΪIntel CPUִ�ж�ջ����ʱ���ȵݼ���ջָ��spֵ��Ȼ����spָ�봦������ջ���ݡ�

 82 long user_stack [ PAGE_SIZE>>2 ] ;

 83

 84 struct {

 85         long * a;

 86         short b;

 87         } stack_start = { & user_stack [PAGE_SIZE>>2] , 0x10 };

 88 /*

 89  *  'math_state_restore()' saves the current math information in the

 90  * old math state array, and gets the new ones from the current task

 91  */

    /*

     * ����ǰЭ���������ݱ��浽��Э������״̬�����У�������ǰ�����Э������

     * ���ݼ��ؽ�Э��������

     */

    // �����񱻵��Ƚ������Ժ󣬸ú������Ա���ԭ�����Э������״̬�������ģ����ָ��µ��Ƚ�

    // ���ĵ�ǰ�����Э������ִ��״̬��

 92 void math_state_restore()

 93 {

    // �������û���򷵻�(��һ��������ǵ�ǰ����)������"��һ������"��ָ�ձ�������ȥ������

 94         if (last_task_used_math == current)

 95                 return;

    // �ڷ���Э����������֮ǰҪ�ȷ�WAITָ�����ϸ�����ʹ����Э���������򱣴���״̬��

 96         __asm__("fwait");

 97         if (last_task_used_math) {

 98                 __asm__("fnsave %0"::"m" (last_task_used_math->tss.i387));

 99         }

    // ���ڣ�last_task_used_mathָ��ǰ�����Ա���ǰ���񱻽�����ȥʱʹ�á���ʱ�����ǰ

    // �����ù�Э����������ָ���״̬������Ļ�˵���ǵ�һ��ʹ�ã����Ǿ���Э����������ʼ��

    // ���������ʹ����Э��������־��

100         last_task_used_math=current;

101         if (current->used_math) {

102                 __asm__("frstor %0"::"m" (current->tss.i387));

103         } else {

104                 __asm__("fninit"::);           // ��Э����������ʼ�����

105                 current->used_math=1;          // ����ʹ����Э��������־��

106         }

107 }

108

109 /*

110  *  'schedule()' is the scheduler function. This is GOOD CODE! There

111  * probably won't be any reason to change this, as it should work well

112  * in all circumstances (ie gives IO-bound processes good response etc).

113  * The one thing you might take a look at is the signal-handler code here.

114  *

115  *   NOTE!!  Task 0 is the 'idle' task, which gets called when no other

116  * tasks can run. It can not be killed, and it cannot sleep. The 'state'

117  * information in task[0] is never used.

118  */

    /*

     * 'schedule()'�ǵ��Ⱥ��������Ǹ��ܺõĴ��룡û���κ����ɶ��������޸ģ���Ϊ

     * �����������еĻ����¹����������ܹ���IO-�߽紦���ܺõ���Ӧ�ȣ���ֻ��һ��

     * ��ֵ�����⣬�Ǿ���������źŴ������롣

     *

     *   ע�⣡������0�Ǹ�����('idle')����ֻ�е�û�����������������ʱ�ŵ���

     * ���������ܱ�ɱ����Ҳ����˯�ߡ�����0�е�״̬��Ϣ'state'�Ǵ������õġ�

     */

119 void schedule(void)

120 {

121         int i,next,c;

122         struct task_struct ** p;              // ����ṹָ���ָ�롣

123

124 /* check alarm, wake up any interruptible tasks that have got a signal */

    /* ���alarm�����̵ı�����ʱֵ���������κ��ѵõ��źŵĿ��ж����� */

125

    // ���������������һ������ʼѭ�����alarm����ѭ��ʱ������ָ���

126         for(p = &LAST_TASK ; p > &FIRST_TASK ; --p)

127                 if (*p) {

    // ������ù�����ʱ��ʱtimeout�������Ѿ���ʱ����λ��ʱ��ʱֵ��������������ڿ�

    // �ж�˯��״̬TASK_INTERRUPTIBLE�£�������Ϊ����״̬��TASK_RUNNING����

128                         if ((*p)->timeout && (*p)->timeout < jiffies) {

129                                 (*p)->timeout = 0;

130                                 if ((*p)->state == TASK_INTERRUPTIBLE)

131                                         (*p)->state = TASK_RUNNING;

132                         }

    // ������ù�����Ķ�ʱֵalarm�������Ѿ�����(alarm<jiffies),�����ź�λͼ����SIGALRM

    // �źţ�����������SIGALARM�źš�Ȼ����alarm�����źŵ�Ĭ�ϲ�������ֹ���̡�jiffies

    // ��ϵͳ�ӿ�����ʼ����ĵδ�����10ms/�δ𣩡�������sched.h��139�С�

133                         if ((*p)->alarm && (*p)->alarm < jiffies) {

134                                 (*p)->signal |= (1<<(SIGALRM-1));

135                                 (*p)->alarm = 0;

136                         }

    // ����ź�λͼ�г����������ź��⻹�������źţ����������ڿ��ж�״̬����������Ϊ����

    // ״̬������'~(_BLOCKABLE & (*p)->blocked)'���ں��Ա��������źţ���SIGKILL��SIGSTOP

    // ���ܱ�������

137                         if (((*p)->signal & ~(_BLOCKABLE & (*p)->blocked)) &&

138                         (*p)->state==TASK_INTERRUPTIBLE)

139                                 (*p)->state=TASK_RUNNING;   //��Ϊ��������ִ�У�״̬��

140                 }

141

142 /* this is the scheduler proper: */

    /* �����ǵ��ȳ������Ҫ���� */

143

144         while (1) {

145                 c = -1;

146                 next = 0;

147                 i = NR_TASKS;

148                 p = &task[NR_TASKS];

    // ��δ���Ҳ�Ǵ�������������һ������ʼѭ���������������������������ۡ��Ƚ�ÿ��

    // ����״̬�����counter����������ʱ��ĵݼ��δ������ֵ����һ��ֵ������ʱ�仹������

    // next��ָ���ĸ�������š�

149                 while (--i) {

150                         if (!*--p)

151                                 continue;

152                         if ((*p)->state == TASK_RUNNING && (*p)->counter > c)

153                                 c = (*p)->counter, next = i;

154                 }

    // ����Ƚϵó���counterֵ������0�Ľ��������ϵͳ��û��һ�������е�������ڣ���ʱc

    // ��ȻΪ-1��next=0�������˳�144�п�ʼ��ѭ����ִ��161���ϵ������л�����������͸���

    // ÿ�����������Ȩֵ������ÿһ�������counterֵ��Ȼ��ص�125�����±Ƚϡ�counter ֵ

    // �ļ��㷽ʽΪ counter = counter /2 + priority��ע�⣬���������̲����ǽ��̵�״̬��

155                 if (c) break;

156                 for(p = &LAST_TASK ; p > &FIRST_TASK ; --p)

157                         if (*p)

158                                 (*p)->counter = ((*p)->counter >> 1) +

159                                                 (*p)->priority;

160         }

    // ������꣨������sched.h�У��ѵ�ǰ����ָ��currentָ�������Ϊnext�����񣬲��л�

    // �������������С���146����next����ʼ��Ϊ0�������ϵͳ��û���κ��������������ʱ��

    // �� next ʼ��Ϊ0����˵��Ⱥ�������ϵͳ����ʱȥִ������0�� ��ʱ����0��ִ��pause()

    // ϵͳ���ã����ֻ���ñ�������

161         switch_to(next);                     // �л��������Ϊnext�����񣬲�����֮��

162 }

163

    //// pause()ϵͳ���á�ת����ǰ�����״̬Ϊ���жϵĵȴ�״̬�������µ��ȡ�

    // ��ϵͳ���ý����½��̽���˯��״̬��ֱ���յ�һ���źš����ź�������ֹ���̻���ʹ����

    // ����һ���źŲ�������ֻ�е�������һ���źţ������źŲ������������أ�pause()��

    // �᷵�ء���ʱ pause()����ֵӦ���� -1������ errno����Ϊ EINTR�����ﻹû����ȫʵ��

    // ��ֱ��0.95�棩��

164 int sys_pause(void)

165 {

166         current->state = TASK_INTERRUPTIBLE;

167         schedule();

168         return 0;

169 }

170

    // �ѵ�ǰ������Ϊָ����˯��״̬�����жϵĻ򲻿��жϵģ�������˯�߶���ͷָ��ָ��ǰ����

    // ��������p�ǵȴ��������ͷָ�롣ָ���Ǻ���һ��������ַ�ı������������pʹ����ָ���

    // ָ����ʽ '**p'��������ΪC��������ֻ�ܴ�ֵ��û��ֱ�ӵķ�ʽ�ñ����ú����ı���øú���

    // �����б�����ֵ������ָ��'*p'ָ���Ŀ�꣨����������ṹ����ı䣬���Ϊ�����޸ĵ��ø�

    // ����������ԭ������ָ�������ֵ������Ҫ����ָ��'*p'��ָ�룬��'**p'���μ�����ǰʾ��ͼ��

    // pָ���ʹ�������

    // ����state������˯��ʹ�õ�״̬��TASK_UNINTERRUPTIBLE��TASK_INTERRUPTIBLE�����ڲ���

    // �ж�˯��״̬��TASK_UNINTERRUPTIBLE����������Ҫ�ں˳�������wake_up()������ȷ����֮��

    // ���ڿ��ж�˯��״̬��TASK_INTERRUPTIBLE������ͨ���źš�����ʱ���ֶλ��� ����Ϊ����

    // ״̬TASK_RUNNING����

    // *** ע�⣬���ڱ��ں˴��벻�Ǻܳ��죬���������˯����صĴ������һЩ���⣬�������

171 static inline void __sleep_on(struct task_struct **p, int state)

172 {

173         struct task_struct *tmp;

174

    // ��ָ����Ч�����˳�����ָ����ָ�Ķ��������NULL����ָ�뱾������Ϊ0)��

    // �����ǰ����������0��������(impossible!)��

175         if (!p)

176                 return;

177         if (current == &(init_task.task))

178                 panic("task[0] trying to sleep");

    // ��tmpָ���Ѿ��ڵȴ������ϵ�����(����еĻ�)������inode->i_wait�����ҽ�˯�߶���ͷ

    // �ĵȴ�ָ��ָ��ǰ���������Ͱѵ�ǰ������뵽�� *p�ĵȴ������С�Ȼ�󽫵�ǰ������

    // Ϊָ���ĵȴ�״̬����ִ�����µ��ȡ�

179         tmp = *p;

180         *p = current;

181         current->state = state;

182 repeat: schedule();

    // ֻ�е�����ȴ����񱻻���ʱ��������ֻ᷵�ص������ʾ�����ѱ���ȷ�ػ��Ѳ�ִ�С�

    // ����ȴ������л��еȴ����񣬲��Ҷ���ͷָ�� *p ��ָ��������ǵ�ǰ����ʱ��˵��

    // �ڱ��������ȴ����к����������ȴ����С���������Ӧ��ҲҪ����������񣬶���

    // ���Լ�Ӧ��˳������Щ���������е������ѣ�������ォ�ȴ�����ͷ��ָ��������Ϊ

    // ����״̬�����Լ�����Ϊ�����жϵȴ�״̬�����Լ�Ҫ�ȴ���Щ���������е����񱻻���

    // ��ִ��ʱ�����ѱ�����Ȼ������ִ�е��ȳ���

183         if (*p && *p != current) {

184                 (**p).state = 0;

185                 current->state = TASK_UNINTERRUPTIBLE;

186                 goto repeat;

187         }

    // ִ�е����˵������������������ִ�С���ʱ�ȴ�����ͷָ��Ӧ��ָ����������Ϊ

    // �գ���������������⣬������ʾ������Ϣ�����������ͷָ��ָ��������ǰ��������

    // ������*p = tmp���� ��ȷʵ��������һ�����񣬼������л�������tmp��Ϊ�գ�����

    // ����֮�����Ƚ�����е������ڻ��Ѻ�����ʱ���ջ�ѵȴ�����ͷָ���ó�NULL��

188         if (!*p)

189                 printk("Warning: *P = NULL\n\r");

190         if (*p = tmp)

191                 tmp->state=0;

192 }

193

    // ����ǰ������Ϊ���жϵĵȴ�״̬��TASK_INTERRUPTIBLE����������ͷָ��*pָ���ĵȴ�

    // �����С�

194 void interruptible_sleep_on(struct task_struct **p)

195 {

196         __sleep_on(p,TASK_INTERRUPTIBLE);

197 }

198

    // �ѵ�ǰ������Ϊ�����жϵĵȴ�״̬��TASK_UNINTERRUPTIBLE��������˯�߶���ͷָ��ָ��

    // ��ǰ����ֻ����ȷ�ػ���ʱ�Ż᷵�ء��ú����ṩ�˽������жϴ�������֮���ͬ�����ơ�

199 void sleep_on(struct task_struct **p)

200 {

201         __sleep_on(p,TASK_UNINTERRUPTIBLE);

202 }

203

    // ���� *pָ�������*p������ȴ�����ͷָ�롣�����µȴ������Dz����ڵȴ�����ͷָ��

    // ���ģ���˻��ѵ���������ȴ����е��������������Ѿ�����ֹͣ����״̬������ʾ

    // ������Ϣ��

204 void wake_up(struct task_struct **p)

205 {

206         if (p && *p) {

207                 if ((**p).state == TASK_STOPPED)         // ����ֹͣ״̬��

208                         printk("wake_up: TASK_STOPPED");

209                 if ((**p).state == TASK_ZOMBIE)          // ���ڽ���״̬��

210                         printk("wake_up: TASK_ZOMBIE");

211                 (**p).state=0;                           // ��Ϊ����״̬TASK_RUNNING��

212         }

213 }

214

215 /*

216  * OK, here are some floppy things that shouldn't be in the kernel

217  * proper. They are here because the floppy needs a timer, and this

218  * was the easiest way of doing it.

219  */

    /*

     * ���ˣ������↑ʼ��һЩ�й����̵��ӳ��򣬱���Ӧ�÷����ں˵���Ҫ����

     * �еġ������Ƿ�����������Ϊ������Ҫ��ʱ���������������������ġ�

     */

    // ����220 -- 281�д������ڴ���������ʱ�����Ķ���δ���֮ǰ���ȿ�һ�¿��豸һ����

    // �й�������������floppy.c�������˵���� ���ߵ��Ķ����̿��豸��������ʱ��������

    // �δ��롣����ʱ�䵥λ��1���δ� = 1/100�롣

    // ��������wait_motor[]���ڴ�ŵȴ�������������������ת�ٵĽ���ָ�롣��������0-3

    // �ֱ��Ӧ����A--D������ mon_timer[]��Ÿ�����������������Ҫ�ĵδ�����������Ĭ��

    // ����ʱ��Ϊ50���δ�0.5�룩������ moff_timer[] ��Ÿ�����������ͣת֮ǰ��ά��

    // ��ʱ�䡣�������趨Ϊ10000���δ�100�룩��

220 static struct task_struct * wait_motor[4] = {NULL,NULL,NULL,NULL};

221 static int  mon_timer[4]={0,0,0,0};

222 static int moff_timer[4]={0,0,0,0};

 

    // ���������Ӧ�����������е�ǰ��������Ĵ������üĴ���ÿλ�Ķ������£�

    // λ7-4���ֱ����������D-A�����������1 - ������0 - �رա�

    // λ��1 - ����DMA���ж�����0 - ��ֹDMA���ж�����

    // λ��1 - �������̿�������    0 - ��λ���̿�������

    // λ1-0��00 - 11������ѡ����Ƶ�����A-D��

    // �������ó�ֵΪ������DMA���ж���������FDC��

223 unsigned char current_DOR = 0x0C;

224

    // ָ������������������ת״̬����ȴ�ʱ�䡣

    // ����nr -- ������(0--3)������ֵΪ�δ�����

    // �ֲ�����selected��ѡ��������־��blk_drv/floppy.c��123�У���mask����ѡ������Ӧ��

    // ��������Ĵ����������������λ��mask��4λ�Ǹ��������������־��

225 int ticks_to_floppy_on(unsigned int nr)

226 {

227         extern unsigned char selected;

228         unsigned char mask = 0x10 << nr;

229

    // ϵͳ�����4������������Ԥ�����ú�ָ������nrͣת֮ǰ��Ҫ������ʱ�䣨100�룩��Ȼ��

    // ȡ��ǰDOR�Ĵ���ֵ����ʱ����mask�У�����ָ������������������־��λ��

230         if (nr>3)

231                 panic("floppy_on: nr>3");

232         moff_timer[nr]=10000;           /* 100 s = very big :-) */   // ͣתά��ʱ�䡣

233         cli();                          /* use floppy_off to turn it off */ // ���жϡ�

234         mask |= current_DOR;

    // �����ǰû��ѡ�������������ȸ�λ����������ѡ��λ��Ȼ����ָ������ѡ��λ��

235         if (!selected) {

236                 mask &= 0xFC;

237                 mask |= nr;

238         }

    // �����������Ĵ����ĵ�ǰֵ��Ҫ���ֵ��ͬ������FDC��������˿������ֵ(mask)������

    // ���Ҫ�����������ﻹû��������������Ӧ����������������ʱ��ֵ��HZ/2 = 0.5��� 50��

    // �δ𣩡����Ѿ���������������������ʱΪ2���δ����������� do_floppy_timer()���ȵ�

    // �����жϵ�Ҫ��ִ�б��ζ�ʱ�����Ҫ�󼴿ɡ��˺���µ�ǰ��������Ĵ���current_DOR��

239         if (mask != current_DOR) {

240                 outb(mask,FD_DOR);

241                 if ((mask ^ current_DOR) & 0xf0)

242                         mon_timer[nr] = HZ/2;

243                 else if (mon_timer[nr] < 2)

244                         mon_timer[nr] = 2;

245                 current_DOR = mask;

246         }

247         sti();                          // ���жϡ�

248         return mon_timer[nr];           // ��󷵻��������������ʱ��ֵ��

249 }

250

    // �ȴ�ָ�������������������һ��ʱ�䣬Ȼ�󷵻ء�

    // ����ָ����������������������ת���������ʱ��Ȼ��˯�ߵȴ����ڶ�ʱ�жϹ����л�һֱ

    // �ݼ��ж������趨����ʱֵ������ʱ���ڣ��ͻỽ������ĵȴ����̡�

251 void floppy_on(unsigned int nr)

252 {

    // ���жϡ��������������ʱ��û������һֱ�ѵ�ǰ������Ϊ�����ж�˯��״̬������ȴ�����

    // ���еĶ����С�Ȼ���жϡ�

253         cli();

254         while (ticks_to_floppy_on(nr))

255                 sleep_on(nr+wait_motor);

256         sti();

257 }

258

    // �ùر���Ӧ��������ͣת��ʱ����3�룩��

    // ����ʹ�øú�����ȷ�ر�ָ������������������↑��100��֮��Ҳ�ᱻ�رա�

259 void floppy_off(unsigned int nr)

260 {

261         moff_timer[nr]=3*HZ;

262 }

263

    // ���̶�ʱ�����ӳ��򡣸�������������ʱֵ������ر�ͣת��ʱֵ�����ӳ������ʱ�Ӷ�ʱ

    // �жϹ����б����ã����ϵͳÿ����һ���δ�(10ms)�ͻᱻ����һ�Σ���ʱ�������↑����

    // ͣת��ʱ����ֵ�����ijһ������ͣת��ʱ��������������Ĵ�����������λ��λ��

264 void do_floppy_timer(void)

265 {

266         int i;

267         unsigned char mask = 0x10;

268

269         for (i=0 ; i<4 ; i++,mask <<= 1) {

270                 if (!(mask & current_DOR))             // �������DORָ����������������

271                         continue;

272                 if (mon_timer[i]) {                    // �������������ʱ�����ѽ��̡�

273                         if (!--mon_timer[i])

274                                 wake_up(i+wait_motor);

275                 } else if (!moff_timer[i]) {           // �������ͣת��ʱ����

276                         current_DOR &= ~mask;          // ��λ��Ӧ��������λ������

277                         outb(current_DOR,FD_DOR);      // ������������Ĵ�����

278                 } else

279                         moff_timer[i]--;               // ��������ͣת��ʱ�ݼ���

280         }

281 }

282

    // �����ǹ��ڶ�ʱ���Ĵ��롣������64����ʱ����

283 #define TIME_REQUESTS 64

284

    // ��ʱ�������ṹ�Ͷ�ʱ�����顣�ö�ʱ������ר���ڹ������ر�������������ﶨʱ������

    // �������Ͷ�ʱ�������ִ�Linuxϵͳ�еĶ�̬��ʱ����Dynamic Timer���������ں�ʹ�á�

285 static struct timer_list {

286         long jiffies;                  // ��ʱ�δ�����

287         void (*fn)();                  // ��ʱ��������

288         struct timer_list * next;      // ����ָ����һ����ʱ����

289 } timer_list[TIME_REQUESTS], * next_timer = NULL;  // next_timer�Ƕ�ʱ������ͷָ�롣

290

    // ���Ӷ�ʱ�����������Ϊָ���Ķ�ʱֵ(�δ���)����Ӧ�Ĵ�������ָ�롣

    // ������������floppy.c�����øú���ִ��������ر��������ʱ������

    // ����jiffies �C ��10����Ƶĵδ�����*fn()- ��ʱʱ�䵽ʱִ�еĺ�����

291 void add_timer(long jiffies, void (*fn)(void))

292 {

293         struct timer_list * p;

294

    // �����ʱ��������ָ��Ϊ�գ����˳���������жϡ�

295         if (!fn)

296                 return;

297         cli();

    // �����ʱֵ<=0�������̵����䴦�����򡣲��Ҹö�ʱ�������������С�

298         if (jiffies <= 0)

299                 (fn)();

300         else {

    // ����Ӷ�ʱ�������У���һ�������

301                 for (p = timer_list ; p < timer_list + TIME_REQUESTS ; p++)

302                         if (!p->fn)

303                                 break;

    // ����Ѿ������˶�ʱ�����飬��ϵͳ����J��������ʱ�����ݽṹ������Ӧ��Ϣ��������

    // ����ͷ��

304                 if (p >= timer_list + TIME_REQUESTS)

305                         panic("No more time requests free");

306                 p->fn = fn;

307                 p->jiffies = jiffies;

308                 p->next = next_timer;

309                 next_timer = p;

    // �������ʱֵ��С��������������ʱ��ȥ����ǰ����Ҫ�ĵδ����������ڴ�����ʱ��ʱ

    // ֻҪ�鿴����ͷ�ĵ�һ��Ķ�ʱ�Ƿ��ڼ��ɡ�[[?? ��γ������û�п�����ȫ�������

    // ����Ķ�ʱ��ֵС��ԭ��ͷһ����ʱ��ֵʱ������������ѭ���У�����ʱ����Ӧ�ý�����

    // ������һ����ʱ��ֵ��ȥ�µĵ�1���Ķ�ʱֵ���������1����ʱֵ<=��2�������2��

    // ��ʱֵ�۳���1����ֵ���ɣ������������ѭ���н��д�����]]

310                 while (p->next && p->next->jiffies < p->jiffies) {

311                         p->jiffies -= p->next->jiffies;

312                         fn = p->fn;

313                         p->fn = p->next->fn;

314                         p->next->fn = fn;

315                         jiffies = p->jiffies;

316                         p->jiffies = p->next->jiffies;

317                         p->next->jiffies = jiffies;

318                         p = p->next;

319                 }

320         }

321         sti();

322 }

323

    //// ʱ���ж�C��������������sys_call.s�е�_timer_interrupt��189�У������á�

    // ����cpl�ǵ�ǰ��Ȩ��0��3����ʱ���жϷ���ʱ����ִ�еĴ���ѡ����е���Ȩ����

    // cpl=0ʱ��ʾ�жϷ���ʱ����ִ���ں˴��룻cpl=3ʱ��ʾ�жϷ���ʱ����ִ���û����롣

    // ����һ����������ִ��ʱ��Ƭ����ʱ������������л�����ִ��һ����ʱ���¹�����

324 void do_timer(long cpl)

325 {

326         static int blanked = 0;

327

    // �����ж��Ƿ񾭹���һ��ʱ�������Ļ������blankout�������blankcount������Ϊ�㣬

    // ���ߺ�����ʱ���ʱ��blankintervalΪ0�Ļ�����ô���Ѿ����ں���״̬��������־

    // blanked = 1����������Ļ�ָ���ʾ����blankcount������Ϊ�㣬��ݼ�֮�����Ҹ�λ

    // ������־��

328         if (blankcount || !blankinterval) {

329                 if (blanked)

330                         unblank_screen();

331                 if (blankcount)

332                         blankcount--;

333                 blanked = 0;

    // ����Ļ���������־δ��λ��������Ļ�������������ú�����־��

334         } else if (!blanked) {

335                 blank_screen();

336                 blanked = 1;

337         }

    // ���Ŵ���Ӳ�̲�����ʱ���⡣���Ӳ�̳�ʱ�����ݼ�֮��Ϊ0�������Ӳ�̷��ʳ�ʱ������

338         if (hd_timeout)

339                 if (!--hd_timeout)

340                         hd_times_out();  // Ӳ�̷��ʳ�ʱ������blk_drv/hdc��318�У���

341

    // ���������������������رշ�����(��0x61�ڷ��������λλ0��1��λ0����8253

    // ������2�Ĺ�����λ1����������)��

342         if (beepcount)          // ����������ʱ��δ�����chr_drv/console.c,950�У���

343                 if (!--beepcount)

344                         sysbeepstop();

345

    // �����ǰ��Ȩ��(cpl)Ϊ0����ߣ���ʾ���ں˳����ڹ����������ں˴�������ʱ��stime

    // ������[ Linus���ں˳���ͳ��Ϊ�����û�(supervisor)�ij��򣬼�sys_call.s��207��

    // �ϵ�Ӣ��ע�͡����ֳƺ�������Intel CPU �ֲᡣ] ���cpl > 0�����ʾ��һ���û�����

    // �ڹ���������utime��

346         if (cpl)

347                 current->utime++;

348         else

349                 current->stime++;

350

    // ����ж�ʱ�����ڣ���������1����ʱ����ֵ��1������ѵ���0���������Ӧ�Ĵ�������

    // �����ô�������ָ����Ϊ�ա�Ȼ��ȥ�����ʱ����next_timer�Ƕ�ʱ��������ͷָ�롣

351         if (next_timer) {

352                 next_timer->jiffies--;

353                 while (next_timer && next_timer->jiffies <= 0) {

354                         void (*fn)(void);        // ���������һ������ָ�붨�壡��L

355                        

356                         fn = next_timer->fn;

357                         next_timer->fn = NULL;

358                         next_timer = next_timer->next;

359                         (fn)();                 // ���ö�ʱ����������

360                 }

361         }

    // �����ǰ���̿�����FDC����������Ĵ�������������λ����λ�ģ���ִ�����̶�ʱ����

362         if (current_DOR & 0xf0)

363                 do_floppy_timer();

  // �����������ʱ�仹û�꣬���˳��������õ�ǰ�������м���ֵΪ0������������ʱ���ж�ʱ

  // �����ں˴����������򷵻أ��������ִ�е��Ⱥ�����

364         if ((--current->counter)>0) return;

365         current->counter=0;

366         if (!cpl) return;              // �����ں�̬���򣬲�����counterֵ���е��ȡ�

367         schedule();

368 }

369

    // ϵͳ���ù��� - ���ñ�����ʱʱ��ֵ(��)��

    // ������seconds����0���������¶�ʱֵ��������ԭ��ʱʱ�̻�ʣ��ļ��ʱ�䡣���򷵻�0��

    // �������ݽṹ�б�����ʱֵalarm�ĵ�λ��ϵͳ�δ�1�δ�Ϊ10���룩������ϵͳ������

    // ���ö�ʱ����ʱϵͳ�δ�ֵjiffies��ת���ɵδ�λ�Ķ�ʱֵ֮�ͣ���'jiffies + HZ*��ʱ

    // ��ֵ'��������������������Ϊ��λ�Ķ�ʱֵ����˱���������Ҫ�����ǽ������ֵ�λ��ת����

    // ���г���HZ = 100�����ں�ϵͳ����Ƶ�ʡ�������include/sched.h��4���ϡ�

    // ����seconds���µĶ�ʱʱ��ֵ����λ���롣

370 int sys_alarm(long seconds)

371 {

372         int old = current->alarm;

373

374         if (old)

375                 old = (old - jiffies) / HZ;

376         current->alarm = (seconds>0)?(jiffies+HZ*seconds):0;

377         return (old);

378 }

379

    // ȡ��ǰ���̺�pid��

380 int sys_getpid(void)

381 {

382         return current->pid;

383 }

384

    // ȡ�����̺�ppid��

385 int sys_getppid(void)

386 {

387         return current->p_pptr->pid;

388 }

389

    // ȡ�û���uid��

390 int sys_getuid(void)

391 {

392         return current->uid;

393 }

394

    // ȡ��Ч���û���euid��

395 int sys_geteuid(void)

396 {

397         return current->euid;

398 }

399

    // ȡ���gid��

400 int sys_getgid(void)

401 {

402         return current->gid;

403 }

404

    // ȡ��Ч�����egid��

405 int sys_getegid(void)

406 {

407         return current->egid;

408 }

409

    // ϵͳ���ù��� -- ���Ͷ�CPU��ʹ������Ȩ�����˻�����J����

    // Ӧ������incrementΪ����0��ֵ�������ʹ����Ȩ���󣡣�

410 int sys_nice(long increment)

411 {

412         if (current->priority-increment>0)

413                 current->priority -= increment;

414         return 0;

415 }

416

    // �ں˵��ȳ���ij�ʼ���ӳ���

417 void sched_init(void)

418 {

419         int i;

420         struct desc_struct * p;        // ���������ṹָ�롣

421

    // Linuxϵͳ����֮�����ں˲����졣�ں˴���ᱻ�����޸ġ�Linus���Լ��������޸�����Щ

    // �ؼ��Ե����ݽṹ�������POSIX��׼�IJ����ݡ����������������ж���䲢�ޱ�Ҫ������

    // ��Ϊ�������Լ��Լ������޸��ں˴�����ˡ�

422         if (sizeof(struct sigaction) != 16)    // sigaction�Ǵ���й��ź�״̬�Ľṹ��

423                 panic("Struct sigaction MUST be 16 bytes");

    // ��ȫ���������������ó�ʼ��������0��������״̬���������;ֲ����ݱ���������

    // FIRST_TSS_ENTRY��FIRST_LDT_ENTRY��ֵ�ֱ���4��5��������include/linux/sched.h

    // �У�gdt ��һ�������������飨include/linux/head.h ����ʵ���϶�Ӧ���� head.s ��

    // ��234���ϵ�ȫ������������ַ��_gdt������� gdt + FIRST_TSS_ENTRY ��Ϊ

    // gdt[FIRST_TSS_ENTRY]������gdt[4]����Ҳ�� gdt �����4��ĵ�ַ�� �μ�

    // include/asm/system.h,��65�п�ʼ��

424         set_tss_desc(gdt+FIRST_TSS_ENTRY,&(init_task.task.tss));

425         set_ldt_desc(gdt+FIRST_LDT_ENTRY,&(init_task.task.ldt));

    // ��������������������ע��i=1��ʼ�����Գ�ʼ��������������ڣ�����������ṹ

    // �������ļ�include/linux/head.h�С�

426         p = gdt+2+FIRST_TSS_ENTRY;

427         for(i=1;i<NR_TASKS;i++) {

428                 task[i] = NULL;

429                 p->a=p->b=0;

430                 p++;

431                 p->a=p->b=0;

432                 p++;

433         }

434 /* Clear NT, so that we won't have troubles with that later on */

    /* �����־�Ĵ����е�λNT�������Ժ�Ͳ������鷳 */

    // EFLAGS�е�NT��־λ���ڿ��������Ƕ�׵��á���NTλ��λʱ����ô��ǰ�ж�����ִ��

    // IRETָ��ʱ�ͻ����������л���NTָ��TSS�е�back_link�ֶ��Ƿ���Ч��NT=0ʱ��Ч��

435         __asm__("pushfl ; andl $0xffffbfff,(%esp) ; popfl");    // ��λNT��־��

    // ������0 �� TSS��ѡ������ص�����Ĵ���tr�����ֲ�����������ѡ������ص��ֲ�����

    // �����Ĵ���ldtr�С�ע�⣡���ǽ�GDT����ӦLDT��������ѡ������ص�ldtr��ֻ��ȷ��

    // ��һ�Σ��Ժ�������LDT�ļ��أ���CPU����TSS�е�LDT���Զ����ء�

436         ltr(0);                    // ������include/linux/sched.h ��157-158�С�

437         lldt(0);                   // ���в�����0��������š�

    // ����������ڳ�ʼ�� 8253��ʱ����ͨ��0��ѡ������ʽ3�������Ƽ�����ʽ��ͨ��0��

    // ������Ž����жϿ�����оƬ��IRQ0�ϣ���ÿ10���뷢��һ��IRQ0����LATCH�dz�ʼ

    // ��ʱ����ֵ��

438         outb_p(0x36,0x43);                /* binary, mode 3, LSB/MSB, ch 0 */

439         outb_p(LATCH & 0xff , 0x40);      /* LSB */    // ��ʱֵ���ֽڡ�

440         outb(LATCH >> 8 , 0x40);          /* MSB */    // ��ʱֵ���ֽڡ�

    // ����ʱ���жϴ���������������ʱ���ж��ţ����޸��жϿ����������룬����ʱ���жϡ�

    // Ȼ������ϵͳ�����ж��š������������ж���������IDT���������ĺ궨�����ļ�

    // include/asm/system.h�е�33��39�д������ߵ�����μ�system.h�ļ���ʼ����˵����

441         set_intr_gate(0x20,&timer_interrupt);

442         outb(inb_p(0x21)&~0x01,0x21);

443         set_system_gate(0x80,&system_call);

444 }

445