main.c
上传用户:jlfgdled
上传日期:2013-04-10
资源大小:33168k
文件大小:13k
源码类别:

Linux/Unix编程

开发平台:

Unix_Linux

  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.  *  Simplified starting of init:  Michael A. Griffith <grif@acm.org> 
  10.  */
  11. #define __KERNEL_SYSCALLS__
  12. #include <linux/config.h>
  13. #include <linux/proc_fs.h>
  14. #include <linux/devfs_fs_kernel.h>
  15. #include <linux/unistd.h>
  16. #include <linux/string.h>
  17. #include <linux/ctype.h>
  18. #include <linux/delay.h>
  19. #include <linux/utsname.h>
  20. #include <linux/ioport.h>
  21. #include <linux/init.h>
  22. #include <linux/smp_lock.h>
  23. #include <linux/blk.h>
  24. #include <linux/hdreg.h>
  25. #include <linux/iobuf.h>
  26. #include <linux/bootmem.h>
  27. #include <linux/tty.h>
  28. #include <asm/io.h>
  29. #include <asm/bugs.h>
  30. #if defined(CONFIG_ARCH_S390)
  31. #include <asm/s390mach.h>
  32. #include <asm/ccwcache.h>
  33. #endif
  34. #ifdef CONFIG_PCI
  35. #include <linux/pci.h>
  36. #endif
  37. #ifdef CONFIG_DIO
  38. #include <linux/dio.h>
  39. #endif
  40. #ifdef CONFIG_ZORRO
  41. #include <linux/zorro.h>
  42. #endif
  43. #ifdef CONFIG_MTRR
  44. #  include <asm/mtrr.h>
  45. #endif
  46. #ifdef CONFIG_NUBUS
  47. #include <linux/nubus.h>
  48. #endif
  49. #ifdef CONFIG_ISAPNP
  50. #include <linux/isapnp.h>
  51. #endif
  52. #ifdef CONFIG_IRDA
  53. extern int irda_proto_init(void);
  54. extern int irda_device_init(void);
  55. #endif
  56. #ifdef CONFIG_X86_LOCAL_APIC
  57. #include <asm/smp.h>
  58. #endif
  59. /*
  60.  * Versions of gcc older than that listed below may actually compile
  61.  * and link okay, but the end product can have subtle run time bugs.
  62.  * To avoid associated bogus bug reports, we flatly refuse to compile
  63.  * with a gcc that is known to be too old from the very beginning.
  64.  */
  65. #if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 91)
  66. #error Sorry, your GCC is too old. It builds incorrect kernels.
  67. #endif
  68. extern char _stext, _etext;
  69. extern char *linux_banner;
  70. static int init(void *);
  71. extern void init_IRQ(void);
  72. extern void init_modules(void);
  73. extern void sock_init(void);
  74. extern void fork_init(unsigned long);
  75. extern void mca_init(void);
  76. extern void sbus_init(void);
  77. extern void ppc_init(void);
  78. extern void sysctl_init(void);
  79. extern void signals_init(void);
  80. extern int init_pcmcia_ds(void);
  81. extern void free_initmem(void);
  82. #ifdef CONFIG_TC
  83. extern void tc_init(void);
  84. #endif
  85. extern void ecard_init(void);
  86. #if defined(CONFIG_SYSVIPC)
  87. extern void ipc_init(void);
  88. #endif
  89. /*
  90.  * Boot command-line arguments
  91.  */
  92. #define MAX_INIT_ARGS 8
  93. #define MAX_INIT_ENVS 8
  94. extern void time_init(void);
  95. extern void softirq_init(void);
  96. int rows, cols;
  97. char *execute_command;
  98. static char * argv_init[MAX_INIT_ARGS+2] = { "init", NULL, };
  99. char * envp_init[MAX_INIT_ENVS+2] = { "HOME=/", "TERM=linux", NULL, };
  100. static int __init profile_setup(char *str)
  101. {
  102.     int par;
  103.     if (get_option(&str,&par)) prof_shift = par;
  104. return 1;
  105. }
  106. __setup("profile=", profile_setup);
  107. static int __init checksetup(char *line)
  108. {
  109. struct kernel_param *p;
  110. p = &__setup_start;
  111. do {
  112. int n = strlen(p->str);
  113. if (!strncmp(line,p->str,n)) {
  114. if (p->setup_func(line+n))
  115. return 1;
  116. }
  117. p++;
  118. } while (p < &__setup_end);
  119. return 0;
  120. }
  121. /* this should be approx 2 Bo*oMips to start (note initial shift), and will
  122.    still work even if initially too large, it will just take slightly longer */
  123. unsigned long loops_per_jiffy = (1<<12);
  124. /* This is the number of bits of precision for the loops_per_jiffy.  Each
  125.    bit takes on average 1.5/HZ seconds.  This (like the original) is a little
  126.    better than 1% */
  127. #define LPS_PREC 8
  128. void __init calibrate_delay(void)
  129. {
  130. unsigned long ticks, loopbit;
  131. int lps_precision = LPS_PREC;
  132. loops_per_jiffy = (1<<12);
  133. printk("Calibrating delay loop... ");
  134. while (loops_per_jiffy <<= 1) {
  135. /* wait for "start of" clock tick */
  136. ticks = jiffies;
  137. while (ticks == jiffies)
  138. /* nothing */;
  139. /* Go .. */
  140. ticks = jiffies;
  141. __delay(loops_per_jiffy);
  142. ticks = jiffies - ticks;
  143. if (ticks)
  144. break;
  145. }
  146. /* Do a binary approximation to get loops_per_jiffy set to equal one clock
  147.    (up to lps_precision bits) */
  148. loops_per_jiffy >>= 1;
  149. loopbit = loops_per_jiffy;
  150. while ( lps_precision-- && (loopbit >>= 1) ) {
  151. loops_per_jiffy |= loopbit;
  152. ticks = jiffies;
  153. while (ticks == jiffies);
  154. ticks = jiffies;
  155. __delay(loops_per_jiffy);
  156. if (jiffies != ticks) /* longer than 1 tick */
  157. loops_per_jiffy &= ~loopbit;
  158. }
  159. /* Round the value and print it */
  160. printk("%lu.%02lu BogoMIPSn",
  161. loops_per_jiffy/(500000/HZ),
  162. (loops_per_jiffy/(5000/HZ)) % 100);
  163. }
  164. static int __init debug_kernel(char *str)
  165. {
  166. if (*str)
  167. return 0;
  168. console_loglevel = 10;
  169. return 1;
  170. }
  171. static int __init quiet_kernel(char *str)
  172. {
  173. if (*str)
  174. return 0;
  175. console_loglevel = 4;
  176. return 1;
  177. }
  178. __setup("debug", debug_kernel);
  179. __setup("quiet", quiet_kernel);
  180. /*
  181.  * This is a simple kernel command line parsing function: it parses
  182.  * the command line, and fills in the arguments/environment to init
  183.  * as appropriate. Any cmd-line option is taken to be an environment
  184.  * variable if it contains the character '='.
  185.  *
  186.  * This routine also checks for options meant for the kernel.
  187.  * These options are not given to init - they are for internal kernel use only.
  188.  */
  189. static void __init parse_options(char *line)
  190. {
  191. char *next,*quote;
  192. int args, envs;
  193. if (!*line)
  194. return;
  195. args = 0;
  196. envs = 1; /* TERM is set to 'linux' by default */
  197. next = line;
  198. while ((line = next) != NULL) {
  199.                 quote = strchr(line,'"');
  200.                 next = strchr(line, ' ');
  201.                 while (next != NULL && quote != NULL && quote < next) {
  202.                         /* we found a left quote before the next blank
  203.                          * now we have to find the matching right quote
  204.                          */
  205.                         next = strchr(quote+1, '"');
  206.                         if (next != NULL) {
  207.                                 quote = strchr(next+1, '"');
  208.                                 next = strchr(next+1, ' ');
  209.                         }
  210.                 }
  211.                 if (next != NULL)
  212.                         *next++ = 0;
  213. if (!strncmp(line,"init=",5)) {
  214. line += 5;
  215. execute_command = line;
  216. /* In case LILO is going to boot us with default command line,
  217.  * it prepends "auto" before the whole cmdline which makes
  218.  * the shell think it should execute a script with such name.
  219.  * So we ignore all arguments entered _before_ init=... [MJ]
  220.  */
  221. args = 0;
  222. continue;
  223. }
  224. if (checksetup(line))
  225. continue;
  226. /*
  227.  * Then check if it's an environment variable or
  228.  * an option.
  229.  */
  230. if (strchr(line,'=')) {
  231. if (envs >= MAX_INIT_ENVS)
  232. break;
  233. envp_init[++envs] = line;
  234. } else {
  235. if (args >= MAX_INIT_ARGS)
  236. break;
  237. if (*line)
  238. argv_init[++args] = line;
  239. }
  240. }
  241. argv_init[args+1] = NULL;
  242. envp_init[envs+1] = NULL;
  243. }
  244. extern void setup_arch(char **);
  245. extern void cpu_idle(void);
  246. unsigned long wait_init_idle;
  247. #ifndef CONFIG_SMP
  248. #ifdef CONFIG_X86_LOCAL_APIC
  249. static void __init smp_init(void)
  250. {
  251. APIC_init_uniprocessor();
  252. }
  253. #else
  254. #define smp_init() do { } while (0)
  255. #endif
  256. #else
  257. /* Called by boot processor to activate the rest. */
  258. static void __init smp_init(void)
  259. {
  260. /* Get other processors into their bootup holding patterns. */
  261. smp_boot_cpus();
  262. wait_init_idle = cpu_online_map;
  263. clear_bit(current->processor, &wait_init_idle); /* Don't wait on me! */
  264. smp_threads_ready=1;
  265. smp_commence();
  266. /* Wait for the other cpus to set up their idle processes */
  267. printk("Waiting on wait_init_idle (map = 0x%lx)n", wait_init_idle);
  268. while (wait_init_idle) {
  269. cpu_relax();
  270. barrier();
  271. }
  272. printk("All processors have done init_idlen");
  273. }
  274. #endif
  275. /*
  276.  * We need to finalize in a non-__init function or else race conditions
  277.  * between the root thread and the init thread may cause start_kernel to
  278.  * be reaped by free_initmem before the root thread has proceeded to
  279.  * cpu_idle.
  280.  */
  281. static void rest_init(void)
  282. {
  283. kernel_thread(init, NULL, CLONE_FS | CLONE_FILES | CLONE_SIGNAL);
  284. unlock_kernel();
  285. current->need_resched = 1;
  286.   cpu_idle();
  287. /*
  288.  * Activate the first processor.
  289.  */
  290. asmlinkage void __init start_kernel(void)
  291. {
  292. char * command_line;
  293. extern char saved_command_line[];
  294. /*
  295.  * Interrupts are still disabled. Do necessary setups, then
  296.  * enable them
  297.  */
  298. lock_kernel();
  299. printk(linux_banner);
  300. setup_arch(&command_line);
  301. printk("Kernel command line: %sn", saved_command_line);
  302. parse_options(command_line);
  303. trap_init();
  304. init_IRQ();
  305. sched_init();
  306. softirq_init();
  307. time_init();
  308. /*
  309.  * HACK ALERT! This is early. We're enabling the console before
  310.  * we've done PCI setups etc, and console_init() must be aware of
  311.  * this. But we do want output early, in case something goes wrong.
  312.  */
  313. console_init();
  314. #ifdef CONFIG_MODULES
  315. init_modules();
  316. #endif
  317. if (prof_shift) {
  318. unsigned int size;
  319. /* only text is profiled */
  320. prof_len = (unsigned long) &_etext - (unsigned long) &_stext;
  321. prof_len >>= prof_shift;
  322. size = prof_len * sizeof(unsigned int) + PAGE_SIZE-1;
  323. prof_buffer = (unsigned int *) alloc_bootmem(size);
  324. }
  325. kmem_cache_init();
  326. sti();
  327. calibrate_delay();
  328. #ifdef CONFIG_BLK_DEV_INITRD
  329. if (initrd_start && !initrd_below_start_ok &&
  330. initrd_start < min_low_pfn << PAGE_SHIFT) {
  331. printk(KERN_CRIT "initrd overwritten (0x%08lx < 0x%08lx) - "
  332.     "disabling it.n",initrd_start,min_low_pfn << PAGE_SHIFT);
  333. initrd_start = 0;
  334. }
  335. #endif
  336. mem_init();
  337. kmem_cache_sizes_init();
  338. pgtable_cache_init();
  339. /*
  340.  * For architectures that have highmem, num_mappedpages represents
  341.  * the amount of memory the kernel can use.  For other architectures
  342.  * it's the same as the total pages.  We need both numbers because
  343.  * some subsystems need to initialize based on how much memory the
  344.  * kernel can use.
  345.  */
  346. if (num_mappedpages == 0)
  347. num_mappedpages = num_physpages;
  348.   
  349. fork_init(num_mappedpages);
  350. proc_caches_init();
  351. vfs_caches_init(num_physpages);
  352. buffer_init(num_physpages);
  353. page_cache_init(num_physpages);
  354. #if defined(CONFIG_ARCH_S390)
  355. ccwcache_init();
  356. #endif
  357. signals_init();
  358. #ifdef CONFIG_PROC_FS
  359. proc_root_init();
  360. #endif
  361. #if defined(CONFIG_SYSVIPC)
  362. ipc_init();
  363. #endif
  364. check_bugs();
  365. printk("POSIX conformance testing by UNIFIXn");
  366. /* 
  367.  * We count on the initial thread going ok 
  368.  * Like idlers init is an unlocked kernel thread, which will
  369.  * make syscalls (and thus be locked).
  370.  */
  371. smp_init();
  372. rest_init();
  373. }
  374. struct task_struct *child_reaper = &init_task;
  375. static void __init do_initcalls(void)
  376. {
  377. initcall_t *call;
  378. call = &__initcall_start;
  379. do {
  380. (*call)();
  381. call++;
  382. } while (call < &__initcall_end);
  383. /* Make sure there is no pending stuff from the initcall sequence */
  384. flush_scheduled_tasks();
  385. }
  386. /*
  387.  * Ok, the machine is now initialized. None of the devices
  388.  * have been touched yet, but the CPU subsystem is up and
  389.  * running, and memory and process management works.
  390.  *
  391.  * Now we can finally start doing some real work..
  392.  */
  393. static void __init do_basic_setup(void)
  394. {
  395. /*
  396.  * Tell the world that we're going to be the grim
  397.  * reaper of innocent orphaned children.
  398.  *
  399.  * We don't want people to have to make incorrect
  400.  * assumptions about where in the task array this
  401.  * can be found.
  402.  */
  403. child_reaper = current;
  404. #if defined(CONFIG_MTRR) /* Do this after SMP initialization */
  405. /*
  406.  * We should probably create some architecture-dependent "fixup after
  407.  * everything is up" style function where this would belong better
  408.  * than in init/main.c..
  409.  */
  410. mtrr_init();
  411. #endif
  412. #ifdef CONFIG_SYSCTL
  413. sysctl_init();
  414. #endif
  415. /*
  416.  * Ok, at this point all CPU's should be initialized, so
  417.  * we can start looking into devices..
  418.  */
  419. #if defined(CONFIG_ARCH_S390)
  420. s390_init_machine_check();
  421. #endif
  422. #ifdef CONFIG_PCI
  423. pci_init();
  424. #endif
  425. #ifdef CONFIG_SBUS
  426. sbus_init();
  427. #endif
  428. #if defined(CONFIG_PPC)
  429. ppc_init();
  430. #endif
  431. #ifdef CONFIG_MCA
  432. mca_init();
  433. #endif
  434. #ifdef CONFIG_ARCH_ACORN
  435. ecard_init();
  436. #endif
  437. #ifdef CONFIG_ZORRO
  438. zorro_init();
  439. #endif
  440. #ifdef CONFIG_DIO
  441. dio_init();
  442. #endif
  443. #ifdef CONFIG_NUBUS
  444. nubus_init();
  445. #endif
  446. #ifdef CONFIG_ISAPNP
  447. isapnp_init();
  448. #endif
  449. #ifdef CONFIG_TC
  450. tc_init();
  451. #endif
  452. /* Networking initialization needs a process context */ 
  453. sock_init();
  454. start_context_thread();
  455. do_initcalls();
  456. #ifdef CONFIG_IRDA
  457. irda_proto_init();
  458. irda_device_init(); /* Must be done after protocol initialization */
  459. #endif
  460. #ifdef CONFIG_PCMCIA
  461. init_pcmcia_ds(); /* Do this last */
  462. #endif
  463. }
  464. extern void prepare_namespace(void);
  465. static int init(void * unused)
  466. {
  467. lock_kernel();
  468. do_basic_setup();
  469. prepare_namespace();
  470. /*
  471.  * Ok, we have completed the initial bootup, and
  472.  * we're essentially up and running. Get rid of the
  473.  * initmem segments and start the user-mode stuff..
  474.  */
  475. free_initmem();
  476. unlock_kernel();
  477. if (open("/dev/console", O_RDWR, 0) < 0)
  478. printk("Warning: unable to open an initial console.n");
  479. (void) dup(0);
  480. (void) dup(0);
  481. /*
  482.  * We try each of these until one succeeds.
  483.  *
  484.  * The Bourne shell can be used instead of init if we are 
  485.  * trying to recover a really broken machine.
  486.  */
  487. if (execute_command)
  488. execve(execute_command,argv_init,envp_init);
  489. execve("/sbin/init",argv_init,envp_init);
  490. execve("/etc/init",argv_init,envp_init);
  491. execve("/bin/init",argv_init,envp_init);
  492. execve("/bin/sh",argv_init,envp_init);
  493. panic("No init found.  Try passing init= option to kernel.");
  494. }