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 ---