diff options
Diffstat (limited to 'init/main.c')
-rw-r--r-- | init/main.c | 104 |
1 files changed, 80 insertions, 24 deletions
diff --git a/init/main.c b/init/main.c index ff49a6dacfb..1ca6b32c482 100644 --- a/init/main.c +++ b/init/main.c | |||
@@ -87,7 +87,6 @@ extern void mca_init(void); | |||
87 | extern void sbus_init(void); | 87 | extern void sbus_init(void); |
88 | extern void prio_tree_init(void); | 88 | extern void prio_tree_init(void); |
89 | extern void radix_tree_init(void); | 89 | extern void radix_tree_init(void); |
90 | extern void free_initmem(void); | ||
91 | #ifndef CONFIG_DEBUG_RODATA | 90 | #ifndef CONFIG_DEBUG_RODATA |
92 | static inline void mark_rodata_ro(void) { } | 91 | static inline void mark_rodata_ro(void) { } |
93 | #endif | 92 | #endif |
@@ -226,13 +225,9 @@ static int __init loglevel(char *str) | |||
226 | 225 | ||
227 | early_param("loglevel", loglevel); | 226 | early_param("loglevel", loglevel); |
228 | 227 | ||
229 | /* | 228 | /* Change NUL term back to "=", to make "param" the whole string. */ |
230 | * Unknown boot options get handed to init, unless they look like | 229 | static int __init repair_env_string(char *param, char *val, const char *unused) |
231 | * unused parameters (modprobe will find them in /proc/cmdline). | ||
232 | */ | ||
233 | static int __init unknown_bootoption(char *param, char *val) | ||
234 | { | 230 | { |
235 | /* Change NUL term back to "=", to make "param" the whole string. */ | ||
236 | if (val) { | 231 | if (val) { |
237 | /* param=val or param="val"? */ | 232 | /* param=val or param="val"? */ |
238 | if (val == param+strlen(param)+1) | 233 | if (val == param+strlen(param)+1) |
@@ -244,6 +239,16 @@ static int __init unknown_bootoption(char *param, char *val) | |||
244 | } else | 239 | } else |
245 | BUG(); | 240 | BUG(); |
246 | } | 241 | } |
242 | return 0; | ||
243 | } | ||
244 | |||
245 | /* | ||
246 | * Unknown boot options get handed to init, unless they look like | ||
247 | * unused parameters (modprobe will find them in /proc/cmdline). | ||
248 | */ | ||
249 | static int __init unknown_bootoption(char *param, char *val, const char *unused) | ||
250 | { | ||
251 | repair_env_string(param, val, unused); | ||
247 | 252 | ||
248 | /* Handle obsolete-style parameters */ | 253 | /* Handle obsolete-style parameters */ |
249 | if (obsolete_checksetup(param)) | 254 | if (obsolete_checksetup(param)) |
@@ -374,16 +379,13 @@ static noinline void __init_refok rest_init(void) | |||
374 | * at least once to get things moving: | 379 | * at least once to get things moving: |
375 | */ | 380 | */ |
376 | init_idle_bootup_task(current); | 381 | init_idle_bootup_task(current); |
377 | preempt_enable_no_resched(); | 382 | schedule_preempt_disabled(); |
378 | schedule(); | ||
379 | |||
380 | /* Call into cpu_idle with preempt disabled */ | 383 | /* Call into cpu_idle with preempt disabled */ |
381 | preempt_disable(); | ||
382 | cpu_idle(); | 384 | cpu_idle(); |
383 | } | 385 | } |
384 | 386 | ||
385 | /* Check for early params. */ | 387 | /* Check for early params. */ |
386 | static int __init do_early_param(char *param, char *val) | 388 | static int __init do_early_param(char *param, char *val, const char *unused) |
387 | { | 389 | { |
388 | const struct obs_kernel_param *p; | 390 | const struct obs_kernel_param *p; |
389 | 391 | ||
@@ -403,7 +405,7 @@ static int __init do_early_param(char *param, char *val) | |||
403 | 405 | ||
404 | void __init parse_early_options(char *cmdline) | 406 | void __init parse_early_options(char *cmdline) |
405 | { | 407 | { |
406 | parse_args("early options", cmdline, NULL, 0, do_early_param); | 408 | parse_args("early options", cmdline, NULL, 0, 0, 0, do_early_param); |
407 | } | 409 | } |
408 | 410 | ||
409 | /* Arch code calls this early on, or if not, just before other parsing. */ | 411 | /* Arch code calls this early on, or if not, just before other parsing. */ |
@@ -449,8 +451,8 @@ void __init __weak thread_info_cache_init(void) | |||
449 | static void __init mm_init(void) | 451 | static void __init mm_init(void) |
450 | { | 452 | { |
451 | /* | 453 | /* |
452 | * page_cgroup requires countinous pages as memmap | 454 | * page_cgroup requires contiguous pages, |
453 | * and it's bigger than MAX_ORDER unless SPARSEMEM. | 455 | * bigger than MAX_ORDER unless SPARSEMEM. |
454 | */ | 456 | */ |
455 | page_cgroup_init_flatmem(); | 457 | page_cgroup_init_flatmem(); |
456 | mem_init(); | 458 | mem_init(); |
@@ -506,7 +508,7 @@ asmlinkage void __init start_kernel(void) | |||
506 | parse_early_param(); | 508 | parse_early_param(); |
507 | parse_args("Booting kernel", static_command_line, __start___param, | 509 | parse_args("Booting kernel", static_command_line, __start___param, |
508 | __stop___param - __start___param, | 510 | __stop___param - __start___param, |
509 | &unknown_bootoption); | 511 | 0, 0, &unknown_bootoption); |
510 | 512 | ||
511 | jump_label_init(); | 513 | jump_label_init(); |
512 | 514 | ||
@@ -558,9 +560,6 @@ asmlinkage void __init start_kernel(void) | |||
558 | early_boot_irqs_disabled = false; | 560 | early_boot_irqs_disabled = false; |
559 | local_irq_enable(); | 561 | local_irq_enable(); |
560 | 562 | ||
561 | /* Interrupts are enabled now so all GFP allocations are safe. */ | ||
562 | gfp_allowed_mask = __GFP_BITS_MASK; | ||
563 | |||
564 | kmem_cache_init_late(); | 563 | kmem_cache_init_late(); |
565 | 564 | ||
566 | /* | 565 | /* |
@@ -702,16 +701,69 @@ int __init_or_module do_one_initcall(initcall_t fn) | |||
702 | } | 701 | } |
703 | 702 | ||
704 | 703 | ||
705 | extern initcall_t __initcall_start[], __initcall_end[], __early_initcall_end[]; | 704 | extern initcall_t __initcall_start[]; |
706 | 705 | extern initcall_t __initcall0_start[]; | |
707 | static void __init do_initcalls(void) | 706 | extern initcall_t __initcall1_start[]; |
707 | extern initcall_t __initcall2_start[]; | ||
708 | extern initcall_t __initcall3_start[]; | ||
709 | extern initcall_t __initcall4_start[]; | ||
710 | extern initcall_t __initcall5_start[]; | ||
711 | extern initcall_t __initcall6_start[]; | ||
712 | extern initcall_t __initcall7_start[]; | ||
713 | extern initcall_t __initcall_end[]; | ||
714 | |||
715 | static initcall_t *initcall_levels[] __initdata = { | ||
716 | __initcall0_start, | ||
717 | __initcall1_start, | ||
718 | __initcall2_start, | ||
719 | __initcall3_start, | ||
720 | __initcall4_start, | ||
721 | __initcall5_start, | ||
722 | __initcall6_start, | ||
723 | __initcall7_start, | ||
724 | __initcall_end, | ||
725 | }; | ||
726 | |||
727 | static char *initcall_level_names[] __initdata = { | ||
728 | "early", | ||
729 | "core", | ||
730 | "postcore", | ||
731 | "arch", | ||
732 | "subsys", | ||
733 | "fs", | ||
734 | "device", | ||
735 | "late", | ||
736 | }; | ||
737 | |||
738 | static void __init do_initcall_level(int level) | ||
708 | { | 739 | { |
740 | extern const struct kernel_param __start___param[], __stop___param[]; | ||
709 | initcall_t *fn; | 741 | initcall_t *fn; |
710 | 742 | ||
711 | for (fn = __early_initcall_end; fn < __initcall_end; fn++) | 743 | strcpy(static_command_line, saved_command_line); |
744 | parse_args(initcall_level_names[level], | ||
745 | static_command_line, __start___param, | ||
746 | __stop___param - __start___param, | ||
747 | level, level, | ||
748 | &repair_env_string); | ||
749 | |||
750 | for (fn = initcall_levels[level]; fn < initcall_levels[level+1]; fn++) | ||
712 | do_one_initcall(*fn); | 751 | do_one_initcall(*fn); |
713 | } | 752 | } |
714 | 753 | ||
754 | static void __init do_initcalls(void) | ||
755 | { | ||
756 | int level; | ||
757 | |||
758 | for (level = 0; level < ARRAY_SIZE(initcall_levels) - 1; level++) { | ||
759 | pr_info("initlevel:%d=%s, %d registered initcalls\n", | ||
760 | level, initcall_level_names[level], | ||
761 | (int) (initcall_levels[level+1] | ||
762 | - initcall_levels[level])); | ||
763 | do_initcall_level(level); | ||
764 | } | ||
765 | } | ||
766 | |||
715 | /* | 767 | /* |
716 | * Ok, the machine is now initialized. None of the devices | 768 | * Ok, the machine is now initialized. None of the devices |
717 | * have been touched yet, but the CPU subsystem is up and | 769 | * have been touched yet, but the CPU subsystem is up and |
@@ -735,7 +787,7 @@ static void __init do_pre_smp_initcalls(void) | |||
735 | { | 787 | { |
736 | initcall_t *fn; | 788 | initcall_t *fn; |
737 | 789 | ||
738 | for (fn = __initcall_start; fn < __early_initcall_end; fn++) | 790 | for (fn = __initcall_start; fn < __initcall0_start; fn++) |
739 | do_one_initcall(*fn); | 791 | do_one_initcall(*fn); |
740 | } | 792 | } |
741 | 793 | ||
@@ -792,6 +844,10 @@ static int __init kernel_init(void * unused) | |||
792 | * Wait until kthreadd is all set-up. | 844 | * Wait until kthreadd is all set-up. |
793 | */ | 845 | */ |
794 | wait_for_completion(&kthreadd_done); | 846 | wait_for_completion(&kthreadd_done); |
847 | |||
848 | /* Now the scheduler is fully set up and can do blocking allocations */ | ||
849 | gfp_allowed_mask = __GFP_BITS_MASK; | ||
850 | |||
795 | /* | 851 | /* |
796 | * init can allocate pages on any node | 852 | * init can allocate pages on any node |
797 | */ | 853 | */ |