This source file includes following definitions.
- get_options
- profile_setup
- ramdisk_start_setup
- load_ramdisk
- prompt_ramdisk
- checksetup
- calibrate_delay
- parse_root_dev
- parse_options
- cpu_idle
- start_secondary
- smp_init
- smp_begin
- start_kernel
- printf
- do_rc
- do_shell
- do_linuxrc
- no_initrd
- init
1
2
3
4
5
6
7
8
9
10 #define __KERNEL_SYSCALLS__
11 #include <stdarg.h>
12
13 #include <asm/system.h>
14 #include <asm/io.h>
15
16 #include <linux/types.h>
17 #include <linux/fcntl.h>
18 #include <linux/config.h>
19 #include <linux/sched.h>
20 #include <linux/kernel.h>
21 #include <linux/tty.h>
22 #include <linux/head.h>
23 #include <linux/unistd.h>
24 #include <linux/string.h>
25 #include <linux/timer.h>
26 #include <linux/fs.h>
27 #include <linux/ctype.h>
28 #include <linux/delay.h>
29 #include <linux/utsname.h>
30 #include <linux/ioport.h>
31 #include <linux/hdreg.h>
32 #include <linux/mm.h>
33 #include <linux/major.h>
34 #include <linux/blk.h>
35 #ifdef CONFIG_ROOT_NFS
36 #include <linux/nfs_fs.h>
37 #endif
38
39 #include <asm/bugs.h>
40
41 extern char _stext, _etext;
42 extern char *linux_banner;
43
44 static char printbuf[1024];
45
46 extern int console_loglevel;
47
48 static int init(void *);
49 extern int bdflush(void *);
50 extern int kswapd(void *);
51
52 extern void init_IRQ(void);
53 extern void init_modules(void);
54 extern long console_init(long, long);
55 extern long kmalloc_init(long,long);
56 extern void sock_init(void);
57 extern long pci_init(long, long);
58 extern void sysctl_init(void);
59
60 extern void no_scroll(char *str, int *ints);
61 extern void swap_setup(char *str, int *ints);
62 extern void buff_setup(char *str, int *ints);
63 extern void panic_setup(char *str, int *ints);
64 extern void bmouse_setup(char *str, int *ints);
65 extern void lp_setup(char *str, int *ints);
66 extern void eth_setup(char *str, int *ints);
67 extern void xd_setup(char *str, int *ints);
68 extern void floppy_setup(char *str, int *ints);
69 extern void st_setup(char *str, int *ints);
70 extern void st0x_setup(char *str, int *ints);
71 extern void advansys_setup(char *str, int *ints);
72 extern void tmc8xx_setup(char *str, int *ints);
73 extern void t128_setup(char *str, int *ints);
74 extern void pas16_setup(char *str, int *ints);
75 extern void generic_NCR5380_setup(char *str, int *intr);
76 extern void generic_NCR53C400_setup(char *str, int *intr);
77 extern void aha152x_setup(char *str, int *ints);
78 extern void aha1542_setup(char *str, int *ints);
79 extern void aic7xxx_setup(char *str, int *ints);
80 extern void AM53C974_setup(char *str, int *ints);
81 extern void BusLogic_Setup(char *str, int *ints);
82 extern void fdomain_setup(char *str, int *ints);
83 extern void NCR53c406a_setup(char *str, int *ints);
84 extern void ppa_setup(char *str, int *ints);
85 extern void scsi_luns_setup(char *str, int *ints);
86 extern void sound_setup(char *str, int *ints);
87 #ifdef CONFIG_CDU31A
88 extern void cdu31a_setup(char *str, int *ints);
89 #endif CONFIG_CDU31A
90 #ifdef CONFIG_MCD
91 extern void mcd_setup(char *str, int *ints);
92 #endif CONFIG_MCD
93 #ifdef CONFIG_MCDX
94 extern void mcdx_setup(char *str, int *ints);
95 #endif CONFIG_MCDX
96 #ifdef CONFIG_SBPCD
97 extern void sbpcd_setup(char *str, int *ints);
98 #endif CONFIG_SBPCD
99 #ifdef CONFIG_AZTCD
100 extern void aztcd_setup(char *str, int *ints);
101 #endif CONFIG_AZTCD
102 #ifdef CONFIG_CDU535
103 extern void sonycd535_setup(char *str, int *ints);
104 #endif CONFIG_CDU535
105 #ifdef CONFIG_GSCD
106 extern void gscd_setup(char *str, int *ints);
107 #endif CONFIG_GSCD
108 #ifdef CONFIG_CM206
109 extern void cm206_setup(char *str, int *ints);
110 #endif CONFIG_CM206
111 #ifdef CONFIG_OPTCD
112 extern void optcd_setup(char *str, int *ints);
113 #endif CONFIG_OPTCD
114 #ifdef CONFIG_SJCD
115 extern void sjcd_setup(char *str, int *ints);
116 #endif CONFIG_SJCD
117 #ifdef CONFIG_ISP16_CDI
118 extern void isp16_setup(char *str, int *ints);
119 #endif CONFIG_ISP16_CDI
120 #ifdef CONFIG_BLK_DEV_RAM
121 static void ramdisk_start_setup(char *str, int *ints);
122 static void load_ramdisk(char *str, int *ints);
123 static void prompt_ramdisk(char *str, int *ints);
124 #ifdef CONFIG_BLK_DEV_INITRD
125 static void no_initrd(char *s,int *ints);
126 #endif
127 #endif CONFIG_BLK_DEV_RAM
128 #ifdef CONFIG_ISDN_DRV_ICN
129 extern void icn_setup(char *str, int *ints);
130 #endif
131 #ifdef CONFIG_ISDN_DRV_TELES
132 extern void teles_setup(char *str, int *ints);
133 #endif
134
135 #ifdef CONFIG_DIGI
136 extern void pcxx_setup(char *str, int *ints);
137 #endif
138 #ifdef CONFIG_ISDN_DRV_PCBIT
139 extern void pcbit_setup(char *str, int *ints);
140 #endif
141 #ifdef CONFIG_RISCOM8
142 extern void riscom8_setup(char *str, int *ints);
143 #endif
144
145
146 #if defined(CONFIG_SYSVIPC) || defined(CONFIG_KERNELD)
147 extern void ipc_init(void);
148 #endif
149
150
151
152
153 #define MAX_INIT_ARGS 8
154 #define MAX_INIT_ENVS 8
155
156 extern void time_init(void);
157
158 static unsigned long memory_start = 0;
159 static unsigned long memory_end = 0;
160
161 int rows, cols;
162
163 #ifdef CONFIG_BLK_DEV_RAM
164 extern int rd_doload;
165 extern int rd_prompt;
166 extern int rd_image_start;
167 #ifdef CONFIG_BLK_DEV_INITRD
168 kdev_t real_root_dev;
169 #endif
170 #endif
171
172 int root_mountflags = MS_RDONLY;
173 char *execute_command = 0;
174
175 #ifdef CONFIG_ROOT_NFS
176 char nfs_root_name[NFS_ROOT_NAME_LEN] = { "default" };
177 char nfs_root_addrs[NFS_ROOT_ADDRS_LEN] = { "" };
178 #endif
179
180 extern void dquot_init(void);
181
182 static char * argv_init[MAX_INIT_ARGS+2] = { "init", NULL, };
183 static char * envp_init[MAX_INIT_ENVS+2] = { "HOME=/", "TERM=linux", NULL, };
184
185 static char * argv_rc[] = { "/bin/sh", NULL };
186 static char * envp_rc[] = { "HOME=/", "TERM=linux", NULL };
187
188 static char * argv[] = { "-/bin/sh",NULL };
189 static char * envp[] = { "HOME=/usr/root", "TERM=linux", NULL };
190
191 char *get_options(char *str, int *ints)
192 {
193 char *cur = str;
194 int i=1;
195
196 while (cur && isdigit(*cur) && i <= 10) {
197 ints[i++] = simple_strtoul(cur,NULL,0);
198 if ((cur = strchr(cur,',')) != NULL)
199 cur++;
200 }
201 ints[0] = i-1;
202 return(cur);
203 }
204
205 static void profile_setup(char *str, int *ints)
206 {
207 if (ints[0] > 0)
208 prof_shift = (unsigned long) ints[1];
209 else
210 #ifdef CONFIG_PROFILE_SHIFT
211 prof_shift = CONFIG_PROFILE_SHIFT;
212 #else
213 prof_shift = 2;
214 #endif
215 }
216
217 struct {
218 const char *str;
219 void (*setup_func)(char *, int *);
220 } bootsetups[] = {
221 { "reserve=", reserve_setup },
222 { "profile=", profile_setup },
223 #ifdef CONFIG_BLK_DEV_RAM
224 { "ramdisk_start=", ramdisk_start_setup },
225 { "load_ramdisk=", load_ramdisk },
226 { "prompt_ramdisk=", prompt_ramdisk },
227 #ifdef CONFIG_BLK_DEV_INITRD
228 { "noinitrd", no_initrd },
229 #endif
230 #endif
231 { "swap=", swap_setup },
232 { "buff=", buff_setup },
233 { "panic=", panic_setup },
234 { "no-scroll", no_scroll },
235 #ifdef CONFIG_BUGi386
236 { "no-hlt", no_halt },
237 { "no387", no_387 },
238 #endif
239 #ifdef CONFIG_INET
240 { "ether=", eth_setup },
241 #endif
242 #ifdef CONFIG_PRINTER
243 { "lp=", lp_setup },
244 #endif
245 #ifdef CONFIG_SCSI
246 { "max_scsi_luns=", scsi_luns_setup },
247 #endif
248 #ifdef CONFIG_SCSI_ADVANSYS
249 { "advansys=", advansys_setup },
250 #endif
251 #if defined(CONFIG_BLK_DEV_HD)
252 { "hd=", hd_setup },
253 #endif
254 #ifdef CONFIG_CHR_DEV_ST
255 { "st=", st_setup },
256 #endif
257 #ifdef CONFIG_BUSMOUSE
258 { "bmouse=", bmouse_setup },
259 #endif
260 #ifdef CONFIG_SCSI_SEAGATE
261 { "st0x=", st0x_setup },
262 { "tmc8xx=", tmc8xx_setup },
263 #endif
264 #ifdef CONFIG_SCSI_T128
265 { "t128=", t128_setup },
266 #endif
267 #ifdef CONFIG_SCSI_PAS16
268 { "pas16=", pas16_setup },
269 #endif
270 #ifdef CONFIG_SCSI_GENERIC_NCR5380
271 { "ncr5380=", generic_NCR5380_setup },
272 { "ncr53c400=", generic_NCR53C400_setup },
273 #endif
274 #ifdef CONFIG_SCSI_AHA152X
275 { "aha152x=", aha152x_setup},
276 #endif
277 #ifdef CONFIG_SCSI_AHA1542
278 { "aha1542=", aha1542_setup},
279 #endif
280 #ifdef CONFIG_SCSI_AIC7XXX
281 { "aic7xxx=", aic7xxx_setup},
282 #endif
283 #ifdef CONFIG_SCSI_BUSLOGIC
284 { "BusLogic=", BusLogic_Setup},
285 #endif
286 #ifdef CONFIG_SCSI_AM53C974
287 { "AM53C974=", AM53C974_setup},
288 #endif
289 #ifdef CONFIG_SCSI_NCR53C406A
290 { "ncr53c406a=", NCR53c406a_setup},
291 #endif
292 #ifdef CONFIG_SCSI_FUTURE_DOMAIN
293 { "fdomain=", fdomain_setup},
294 #endif
295 #ifdef CONFIG_SCSI_PPA
296 { "ppa=", ppa_setup },
297 #endif
298 #ifdef CONFIG_BLK_DEV_XD
299 { "xd=", xd_setup },
300 #endif
301 #ifdef CONFIG_BLK_DEV_FD
302 { "floppy=", floppy_setup },
303 #endif
304 #ifdef CONFIG_CDU31A
305 { "cdu31a=", cdu31a_setup },
306 #endif CONFIG_CDU31A
307 #ifdef CONFIG_MCD
308 { "mcd=", mcd_setup },
309 #endif CONFIG_MCD
310 #ifdef CONFIG_MCDX
311 { "mcdx=", mcdx_setup },
312 #endif CONFIG_MCDX
313 #ifdef CONFIG_SBPCD
314 { "sbpcd=", sbpcd_setup },
315 #endif CONFIG_SBPCD
316 #ifdef CONFIG_AZTCD
317 { "aztcd=", aztcd_setup },
318 #endif CONFIG_AZTCD
319 #ifdef CONFIG_CDU535
320 { "sonycd535=", sonycd535_setup },
321 #endif CONFIG_CDU535
322 #ifdef CONFIG_GSCD
323 { "gscd=", gscd_setup },
324 #endif CONFIG_GSCD
325 #ifdef CONFIG_CM206
326 { "cm206=", cm206_setup },
327 #endif CONFIG_CM206
328 #ifdef CONFIG_OPTCD
329 { "optcd=", optcd_setup },
330 #endif CONFIG_OPTCD
331 #ifdef CONFIG_SJCD
332 { "sjcd=", sjcd_setup },
333 #endif CONFIG_SJCD
334 #ifdef CONFIG_ISP16_CDI
335 { "isp16=", isp16_setup },
336 #endif CONFIG_ISP16_CDI
337 #ifdef CONFIG_SOUND
338 { "sound=", sound_setup },
339 #endif
340 #ifdef CONFIG_ISDN_DRV_ICN
341 { "icn=", icn_setup },
342 #endif
343 #ifdef CONFIG_ISDN_DRV_TELES
344 { "teles=", teles_setup },
345 #endif
346 #ifdef CONFIG_ISDN_DRV_PCBIT
347 { "pcbit=", pcbit_setup },
348 #endif
349 #ifdef CONFIG_DIGI
350 { "digi=", pcxx_setup },
351 #endif
352 #ifdef CONFIG_RISCOM8
353 { "riscom8=", riscom8_setup },
354 #endif
355 { 0, 0 }
356 };
357
358 #ifdef CONFIG_BLK_DEV_RAM
359 static void ramdisk_start_setup(char *str, int *ints)
360 {
361 if (ints[0] > 0 && ints[1] >= 0)
362 rd_image_start = ints[1];
363 }
364
365 static void load_ramdisk(char *str, int *ints)
366 {
367 if (ints[0] > 0 && ints[1] >= 0)
368 rd_doload = ints[1] & 1;
369 }
370
371 static void prompt_ramdisk(char *str, int *ints)
372 {
373 if (ints[0] > 0 && ints[1] >= 0)
374 rd_prompt = ints[1] & 1;
375 }
376 #endif
377
378 static int checksetup(char *line)
379 {
380 int i = 0;
381 int ints[11];
382
383 #ifdef CONFIG_BLK_DEV_IDE
384
385 if (!strncmp(line,"ide",3) || (!strncmp(line,"hd",2) && line[2] != '=')) {
386 ide_setup(line);
387 return 1;
388 }
389 #endif
390 while (bootsetups[i].str) {
391 int n = strlen(bootsetups[i].str);
392 if (!strncmp(line,bootsetups[i].str,n)) {
393 bootsetups[i].setup_func(get_options(line+n,ints), ints);
394 return 1;
395 }
396 i++;
397 }
398 return 0;
399 }
400
401
402
403 unsigned long loops_per_sec = (1<<12);
404
405
406
407
408 #define LPS_PREC 8
409
410 void calibrate_delay(void)
411 {
412 int ticks;
413 int loopbit;
414 int lps_precision = LPS_PREC;
415
416 loops_per_sec = (1<<12);
417
418 printk("Calibrating delay loop.. ");
419 while (loops_per_sec <<= 1) {
420
421 ticks = jiffies;
422 while (ticks == jiffies)
423 ;
424
425 ticks = jiffies;
426 __delay(loops_per_sec);
427 ticks = jiffies - ticks;
428 if (ticks)
429 break;
430 }
431
432
433
434 loops_per_sec >>= 1;
435 loopbit = loops_per_sec;
436 while ( lps_precision-- && (loopbit >>= 1) ) {
437 loops_per_sec |= loopbit;
438 ticks = jiffies;
439 while (ticks == jiffies);
440 ticks = jiffies;
441 __delay(loops_per_sec);
442 if (jiffies != ticks)
443 loops_per_sec &= ~loopbit;
444 }
445
446
447 loops_per_sec *= HZ;
448
449 printk("ok - %lu.%02lu BogoMIPS\n",
450 (loops_per_sec+2500)/500000,
451 ((loops_per_sec+2500)/5000) % 100);
452 }
453
454 static void parse_root_dev(char * line)
455 {
456 int base = 0;
457 static struct dev_name_struct {
458 const char *name;
459 const int num;
460 } devices[] = {
461 { "nfs", 0x00ff },
462 { "hda", 0x0300 },
463 { "hdb", 0x0340 },
464 { "hdc", 0x1600 },
465 { "hdd", 0x1640 },
466 { "sda", 0x0800 },
467 { "sdb", 0x0810 },
468 { "sdc", 0x0820 },
469 { "sdd", 0x0830 },
470 { "sde", 0x0840 },
471 { "fd", 0x0200 },
472 { "xda", 0x0d00 },
473 { "xdb", 0x0d40 },
474 { "ram", 0x0100 },
475 { "scd", 0x0b00 },
476 { "mcd", 0x1700 },
477 { "cdu535", 0x1800 },
478 { "aztcd", 0x1d00 },
479 { "cm206cd", 0x2000 },
480 { "gscd", 0x1000 },
481 { "sbpcd", 0x1900 },
482 { "sonycd", 0x1800 },
483 { NULL, 0 }
484 };
485
486 if (strncmp(line,"/dev/",5) == 0) {
487 struct dev_name_struct *dev = devices;
488 line += 5;
489 do {
490 int len = strlen(dev->name);
491 if (strncmp(line,dev->name,len) == 0) {
492 line += len;
493 base = dev->num;
494 break;
495 }
496 dev++;
497 } while (dev->name);
498 }
499 ROOT_DEV = to_kdev_t(base + simple_strtoul(line,NULL,base?10:16));
500 }
501
502
503
504
505
506
507
508
509
510
511
512 static void parse_options(char *line)
513 {
514 char *next;
515 int args, envs;
516
517 if (!*line)
518 return;
519 args = 0;
520 envs = 1;
521 next = line;
522 while ((line = next) != NULL) {
523 if ((next = strchr(line,' ')) != NULL)
524 *next++ = 0;
525
526
527
528 if (!strncmp(line,"root=",5)) {
529 parse_root_dev(line+5);
530 continue;
531 }
532 #ifdef CONFIG_ROOT_NFS
533 if (!strncmp(line, "nfsroot=", 8)) {
534 int n;
535 line += 8;
536 ROOT_DEV = MKDEV(UNNAMED_MAJOR, 255);
537 if (line[0] == '/' || line[0] == ',' || (line[0] >= '0' && line[0] <= '9')) {
538 strncpy(nfs_root_name, line, sizeof(nfs_root_name));
539 nfs_root_name[sizeof(nfs_root_name)-1] = '\0';
540 continue;
541 }
542 n = strlen(line) + strlen(NFS_ROOT);
543 if (n >= sizeof(nfs_root_name))
544 line[sizeof(nfs_root_name) - strlen(NFS_ROOT) - 1] = '\0';
545 sprintf(nfs_root_name, NFS_ROOT, line);
546 continue;
547 }
548 if (!strncmp(line, "nfsaddrs=", 9)) {
549 line += 9;
550 strncpy(nfs_root_addrs, line, sizeof(nfs_root_addrs));
551 nfs_root_addrs[sizeof(nfs_root_addrs)-1] = '\0';
552 continue;
553 }
554 #endif
555 if (!strcmp(line,"ro")) {
556 root_mountflags |= MS_RDONLY;
557 continue;
558 }
559 if (!strcmp(line,"rw")) {
560 root_mountflags &= ~MS_RDONLY;
561 continue;
562 }
563 if (!strcmp(line,"debug")) {
564 console_loglevel = 10;
565 continue;
566 }
567 if (!strncmp(line,"init=",5)) {
568 line += 5;
569 execute_command = line;
570 continue;
571 }
572 if (checksetup(line))
573 continue;
574
575
576
577
578 if (strchr(line,'=')) {
579 if (envs >= MAX_INIT_ENVS)
580 break;
581 envp_init[++envs] = line;
582 } else {
583 if (args >= MAX_INIT_ARGS)
584 break;
585 argv_init[++args] = line;
586 }
587 }
588 argv_init[args+1] = NULL;
589 envp_init[envs+1] = NULL;
590 }
591
592
593 extern void setup_arch(char **, unsigned long *, unsigned long *);
594 extern void arch_syms_export(void);
595
596 #ifndef __SMP__
597
598
599
600
601
602 int cpu_idle(void *unused)
603 {
604 for(;;)
605 idle();
606 }
607
608 #else
609
610
611
612
613
614 extern int cpu_idle(void * unused);
615
616
617
618
619
620 asmlinkage void start_secondary(void)
621 {
622 trap_init();
623 init_IRQ();
624 smp_callin();
625 cpu_idle(NULL);
626 }
627
628
629
630
631
632
633
634 static void smp_init(void)
635 {
636 int i, j;
637 smp_boot_cpus();
638
639
640
641
642
643
644
645
646 for (i=1; i<smp_num_cpus; i++)
647 {
648 struct task_struct *n, *p;
649
650 j = cpu_logical_map[i];
651
652
653
654
655 kernel_thread(cpu_idle, NULL, CLONE_PID);
656
657
658
659 current_set[j]=task[i];
660 current_set[j]->processor=j;
661 cli();
662 n = task[i]->next_run;
663 p = task[i]->prev_run;
664 nr_running--;
665 n->prev_run = p;
666 p->next_run = n;
667 task[i]->next_run = task[i]->prev_run = task[i];
668 sti();
669 }
670 }
671
672
673
674
675
676
677
678 static void smp_begin(void)
679 {
680 smp_threads_ready=1;
681 smp_commence();
682 }
683
684 #endif
685
686
687
688
689
690 asmlinkage void start_kernel(void)
691 {
692 char * command_line;
693
694
695
696
697
698 #ifdef __SMP__
699 static int first_cpu=1;
700
701 if(!first_cpu)
702 start_secondary();
703 first_cpu=0;
704
705 #endif
706
707
708
709
710 setup_arch(&command_line, &memory_start, &memory_end);
711 memory_start = paging_init(memory_start,memory_end);
712 trap_init();
713 init_IRQ();
714 sched_init();
715 time_init();
716 parse_options(command_line);
717 #ifdef CONFIG_MODULES
718 init_modules();
719 #endif
720 #ifdef CONFIG_PROFILE
721 if (!prof_shift)
722 #ifdef CONFIG_PROFILE_SHIFT
723 prof_shift = CONFIG_PROFILE_SHIFT;
724 #else
725 prof_shift = 2;
726 #endif
727 #endif
728 if (prof_shift) {
729 prof_buffer = (unsigned int *) memory_start;
730
731 prof_len = (unsigned long) &_etext - (unsigned long) &_stext;
732 prof_len >>= prof_shift;
733 memory_start += prof_len * sizeof(unsigned int);
734 }
735 memory_start = console_init(memory_start,memory_end);
736 #ifdef CONFIG_PCI
737 memory_start = pci_init(memory_start,memory_end);
738 #endif
739 memory_start = kmalloc_init(memory_start,memory_end);
740 sti();
741 calibrate_delay();
742 memory_start = inode_init(memory_start,memory_end);
743 memory_start = file_table_init(memory_start,memory_end);
744 memory_start = name_cache_init(memory_start,memory_end);
745 #ifdef CONFIG_BLK_DEV_INITRD
746 if (initrd_start && initrd_start < memory_start) {
747 printk(KERN_CRIT "initrd overwritten (0x%08lx < 0x%08lx) - "
748 "disabling it.\n",initrd_start,memory_start);
749 initrd_start = 0;
750 }
751 #endif
752 mem_init(memory_start,memory_end);
753 buffer_init();
754 sock_init();
755 #if defined(CONFIG_SYSVIPC) || defined(CONFIG_KERNELD)
756 ipc_init();
757 #endif
758 dquot_init();
759 arch_syms_export();
760 sti();
761 check_bugs();
762
763 printk(linux_banner);
764 #ifdef __SMP__
765 smp_init();
766 #endif
767 sysctl_init();
768
769
770
771
772
773 kernel_thread(init, NULL, 0);
774
775
776
777
778
779
780
781
782
783 cpu_idle(NULL);
784 }
785
786 static int printf(const char *fmt, ...)
787 {
788 va_list args;
789 int i;
790
791 va_start(args, fmt);
792 write(1,printbuf,i=vsprintf(printbuf, fmt, args));
793 va_end(args);
794 return i;
795 }
796
797 static int do_rc(void * rc)
798 {
799 close(0);
800 if (open(rc,O_RDONLY,0))
801 return -1;
802 return execve("/bin/sh", argv_rc, envp_rc);
803 }
804
805 static int do_shell(void * shell)
806 {
807 close(0);close(1);close(2);
808 setsid();
809 (void) open("/dev/tty1",O_RDWR,0);
810 (void) dup(0);
811 (void) dup(0);
812 return execve(shell, argv, envp);
813 }
814
815 #ifdef CONFIG_BLK_DEV_INITRD
816 static int do_linuxrc(void * shell)
817 {
818 static char *argv[] = { "linuxrc", NULL, };
819
820 close(0);close(1);close(2);
821 setsid();
822 (void) open("/dev/tty1",O_RDWR,0);
823 (void) dup(0);
824 (void) dup(0);
825 return execve(shell, argv, envp_init);
826 }
827
828 static void no_initrd(char *s,int *ints)
829 {
830 mount_initrd = 0;
831 }
832 #endif
833
834 static int init(void * unused)
835 {
836 int pid,i;
837 #ifdef CONFIG_BLK_DEV_INITRD
838 int real_root_mountflags;
839 #endif
840
841
842 kernel_thread(bdflush, NULL, 0);
843
844 kernel_thread(kswapd, NULL, 0);
845
846 #ifdef CONFIG_BLK_DEV_INITRD
847 real_root_dev = ROOT_DEV;
848 real_root_mountflags = root_mountflags;
849 if (initrd_start && mount_initrd) root_mountflags &= ~MS_RDONLY;
850 else mount_initrd =0;
851 #endif
852 setup();
853
854 #ifdef __SMP__
855
856
857
858
859
860 smp_begin();
861 #endif
862
863 #ifdef CONFIG_UMSDOS_FS
864 {
865
866
867
868
869
870 extern struct inode *pseudo_root;
871 if (pseudo_root != NULL){
872 current->fs->root = pseudo_root;
873 current->fs->pwd = pseudo_root;
874 }
875 }
876 #endif
877
878 #ifdef CONFIG_BLK_DEV_INITRD
879 root_mountflags = real_root_mountflags;
880 if (mount_initrd && ROOT_DEV != real_root_dev && ROOT_DEV == MKDEV(RAMDISK_MAJOR,0)) {
881 int error;
882
883 pid = kernel_thread(do_linuxrc, "/linuxrc", SIGCHLD);
884 if (pid>0)
885 while (pid != wait(&i));
886 if (real_root_dev != MKDEV(RAMDISK_MAJOR, 0)) {
887 error = change_root(real_root_dev,"/initrd");
888 if (error)
889 printk(KERN_ERR "Change root to /initrd: "
890 "error %d\n",error);
891 }
892 }
893 #endif
894
895 (void) open("/dev/tty1",O_RDWR,0);
896 (void) dup(0);
897 (void) dup(0);
898
899 if (!execute_command) {
900 execve("/etc/init",argv_init,envp_init);
901 execve("/bin/init",argv_init,envp_init);
902 execve("/sbin/init",argv_init,envp_init);
903
904
905 pid = kernel_thread(do_rc, "/etc/rc", SIGCHLD);
906 if (pid>0)
907 while (pid != wait(&i))
908 ;
909 }
910
911 while (1) {
912 pid = kernel_thread(do_shell,
913 execute_command ? execute_command : "/bin/sh",
914 SIGCHLD);
915 if (pid < 0) {
916 printf("Fork failed in init\n\r");
917 continue;
918 }
919 while (1)
920 if (pid == wait(&i))
921 break;
922 printf("\n\rchild %d died with code %04x\n\r",pid,i);
923 sync();
924 }
925 return -1;
926 }