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