main.c (1319916209ce8f55a4f4f848e74500633e24bb99) | main.c (8e57f8acbbd121ecfb0c9dc13b8b030f86c6bd3b) |
---|---|
1// SPDX-License-Identifier: GPL-2.0-only 2/* 3 * linux/init/main.c 4 * 5 * Copyright (C) 1991, 1992 Linus Torvalds 6 * 7 * GK 2/5/95 - Changed to support mounting root fs via NFS 8 * Added initrd & change_root: Werner Almesberger & Hans Lermen, Feb '96 --- 14 unchanged lines hidden (view full) --- 23#include <linux/string.h> 24#include <linux/ctype.h> 25#include <linux/delay.h> 26#include <linux/ioport.h> 27#include <linux/init.h> 28#include <linux/initrd.h> 29#include <linux/memblock.h> 30#include <linux/acpi.h> | 1// SPDX-License-Identifier: GPL-2.0-only 2/* 3 * linux/init/main.c 4 * 5 * Copyright (C) 1991, 1992 Linus Torvalds 6 * 7 * GK 2/5/95 - Changed to support mounting root fs via NFS 8 * Added initrd & change_root: Werner Almesberger & Hans Lermen, Feb '96 --- 14 unchanged lines hidden (view full) --- 23#include <linux/string.h> 24#include <linux/ctype.h> 25#include <linux/delay.h> 26#include <linux/ioport.h> 27#include <linux/init.h> 28#include <linux/initrd.h> 29#include <linux/memblock.h> 30#include <linux/acpi.h> |
31#include <linux/bootconfig.h> | |
32#include <linux/console.h> 33#include <linux/nmi.h> 34#include <linux/percpu.h> 35#include <linux/kmod.h> 36#include <linux/vmalloc.h> 37#include <linux/kernel_stat.h> 38#include <linux/start_kernel.h> 39#include <linux/security.h> --- 92 unchanged lines hidden (view full) --- 132void (*__initdata late_time_init)(void); 133 134/* Untouched command line saved by arch-specific code. */ 135char __initdata boot_command_line[COMMAND_LINE_SIZE]; 136/* Untouched saved command line (eg. for /proc) */ 137char *saved_command_line; 138/* Command line for parameter parsing */ 139static char *static_command_line; | 31#include <linux/console.h> 32#include <linux/nmi.h> 33#include <linux/percpu.h> 34#include <linux/kmod.h> 35#include <linux/vmalloc.h> 36#include <linux/kernel_stat.h> 37#include <linux/start_kernel.h> 38#include <linux/security.h> --- 92 unchanged lines hidden (view full) --- 131void (*__initdata late_time_init)(void); 132 133/* Untouched command line saved by arch-specific code. */ 134char __initdata boot_command_line[COMMAND_LINE_SIZE]; 135/* Untouched saved command line (eg. for /proc) */ 136char *saved_command_line; 137/* Command line for parameter parsing */ 138static char *static_command_line; |
140/* Untouched extra command line */ 141static char *extra_command_line; 142/* Extra init arguments */ 143static char *extra_init_args; | 139/* Command line for per-initcall parameter parsing */ 140static char *initcall_command_line; |
144 145static char *execute_command; 146static char *ramdisk_execute_command; 147 148/* 149 * Used to generate warnings if static_key manipulation functions are used 150 * before jump_label_init is called. 151 */ --- 91 unchanged lines hidden (view full) --- 243 return 0; 244 } 245 246 return -EINVAL; 247} 248 249early_param("loglevel", loglevel); 250 | 141 142static char *execute_command; 143static char *ramdisk_execute_command; 144 145/* 146 * Used to generate warnings if static_key manipulation functions are used 147 * before jump_label_init is called. 148 */ --- 91 unchanged lines hidden (view full) --- 240 return 0; 241 } 242 243 return -EINVAL; 244} 245 246early_param("loglevel", loglevel); 247 |
251#ifdef CONFIG_BOOT_CONFIG 252 253char xbc_namebuf[XBC_KEYLEN_MAX] __initdata; 254 255#define rest(dst, end) ((end) > (dst) ? (end) - (dst) : 0) 256 257static int __init xbc_snprint_cmdline(char *buf, size_t size, 258 struct xbc_node *root) 259{ 260 struct xbc_node *knode, *vnode; 261 char *end = buf + size; 262 char c = '\"'; 263 const char *val; 264 int ret; 265 266 xbc_node_for_each_key_value(root, knode, val) { 267 ret = xbc_node_compose_key_after(root, knode, 268 xbc_namebuf, XBC_KEYLEN_MAX); 269 if (ret < 0) 270 return ret; 271 272 vnode = xbc_node_get_child(knode); 273 ret = snprintf(buf, rest(buf, end), "%s%c", xbc_namebuf, 274 vnode ? '=' : ' '); 275 if (ret < 0) 276 return ret; 277 buf += ret; 278 if (!vnode) 279 continue; 280 281 c = '\"'; 282 xbc_array_for_each_value(vnode, val) { 283 ret = snprintf(buf, rest(buf, end), "%c%s", c, val); 284 if (ret < 0) 285 return ret; 286 buf += ret; 287 c = ','; 288 } 289 if (rest(buf, end) > 2) 290 strcpy(buf, "\" "); 291 buf += 2; 292 } 293 294 return buf - (end - size); 295} 296#undef rest 297 298/* Make an extra command line under given key word */ 299static char * __init xbc_make_cmdline(const char *key) 300{ 301 struct xbc_node *root; 302 char *new_cmdline; 303 int ret, len = 0; 304 305 root = xbc_find_node(key); 306 if (!root) 307 return NULL; 308 309 /* Count required buffer size */ 310 len = xbc_snprint_cmdline(NULL, 0, root); 311 if (len <= 0) 312 return NULL; 313 314 new_cmdline = memblock_alloc(len + 1, SMP_CACHE_BYTES); 315 if (!new_cmdline) { 316 pr_err("Failed to allocate memory for extra kernel cmdline.\n"); 317 return NULL; 318 } 319 320 ret = xbc_snprint_cmdline(new_cmdline, len + 1, root); 321 if (ret < 0 || ret > len) { 322 pr_err("Failed to print extra kernel cmdline.\n"); 323 return NULL; 324 } 325 326 return new_cmdline; 327} 328 329u32 boot_config_checksum(unsigned char *p, u32 size) 330{ 331 u32 ret = 0; 332 333 while (size--) 334 ret += *p++; 335 336 return ret; 337} 338 339static void __init setup_boot_config(void) 340{ 341 u32 size, csum; 342 char *data, *copy; 343 u32 *hdr; 344 345 if (!initrd_end) 346 return; 347 348 hdr = (u32 *)(initrd_end - 8); 349 size = hdr[0]; 350 csum = hdr[1]; 351 352 if (size >= XBC_DATA_MAX) 353 return; 354 355 data = ((void *)hdr) - size; 356 if ((unsigned long)data < initrd_start) 357 return; 358 359 if (boot_config_checksum((unsigned char *)data, size) != csum) 360 return; 361 362 copy = memblock_alloc(size + 1, SMP_CACHE_BYTES); 363 if (!copy) { 364 pr_err("Failed to allocate memory for boot config\n"); 365 return; 366 } 367 368 memcpy(copy, data, size); 369 copy[size] = '\0'; 370 371 if (xbc_init(copy) < 0) 372 pr_err("Failed to parse boot config\n"); 373 else { 374 pr_info("Load boot config: %d bytes\n", size); 375 /* keys starting with "kernel." are passed via cmdline */ 376 extra_command_line = xbc_make_cmdline("kernel"); 377 /* Also, "init." keys are init arguments */ 378 extra_init_args = xbc_make_cmdline("init"); 379 } 380} 381#else 382#define setup_boot_config() do { } while (0) 383#endif 384 | |
385/* Change NUL term back to "=", to make "param" the whole string. */ 386static int __init repair_env_string(char *param, char *val, 387 const char *unused, void *arg) 388{ 389 if (val) { 390 /* param=val or param="val"? */ 391 if (val == param+strlen(param)+1) 392 val[-1] = '='; --- 113 unchanged lines hidden (view full) --- 506/* 507 * We need to store the untouched command line for future reference. 508 * We also need to store the touched command line since the parameter 509 * parsing is performed in place, and we should allow a component to 510 * store reference of name/value for future reference. 511 */ 512static void __init setup_command_line(char *command_line) 513{ | 248/* Change NUL term back to "=", to make "param" the whole string. */ 249static int __init repair_env_string(char *param, char *val, 250 const char *unused, void *arg) 251{ 252 if (val) { 253 /* param=val or param="val"? */ 254 if (val == param+strlen(param)+1) 255 val[-1] = '='; --- 113 unchanged lines hidden (view full) --- 369/* 370 * We need to store the untouched command line for future reference. 371 * We also need to store the touched command line since the parameter 372 * parsing is performed in place, and we should allow a component to 373 * store reference of name/value for future reference. 374 */ 375static void __init setup_command_line(char *command_line) 376{ |
514 size_t len, xlen = 0, ilen = 0; | 377 size_t len = strlen(boot_command_line) + 1; |
515 | 378 |
516 if (extra_command_line) 517 xlen = strlen(extra_command_line); 518 if (extra_init_args) 519 ilen = strlen(extra_init_args) + 4; /* for " -- " */ 520 521 len = xlen + strlen(boot_command_line) + 1; 522 523 saved_command_line = memblock_alloc(len + ilen, SMP_CACHE_BYTES); | 379 saved_command_line = memblock_alloc(len, SMP_CACHE_BYTES); |
524 if (!saved_command_line) | 380 if (!saved_command_line) |
525 panic("%s: Failed to allocate %zu bytes\n", __func__, len + ilen); | 381 panic("%s: Failed to allocate %zu bytes\n", __func__, len); |
526 | 382 |
383 initcall_command_line = memblock_alloc(len, SMP_CACHE_BYTES); 384 if (!initcall_command_line) 385 panic("%s: Failed to allocate %zu bytes\n", __func__, len); 386 |
|
527 static_command_line = memblock_alloc(len, SMP_CACHE_BYTES); 528 if (!static_command_line) 529 panic("%s: Failed to allocate %zu bytes\n", __func__, len); 530 | 387 static_command_line = memblock_alloc(len, SMP_CACHE_BYTES); 388 if (!static_command_line) 389 panic("%s: Failed to allocate %zu bytes\n", __func__, len); 390 |
531 if (xlen) { 532 /* 533 * We have to put extra_command_line before boot command 534 * lines because there could be dashes (separator of init 535 * command line) in the command lines. 536 */ 537 strcpy(saved_command_line, extra_command_line); 538 strcpy(static_command_line, extra_command_line); 539 } 540 strcpy(saved_command_line + xlen, boot_command_line); 541 strcpy(static_command_line + xlen, command_line); 542 543 if (ilen) { 544 /* 545 * Append supplemental init boot args to saved_command_line 546 * so that user can check what command line options passed 547 * to init. 548 */ 549 len = strlen(saved_command_line); 550 if (!strstr(boot_command_line, " -- ")) { 551 strcpy(saved_command_line + len, " -- "); 552 len += 4; 553 } else 554 saved_command_line[len++] = ' '; 555 556 strcpy(saved_command_line + len, extra_init_args); 557 } | 391 strcpy(saved_command_line, boot_command_line); 392 strcpy(static_command_line, command_line); |
558} 559 560/* 561 * We need to finalize in a non-__init function or else race conditions 562 * between the root thread and the init thread may cause start_kernel to 563 * be reaped by free_initmem before the root thread has proceeded to 564 * cpu_idle. 565 * --- 147 unchanged lines hidden (view full) --- 713 */ 714static void __init mm_init(void) 715{ 716 /* 717 * page_ext requires contiguous pages, 718 * bigger than MAX_ORDER unless SPARSEMEM. 719 */ 720 page_ext_init_flatmem(); | 393} 394 395/* 396 * We need to finalize in a non-__init function or else race conditions 397 * between the root thread and the init thread may cause start_kernel to 398 * be reaped by free_initmem before the root thread has proceeded to 399 * cpu_idle. 400 * --- 147 unchanged lines hidden (view full) --- 548 */ 549static void __init mm_init(void) 550{ 551 /* 552 * page_ext requires contiguous pages, 553 * bigger than MAX_ORDER unless SPARSEMEM. 554 */ 555 page_ext_init_flatmem(); |
556 init_debug_pagealloc(); |
|
721 report_meminit(); 722 mem_init(); 723 kmem_cache_init(); 724 kmemleak_init(); 725 pgtable_init(); 726 debug_objects_mem_init(); 727 vmalloc_init(); 728 ioremap_huge_init(); --- 26 unchanged lines hidden (view full) --- 755 * Interrupts are still disabled. Do necessary setups, then 756 * enable them. 757 */ 758 boot_cpu_init(); 759 page_address_init(); 760 pr_notice("%s", linux_banner); 761 early_security_init(); 762 setup_arch(&command_line); | 557 report_meminit(); 558 mem_init(); 559 kmem_cache_init(); 560 kmemleak_init(); 561 pgtable_init(); 562 debug_objects_mem_init(); 563 vmalloc_init(); 564 ioremap_huge_init(); --- 26 unchanged lines hidden (view full) --- 591 * Interrupts are still disabled. Do necessary setups, then 592 * enable them. 593 */ 594 boot_cpu_init(); 595 page_address_init(); 596 pr_notice("%s", linux_banner); 597 early_security_init(); 598 setup_arch(&command_line); |
763 setup_boot_config(); | |
764 setup_command_line(command_line); 765 setup_nr_cpu_ids(); 766 setup_per_cpu_areas(); 767 smp_prepare_boot_cpu(); /* arch-specific boot-cpu hooks */ 768 boot_cpu_hotplug_init(); 769 770 build_all_zonelists(NULL); 771 page_alloc_init(); 772 | 599 setup_command_line(command_line); 600 setup_nr_cpu_ids(); 601 setup_per_cpu_areas(); 602 smp_prepare_boot_cpu(); /* arch-specific boot-cpu hooks */ 603 boot_cpu_hotplug_init(); 604 605 build_all_zonelists(NULL); 606 page_alloc_init(); 607 |
773 pr_notice("Kernel command line: %s\n", saved_command_line); | 608 pr_notice("Kernel command line: %s\n", boot_command_line); |
774 /* parameters may set static keys */ 775 jump_label_init(); 776 parse_early_param(); 777 after_dashes = parse_args("Booting kernel", 778 static_command_line, __start___param, 779 __stop___param - __start___param, 780 -1, -1, NULL, &unknown_bootoption); 781 if (!IS_ERR_OR_NULL(after_dashes)) 782 parse_args("Setting init args", after_dashes, NULL, 0, -1, -1, 783 NULL, set_init_arg); | 609 /* parameters may set static keys */ 610 jump_label_init(); 611 parse_early_param(); 612 after_dashes = parse_args("Booting kernel", 613 static_command_line, __start___param, 614 __stop___param - __start___param, 615 -1, -1, NULL, &unknown_bootoption); 616 if (!IS_ERR_OR_NULL(after_dashes)) 617 parse_args("Setting init args", after_dashes, NULL, 0, -1, -1, 618 NULL, set_init_arg); |
784 if (extra_init_args) 785 parse_args("Setting extra init args", extra_init_args, 786 NULL, 0, -1, -1, NULL, set_init_arg); | |
787 788 /* 789 * These use large bootmem allocations and must precede 790 * kmem_cache_init() 791 */ 792 setup_log_buf(0); 793 vfs_caches_init_early(); 794 sort_main_extable(); --- 359 unchanged lines hidden (view full) --- 1154 "postcore", 1155 "arch", 1156 "subsys", 1157 "fs", 1158 "device", 1159 "late", 1160}; 1161 | 619 620 /* 621 * These use large bootmem allocations and must precede 622 * kmem_cache_init() 623 */ 624 setup_log_buf(0); 625 vfs_caches_init_early(); 626 sort_main_extable(); --- 359 unchanged lines hidden (view full) --- 986 "postcore", 987 "arch", 988 "subsys", 989 "fs", 990 "device", 991 "late", 992}; 993 |
1162static void __init do_initcall_level(int level, char *command_line) | 994static void __init do_initcall_level(int level) |
1163{ 1164 initcall_entry_t *fn; 1165 | 995{ 996 initcall_entry_t *fn; 997 |
998 strcpy(initcall_command_line, saved_command_line); |
|
1166 parse_args(initcall_level_names[level], | 999 parse_args(initcall_level_names[level], |
1167 command_line, __start___param, | 1000 initcall_command_line, __start___param, |
1168 __stop___param - __start___param, 1169 level, level, 1170 NULL, &repair_env_string); 1171 1172 trace_initcall_level(initcall_level_names[level]); 1173 for (fn = initcall_levels[level]; fn < initcall_levels[level+1]; fn++) 1174 do_one_initcall(initcall_from_entry(fn)); 1175} 1176 1177static void __init do_initcalls(void) 1178{ 1179 int level; | 1001 __stop___param - __start___param, 1002 level, level, 1003 NULL, &repair_env_string); 1004 1005 trace_initcall_level(initcall_level_names[level]); 1006 for (fn = initcall_levels[level]; fn < initcall_levels[level+1]; fn++) 1007 do_one_initcall(initcall_from_entry(fn)); 1008} 1009 1010static void __init do_initcalls(void) 1011{ 1012 int level; |
1180 size_t len = strlen(saved_command_line) + 1; 1181 char *command_line; | |
1182 | 1013 |
1183 command_line = kzalloc(len, GFP_KERNEL); 1184 if (!command_line) 1185 panic("%s: Failed to allocate %zu bytes\n", __func__, len); 1186 1187 for (level = 0; level < ARRAY_SIZE(initcall_levels) - 1; level++) { 1188 /* Parser modifies command_line, restore it each time */ 1189 strcpy(command_line, saved_command_line); 1190 do_initcall_level(level, command_line); 1191 } 1192 1193 kfree(command_line); | 1014 for (level = 0; level < ARRAY_SIZE(initcall_levels) - 1; level++) 1015 do_initcall_level(level); |
1194} 1195 1196/* 1197 * Ok, the machine is now initialized. None of the devices 1198 * have been touched yet, but the CPU subsystem is up and 1199 * running, and memory and process management works. 1200 * 1201 * Now we can finally start doing some real work.. --- 208 unchanged lines hidden --- | 1016} 1017 1018/* 1019 * Ok, the machine is now initialized. None of the devices 1020 * have been touched yet, but the CPU subsystem is up and 1021 * running, and memory and process management works. 1022 * 1023 * Now we can finally start doing some real work.. --- 208 unchanged lines hidden --- |