root/init/main.c

/* [previous][next][first][last][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. get_options
  2. profile_setup
  3. ramdisk_start_setup
  4. load_ramdisk
  5. prompt_ramdisk
  6. ramdisk_size
  7. checksetup
  8. calibrate_delay
  9. parse_root_dev
  10. parse_options
  11. cpu_idle
  12. start_secondary
  13. smp_init
  14. smp_begin
  15. start_kernel
  16. printf
  17. do_rc
  18. do_shell
  19. do_linuxrc
  20. no_initrd
  21. init

   1 /*
   2  *  linux/init/main.c
   3  *
   4  *  Copyright (C) 1991, 1992  Linus Torvalds
   5  *
   6  *  GK 2/5/95  -  Changed to support mounting root fs via NFS
   7  *  Added initrd & change_root: Werner Almesberger & Hans Lermen, Feb '96
   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 static void ramdisk_size(char *str, int *ints);
 125 #ifdef CONFIG_BLK_DEV_INITRD
 126 static void no_initrd(char *s,int *ints);
 127 #endif
 128 #endif CONFIG_BLK_DEV_RAM
 129 #ifdef CONFIG_ISDN_DRV_ICN
 130 extern void icn_setup(char *str, int *ints);
 131 #endif
 132 #ifdef CONFIG_ISDN_DRV_TELES
 133 extern void teles_setup(char *str, int *ints);
 134 #endif
 135 
 136 #ifdef CONFIG_ATARIMOUSE
 137 extern void atari_mouse_setup (char *str, int *ints);
 138 #endif
 139 #ifdef CONFIG_DMASOUND
 140 extern void dmasound_setup (char *str, int *ints);
 141 #endif
 142 #ifdef CONFIG_ATARI_SCSI
 143 extern void atari_scsi_setup (char *str, int *ints);
 144 #endif
 145 extern void wd33c93_setup (char *str, int *ints);
 146 extern void gvp11_setup (char *str, int *ints);
 147 
 148 #ifdef CONFIG_DIGI
 149 extern void pcxx_setup(char *str, int *ints);
 150 #endif
 151 #ifdef CONFIG_ISDN_DRV_PCBIT
 152 extern void pcbit_setup(char *str, int *ints);
 153 #endif
 154 #ifdef CONFIG_RISCOM8
 155 extern void riscom8_setup(char *str, int *ints);
 156 #endif
 157 
 158 
 159 #if defined(CONFIG_SYSVIPC) || defined(CONFIG_KERNELD)
 160 extern void ipc_init(void);
 161 #endif
 162 
 163 /*
 164  * Boot command-line arguments
 165  */
 166 #define MAX_INIT_ARGS 8
 167 #define MAX_INIT_ENVS 8
 168 
 169 extern void time_init(void);
 170 
 171 static unsigned long memory_start = 0;
 172 static unsigned long memory_end = 0;
 173 
 174 int rows, cols;
 175 
 176 #ifdef CONFIG_BLK_DEV_RAM
 177 extern int rd_doload;           /* 1 = load ramdisk, 0 = don't load */
 178 extern int rd_prompt;           /* 1 = prompt for ramdisk, 0 = don't prompt */
 179 extern int rd_size;             /* Size of the ramdisk(s) */
 180 extern int rd_image_start;      /* starting block # of image */
 181 #ifdef CONFIG_BLK_DEV_INITRD
 182 kdev_t real_root_dev;
 183 #endif
 184 #endif
 185 
 186 int root_mountflags = MS_RDONLY;
 187 char *execute_command = 0;
 188 
 189 #ifdef CONFIG_ROOT_NFS
 190 char nfs_root_name[NFS_ROOT_NAME_LEN] = { "default" };
 191 char nfs_root_addrs[NFS_ROOT_ADDRS_LEN] = { "" };
 192 #endif
 193 
 194 extern void dquot_init(void);
 195 
 196 static char * argv_init[MAX_INIT_ARGS+2] = { "init", NULL, };
 197 static char * envp_init[MAX_INIT_ENVS+2] = { "HOME=/", "TERM=linux", NULL, };
 198 
 199 static char * argv_rc[] = { "/bin/sh", NULL };
 200 static char * envp_rc[] = { "HOME=/", "TERM=linux", NULL };
 201 
 202 static char * argv[] = { "-/bin/sh",NULL };
 203 static char * envp[] = { "HOME=/usr/root", "TERM=linux", NULL };
 204 
 205 char *get_options(char *str, int *ints)
     /* [previous][next][first][last][top][bottom][index][help] */
 206 {
 207         char *cur = str;
 208         int i=1;
 209 
 210         while (cur && isdigit(*cur) && i <= 10) {
 211                 ints[i++] = simple_strtoul(cur,NULL,0);
 212                 if ((cur = strchr(cur,',')) != NULL)
 213                         cur++;
 214         }
 215         ints[0] = i-1;
 216         return(cur);
 217 }
 218 
 219 static void profile_setup(char *str, int *ints)
     /* [previous][next][first][last][top][bottom][index][help] */
 220 {
 221         if (ints[0] > 0)
 222                 prof_shift = (unsigned long) ints[1];
 223         else
 224 #ifdef CONFIG_PROFILE_SHIFT
 225                 prof_shift = CONFIG_PROFILE_SHIFT;
 226 #else
 227                 prof_shift = 2;
 228 #endif
 229 }
 230 
 231 struct {
 232         const char *str;
 233         void (*setup_func)(char *, int *);
 234 } bootsetups[] = {
 235         { "reserve=", reserve_setup },
 236         { "profile=", profile_setup },
 237 #ifdef CONFIG_BLK_DEV_RAM
 238         { "ramdisk_start=", ramdisk_start_setup },
 239         { "load_ramdisk=", load_ramdisk },
 240         { "prompt_ramdisk=", prompt_ramdisk },
 241         { "ramdisk=", ramdisk_size },
 242         { "ramdisk_size=", ramdisk_size },
 243 #ifdef CONFIG_BLK_DEV_INITRD
 244         { "noinitrd", no_initrd },
 245 #endif
 246 #endif
 247         { "swap=", swap_setup },
 248         { "buff=", buff_setup },
 249         { "panic=", panic_setup },
 250         { "no-scroll", no_scroll },
 251 #ifdef CONFIG_BUGi386
 252         { "no-hlt", no_halt },
 253         { "no387", no_387 },
 254 #endif
 255 #ifdef CONFIG_INET
 256         { "ether=", eth_setup },
 257 #endif
 258 #ifdef CONFIG_PRINTER
 259         { "lp=", lp_setup },
 260 #endif
 261 #ifdef CONFIG_SCSI
 262         { "max_scsi_luns=", scsi_luns_setup },
 263 #endif
 264 #ifdef CONFIG_SCSI_ADVANSYS
 265         { "advansys=", advansys_setup },
 266 #endif
 267 #if defined(CONFIG_BLK_DEV_HD)
 268         { "hd=", hd_setup },
 269 #endif
 270 #ifdef CONFIG_CHR_DEV_ST
 271         { "st=", st_setup },
 272 #endif
 273 #ifdef CONFIG_BUSMOUSE
 274         { "bmouse=", bmouse_setup },
 275 #endif
 276 #ifdef CONFIG_SCSI_SEAGATE
 277         { "st0x=", st0x_setup },
 278         { "tmc8xx=", tmc8xx_setup },
 279 #endif
 280 #ifdef CONFIG_SCSI_T128
 281         { "t128=", t128_setup },
 282 #endif
 283 #ifdef CONFIG_SCSI_PAS16
 284         { "pas16=", pas16_setup },
 285 #endif
 286 #ifdef CONFIG_SCSI_GENERIC_NCR5380
 287         { "ncr5380=", generic_NCR5380_setup },
 288         { "ncr53c400=", generic_NCR53C400_setup },
 289 #endif
 290 #ifdef CONFIG_SCSI_AHA152X
 291         { "aha152x=", aha152x_setup},
 292 #endif
 293 #ifdef CONFIG_SCSI_AHA1542
 294         { "aha1542=", aha1542_setup},
 295 #endif
 296 #ifdef CONFIG_SCSI_AIC7XXX
 297         { "aic7xxx=", aic7xxx_setup},
 298 #endif
 299 #ifdef CONFIG_SCSI_BUSLOGIC
 300         { "BusLogic=", BusLogic_Setup},
 301 #endif
 302 #ifdef CONFIG_SCSI_AM53C974
 303         { "AM53C974=", AM53C974_setup},
 304 #endif
 305 #ifdef CONFIG_SCSI_NCR53C406A
 306         { "ncr53c406a=", NCR53c406a_setup},
 307 #endif
 308 #ifdef CONFIG_SCSI_FUTURE_DOMAIN
 309         { "fdomain=", fdomain_setup},
 310 #endif
 311 #ifdef CONFIG_SCSI_PPA
 312         { "ppa=", ppa_setup },
 313 #endif
 314 #ifdef CONFIG_BLK_DEV_XD
 315         { "xd=", xd_setup },
 316 #endif
 317 #ifdef CONFIG_BLK_DEV_FD
 318         { "floppy=", floppy_setup },
 319 #endif
 320 #ifdef CONFIG_CDU31A
 321         { "cdu31a=", cdu31a_setup },
 322 #endif CONFIG_CDU31A
 323 #ifdef CONFIG_MCD
 324         { "mcd=", mcd_setup },
 325 #endif CONFIG_MCD
 326 #ifdef CONFIG_MCDX
 327         { "mcdx=", mcdx_setup },
 328 #endif CONFIG_MCDX
 329 #ifdef CONFIG_SBPCD
 330         { "sbpcd=", sbpcd_setup },
 331 #endif CONFIG_SBPCD
 332 #ifdef CONFIG_AZTCD
 333         { "aztcd=", aztcd_setup },
 334 #endif CONFIG_AZTCD
 335 #ifdef CONFIG_CDU535
 336         { "sonycd535=", sonycd535_setup },
 337 #endif CONFIG_CDU535
 338 #ifdef CONFIG_GSCD
 339         { "gscd=", gscd_setup },
 340 #endif CONFIG_GSCD
 341 #ifdef CONFIG_CM206
 342         { "cm206=", cm206_setup },
 343 #endif CONFIG_CM206
 344 #ifdef CONFIG_OPTCD
 345         { "optcd=", optcd_setup },
 346 #endif CONFIG_OPTCD
 347 #ifdef CONFIG_SJCD
 348         { "sjcd=", sjcd_setup },
 349 #endif CONFIG_SJCD
 350 #ifdef CONFIG_ISP16_CDI
 351         { "isp16=", isp16_setup },
 352 #endif CONFIG_ISP16_CDI
 353 #ifdef CONFIG_SOUND
 354         { "sound=", sound_setup },
 355 #endif
 356 #ifdef CONFIG_ISDN_DRV_ICN
 357         { "icn=", icn_setup },
 358 #endif
 359 #ifdef CONFIG_ISDN_DRV_TELES
 360         { "teles=", teles_setup },
 361 #endif
 362 #ifdef CONFIG_ISDN_DRV_PCBIT
 363         { "pcbit=", pcbit_setup },
 364 #endif
 365 #ifdef CONFIG_ATARIMOUSE
 366         { "atamouse=", atari_mouse_setup },
 367 #endif
 368 #ifdef CONFIG_DMASOUND
 369         { "dmasound=", dmasound_setup },
 370 #endif
 371 #ifdef CONFIG_ATARI_SCSI
 372         { "atascsi=", atari_scsi_setup },
 373 #endif
 374 #if defined(CONFIG_A3000_SCSI) || defined(CONFIG_A2091_SCSI) \
 375             || defined(CONFIG_GVP11_SCSI)
 376         { "wd33c93=", wd33c93_setup },
 377 #endif
 378 #if defined(CONFIG_GVP11_SCSI)
 379         { "gvp11=", gvp11_setup },
 380 #endif
 381 #ifdef CONFIG_DIGI
 382         { "digi=", pcxx_setup },
 383 #endif
 384 #ifdef CONFIG_RISCOM8
 385         { "riscom8=", riscom8_setup },
 386 #endif
 387         { 0, 0 }
 388 };
 389 
 390 #ifdef CONFIG_BLK_DEV_RAM
 391 static void ramdisk_start_setup(char *str, int *ints)
     /* [previous][next][first][last][top][bottom][index][help] */
 392 {
 393    if (ints[0] > 0 && ints[1] >= 0)
 394       rd_image_start = ints[1];
 395 }
 396 
 397 static void load_ramdisk(char *str, int *ints)
     /* [previous][next][first][last][top][bottom][index][help] */
 398 {
 399    if (ints[0] > 0 && ints[1] >= 0)
 400       rd_doload = ints[1] & 1;
 401 }
 402 
 403 static void prompt_ramdisk(char *str, int *ints)
     /* [previous][next][first][last][top][bottom][index][help] */
 404 {
 405    if (ints[0] > 0 && ints[1] >= 0)
 406       rd_prompt = ints[1] & 1;
 407 }
 408 
 409 static void ramdisk_size(char *str, int *ints)
     /* [previous][next][first][last][top][bottom][index][help] */
 410 {
 411         if (ints[0] > 0 && ints[1] >= 0)
 412                 rd_size = ints[1];
 413 }
 414 
 415 #endif
 416 
 417 static int checksetup(char *line)
     /* [previous][next][first][last][top][bottom][index][help] */
 418 {
 419         int i = 0;
 420         int ints[11];
 421 
 422 #ifdef CONFIG_BLK_DEV_IDE
 423         /* ide driver needs the basic string, rather than pre-processed values */
 424         if (!strncmp(line,"ide",3) || (!strncmp(line,"hd",2) && line[2] != '=')) {
 425                 ide_setup(line);
 426                 return 1;
 427         }
 428 #endif
 429         while (bootsetups[i].str) {
 430                 int n = strlen(bootsetups[i].str);
 431                 if (!strncmp(line,bootsetups[i].str,n)) {
 432                         bootsetups[i].setup_func(get_options(line+n,ints), ints);
 433                         return 1;
 434                 }
 435                 i++;
 436         }
 437         return 0;
 438 }
 439 
 440 /* this should be approx 2 Bo*oMips to start (note initial shift), and will
 441    still work even if initially too large, it will just take slightly longer */
 442 unsigned long loops_per_sec = (1<<12);
 443 
 444 /* This is the number of bits of precision for the loops_per_second.  Each
 445    bit takes on average 1.5/HZ seconds.  This (like the original) is a little
 446    better than 1% */
 447 #define LPS_PREC 8
 448 
 449 void calibrate_delay(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 450 {
 451         int ticks;
 452         int loopbit;
 453         int lps_precision = LPS_PREC;
 454 
 455         loops_per_sec = (1<<12);
 456 
 457         printk("Calibrating delay loop.. ");
 458         while (loops_per_sec <<= 1) {
 459                 /* wait for "start of" clock tick */
 460                 ticks = jiffies;
 461                 while (ticks == jiffies)
 462                         /* nothing */;
 463                 /* Go .. */
 464                 ticks = jiffies;
 465                 __delay(loops_per_sec);
 466                 ticks = jiffies - ticks;
 467                 if (ticks)
 468                         break;
 469                 }
 470 
 471 /* Do a binary approximation to get loops_per_second set to equal one clock
 472    (up to lps_precision bits) */
 473         loops_per_sec >>= 1;
 474         loopbit = loops_per_sec;
 475         while ( lps_precision-- && (loopbit >>= 1) ) {
 476                 loops_per_sec |= loopbit;
 477                 ticks = jiffies;
 478                 while (ticks == jiffies);
 479                 ticks = jiffies;
 480                 __delay(loops_per_sec);
 481                 if (jiffies != ticks)   /* longer than 1 tick */
 482                         loops_per_sec &= ~loopbit;
 483         }
 484 
 485 /* finally, adjust loops per second in terms of seconds instead of clocks */    
 486         loops_per_sec *= HZ;
 487 /* Round the value and print it */      
 488         printk("ok - %lu.%02lu BogoMIPS\n",
 489                 (loops_per_sec+2500)/500000,
 490                 ((loops_per_sec+2500)/5000) % 100);
 491 }
 492 
 493 static void parse_root_dev(char * line)
     /* [previous][next][first][last][top][bottom][index][help] */
 494 {
 495         int base = 0;
 496         static struct dev_name_struct {
 497                 const char *name;
 498                 const int num;
 499         } devices[] = {
 500                 { "nfs",     0x00ff },
 501                 { "hda",     0x0300 },
 502                 { "hdb",     0x0340 },
 503                 { "hdc",     0x1600 },
 504                 { "hdd",     0x1640 },
 505                 { "sda",     0x0800 },
 506                 { "sdb",     0x0810 },
 507                 { "sdc",     0x0820 },
 508                 { "sdd",     0x0830 },
 509                 { "sde",     0x0840 },
 510                 { "fd",      0x0200 },
 511                 { "xda",     0x0d00 },
 512                 { "xdb",     0x0d40 },
 513                 { "ram",     0x0100 },
 514                 { "scd",     0x0b00 },
 515                 { "mcd",     0x1700 },
 516                 { "cdu535",  0x1800 },
 517                 { "aztcd",   0x1d00 },
 518                 { "cm206cd", 0x2000 },
 519                 { "gscd",    0x1000 },
 520                 { "sbpcd",   0x1900 },
 521                 { "sonycd",  0x1800 },
 522                 { NULL, 0 }
 523         };
 524 
 525         if (strncmp(line,"/dev/",5) == 0) {
 526                 struct dev_name_struct *dev = devices;
 527                 line += 5;
 528                 do {
 529                         int len = strlen(dev->name);
 530                         if (strncmp(line,dev->name,len) == 0) {
 531                                 line += len;
 532                                 base = dev->num;
 533                                 break;
 534                         }
 535                         dev++;
 536                 } while (dev->name);
 537         }
 538         ROOT_DEV = to_kdev_t(base + simple_strtoul(line,NULL,base?10:16));
 539 }
 540 
 541 /*
 542  * This is a simple kernel command line parsing function: it parses
 543  * the command line, and fills in the arguments/environment to init
 544  * as appropriate. Any cmd-line option is taken to be an environment
 545  * variable if it contains the character '='.
 546  *
 547  *
 548  * This routine also checks for options meant for the kernel.
 549  * These options are not given to init - they are for internal kernel use only.
 550  */
 551 static void parse_options(char *line)
     /* [previous][next][first][last][top][bottom][index][help] */
 552 {
 553         char *next;
 554         int args, envs;
 555 
 556         if (!*line)
 557                 return;
 558         args = 0;
 559         envs = 1;       /* TERM is set to 'linux' by default */
 560         next = line;
 561         while ((line = next) != NULL) {
 562                 if ((next = strchr(line,' ')) != NULL)
 563                         *next++ = 0;
 564                 /*
 565                  * check for kernel options first..
 566                  */
 567                 if (!strncmp(line,"root=",5)) {
 568                         parse_root_dev(line+5);
 569                         continue;
 570                 }
 571 #ifdef CONFIG_ROOT_NFS
 572                 if (!strncmp(line, "nfsroot=", 8)) {
 573                         int n;
 574                         line += 8;
 575                         ROOT_DEV = MKDEV(UNNAMED_MAJOR, 255);
 576                         if (line[0] == '/' || line[0] == ',' || (line[0] >= '0' && line[0] <= '9')) {
 577                                 strncpy(nfs_root_name, line, sizeof(nfs_root_name));
 578                                 nfs_root_name[sizeof(nfs_root_name)-1] = '\0';
 579                                 continue;
 580                         }
 581                         n = strlen(line) + strlen(NFS_ROOT);
 582                         if (n >= sizeof(nfs_root_name))
 583                                 line[sizeof(nfs_root_name) - strlen(NFS_ROOT) - 1] = '\0';
 584                         sprintf(nfs_root_name, NFS_ROOT, line);
 585                         continue;
 586                 }
 587                 if (!strncmp(line, "nfsaddrs=", 9)) {
 588                         line += 9;
 589                         strncpy(nfs_root_addrs, line, sizeof(nfs_root_addrs));
 590                         nfs_root_addrs[sizeof(nfs_root_addrs)-1] = '\0';
 591                         continue;
 592                 }
 593 #endif
 594                 if (!strcmp(line,"ro")) {
 595                         root_mountflags |= MS_RDONLY;
 596                         continue;
 597                 }
 598                 if (!strcmp(line,"rw")) {
 599                         root_mountflags &= ~MS_RDONLY;
 600                         continue;
 601                 }
 602                 if (!strcmp(line,"debug")) {
 603                         console_loglevel = 10;
 604                         continue;
 605                 }
 606                 if (!strncmp(line,"init=",5)) {
 607                         line += 5;
 608                         execute_command = line;
 609                         continue;
 610                 }
 611                 if (checksetup(line))
 612                         continue;
 613                 /*
 614                  * Then check if it's an environment variable or
 615                  * an option.
 616                  */
 617                 if (strchr(line,'=')) {
 618                         if (envs >= MAX_INIT_ENVS)
 619                                 break;
 620                         envp_init[++envs] = line;
 621                 } else {
 622                         if (args >= MAX_INIT_ARGS)
 623                                 break;
 624                         argv_init[++args] = line;
 625                 }
 626         }
 627         argv_init[args+1] = NULL;
 628         envp_init[envs+1] = NULL;
 629 }
 630 
 631 
 632 extern void setup_arch(char **, unsigned long *, unsigned long *);
 633 extern void arch_syms_export(void);
 634 
 635 #ifndef __SMP__
 636 
 637 /*
 638  *      Uniprocessor idle thread
 639  */
 640  
 641 int cpu_idle(void *unused)
     /* [previous][next][first][last][top][bottom][index][help] */
 642 {
 643         for(;;)
 644                 idle();
 645 }
 646 
 647 #else
 648 
 649 /*
 650  *      Multiprocessor idle thread is in arch/...
 651  */
 652  
 653 extern int cpu_idle(void * unused);
 654 
 655 /*
 656  *      Activate a secondary processor.
 657  */
 658  
 659 asmlinkage void start_secondary(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 660 {
 661         trap_init();
 662         init_IRQ();
 663         smp_callin();
 664         cpu_idle(NULL);
 665 }
 666 
 667 
 668 
 669 /*
 670  *      Called by CPU#0 to activate the rest.
 671  */
 672  
 673 static void smp_init(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 674 {
 675         int i, j;
 676         smp_boot_cpus();
 677         
 678         /*
 679          *      Create the slave init tasks as sharing pid 0.
 680          *
 681          *      This should only happen if we have virtual CPU numbers
 682          *      higher than 0.
 683          */
 684 
 685         for (i=1; i<smp_num_cpus; i++)
 686         {
 687                 struct task_struct *n, *p;
 688 
 689                 j = cpu_logical_map[i];
 690                 /*
 691                  *      We use kernel_thread for the idlers which are
 692                  *      unlocked tasks running in kernel space.
 693                  */
 694                 kernel_thread(cpu_idle, NULL, CLONE_PID);
 695                 /*
 696                  *      Don't assume linear processor numbering
 697                  */
 698                 current_set[j]=task[i];
 699                 current_set[j]->processor=j;
 700                 cli();
 701                 n = task[i]->next_run;
 702                 p = task[i]->prev_run;
 703                 nr_running--;
 704                 n->prev_run = p;
 705                 p->next_run = n;
 706                 task[i]->next_run = task[i]->prev_run = task[i];
 707                 sti();
 708         }
 709 }               
 710 
 711 /*
 712  *      The autoprobe routines assume CPU#0 on the i386
 713  *      so we don't actually set the game in motion until
 714  *      they are finished.
 715  */
 716  
 717 static void smp_begin(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 718 {
 719         smp_threads_ready=1;
 720         smp_commence();
 721 }
 722         
 723 #endif
 724 
 725 /*
 726  *      Activate the first processor.
 727  */
 728  
 729 asmlinkage void start_kernel(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 730 {
 731         char * command_line;
 732 
 733 /*
 734  *      This little check will move.
 735  */
 736 
 737 #ifdef __SMP__
 738         static int first_cpu=1;
 739         
 740         if(!first_cpu)
 741                 start_secondary();
 742         first_cpu=0;
 743         
 744 #endif  
 745 /*
 746  * Interrupts are still disabled. Do necessary setups, then
 747  * enable them
 748  */
 749         setup_arch(&command_line, &memory_start, &memory_end);
 750         memory_start = paging_init(memory_start,memory_end);
 751         trap_init();
 752         init_IRQ();
 753         sched_init();
 754         time_init();
 755         parse_options(command_line);
 756 #ifdef CONFIG_MODULES
 757         init_modules();
 758 #endif
 759 #ifdef CONFIG_PROFILE
 760         if (!prof_shift)
 761 #ifdef CONFIG_PROFILE_SHIFT
 762                 prof_shift = CONFIG_PROFILE_SHIFT;
 763 #else
 764                 prof_shift = 2;
 765 #endif
 766 #endif
 767         if (prof_shift) {
 768                 prof_buffer = (unsigned int *) memory_start;
 769                 /* only text is profiled */
 770                 prof_len = (unsigned long) &_etext - (unsigned long) &_stext;
 771                 prof_len >>= prof_shift;
 772                 memory_start += prof_len * sizeof(unsigned int);
 773         }
 774         memory_start = console_init(memory_start,memory_end);
 775 #ifdef CONFIG_PCI
 776         memory_start = pci_init(memory_start,memory_end);
 777 #endif
 778         memory_start = kmalloc_init(memory_start,memory_end);
 779         sti();
 780         calibrate_delay();
 781         memory_start = inode_init(memory_start,memory_end);
 782         memory_start = file_table_init(memory_start,memory_end);
 783         memory_start = name_cache_init(memory_start,memory_end);
 784 #ifdef CONFIG_BLK_DEV_INITRD
 785         if (initrd_start && initrd_start < memory_start) {
 786                 printk(KERN_CRIT "initrd overwritten (0x%08lx < 0x%08lx) - "
 787                     "disabling it.\n",initrd_start,memory_start);
 788                 initrd_start = 0;
 789         }
 790 #endif
 791         mem_init(memory_start,memory_end);
 792         buffer_init();
 793         sock_init();
 794 #if defined(CONFIG_SYSVIPC) || defined(CONFIG_KERNELD)
 795         ipc_init();
 796 #endif
 797         dquot_init();
 798         arch_syms_export();
 799         sti();
 800         check_bugs();
 801 
 802         printk(linux_banner);
 803 #ifdef __SMP__
 804         smp_init();
 805 #endif
 806         sysctl_init();
 807         /* 
 808          *      We count on the initial thread going ok 
 809          *      Like idlers init is an unlocked kernel thread, which will
 810          *      make syscalls (and thus be locked).
 811          */
 812         kernel_thread(init, NULL, 0);
 813 /*
 814  * task[0] is meant to be used as an "idle" task: it may not sleep, but
 815  * it might do some general things like count free pages or it could be
 816  * used to implement a reasonable LRU algorithm for the paging routines:
 817  * anything that can be useful, but shouldn't take time from the real
 818  * processes.
 819  *
 820  * Right now task[0] just does a infinite idle loop.
 821  */
 822         cpu_idle(NULL);
 823 }
 824 
 825 static int printf(const char *fmt, ...)
     /* [previous][next][first][last][top][bottom][index][help] */
 826 {
 827         va_list args;
 828         int i;
 829 
 830         va_start(args, fmt);
 831         write(1,printbuf,i=vsprintf(printbuf, fmt, args));
 832         va_end(args);
 833         return i;
 834 }
 835 
 836 static int do_rc(void * rc)
     /* [previous][next][first][last][top][bottom][index][help] */
 837 {
 838         close(0);
 839         if (open(rc,O_RDONLY,0))
 840                 return -1;
 841         return execve("/bin/sh", argv_rc, envp_rc);
 842 }
 843 
 844 static int do_shell(void * shell)
     /* [previous][next][first][last][top][bottom][index][help] */
 845 {
 846         close(0);close(1);close(2);
 847         setsid();
 848         (void) open("/dev/tty1",O_RDWR,0);
 849         (void) dup(0);
 850         (void) dup(0);
 851         return execve(shell, argv, envp);
 852 }
 853 
 854 #ifdef CONFIG_BLK_DEV_INITRD
 855 static int do_linuxrc(void * shell)
     /* [previous][next][first][last][top][bottom][index][help] */
 856 {
 857         static char *argv[] = { "linuxrc", NULL, };
 858 
 859         close(0);close(1);close(2);
 860         setsid();
 861         (void) open("/dev/tty1",O_RDWR,0);
 862         (void) dup(0);
 863         (void) dup(0);
 864         return execve(shell, argv, envp_init);
 865 }
 866 
 867 static void no_initrd(char *s,int *ints)
     /* [previous][next][first][last][top][bottom][index][help] */
 868 {
 869         mount_initrd = 0;
 870 }
 871 #endif
 872 
 873 static int init(void * unused)
     /* [previous][next][first][last][top][bottom][index][help] */
 874 {
 875         int pid,i;
 876 #ifdef CONFIG_BLK_DEV_INITRD
 877         int real_root_mountflags;
 878 #endif
 879 
 880         /* Launch bdflush from here, instead of the old syscall way. */
 881         kernel_thread(bdflush, NULL, 0);
 882         /* Start the background pageout daemon. */
 883         kernel_thread(kswapd, NULL, 0);
 884 
 885 #ifdef CONFIG_BLK_DEV_INITRD
 886         real_root_dev = ROOT_DEV;
 887         real_root_mountflags = root_mountflags;
 888         if (initrd_start && mount_initrd) root_mountflags &= ~MS_RDONLY;
 889         else mount_initrd =0;
 890 #endif
 891         setup();
 892 
 893 #ifdef __SMP__
 894         /*
 895          *      With the devices probed and setup we can
 896          *      now enter SMP mode.
 897          */
 898         
 899         smp_begin();
 900 #endif  
 901 
 902         #ifdef CONFIG_UMSDOS_FS
 903         {
 904                 /*
 905                         When mounting a umsdos fs as root, we detect
 906                         the pseudo_root (/linux) and initialise it here.
 907                         pseudo_root is defined in fs/umsdos/inode.c
 908                 */
 909                 extern struct inode *pseudo_root;
 910                 if (pseudo_root != NULL){
 911                         current->fs->root = pseudo_root;
 912                         current->fs->pwd  = pseudo_root;
 913                 }
 914         }
 915         #endif
 916 
 917 #ifdef CONFIG_BLK_DEV_INITRD
 918         root_mountflags = real_root_mountflags;
 919         if (mount_initrd && ROOT_DEV != real_root_dev && ROOT_DEV == MKDEV(RAMDISK_MAJOR,0)) {
 920                 int error;
 921 
 922                 pid = kernel_thread(do_linuxrc, "/linuxrc", SIGCHLD);
 923                 if (pid>0)
 924                         while (pid != wait(&i));
 925                 if (real_root_dev != MKDEV(RAMDISK_MAJOR, 0)) {
 926                         error = change_root(real_root_dev,"/initrd");
 927                         if (error)
 928                                 printk(KERN_ERR "Change root to /initrd: "
 929                                     "error %d\n",error);
 930                 }
 931         }
 932 #endif
 933 
 934         (void) open("/dev/tty1",O_RDWR,0);
 935         (void) dup(0);
 936         (void) dup(0);
 937 
 938         if (!execute_command) {
 939                 execve("/etc/init",argv_init,envp_init);
 940                 execve("/bin/init",argv_init,envp_init);
 941                 execve("/sbin/init",argv_init,envp_init);
 942                 /* if this fails, fall through to original stuff */
 943 
 944                 pid = kernel_thread(do_rc, "/etc/rc", SIGCHLD);
 945                 if (pid>0)
 946                         while (pid != wait(&i))
 947                                 /* nothing */;
 948         }
 949 
 950         while (1) {
 951                 pid = kernel_thread(do_shell,
 952                         execute_command ? execute_command : "/bin/sh",
 953                         SIGCHLD);
 954                 if (pid < 0) {
 955                         printf("Fork failed in init\n\r");
 956                         continue;
 957                 }
 958                 while (1)
 959                         if (pid == wait(&i))
 960                                 break;
 961                 printf("\n\rchild %d died with code %04x\n\r",pid,i);
 962                 sync();
 963         }
 964         return -1;
 965 }

/* [previous][next][first][last][top][bottom][index][help] */