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