����7-1 linux/init/main.c


  1 /*

  2  *  linux/init/main.c

  3  *

  4  *  (C) 1991  Linus Torvalds

  5  */

  6

    // ����ꡰ__LIBRARY__����Ϊ�˰���������unistd.h�е���Ƕ���������Ϣ��

  7 #define __LIBRARY__

    // *.hͷ�ļ����ڵ�Ĭ��Ŀ¼��include/�����ڴ����оͲ�����ȷָ����λ�á��������UNIX��

    // ��׼ͷ�ļ�������Ҫָ�����ڵ�Ŀ¼������˫������ס��unistd.h�DZ�׼���ų����������ļ���

    // ���ж����˸��ַ��ų��������ͣ��������˸��ֺ���������������˷���__LIBRARY__���򻹻�

    // ����ϵͳ���úź���Ƕ������syscall0()�ȡ�

  8 #include <unistd.h>

  9 #include <time.h>    // ʱ������ͷ�ļ�����������Ҫ������tm�ṹ��һЩ�й�ʱ��ĺ���ԭ�Ρ�

 10

 11 /*

 12  * we need this inline - forking from kernel space will result

 13  * in NO COPY ON WRITE (!!!), until an execve is executed. This

 14  * is no problem, but for the stack. This is handled by not letting

 15  * main() use the stack at all after fork(). Thus, no function

 16  * calls - which means inline code for fork too, as otherwise we

 17  * would use the stack upon exit from 'fork()'.

 18  *

 19  * Actually only pause and fork are needed inline, so that there

 20  * won't be any messing with the stack from main(), but we define

 21  * some others too.

 22  */

    /*

     * ������Ҫ������Щ��Ƕ��� - ���ں˿ռ䴴�����̽�����û��дʱ����(COPY ON WRITE)!!!

     * ֱ��ִ��һ��execve���á���Զ�ջ���ܴ������⡣������������fork()���ú���main()

     * ʹ���κζ�ջ����˾Ͳ����к������� - ����ζ��forkҲҪʹ����Ƕ�Ĵ��룬���������ڴ�

     * fork()�˳�ʱ��Ҫʹ�ö�ջ�ˡ�

     *

     * ʵ����ֻ��pause��fork��Ҫʹ����Ƕ��ʽ���Ա�֤��main()�в���Ū�Ҷ�ջ����������ͬ

     * ʱ������������һЩ������

     */

    // Linux���ں˿ռ䴴������ʱ��ʹ��дʱ���Ƽ�����Copy on write����main()���ƶ����û�

    // ģʽ��������0����ִ����Ƕ��ʽ��fork()��pause()����˿ɱ�֤��ʹ������0���û�ջ��

    // ��ִ��moveto_user_mode()֮�󣬱�����main()��������0�������������ˡ�������0����

    // �н������ӽ��̵ĸ����̡���������һ���ӽ���ʱ��init���̣�����������1���������ں�

    // �ռ䣬���û��ʹ��дʱ���ƹ��ܡ���ʱ����0���û�ջ��������1���û�ջ�������ǹ�ͬ

    // ʹ��һ��ջ�ռ䡣���ϣ����main.c����������0�Ļ�����ʱ��Ҫ�жԶ�ջ���κβ�������

    // ��Ū�Ҷ�ջ�������ٴ�ִ��fork()��ִ�й�execve()�����󣬱����س����Ѳ������ں˿ռ䣬

    // ��˿���ʹ��дʱ���Ƽ����ˡ���μ�5.3�ڡ�Linux�ں�ʹ���ڴ�ķ��������ݡ�

 

    // ����_syscall0()��unistd.h�е���Ƕ����롣��Ƕ�������ʽ����Linux��ϵͳ�����ж�

    // 0x80�����ж�������ϵͳ���õ���ڡ��������ʵ������int fork()��������ϵͳ���á���չ

    // ����֮�ͻ��������ס�syscall0����������0��ʾ�޲�����1��ʾ1��������

    // �μ�include/unistd.h��133�С�

 23 static inline _syscall0(int,fork)

    // int pause()ϵͳ���ã���ͣ���̵�ִ�У�ֱ���յ�һ���źš�

 24 static inline _syscall0(int,pause)

    // int setup(void * BIOS)ϵͳ���ã�������linux��ʼ����������������б����ã���

 25 static inline _syscall1(int,setup,void *,BIOS)

    // int sync()ϵͳ���ã������ļ�ϵͳ��

 26 static inline _syscall0(int,sync)

 27

 28 #include <linux/tty.h>    // ttyͷ�ļ����������й�tty_io������ͨ�ŷ���IJ�����������

 29 #include <linux/sched.h>  // ���ȳ���ͷ�ļ�������������ṹtask_struct����1����ʼ����

                              // �����ݡ�����һЩ�Ժ����ʽ������й��������������úͻ�ȡ��

                              // Ƕ��ʽ��ຯ������

 30 #include <linux/head.h>   // headͷ�ļ��������˶��������ļ򵥽ṹ���ͼ���ѡ���������

 31 #include <asm/system.h>   // ϵͳͷ�ļ����Ժ���ʽ�����������й����û��޸�������/�ж���

                              // �ȵ�Ƕ��ʽ����ӳ���

 32 #include <asm/io.h>       // ioͷ�ļ����Ժ��Ƕ���������ʽ�����io�˿ڲ����ĺ�����

 33

 34 #include <stddef.h>       // ��׼����ͷ�ļ���������NULL, offsetof(TYPE, MEMBER)��

 35 #include <stdarg.h>       // ��׼����ͷ�ļ����Ժ����ʽ������������б�����Ҫ˵����-��

                              // ����(va_list)��������(va_start, va_arg��va_end)��vsprintf��

                              // vprintf��vfprintf��

 36 #include <unistd.h>

 37 #include <fcntl.h>        // �ļ�����ͷ�ļ��������ļ������������IJ������Ƴ������ŵĶ��塣

 38 #include <sys/types.h>    // ����ͷ�ļ��������˻�����ϵͳ�������͡�

 39

 40 #include <linux/fs.h>     // �ļ�ϵͳͷ�ļ��������ļ����ṹ��file,buffer_head,m_inode�ȣ���

 41                           // �����ж��壺extern int ROOT_DEV��

 42 #include <string.h>       // �ַ���ͷ�ļ�����Ҫ������һЩ�й��ڴ���ַ���������Ƕ�뺯����

 43

 44 static char printbuf[1024];           // ��̬�ַ������飬�����ں���ʾ��Ϣ�Ļ��档

 45

 46 extern char *strcpy();

 47 extern int vsprintf();                // �͸�ʽ�������һ�ַ����У�vsprintf.c��92�У���

 48 extern void init(void);               // ����ԭ�Σ���ʼ����������168�У���

 49 extern void blk_dev_init(void);       // ���豸��ʼ���ӳ���blk_drv/ll_rw_blk.c,157�У�

 50 extern void chr_dev_init(void);       // �ַ��豸��ʼ����chr_drv/tty_io.c, 347�У�

 51 extern void hd_init(void);            // Ӳ�̳�ʼ������blk_drv/hd.c, 343�У�

 52 extern void floppy_init(void);        // ������ʼ������blk_drv/floppy.c, 457�У�

 53 extern void mem_init(long start, long end);      // �ڴ������ʼ����mm/memory.c, 399�У�

 54 extern long rd_init(long mem_start, int length); // �����̳�ʼ��(blk_drv/ramdisk.c,52)

 55 extern long kernel_mktime(struct tm * tm);       // ����ϵͳ��������ʱ�䣨�룩��

 56

    // �ں�ר��sprintf()�������ú������ڲ�����ʽ����Ϣ�������ָ��������str�С�����'*fmt'

    // ָ����������õĸ�ʽ���μ���׼C�����鼮�����ӳ���������vsprintf���ʹ�õ�һ����

    // ���ӡ�����ʹ��vsprintf()����ʽ���ַ�������str���������μ���179���ϵ�printf()������

 57 static int sprintf(char * str, const char *fmt, ...)

 58 {

 59         va_list args;

 60         int i;

 61

 62         va_start(args, fmt);

 63         i = vsprintf(str, fmt, args);

 64         va_end(args);

 65         return i;

 66 }

 67

 68 /*

 69  * This is set up by the setup-routine at boot-time

 70  */

    /*

     * ������Щ���������ں������ڼ���setup.s�������õġ�

     */

    // �������зֱ�ָ�������Ե�ַǿ��ת��Ϊ�����������͵�ָ�룬����ȡָ����ָ���ݡ�����

    // �ں˴���α�ӳ�䵽��������ַ�㿪ʼ�ĵط��������Щ���Ե�ַ����Ҳ�Ƕ�Ӧ��������ַ��

    // ��Щָ����ַ���ڴ�ֵ�ĺ�����μ���6�µı�6-2��setup�����ȡ������IJ�������

    // drive_info�ṹ��μ������125�С�

 71 #define EXT_MEM_K (*(unsigned short *)0x90002)      // 1MB�Ժ����չ�ڴ��С��KB����

 72 #define CON_ROWS ((*(unsigned short *)0x9000e) & 0xff)  // ѡ���Ŀ���̨��Ļ�С�������

 73 #define CON_COLS (((*(unsigned short *)0x9000e) & 0xff00) >> 8)

 74 #define DRIVE_INFO (*(struct drive_info *)0x90080)  // Ӳ�̲�����32�ֽ����ݡ�

 75 #define ORIG_ROOT_DEV (*(unsigned short *)0x901FC)  // ���ļ�ϵͳ�����豸�š�

 76 #define ORIG_SWAP_DEV (*(unsigned short *)0x901FA)  // �����ļ������豸�š�

 77

 78 /*

 79  * Yeah, yeah, it's ugly, but I cannot find how to do this correctly

 80  * and this seems to work. I anybody has more info on the real-time

 81  * clock I'd be interested. Most of this was trial and error, and some

 82  * bios-listing reading. Urghh.

 83  */

    /*

     * �ǰ����ǰ���������γ���ܲ�����Ҳ�֪�������ȷ��ʵ�֣����Һ���

     * ���������С�����й���ʵʱʱ�Ӹ�������ϣ����Һܸ���Ȥ����Щ������

     * ̽�����ģ����⻹����һЩbios���򣬺ǣ�

     */

 84

    // ��κ��ȡCMOSʵʱʱ����Ϣ��outb_p��inb_p��include/asm/io.h�ж���Ķ˿���������ꡣ

 85 #define CMOS_READ(addr) ({ \

 86 outb_p(0x80|addr,0x70); \       // 0x70��д��ַ�˿ںţ�0x80|addr��Ҫ��ȡ��CMOS�ڴ��ַ��

 87 inb_p(0x71); \                  // 0x71�Ƕ����ݶ˿ںš�

 88 })

 89

    // ����ꡣ��BCD��ת���ɶ�������ֵ��BCD�����ð���ֽڣ�4���أ���ʾһ��10�����������

    // һ���ֽڱ�ʾ2��10��������(val)&15ȡBCD��ʾ��10���Ƹ�λ������ (val)>>4ȡBCD��ʾ

    // ��10����ʮλ�����ٳ���10��������������Ӿ���һ���ֽ�BCD���ʵ�ʶ�������ֵ��

 90 #define BCD_TO_BIN(val) ((val)=((val)&15) + ((val)>>4)*10)

 91

    // �ú���ȡCMOSʵʱ����Ϣ��Ϊ����ʱ�䣬�����浽ȫ�ֱ���startup_time(��)�С��μ�����

    // CMOS�ڴ��б�˵�������е��õĺ���kernel_mktime()���ڼ����1970��1��1��0ʱ��

    // �������վ�������������Ϊ����ʱ�䣨kernel/mktime.c 41�У���

 92 static void time_init(void)

 93 {

 94         struct tm time;                        // ʱ��ṹtm������include/time.h�С�

 95

    // CMOS�ķ����ٶȺ�����Ϊ�˼�Сʱ�����ڶ�ȡ������ѭ����������ֵ������ʱCMOS��

    // ��ֵ�����˱仯����ô�����¶�ȡ����ֵ�������ں˾��ܰ���CMOSʱ����������1��֮�ڡ�

 96         do {

 97                 time.tm_sec = CMOS_READ(0);       // ��ǰʱ����ֵ������BCD��ֵ����

 98                 time.tm_min = CMOS_READ(2);       // ��ǰ����ֵ��

 99                 time.tm_hour = CMOS_READ(4);      // ��ǰСʱֵ��

100                 time.tm_mday = CMOS_READ(7);      // һ���еĵ������ڡ�

101                 time.tm_mon = CMOS_READ(8);       // ��ǰ�·ݣ�1��12����

102                 time.tm_year = CMOS_READ(9);      // ��ǰ��ݡ�

103         } while (time.tm_sec != CMOS_READ(0));

104         BCD_TO_BIN(time.tm_sec);                  // ת���ɶ�������ֵ��

105         BCD_TO_BIN(time.tm_min);

106         BCD_TO_BIN(time.tm_hour);

107         BCD_TO_BIN(time.tm_mday);

108         BCD_TO_BIN(time.tm_mon);

109         BCD_TO_BIN(time.tm_year);

110         time.tm_mon--;                            // tm_mon���·ݷ�Χ��0��11��

111         startup_time = kernel_mktime(&time);      // ���㿪��ʱ�䡣kernel/mktime.c 41�С�

112 }

113

    // ���涨��һЩ�ֲ�������

114 static long memory_end = 0;                       // �������е������ڴ��������ֽ�������

115 static long buffer_memory_end = 0;                // ���ٻ�����ĩ�˵�ַ��

116 static long main_memory_start = 0;                // ���ڴ棨�����ڷ�ҳ����ʼ��λ�á�

117 static char term[32];                             // �ն������ַ�����������������

118

    // ��ȡ��ִ��/etc/rc�ļ�ʱ��ʹ�õ������в����ͻ���������

119 static char * argv_rc[] = { "/bin/sh", NULL };       // ����ִ�г���ʱ�������ַ������顣

120 static char * envp_rc[] = { "HOME=/", NULL ,NULL };  // ����ִ�г���ʱ�Ļ����ַ������顣

121

    // ���е�¼shellʱ��ʹ�õ������в����ͻ���������

    // ��122����argv[0]�е��ַ���-���Ǵ��ݸ�shell����sh��һ����־��ͨ��ʶ��ñ�־��

    // sh�������Ϊ��¼shellִ�С���ִ�й�������shell��ʾ����ִ��sh��һ����

122 static char * argv[] = { "-/bin/sh",NULL };          // ͬ�ϡ�

123 static char * envp[] = { "HOME=/usr/root", NULL, NULL };

124

125 struct drive_info { char dummy[32]; } drive_info;    // ���ڴ��Ӳ�̲�������Ϣ��

126

    // �ں˳�ʼ�������򡣳�ʼ��������������0��idle���񼴿������񣩵��������С�

    // Ӣ��ע�ͺ����ǡ�����ȷʵ��void��û������startup����(head.s)�о�����������ġ����μ�

    // head.s�����136�п�ʼ�ļ��д��롣

127 void main(void)         /* This really IS void, no error here. */

128 {                       /* The startup routine assumes (well, ...) this */

129 /*

130  * Interrupts are still disabled. Do necessary setups, then

131  * enable them

132  */

    /*

     * ��ʱ�ж��Ա���ֹ�ţ������Ҫ�����ú�ͽ��俪����

     */

    // ���ȱ�����ļ�ϵͳ�豸�źͽ����ļ��豸�ţ�������setup.s�����л�ȡ����Ϣ���ÿ���̨

    // �ն���Ļ�С�������������TERM�����������ó�ʼinit������ִ��etc/rc�ļ���shell����

    // ʹ�õĻ����������Լ������ڴ�0x90080����Ӳ�̲�������

    // ����ROOT_DEV ����ǰ���������include/linux/fs.h�ļ���206���ϱ�����Ϊextern int��

    // ��SWAP_DEV��include/linux/mm.h�ļ���Ҳ������ͬ����������mm.h�ļ���û����ʽ������

    // ������ǰ������Ϊǰ���������include/linux/sched.h�ļ����Ѿ���������

133         ROOT_DEV = ORIG_ROOT_DEV;               // ROOT_DEV������fs/super.c��29�С�

134         SWAP_DEV = ORIG_SWAP_DEV;               // SWAP_DEV������mm/swap.c��36�С�

135         sprintf(term, "TERM=con%dx%d", CON_COLS, CON_ROWS);

136         envp[1] = term;

137         envp_rc[1] = term;

138         drive_info = DRIVE_INFO;                // �����ڴ�0x90080����Ӳ�̲�������

 

    // ���Ÿ��ݻ��������ڴ��������ø��ٻ����������ڴ�����λ�úͷ�Χ��

    // ���ٻ���ĩ�˵�ַ��buffer_memory_end�������ڴ�������memory_end��

    // ���ڴ濪ʼ��ַ  ��main_memory_start��

139         memory_end = (1<<20) + (EXT_MEM_K<<10); // �ڴ��С=1Mb + ��չ�ڴ�(k)*1024�ֽڡ�

140         memory_end &= 0xfffff000;               // ���Բ���4Kb��1ҳ�����ڴ�����

141         if (memory_end > 16*1024*1024)          // ����ڴ�������16Mb����16Mb�ơ�

142                 memory_end = 16*1024*1024;

143         if (memory_end > 12*1024*1024)          // ����ڴ�>12Mb�������û�����ĩ��=4Mb

144                 buffer_memory_end = 4*1024*1024;

145         else if (memory_end > 6*1024*1024)      // �������ڴ�>6Mb�������û�����ĩ��=2Mb

146                 buffer_memory_end = 2*1024*1024;

147         else

148                 buffer_memory_end = 1*1024*1024; // ���������û�����ĩ��=1Mb

149         main_memory_start = buffer_memory_end;  // ���ڴ���ʼλ�� = ������ĩ�ˡ�

 

    // �����Makefile�ļ��ж������ڴ������̷���RAMDISK�����ʼ�������̡���ʱ���ڴ潫���١�

    //�μ�kernel/blk_drv/ramdisk.c��

150 #ifdef RAMDISK

151         main_memory_start += rd_init(main_memory_start, RAMDISK*1024);

152 #endif

    // �������ں˽������з���ij�ʼ���������Ķ�ʱ��ø��ŵ��õij��������ȥ������ʵ�ڿ�

    // ����ȥ�ˣ����ȷ�һ�ţ���������һ����ʼ������ -- ���Ǿ���̸֮J��

153         mem_init(main_memory_start,memory_end);  // ���ڴ�����ʼ������mm/memory.c��399��

154         trap_init();          // �����ţ�Ӳ���ж���������ʼ������kernel/traps.c��181��

155         blk_dev_init();       // ���豸��ʼ����    ��blk_drv/ll_rw_blk.c��157��

156         chr_dev_init();       // �ַ��豸��ʼ����  ��chr_drv/tty_io.c��347��

157         tty_init();           // tty��ʼ����      ��chr_drv/tty_io.c��406��

158         time_init();          // ���ÿ�������ʱ�䡣������92�У�

159         sched_init();         // ���ȳ����ʼ������������0��tr,ldtr����kernel/sched.c��385��

160         buffer_init(buffer_memory_end); // ���������ʼ�������ڴ������ȡ���fs/buffer.c��348��

161         hd_init();            // Ӳ�̳�ʼ����      ��blk_drv/hd.c��343��

162         floppy_init();        // ������ʼ����      ��blk_drv/floppy.c��457��

163         sti();                // ���г�ʼ�������������ˣ����ǿ����жϡ�

 

    // �������ͨ���ڶ�ջ�����õIJ����������жϷ���ָ����������0ִ�С�

164         move_to_user_mode();    // �Ƶ��û�ģʽ��ִ�С���include/asm/system.h����1�У�

165         if (!fork()) {          /* we count on this going ok */

166                 init();         // ���½����ӽ��̣�����1��init���̣���ִ�С�

167         }

 

    // ������뿪ʼ������0���������С�

168 /*

169  *   NOTE!!   For any other task 'pause()' would mean we have to get a

170  * signal to awaken, but task0 is the sole exception (see 'schedule()')

171  * as task 0 gets activated at every idle moment (when no other tasks

172  * can run). For task0 'pause()' just means we go check if some other

173  * task can run, and if not we return here.

174  */

    /* ע��!! �����κ�����������'pause()'����ζ�����DZ���ȴ��յ�һ���ź�

     * �Ż᷵�ؾ���̬��������0��task0����Ψһ����������μ�'schedule()'����

     * ��Ϊ����0���κο���ʱ���ﶼ�ᱻ�����û����������������ʱ�������

     * ��������0'pause()'����ζ�����Ƿ������鿴�Ƿ�����������������У����

     * û�еĻ����Ǿͻص����һֱѭ��ִ��'pause()'��

     */

    // pause()ϵͳ���ã�kernel/sched.c,144���������0ת���ɿ��жϵȴ�״̬����ִ�е��Ⱥ�����

    // ���ǵ��Ⱥ���ֻҪ����ϵͳ��û�����������������ʱ�ͻ��л�������0����������������0��

    // ״̬��

175         for(;;)

176                 __asm__("int $0x80"::"a" (__NR_pause):"ax");  // ��ִ��ϵͳ����pause()��

177 }

178

    // ���溯��������ʽ����Ϣ���������׼����豸stdout(1)��������ָ��Ļ����ʾ������'*fmt'

    // ָ����������õĸ�ʽ���μ���׼C�����鼮�����ӳ���������vsprintf���ʹ�õ�һ����

    // ���ӡ��ó���ʹ��vsprintf()����ʽ�����ַ�������printbuf��������Ȼ����write()������

    // ���������������׼�豸��1--stdout����vsprintf()������ʵ�ּ�kernel/vsprintf.c��

179 static int printf(const char *fmt, ...)

180 {

181         va_list args;

182         int i;

183

184         va_start(args, fmt);

185         write(1,printbuf,i=vsprintf(printbuf, fmt, args));

186         va_end(args);

187         return i;

188 }

189

 

    // ��main()���Ѿ�������ϵͳ��ʼ���������ڴ����������Ӳ���豸����������init()����

    // ����������0��1�δ������ӽ��̣�����1���С������ȶԵ�һ����Ҫִ�еij���shell��

    // �Ļ������г�ʼ����Ȼ���Ե�¼shell��ʽ���ظó���ִ��֮��

190 void init(void)

191 {

192         int pid,i;

193

    // setup() ��һ��ϵͳ���á����ڶ�ȡӲ�̲���������������Ϣ�����������̣������ڵĻ�����

    // ��װ���ļ�ϵͳ�豸���ú�����25���ϵĺ궨�壬��Ӧ������sys_setup()���ڿ��豸��Ŀ¼

    // kernel/blk_drv/hd.c��74�С�

194         setup((void *) &drive_info);

 

    // �����Զ�д���ʷ�ʽ���豸��/dev/tty0��������Ӧ�ն˿���̨���������ǵ�һ�δ��ļ�

    // ��������˲������ļ�����ţ��ļ����������϶���0���þ����UNIX�����ϵͳĬ�ϵĿ�

    // ��̨��׼������stdin�������ٰ����Զ���д�ķ�ʽ�ֱ����Ϊ�˸��Ʋ�����׼�����д��

    // ���stdout�ͱ�׼����������stderr������ǰ��ġ�(void)��ǰ׺���ڱ�ʾǿ�ƺ�������

    // ����ֵ��

195         (void) open("/dev/tty1",O_RDWR,0);

196         (void) dup(0);             // ���ƾ�����������1��--stdout��׼����豸��

197         (void) dup(0);             // ���ƾ�����������2��--stderr��׼��������豸��

 

    // �����ӡ���������������ֽ�����ÿ��1024�ֽڣ��Լ����ڴ��������ڴ��ֽ�����

198         printf("%d buffers = %d bytes buffer space\n\r",NR_BUFFERS,

199                 NR_BUFFERS*BLOCK_SIZE);

200         printf("Free mem: %d bytes\n\r",memory_end-main_memory_start);

 

    // ����fork()���ڴ���һ���ӽ��̣�����2�������ڱ��������ӽ��̣�fork()������0ֵ������

    // ԭ���̣������̣��򷵻��ӽ��̵Ľ��̺�pid�����Ե�202--206�����ӽ���ִ�е����ݡ�����

    // ���̹ر��˾��0��stdin������ֻ����ʽ��/etc/rc�ļ�����ʹ��execve()��������������

    // �滻�� /bin/sh���򣨼�shell���򣩣�Ȼ��ִ�� /bin/sh������Я���IJ����ͻ���������

    // ����argv_rc��envp_rc����������رվ��0�����̴� /etc/rc�ļ��������ǰѱ�׼����

    // stdin�ض��� /etc/rc�ļ�������shell����/bin/sh�Ϳ�������rc�ļ������õ������

    // ������sh�����з�ʽ�Ƿǽ���ʽ�ģ������ִ����rc�ļ��е������ͻ������˳�������2

    // Ҳ��֮����������execve()����˵����μ�fs/exec.c����207�С�

    // ����_exit()�˳�ʱ�ij�����1 �C ����δ���ɣ�2 -- �ļ���Ŀ¼�����ڡ�

201         if (!(pid=fork())) {

202                 close(0);

203                 if (open("/etc/rc",O_RDONLY,0))

204                         _exit(1);                // �����ļ�ʧ�ܣ����˳�(lib/_exit.c,10)��

205                 execve("/bin/sh",argv_rc,envp_rc);         // �滻��/bin/sh����ִ�С�

206                 _exit(2);                                  // ��execve()ִ��ʧ�����˳���

207         }

 

    // ���滹�Ǹ����̣�1��ִ�е���䡣wait()�ȴ��ӽ���ֹͣ����ֹ������ֵӦ���ӽ��̵Ľ��̺�

    // (pid)��������������Ǹ����̵ȴ��ӽ��̵Ľ�����&i�Ǵ�ŷ���״̬��Ϣ��λ�á����wait()

    // ����ֵ�������ӽ��̺ţ�������ȴ���

208         if (pid>0)

209                 while (pid != wait(&i))

210                         /* nothing */;       /* ��ѭ�� */

 

    // ���ִ�е����˵���մ������ӽ��̵�ִ����ֹͣ����ֹ�ˡ�����ѭ���������ٴ���һ����

    // ���̣��������������ʾ����ʼ�����򴴽��ӽ���ʧ�ܡ���Ϣ������ִ�С��������������ӽ�

    // �̽��ر�������ǰ�������ľ��(stdin, stdout, stderr)���´���һ���Ự�����ý�����ţ�

    // Ȼ�����´� /dev/tty0 ��Ϊ stdin�������Ƴ� stdout�� stderr���ٴ�ִ��ϵͳ���ͳ���

    // /bin/sh�������ִ����ѡ�õIJ����ͻ���������ѡ��һ�ף�������122--123�У���Ȼ�󸸽�

    // ���ٴ����� wait()�ȴ�������ӽ�����ֹͣ��ִ�У����ڱ�׼�������ʾ������Ϣ���ӽ���

    // pidֹͣ�����У���������i����Ȼ�����������ȥ�����γɡ�����ѭ����

211         while (1) {

212                 if ((pid=fork())<0) {

213                         printf("Fork failed in init\r\n");

214                         continue;

215                 }

216                 if (!pid) {                           // �µ��ӽ��̡�

217                         close(0);close(1);close(2);

218                         setsid();                     // ����һ�µĻỰ�ڣ�������˵����

219                         (void) open("/dev/tty1",O_RDWR,0);

220                         (void) dup(0);

221                         (void) dup(0);

222                         _exit(execve("/bin/sh",argv,envp));

223                 }

224                 while (1)

225                         if (pid == wait(&i))

226                                 break;

227                 printf("\n\rchild %d died with code %04x\n\r",pid,i);

228                 sync();                               // ͬ��������ˢ�»�������

229         }

230         _exit(0);       /* NOTE! _exit, not exit() */  /*ע�⣡��_exit()����exit()*/

    // _exit()��exit()������������ֹһ����������_exit()ֱ����һ��sys_exitϵͳ���ã���

    // exit()��ͨ������ͨ�������е�һ��������������ִ��һЩ����������������ִ�и���ֹ

    // �������򡢹ر����б�׼IO�ȣ�Ȼ�����sys_exit��

231 }

232