|
|
1.1 ! root 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: * Moan early if gcc is old, avoiding bogus kernels - Paul Gortmaker, May '96 ! 9: */ ! 10: ! 11: #define __KERNEL_SYSCALLS__ ! 12: #include <stdarg.h> ! 13: ! 14: #include <asm/system.h> ! 15: #include <asm/io.h> ! 16: ! 17: #include <linux/types.h> ! 18: #include <linux/fcntl.h> ! 19: #include <linux/config.h> ! 20: #include <linux/sched.h> ! 21: #include <linux/kernel.h> ! 22: #include <linux/tty.h> ! 23: #include <linux/head.h> ! 24: #include <linux/unistd.h> ! 25: #include <linux/string.h> ! 26: #include <linux/timer.h> ! 27: #include <linux/fs.h> ! 28: #include <linux/ctype.h> ! 29: #include <linux/delay.h> ! 30: #include <linux/utsname.h> ! 31: #include <linux/ioport.h> ! 32: #include <linux/hdreg.h> ! 33: #include <linux/mm.h> ! 34: #include <linux/major.h> ! 35: #include <linux/blk.h> ! 36: #ifdef CONFIG_ROOT_NFS ! 37: #include <linux/nfs_fs.h> ! 38: #endif ! 39: #ifdef CONFIG_MTRR ! 40: #include <asm/mtrr.h> ! 41: #endif ! 42: ! 43: #include <asm/bugs.h> ! 44: ! 45: /* ! 46: * Versions of gcc older than that listed below may actually compile ! 47: * and link okay, but the end product can have subtle run time bugs. ! 48: * To avoid associated bogus bug reports, we flatly refuse to compile ! 49: * with a gcc that is known to be too old from the very beginning. ! 50: */ ! 51: #if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 6) ! 52: #error sorry, your GCC is too old. It builds incorrect kernels. ! 53: #endif ! 54: ! 55: extern char _stext, _etext; ! 56: extern const char *linux_banner; ! 57: ! 58: static char printbuf[1024]; ! 59: ! 60: extern int console_loglevel; ! 61: ! 62: static int init(void *); ! 63: extern int bdflush(void *); ! 64: extern int kswapd(void *); ! 65: extern void kswapd_setup(void); ! 66: ! 67: extern void init_IRQ(void); ! 68: extern void init_modules(void); ! 69: extern long console_init(long, long); ! 70: extern long kmalloc_init(long,long); ! 71: extern void sock_init(void); ! 72: extern unsigned long pci_init(unsigned long, unsigned long); ! 73: extern void sysctl_init(void); ! 74: ! 75: extern void no_scroll(char *str, int *ints); ! 76: extern void swap_setup(char *str, int *ints); ! 77: extern void buff_setup(char *str, int *ints); ! 78: extern void panic_setup(char *str, int *ints); ! 79: extern void bmouse_setup(char *str, int *ints); ! 80: extern void msmouse_setup(char *str, int *ints); ! 81: extern void lp_setup(char *str, int *ints); ! 82: extern void eth_setup(char *str, int *ints); ! 83: extern void xd_setup(char *str, int *ints); ! 84: extern void xd_manual_geo_init(char *str, int *ints); ! 85: extern void floppy_setup(char *str, int *ints); ! 86: extern void st_setup(char *str, int *ints); ! 87: extern void st0x_setup(char *str, int *ints); ! 88: extern void advansys_setup(char *str, int *ints); ! 89: extern void tmc8xx_setup(char *str, int *ints); ! 90: extern void t128_setup(char *str, int *ints); ! 91: extern void pas16_setup(char *str, int *ints); ! 92: extern void generic_NCR5380_setup(char *str, int *intr); ! 93: extern void generic_NCR53C400_setup(char *str, int *intr); ! 94: extern void aha152x_setup(char *str, int *ints); ! 95: extern void aha1542_setup(char *str, int *ints); ! 96: extern void gdth_setup(char *str, int *ints); ! 97: extern void aic7xxx_setup(char *str, int *ints); ! 98: extern void AM53C974_setup(char *str, int *ints); ! 99: extern void BusLogic_Setup(char *str, int *ints); ! 100: extern void ncr53c8xx_setup(char *str, int *ints); ! 101: extern void eata2x_setup(char *str, int *ints); ! 102: extern void u14_34f_setup(char *str, int *ints); ! 103: extern void fdomain_setup(char *str, int *ints); ! 104: extern void in2000_setup(char *str, int *ints); ! 105: extern void NCR53c406a_setup(char *str, int *ints); ! 106: extern void wd7000_setup(char *str, int *ints); ! 107: extern void ppa_setup(char *str, int *ints); ! 108: extern void scsi_luns_setup(char *str, int *ints); ! 109: extern void sound_setup(char *str, int *ints); ! 110: extern void apm_setup(char *str, int *ints); ! 111: extern void reboot_setup(char *str, int *ints); ! 112: #ifdef CONFIG_CDU31A ! 113: extern void cdu31a_setup(char *str, int *ints); ! 114: #endif CONFIG_CDU31A ! 115: #ifdef CONFIG_MCD ! 116: extern void mcd_setup(char *str, int *ints); ! 117: #endif CONFIG_MCD ! 118: #ifdef CONFIG_MCDX ! 119: extern void mcdx_setup(char *str, int *ints); ! 120: #endif CONFIG_MCDX ! 121: #ifdef CONFIG_SBPCD ! 122: extern void sbpcd_setup(char *str, int *ints); ! 123: #endif CONFIG_SBPCD ! 124: #ifdef CONFIG_AZTCD ! 125: extern void aztcd_setup(char *str, int *ints); ! 126: #endif CONFIG_AZTCD ! 127: #ifdef CONFIG_CDU535 ! 128: extern void sonycd535_setup(char *str, int *ints); ! 129: #endif CONFIG_CDU535 ! 130: #ifdef CONFIG_GSCD ! 131: extern void gscd_setup(char *str, int *ints); ! 132: #endif CONFIG_GSCD ! 133: #ifdef CONFIG_CM206 ! 134: extern void cm206_setup(char *str, int *ints); ! 135: #endif CONFIG_CM206 ! 136: #ifdef CONFIG_OPTCD ! 137: extern void optcd_setup(char *str, int *ints); ! 138: #endif CONFIG_OPTCD ! 139: #ifdef CONFIG_SJCD ! 140: extern void sjcd_setup(char *str, int *ints); ! 141: #endif CONFIG_SJCD ! 142: #ifdef CONFIG_ISP16_CDI ! 143: extern void isp16_setup(char *str, int *ints); ! 144: #endif CONFIG_ISP16_CDI ! 145: #ifdef CONFIG_BLK_DEV_RAM ! 146: static void ramdisk_start_setup(char *str, int *ints); ! 147: static void load_ramdisk(char *str, int *ints); ! 148: static void prompt_ramdisk(char *str, int *ints); ! 149: static void ramdisk_size(char *str, int *ints); ! 150: #ifdef CONFIG_BLK_DEV_INITRD ! 151: static void no_initrd(char *s,int *ints); ! 152: #endif ! 153: #endif CONFIG_BLK_DEV_RAM ! 154: #ifdef CONFIG_ISDN_DRV_ICN ! 155: extern void icn_setup(char *str, int *ints); ! 156: #endif ! 157: #ifdef CONFIG_ISDN_DRV_HISAX ! 158: extern void HiSax_setup(char *str, int *ints); ! 159: #endif ! 160: #ifdef CONFIG_ISDN_DRV_PCBIT ! 161: extern void pcbit_setup(char *str, int *ints); ! 162: #endif ! 163: ! 164: #ifdef CONFIG_ATARIMOUSE ! 165: extern void atari_mouse_setup (char *str, int *ints); ! 166: #endif ! 167: #ifdef CONFIG_DMASOUND ! 168: extern void dmasound_setup (char *str, int *ints); ! 169: #endif ! 170: #ifdef CONFIG_ATARI_SCSI ! 171: extern void atari_scsi_setup (char *str, int *ints); ! 172: #endif ! 173: extern void wd33c93_setup (char *str, int *ints); ! 174: extern void gvp11_setup (char *str, int *ints); ! 175: ! 176: #ifdef CONFIG_CYCLADES ! 177: extern void cy_setup(char *str, int *ints); ! 178: #endif ! 179: #ifdef CONFIG_DIGI ! 180: extern void pcxx_setup(char *str, int *ints); ! 181: #endif ! 182: #ifdef CONFIG_RISCOM8 ! 183: extern void riscom8_setup(char *str, int *ints); ! 184: #endif ! 185: #ifdef CONFIG_SPECIALIX ! 186: extern void specialix_setup(char *str, int *ints); ! 187: #endif ! 188: #ifdef CONFIG_BAYCOM ! 189: extern void baycom_setup(char *str, int *ints); ! 190: #endif ! 191: ! 192: #ifdef CONFIG_PARIDE_PD ! 193: extern void pd_setup(char *str, int *ints); ! 194: #endif ! 195: #ifdef CONFIG_PARIDE_PF ! 196: extern void pf_setup(char *str, int *ints); ! 197: #endif ! 198: #ifdef CONFIG_PARIDE_PT ! 199: extern void pt_setup(char *str, int *ints); ! 200: #endif ! 201: #ifdef CONFIG_PARIDE_PG ! 202: extern void pg_setup(char *str, int *ints); ! 203: #endif ! 204: #ifdef CONFIG_PARIDE_PCD ! 205: extern void pcd_setup(char *str, int *ints); ! 206: #endif ! 207: ! 208: #if defined(CONFIG_SYSVIPC) || defined(CONFIG_KERNELD) ! 209: extern void ipc_init(void); ! 210: #endif ! 211: ! 212: /* ! 213: * Boot command-line arguments ! 214: */ ! 215: #define MAX_INIT_ARGS 8 ! 216: #define MAX_INIT_ENVS 8 ! 217: ! 218: extern void time_init(void); ! 219: ! 220: static unsigned long memory_start = 0; ! 221: static unsigned long memory_end = 0; ! 222: ! 223: int rows, cols; ! 224: ! 225: #ifdef CONFIG_BLK_DEV_RAM ! 226: extern int rd_doload; /* 1 = load ramdisk, 0 = don't load */ ! 227: extern int rd_prompt; /* 1 = prompt for ramdisk, 0 = don't prompt */ ! 228: extern int rd_size; /* Size of the ramdisk(s) */ ! 229: extern int rd_image_start; /* starting block # of image */ ! 230: #ifdef CONFIG_BLK_DEV_INITRD ! 231: kdev_t real_root_dev; ! 232: #endif ! 233: #endif ! 234: ! 235: int root_mountflags = MS_RDONLY; ! 236: char *execute_command = 0; ! 237: ! 238: #ifdef CONFIG_ROOT_NFS ! 239: char nfs_root_name[NFS_ROOT_NAME_LEN] = { "default" }; ! 240: char nfs_root_addrs[NFS_ROOT_ADDRS_LEN] = { "" }; ! 241: #endif ! 242: ! 243: extern void dquot_init(void); ! 244: ! 245: static char * argv_init[MAX_INIT_ARGS+2] = { "init", NULL, }; ! 246: static char * envp_init[MAX_INIT_ENVS+2] = { "HOME=/", "TERM=linux", NULL, }; ! 247: ! 248: static char * argv_rc[] = { "/bin/sh", NULL }; ! 249: static char * envp_rc[] = { "HOME=/", "TERM=linux", NULL }; ! 250: ! 251: static char * argv[] = { "-/bin/sh",NULL }; ! 252: static char * envp[] = { "HOME=/usr/root", "TERM=linux", NULL }; ! 253: ! 254: char *get_options(char *str, int *ints) ! 255: { ! 256: char *cur = str; ! 257: int i=1; ! 258: ! 259: while (cur && isdigit(*cur) && i <= 10) { ! 260: ints[i++] = simple_strtoul(cur,NULL,0); ! 261: if ((cur = strchr(cur,',')) != NULL) ! 262: cur++; ! 263: } ! 264: ints[0] = i-1; ! 265: return(cur); ! 266: } ! 267: ! 268: static void profile_setup(char *str, int *ints) ! 269: { ! 270: if (ints[0] > 0) ! 271: prof_shift = (unsigned long) ints[1]; ! 272: else ! 273: #ifdef CONFIG_PROFILE_SHIFT ! 274: prof_shift = CONFIG_PROFILE_SHIFT; ! 275: #else ! 276: prof_shift = 2; ! 277: #endif ! 278: } ! 279: ! 280: struct kernel_param { ! 281: const char *str; ! 282: void (*setup_func)(char *, int *); ! 283: } ; ! 284: ! 285: struct kernel_param bootsetups[] = { ! 286: { "reserve=", reserve_setup }, ! 287: { "profile=", profile_setup }, ! 288: #ifdef CONFIG_BLK_DEV_RAM ! 289: { "ramdisk_start=", ramdisk_start_setup }, ! 290: { "load_ramdisk=", load_ramdisk }, ! 291: { "prompt_ramdisk=", prompt_ramdisk }, ! 292: { "ramdisk=", ramdisk_size }, ! 293: { "ramdisk_size=", ramdisk_size }, ! 294: #ifdef CONFIG_BLK_DEV_INITRD ! 295: { "noinitrd", no_initrd }, ! 296: #endif ! 297: #endif ! 298: { "swap=", swap_setup }, ! 299: { "buff=", buff_setup }, ! 300: { "panic=", panic_setup }, ! 301: { "no-scroll", no_scroll }, ! 302: #ifdef CONFIG_BUGi386 ! 303: { "no-hlt", no_halt }, ! 304: { "no387", no_387 }, ! 305: { "reboot=", reboot_setup }, ! 306: #endif ! 307: #ifdef CONFIG_INET ! 308: { "ether=", eth_setup }, ! 309: #endif ! 310: #ifdef CONFIG_PRINTER ! 311: { "lp=", lp_setup }, ! 312: #endif ! 313: #ifdef CONFIG_SCSI ! 314: { "max_scsi_luns=", scsi_luns_setup }, ! 315: #endif ! 316: #ifdef CONFIG_SCSI_ADVANSYS ! 317: { "advansys=", advansys_setup }, ! 318: #endif ! 319: #if defined(CONFIG_BLK_DEV_HD) ! 320: { "hd=", hd_setup }, ! 321: #endif ! 322: #ifdef CONFIG_CHR_DEV_ST ! 323: { "st=", st_setup }, ! 324: #endif ! 325: #ifdef CONFIG_BUSMOUSE ! 326: { "bmouse=", bmouse_setup }, ! 327: #endif ! 328: #ifdef CONFIG_MS_BUSMOUSE ! 329: { "msmouse=", msmouse_setup }, ! 330: #endif ! 331: #ifdef CONFIG_SCSI_SEAGATE ! 332: { "st0x=", st0x_setup }, ! 333: { "tmc8xx=", tmc8xx_setup }, ! 334: #endif ! 335: #ifdef CONFIG_SCSI_T128 ! 336: { "t128=", t128_setup }, ! 337: #endif ! 338: #ifdef CONFIG_SCSI_PAS16 ! 339: { "pas16=", pas16_setup }, ! 340: #endif ! 341: #ifdef CONFIG_SCSI_GENERIC_NCR5380 ! 342: { "ncr5380=", generic_NCR5380_setup }, ! 343: { "ncr53c400=", generic_NCR53C400_setup }, ! 344: #endif ! 345: #ifdef CONFIG_SCSI_AHA152X ! 346: { "aha152x=", aha152x_setup}, ! 347: #endif ! 348: #ifdef CONFIG_SCSI_AHA1542 ! 349: { "aha1542=", aha1542_setup}, ! 350: #endif ! 351: #ifdef CONFIG_SCSI_GDTH ! 352: { "gdth=", gdth_setup}, ! 353: #endif ! 354: #ifdef CONFIG_SCSI_AIC7XXX ! 355: { "aic7xxx=", aic7xxx_setup}, ! 356: #endif ! 357: #ifdef CONFIG_SCSI_BUSLOGIC ! 358: { "BusLogic=", BusLogic_Setup}, ! 359: #endif ! 360: #ifdef CONFIG_SCSI_NCR53C8XX ! 361: { "ncr53c8xx=", ncr53c8xx_setup}, ! 362: #endif ! 363: #ifdef CONFIG_SCSI_EATA ! 364: { "eata=", eata2x_setup}, ! 365: #endif ! 366: #ifdef CONFIG_SCSI_U14_34F ! 367: { "u14-34f=", u14_34f_setup}, ! 368: #endif ! 369: #ifdef CONFIG_SCSI_AM53C974 ! 370: { "AM53C974=", AM53C974_setup}, ! 371: #endif ! 372: #ifdef CONFIG_SCSI_NCR53C406A ! 373: { "ncr53c406a=", NCR53c406a_setup}, ! 374: #endif ! 375: #ifdef CONFIG_SCSI_FUTURE_DOMAIN ! 376: { "fdomain=", fdomain_setup}, ! 377: #endif ! 378: #ifdef CONFIG_SCSI_IN2000 ! 379: { "in2000=", in2000_setup}, ! 380: #endif ! 381: #ifdef CONFIG_SCSI_7000FASST ! 382: { "wd7000=", wd7000_setup}, ! 383: #endif ! 384: #ifdef CONFIG_SCSI_PPA ! 385: { "ppa=", ppa_setup }, ! 386: #endif ! 387: #ifdef CONFIG_BLK_DEV_XD ! 388: { "xd=", xd_setup }, ! 389: { "xd_geo=", xd_manual_geo_init }, ! 390: #endif ! 391: #ifdef CONFIG_BLK_DEV_FD ! 392: { "floppy=", floppy_setup }, ! 393: #endif ! 394: #ifdef CONFIG_CDU31A ! 395: { "cdu31a=", cdu31a_setup }, ! 396: #endif CONFIG_CDU31A ! 397: #ifdef CONFIG_MCD ! 398: { "mcd=", mcd_setup }, ! 399: #endif CONFIG_MCD ! 400: #ifdef CONFIG_MCDX ! 401: { "mcdx=", mcdx_setup }, ! 402: #endif CONFIG_MCDX ! 403: #ifdef CONFIG_SBPCD ! 404: { "sbpcd=", sbpcd_setup }, ! 405: #endif CONFIG_SBPCD ! 406: #ifdef CONFIG_AZTCD ! 407: { "aztcd=", aztcd_setup }, ! 408: #endif CONFIG_AZTCD ! 409: #ifdef CONFIG_CDU535 ! 410: { "sonycd535=", sonycd535_setup }, ! 411: #endif CONFIG_CDU535 ! 412: #ifdef CONFIG_GSCD ! 413: { "gscd=", gscd_setup }, ! 414: #endif CONFIG_GSCD ! 415: #ifdef CONFIG_CM206 ! 416: { "cm206=", cm206_setup }, ! 417: #endif CONFIG_CM206 ! 418: #ifdef CONFIG_OPTCD ! 419: { "optcd=", optcd_setup }, ! 420: #endif CONFIG_OPTCD ! 421: #ifdef CONFIG_SJCD ! 422: { "sjcd=", sjcd_setup }, ! 423: #endif CONFIG_SJCD ! 424: #ifdef CONFIG_ISP16_CDI ! 425: { "isp16=", isp16_setup }, ! 426: #endif CONFIG_ISP16_CDI ! 427: #ifdef CONFIG_SOUND ! 428: { "sound=", sound_setup }, ! 429: #endif ! 430: #ifdef CONFIG_ISDN_DRV_ICN ! 431: { "icn=", icn_setup }, ! 432: #endif ! 433: #ifdef CONFIG_ISDN_DRV_HISAX ! 434: { "hisax=", HiSax_setup }, ! 435: { "HiSax=", HiSax_setup }, ! 436: #endif ! 437: #ifdef CONFIG_ISDN_DRV_PCBIT ! 438: { "pcbit=", pcbit_setup }, ! 439: #endif ! 440: #ifdef CONFIG_ATARIMOUSE ! 441: { "atamouse=", atari_mouse_setup }, ! 442: #endif ! 443: #ifdef CONFIG_DMASOUND ! 444: { "dmasound=", dmasound_setup }, ! 445: #endif ! 446: #ifdef CONFIG_ATARI_SCSI ! 447: { "atascsi=", atari_scsi_setup }, ! 448: #endif ! 449: #if defined(CONFIG_A3000_SCSI) || defined(CONFIG_A2091_SCSI) \ ! 450: || defined(CONFIG_GVP11_SCSI) ! 451: { "wd33c93=", wd33c93_setup }, ! 452: #endif ! 453: #if defined(CONFIG_GVP11_SCSI) ! 454: { "gvp11=", gvp11_setup }, ! 455: #endif ! 456: #ifdef CONFIG_CYCLADES ! 457: { "cyclades=", cy_setup }, ! 458: #endif ! 459: #ifdef CONFIG_DIGI ! 460: { "digi=", pcxx_setup }, ! 461: #endif ! 462: #ifdef CONFIG_RISCOM8 ! 463: { "riscom8=", riscom8_setup }, ! 464: #endif ! 465: #ifdef CONFIG_SPECIALIX ! 466: { "specialix=", specialix_setup }, ! 467: #endif ! 468: #ifdef CONFIG_BAYCOM ! 469: { "baycom=", baycom_setup }, ! 470: #endif ! 471: #ifdef CONFIG_APM ! 472: { "apm=", apm_setup }, ! 473: #endif ! 474: { 0, 0 } ! 475: }; ! 476: ! 477: static struct kernel_param raw_params[] = { ! 478: ! 479: #ifdef CONFIG_PARIDE_PD ! 480: { "pd.", pd_setup }, ! 481: #endif ! 482: #ifdef CONFIG_PARIDE_PCD ! 483: { "pcd.", pcd_setup }, ! 484: #endif ! 485: #ifdef CONFIG_PARIDE_PF ! 486: { "pf.", pf_setup }, ! 487: #endif ! 488: #ifdef CONFIG_PARIDE_PT ! 489: { "pt.", pt_setup }, ! 490: #endif ! 491: #ifdef CONFIG_PARIDE_PG ! 492: { "pg.", pg_setup }, ! 493: #endif ! 494: { 0, 0 } ! 495: } ; ! 496: ! 497: ! 498: #ifdef CONFIG_BLK_DEV_RAM ! 499: static void ramdisk_start_setup(char *str, int *ints) ! 500: { ! 501: if (ints[0] > 0 && ints[1] >= 0) ! 502: rd_image_start = ints[1]; ! 503: } ! 504: ! 505: static void load_ramdisk(char *str, int *ints) ! 506: { ! 507: if (ints[0] > 0 && ints[1] >= 0) ! 508: rd_doload = ints[1] & 3; ! 509: } ! 510: ! 511: static void prompt_ramdisk(char *str, int *ints) ! 512: { ! 513: if (ints[0] > 0 && ints[1] >= 0) ! 514: rd_prompt = ints[1] & 1; ! 515: } ! 516: ! 517: static void ramdisk_size(char *str, int *ints) ! 518: { ! 519: if (ints[0] > 0 && ints[1] >= 0) ! 520: rd_size = ints[1]; ! 521: } ! 522: ! 523: #endif ! 524: ! 525: static int checksetup(char *line) ! 526: { ! 527: int i = 0; ! 528: int ints[11]; ! 529: ! 530: #ifdef CONFIG_BLK_DEV_IDE ! 531: /* ide driver needs the basic string, rather than pre-processed values */ ! 532: if (!strncmp(line,"ide",3) || (!strncmp(line,"hd",2) && line[2] != '=')) { ! 533: ide_setup(line); ! 534: return 1; ! 535: } ! 536: #endif ! 537: while (bootsetups[i].str) { ! 538: int n = strlen(bootsetups[i].str); ! 539: if (!strncmp(line,bootsetups[i].str,n)) { ! 540: bootsetups[i].setup_func(get_options(line+n,ints), ints); ! 541: return 1; ! 542: } ! 543: i++; ! 544: } ! 545: ! 546: for (i=0; raw_params[i].str; i++) { ! 547: int n = strlen(raw_params[i].str); ! 548: if (!strncmp(line,raw_params[i].str,n)) { ! 549: raw_params[i].setup_func(line+n, NULL); ! 550: return 1; ! 551: } ! 552: } ! 553: ! 554: return 0; ! 555: } ! 556: ! 557: /* this should be approx 2 Bo*oMips to start (note initial shift), and will ! 558: still work even if initially too large, it will just take slightly longer */ ! 559: unsigned long loops_per_sec = (1<<12); ! 560: ! 561: #if defined(__SMP__) && defined(__i386__) ! 562: unsigned long smp_loops_per_tick = 1000000; ! 563: #endif ! 564: ! 565: /* This is the number of bits of precision for the loops_per_second. Each ! 566: bit takes on average 1.5/HZ seconds. This (like the original) is a little ! 567: better than 1% */ ! 568: #define LPS_PREC 8 ! 569: ! 570: void calibrate_delay(void) ! 571: { ! 572: int ticks; ! 573: int loopbit; ! 574: int lps_precision = LPS_PREC; ! 575: ! 576: loops_per_sec = (1<<12); ! 577: ! 578: printk("Calibrating delay loop.. "); ! 579: while (loops_per_sec <<= 1) { ! 580: /* wait for "start of" clock tick */ ! 581: ticks = jiffies; ! 582: while (ticks == jiffies) ! 583: /* nothing */; ! 584: /* Go .. */ ! 585: ticks = jiffies; ! 586: __delay(loops_per_sec); ! 587: ticks = jiffies - ticks; ! 588: if (ticks) ! 589: break; ! 590: } ! 591: ! 592: /* Do a binary approximation to get loops_per_second set to equal one clock ! 593: (up to lps_precision bits) */ ! 594: loops_per_sec >>= 1; ! 595: loopbit = loops_per_sec; ! 596: while ( lps_precision-- && (loopbit >>= 1) ) { ! 597: loops_per_sec |= loopbit; ! 598: ticks = jiffies; ! 599: while (ticks == jiffies); ! 600: ticks = jiffies; ! 601: __delay(loops_per_sec); ! 602: if (jiffies != ticks) /* longer than 1 tick */ ! 603: loops_per_sec &= ~loopbit; ! 604: } ! 605: ! 606: /* finally, adjust loops per second in terms of seconds instead of clocks */ ! 607: loops_per_sec *= HZ; ! 608: /* Round the value and print it */ ! 609: printk("ok - %lu.%02lu BogoMIPS\n", ! 610: (loops_per_sec+2500)/500000, ! 611: ((loops_per_sec+2500)/5000) % 100); ! 612: ! 613: #if defined(__SMP__) && defined(__i386__) ! 614: smp_loops_per_tick = loops_per_sec / 400; ! 615: #endif ! 616: } ! 617: ! 618: static void parse_root_dev(char * line) ! 619: { ! 620: int base = 0; ! 621: static struct dev_name_struct { ! 622: const char *name; ! 623: const int num; ! 624: } devices[] = { ! 625: { "nfs", 0x00ff }, ! 626: { "loop", 0x0700 }, ! 627: { "hda", 0x0300 }, ! 628: { "hdb", 0x0340 }, ! 629: { "hdc", 0x1600 }, ! 630: { "hdd", 0x1640 }, ! 631: { "hde", 0x2100 }, ! 632: { "hdf", 0x2140 }, ! 633: { "hdg", 0x2200 }, ! 634: { "hdh", 0x2240 }, ! 635: { "sda", 0x0800 }, ! 636: { "sdb", 0x0810 }, ! 637: { "sdc", 0x0820 }, ! 638: { "sdd", 0x0830 }, ! 639: { "sde", 0x0840 }, ! 640: { "sdf", 0x0850 }, ! 641: { "sdg", 0x0860 }, ! 642: { "sdh", 0x0870 }, ! 643: { "sdi", 0x0880 }, ! 644: { "sdj", 0x0890 }, ! 645: { "sdk", 0x08a0 }, ! 646: { "sdl", 0x08b0 }, ! 647: { "sdm", 0x08c0 }, ! 648: { "sdn", 0x08d0 }, ! 649: { "sdo", 0x08e0 }, ! 650: { "sdp", 0x08f0 }, ! 651: { "fd", 0x0200 }, ! 652: { "xda", 0x0d00 }, ! 653: { "xdb", 0x0d40 }, ! 654: { "ram", 0x0100 }, ! 655: { "scd", 0x0b00 }, ! 656: { "mcd", 0x1700 }, ! 657: { "cdu535", 0x1800 }, ! 658: { "aztcd", 0x1d00 }, ! 659: { "cm206cd", 0x2000 }, ! 660: { "gscd", 0x1000 }, ! 661: { "sbpcd", 0x1900 }, ! 662: { "sonycd", 0x1800 }, ! 663: #ifdef CONFIG_PARIDE_PD ! 664: { "pda", 0x2d00 }, ! 665: { "pdb", 0x2d10 }, ! 666: { "pdc", 0x2d20 }, ! 667: { "pdd", 0x2d30 }, ! 668: #endif ! 669: #ifdef CONFIG_PARIDE_PCD ! 670: { "pcd", 0x2e00 }, ! 671: #endif ! 672: #ifdef CONFIG_PARIDE_PF ! 673: { "pf", 0x2f00 }, ! 674: #endif ! 675: { NULL, 0 } ! 676: }; ! 677: ! 678: if (strncmp(line,"/dev/",5) == 0) { ! 679: struct dev_name_struct *dev = devices; ! 680: line += 5; ! 681: do { ! 682: int len = strlen(dev->name); ! 683: if (strncmp(line,dev->name,len) == 0) { ! 684: line += len; ! 685: base = dev->num; ! 686: break; ! 687: } ! 688: dev++; ! 689: } while (dev->name); ! 690: } ! 691: ROOT_DEV = to_kdev_t(base + simple_strtoul(line,NULL,base?10:16)); ! 692: } ! 693: ! 694: /* ! 695: * This is a simple kernel command line parsing function: it parses ! 696: * the command line, and fills in the arguments/environment to init ! 697: * as appropriate. Any cmd-line option is taken to be an environment ! 698: * variable if it contains the character '='. ! 699: * ! 700: * ! 701: * This routine also checks for options meant for the kernel. ! 702: * These options are not given to init - they are for internal kernel use only. ! 703: */ ! 704: static void parse_options(char *line) ! 705: { ! 706: char *next; ! 707: int args, envs; ! 708: ! 709: if (!*line) ! 710: return; ! 711: args = 0; ! 712: envs = 1; /* TERM is set to 'linux' by default */ ! 713: next = line; ! 714: while ((line = next) != NULL) { ! 715: if ((next = strchr(line,' ')) != NULL) ! 716: *next++ = 0; ! 717: /* ! 718: * check for kernel options first.. ! 719: */ ! 720: if (!strncmp(line,"root=",5)) { ! 721: parse_root_dev(line+5); ! 722: continue; ! 723: } ! 724: #ifdef CONFIG_ROOT_NFS ! 725: if (!strncmp(line, "nfsroot=", 8)) { ! 726: int n; ! 727: line += 8; ! 728: ROOT_DEV = MKDEV(UNNAMED_MAJOR, 255); ! 729: if (line[0] == '/' || line[0] == ',' || (line[0] >= '0' && line[0] <= '9')) { ! 730: strncpy(nfs_root_name, line, sizeof(nfs_root_name)); ! 731: nfs_root_name[sizeof(nfs_root_name)-1] = '\0'; ! 732: continue; ! 733: } ! 734: n = strlen(line) + strlen(NFS_ROOT); ! 735: if (n >= sizeof(nfs_root_name)) ! 736: line[sizeof(nfs_root_name) - strlen(NFS_ROOT) - 1] = '\0'; ! 737: sprintf(nfs_root_name, NFS_ROOT, line); ! 738: continue; ! 739: } ! 740: if (!strncmp(line, "nfsaddrs=", 9)) { ! 741: line += 9; ! 742: strncpy(nfs_root_addrs, line, sizeof(nfs_root_addrs)); ! 743: nfs_root_addrs[sizeof(nfs_root_addrs)-1] = '\0'; ! 744: continue; ! 745: } ! 746: #endif ! 747: if (!strcmp(line,"ro")) { ! 748: root_mountflags |= MS_RDONLY; ! 749: continue; ! 750: } ! 751: if (!strcmp(line,"rw")) { ! 752: root_mountflags &= ~MS_RDONLY; ! 753: continue; ! 754: } ! 755: if (!strcmp(line,"debug")) { ! 756: console_loglevel = 10; ! 757: continue; ! 758: } ! 759: if (!strncmp(line,"init=",5)) { ! 760: line += 5; ! 761: execute_command = line; ! 762: continue; ! 763: } ! 764: if (checksetup(line)) ! 765: continue; ! 766: /* ! 767: * Then check if it's an environment variable or ! 768: * an option. ! 769: */ ! 770: if (strchr(line,'=')) { ! 771: if (envs >= MAX_INIT_ENVS) ! 772: break; ! 773: envp_init[++envs] = line; ! 774: } else { ! 775: if (args >= MAX_INIT_ARGS) ! 776: break; ! 777: argv_init[++args] = line; ! 778: } ! 779: } ! 780: argv_init[args+1] = NULL; ! 781: envp_init[envs+1] = NULL; ! 782: } ! 783: ! 784: ! 785: extern void setup_arch(char **, unsigned long *, unsigned long *); ! 786: extern void arch_syms_export(void); ! 787: ! 788: #ifndef __SMP__ ! 789: ! 790: /* ! 791: * Uniprocessor idle thread ! 792: */ ! 793: ! 794: int cpu_idle(void *unused) ! 795: { ! 796: for(;;) ! 797: idle(); ! 798: } ! 799: ! 800: #else ! 801: ! 802: /* ! 803: * Multiprocessor idle thread is in arch/... ! 804: */ ! 805: ! 806: extern int cpu_idle(void * unused); ! 807: ! 808: /* ! 809: * Activate a secondary processor. ! 810: */ ! 811: ! 812: asmlinkage void start_secondary(void) ! 813: { ! 814: trap_init(); ! 815: init_IRQ(); ! 816: smp_callin(); ! 817: cpu_idle(NULL); ! 818: } ! 819: ! 820: ! 821: ! 822: /* ! 823: * Called by CPU#0 to activate the rest. ! 824: */ ! 825: ! 826: static void smp_init(void) ! 827: { ! 828: int i, j; ! 829: smp_boot_cpus(); ! 830: ! 831: /* ! 832: * Create the slave init tasks as sharing pid 0. ! 833: * ! 834: * This should only happen if we have virtual CPU numbers ! 835: * higher than 0. ! 836: */ ! 837: ! 838: for (i=1; i<smp_num_cpus; i++) ! 839: { ! 840: struct task_struct *n, *p; ! 841: ! 842: j = cpu_logical_map[i]; ! 843: /* ! 844: * We use kernel_thread for the idlers which are ! 845: * unlocked tasks running in kernel space. ! 846: */ ! 847: kernel_thread(cpu_idle, NULL, CLONE_PID); ! 848: /* ! 849: * Don't assume linear processor numbering ! 850: */ ! 851: current_set[j]=task[i]; ! 852: current_set[j]->processor=j; ! 853: cli(); ! 854: n = task[i]->next_run; ! 855: p = task[i]->prev_run; ! 856: nr_running--; ! 857: n->prev_run = p; ! 858: p->next_run = n; ! 859: task[i]->next_run = task[i]->prev_run = task[i]; ! 860: sti(); ! 861: } ! 862: } ! 863: ! 864: /* ! 865: * The autoprobe routines assume CPU#0 on the i386 ! 866: * so we don't actually set the game in motion until ! 867: * they are finished. ! 868: */ ! 869: ! 870: static void smp_begin(void) ! 871: { ! 872: smp_threads_ready=1; ! 873: smp_commence(); ! 874: } ! 875: ! 876: #endif ! 877: ! 878: /* ! 879: * Activate the first processor. ! 880: */ ! 881: ! 882: asmlinkage void start_kernel(void) ! 883: { ! 884: char * command_line; ! 885: ! 886: /* ! 887: * This little check will move. ! 888: */ ! 889: ! 890: #ifdef __SMP__ ! 891: static int first_cpu=1; ! 892: ! 893: if(!first_cpu) ! 894: start_secondary(); ! 895: first_cpu=0; ! 896: ! 897: #endif ! 898: /* ! 899: * Interrupts are still disabled. Do necessary setups, then ! 900: * enable them ! 901: */ ! 902: setup_arch(&command_line, &memory_start, &memory_end); ! 903: memory_start = paging_init(memory_start,memory_end); ! 904: trap_init(); ! 905: init_IRQ(); ! 906: sched_init(); ! 907: time_init(); ! 908: parse_options(command_line); ! 909: #ifdef CONFIG_MODULES ! 910: init_modules(); ! 911: #endif ! 912: #ifdef CONFIG_PROFILE ! 913: if (!prof_shift) ! 914: #ifdef CONFIG_PROFILE_SHIFT ! 915: prof_shift = CONFIG_PROFILE_SHIFT; ! 916: #else ! 917: prof_shift = 2; ! 918: #endif ! 919: #endif ! 920: if (prof_shift) { ! 921: prof_buffer = (unsigned int *) memory_start; ! 922: /* only text is profiled */ ! 923: prof_len = (unsigned long) &_etext - (unsigned long) &_stext; ! 924: prof_len >>= prof_shift; ! 925: memory_start += prof_len * sizeof(unsigned int); ! 926: memset(prof_buffer, 0, prof_len * sizeof(unsigned int)); ! 927: } ! 928: memory_start = console_init(memory_start,memory_end); ! 929: #ifdef CONFIG_PCI ! 930: memory_start = pci_init(memory_start,memory_end); ! 931: #endif ! 932: memory_start = kmalloc_init(memory_start,memory_end); ! 933: sti(); ! 934: calibrate_delay(); ! 935: memory_start = inode_init(memory_start,memory_end); ! 936: memory_start = file_table_init(memory_start,memory_end); ! 937: memory_start = name_cache_init(memory_start,memory_end); ! 938: #ifdef CONFIG_BLK_DEV_INITRD ! 939: if (initrd_start && initrd_start < memory_start) { ! 940: printk(KERN_CRIT "initrd overwritten (0x%08lx < 0x%08lx) - " ! 941: "disabling it.\n",initrd_start,memory_start); ! 942: initrd_start = 0; ! 943: } ! 944: #endif ! 945: mem_init(memory_start,memory_end); ! 946: buffer_init(); ! 947: sock_init(); ! 948: #if defined(CONFIG_SYSVIPC) || defined(CONFIG_KERNELD) ! 949: ipc_init(); ! 950: #endif ! 951: dquot_init(); ! 952: arch_syms_export(); ! 953: sti(); ! 954: check_bugs(); ! 955: ! 956: #if defined(CONFIG_MTRR) && defined(__SMP__) ! 957: init_mtrr_config(); ! 958: #endif ! 959: ! 960: ! 961: printk(linux_banner); ! 962: #ifdef __SMP__ ! 963: smp_init(); ! 964: #endif ! 965: sysctl_init(); ! 966: /* ! 967: * We count on the initial thread going ok ! 968: * Like idlers init is an unlocked kernel thread, which will ! 969: * make syscalls (and thus be locked). ! 970: */ ! 971: kernel_thread(init, NULL, 0); ! 972: /* ! 973: * task[0] is meant to be used as an "idle" task: it may not sleep, but ! 974: * it might do some general things like count free pages or it could be ! 975: * used to implement a reasonable LRU algorithm for the paging routines: ! 976: * anything that can be useful, but shouldn't take time from the real ! 977: * processes. ! 978: * ! 979: * Right now task[0] just does a infinite idle loop. ! 980: */ ! 981: cpu_idle(NULL); ! 982: } ! 983: ! 984: static int printf(const char *fmt, ...) ! 985: { ! 986: va_list args; ! 987: int i; ! 988: ! 989: va_start(args, fmt); ! 990: write(1,printbuf,i=vsprintf(printbuf, fmt, args)); ! 991: va_end(args); ! 992: return i; ! 993: } ! 994: ! 995: static int do_rc(void * rc) ! 996: { ! 997: close(0); ! 998: if (open(rc,O_RDONLY,0)) ! 999: return -1; ! 1000: return execve("/bin/sh", argv_rc, envp_rc); ! 1001: } ! 1002: ! 1003: static int do_shell(void * shell) ! 1004: { ! 1005: close(0);close(1);close(2); ! 1006: setsid(); ! 1007: (void) open("/dev/tty1",O_RDWR,0); ! 1008: (void) dup(0); ! 1009: (void) dup(0); ! 1010: return execve(shell, argv, envp); ! 1011: } ! 1012: ! 1013: #ifdef CONFIG_BLK_DEV_INITRD ! 1014: static int do_linuxrc(void * shell) ! 1015: { ! 1016: static char *argv[] = { "linuxrc", NULL, }; ! 1017: ! 1018: close(0);close(1);close(2); ! 1019: setsid(); ! 1020: (void) open("/dev/tty1",O_RDWR,0); ! 1021: (void) dup(0); ! 1022: (void) dup(0); ! 1023: return execve(shell, argv, envp_init); ! 1024: } ! 1025: ! 1026: static void no_initrd(char *s,int *ints) ! 1027: { ! 1028: mount_initrd = 0; ! 1029: } ! 1030: #endif ! 1031: ! 1032: static int init(void * unused) ! 1033: { ! 1034: int pid,i; ! 1035: #ifdef CONFIG_BLK_DEV_INITRD ! 1036: int real_root_mountflags; ! 1037: #endif ! 1038: ! 1039: /* Launch bdflush from here, instead of the old syscall way. */ ! 1040: kernel_thread(bdflush, NULL, 0); ! 1041: /* Start the background pageout daemon. */ ! 1042: kswapd_setup(); ! 1043: kernel_thread(kswapd, NULL, 0); ! 1044: ! 1045: #ifdef CONFIG_BLK_DEV_INITRD ! 1046: real_root_dev = ROOT_DEV; ! 1047: real_root_mountflags = root_mountflags; ! 1048: if (initrd_start && mount_initrd) root_mountflags &= ~MS_RDONLY; ! 1049: else mount_initrd =0; ! 1050: #endif ! 1051: setup(); ! 1052: ! 1053: #ifdef __SMP__ ! 1054: /* ! 1055: * With the devices probed and setup we can ! 1056: * now enter SMP mode. ! 1057: */ ! 1058: ! 1059: smp_begin(); ! 1060: #endif ! 1061: ! 1062: #ifdef CONFIG_UMSDOS_FS ! 1063: { ! 1064: /* ! 1065: When mounting a umsdos fs as root, we detect ! 1066: the pseudo_root (/linux) and initialise it here. ! 1067: pseudo_root is defined in fs/umsdos/inode.c ! 1068: */ ! 1069: extern struct inode *pseudo_root; ! 1070: if (pseudo_root != NULL){ ! 1071: current->fs->root = pseudo_root; ! 1072: current->fs->pwd = pseudo_root; ! 1073: } ! 1074: } ! 1075: #endif ! 1076: ! 1077: #ifdef CONFIG_BLK_DEV_INITRD ! 1078: root_mountflags = real_root_mountflags; ! 1079: if (mount_initrd && ROOT_DEV != real_root_dev && ROOT_DEV == MKDEV(RAMDISK_MAJOR,0)) { ! 1080: int error; ! 1081: ! 1082: pid = kernel_thread(do_linuxrc, "/linuxrc", SIGCHLD); ! 1083: if (pid>0) ! 1084: while (pid != wait(&i)); ! 1085: if (real_root_dev != MKDEV(RAMDISK_MAJOR, 0)) { ! 1086: error = change_root(real_root_dev,"/initrd"); ! 1087: if (error) ! 1088: printk(KERN_ERR "Change root to /initrd: " ! 1089: "error %d\n",error); ! 1090: } ! 1091: } ! 1092: #endif ! 1093: ! 1094: /* ! 1095: * This keeps serial console MUCH cleaner, but does assume ! 1096: * the console driver checks there really is a video device ! 1097: * attached (Sparc effectively does). ! 1098: */ ! 1099: ! 1100: if ((open("/dev/tty1",O_RDWR,0) < 0) && ! 1101: (open("/dev/ttyS0",O_RDWR,0) < 0)) ! 1102: printk("Unable to open an initial console.\n"); ! 1103: ! 1104: (void) dup(0); ! 1105: (void) dup(0); ! 1106: ! 1107: if (!execute_command) { ! 1108: execve("/etc/init",argv_init,envp_init); ! 1109: execve("/bin/init",argv_init,envp_init); ! 1110: execve("/sbin/init",argv_init,envp_init); ! 1111: /* if this fails, fall through to original stuff */ ! 1112: ! 1113: pid = kernel_thread(do_rc, "/etc/rc", SIGCHLD); ! 1114: if (pid>0) ! 1115: while (pid != wait(&i)) ! 1116: /* nothing */; ! 1117: } ! 1118: ! 1119: while (1) { ! 1120: pid = kernel_thread(do_shell, ! 1121: execute_command ? execute_command : "/bin/sh", ! 1122: SIGCHLD); ! 1123: if (pid < 0) { ! 1124: printf("Fork failed in init\n\r"); ! 1125: continue; ! 1126: } ! 1127: while (1) ! 1128: if (pid == wait(&i)) ! 1129: break; ! 1130: printf("\n\rchild %d died with code %04x\n\r",pid,i); ! 1131: sync(); ! 1132: } ! 1133: return -1; ! 1134: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.