Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

bootconfig: Support embedding a bootconfig file in kernel

This allows kernel developer to embed a default bootconfig file in
the kernel instead of embedding it in the initrd. This will be good
for who are using the kernel without initrd, or who needs a default
bootconfigs.
This needs to set two kconfigs: CONFIG_BOOT_CONFIG_EMBED=y and set
the file path to CONFIG_BOOT_CONFIG_EMBED_FILE.

Note that you still need 'bootconfig' command line option to load the
embedded bootconfig. Also if you boot using an initrd with a different
bootconfig, the kernel will use the bootconfig in the initrd, instead
of the default bootconfig.

Link: https://lkml.kernel.org/r/164921227943.1090670.14035119557571329218.stgit@devnote2

Cc: Padmanabha Srinivasaiah <treasure4paddy@gmail.com>
Cc: Jonathan Corbet <corbet@lwn.net>
Cc: Randy Dunlap <rdunlap@infradead.org>
Cc: Nick Desaulniers <ndesaulniers@google.com>
Cc: Sami Tolvanen <samitolvanen@google.com>
Cc: Nathan Chancellor <nathan@kernel.org>
Cc: Masahiro Yamada <masahiroy@kernel.org>
Cc: Linux Kbuild mailing list <linux-kbuild@vger.kernel.org>
Signed-off-by: Masami Hiramatsu <mhiramat@kernel.org>
Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org>

authored by

Masami Hiramatsu and committed by
Steven Rostedt (Google)
a2a9d67a 765b8552

+75 -11
+1
MAINTAINERS
··· 7457 7457 F: Documentation/admin-guide/bootconfig.rst 7458 7458 F: fs/proc/bootconfig.c 7459 7459 F: include/linux/bootconfig.h 7460 + F: lib/bootconfig-data.S 7460 7461 F: lib/bootconfig.c 7461 7462 F: tools/bootconfig/* 7462 7463 F: tools/bootconfig/scripts/*
+10
include/linux/bootconfig.h
··· 289 289 /* XBC cleanup data structures */ 290 290 void __init xbc_exit(void); 291 291 292 + /* XBC embedded bootconfig data in kernel */ 293 + #ifdef CONFIG_BOOT_CONFIG_EMBED 294 + const char * __init xbc_get_embedded_bootconfig(size_t *size); 295 + #else 296 + static inline const char *xbc_get_embedded_bootconfig(size_t *size) 297 + { 298 + return NULL; 299 + } 300 + #endif 301 + 292 302 #endif
+20 -1
init/Kconfig
··· 1351 1351 1352 1352 config BOOT_CONFIG 1353 1353 bool "Boot config support" 1354 - select BLK_DEV_INITRD 1354 + select BLK_DEV_INITRD if !BOOT_CONFIG_EMBED 1355 1355 help 1356 1356 Extra boot config allows system admin to pass a config file as 1357 1357 complemental extension of kernel cmdline when booting. ··· 1360 1360 See <file:Documentation/admin-guide/bootconfig.rst> for details. 1361 1361 1362 1362 If unsure, say Y. 1363 + 1364 + config BOOT_CONFIG_EMBED 1365 + bool "Embed bootconfig file in the kernel" 1366 + depends on BOOT_CONFIG 1367 + help 1368 + Embed a bootconfig file given by BOOT_CONFIG_EMBED_FILE in the 1369 + kernel. Usually, the bootconfig file is loaded with the initrd 1370 + image. But if the system doesn't support initrd, this option will 1371 + help you by embedding a bootconfig file while building the kernel. 1372 + 1373 + If unsure, say N. 1374 + 1375 + config BOOT_CONFIG_EMBED_FILE 1376 + string "Embedded bootconfig file path" 1377 + depends on BOOT_CONFIG_EMBED 1378 + help 1379 + Specify a bootconfig file which will be embedded to the kernel. 1380 + This bootconfig will be used if there is no initrd or no other 1381 + bootconfig in the initrd. 1363 1382 1364 1383 choice 1365 1384 prompt "Compiler optimization level"
+12 -10
init/main.c
··· 266 266 early_param("loglevel", loglevel); 267 267 268 268 #ifdef CONFIG_BLK_DEV_INITRD 269 - static void * __init get_boot_config_from_initrd(u32 *_size) 269 + static void * __init get_boot_config_from_initrd(size_t *_size) 270 270 { 271 271 u32 size, csum; 272 272 char *data; ··· 313 313 return data; 314 314 } 315 315 #else 316 - static void * __init get_boot_config_from_initrd(u32 *_size) 316 + static void * __init get_boot_config_from_initrd(size_t *_size) 317 317 { 318 318 return NULL; 319 319 } ··· 410 410 static void __init setup_boot_config(void) 411 411 { 412 412 static char tmp_cmdline[COMMAND_LINE_SIZE] __initdata; 413 - const char *msg; 414 - int pos; 415 - u32 size; 416 - char *data, *err; 417 - int ret; 413 + const char *msg, *data; 414 + int pos, ret; 415 + size_t size; 416 + char *err; 418 417 419 418 /* Cut out the bootconfig data even if we have no bootconfig option */ 420 419 data = get_boot_config_from_initrd(&size); 420 + /* If there is no bootconfig in initrd, try embedded one. */ 421 + if (!data) 422 + data = xbc_get_embedded_bootconfig(&size); 421 423 422 424 strlcpy(tmp_cmdline, boot_command_line, COMMAND_LINE_SIZE); 423 425 err = parse_args("bootconfig", tmp_cmdline, NULL, 0, 0, 0, NULL, ··· 438 436 } 439 437 440 438 if (size >= XBC_DATA_MAX) { 441 - pr_err("bootconfig size %d greater than max size %d\n", 442 - size, XBC_DATA_MAX); 439 + pr_err("bootconfig size %ld greater than max size %d\n", 440 + (long)size, XBC_DATA_MAX); 443 441 return; 444 442 } 445 443 ··· 452 450 msg, pos); 453 451 } else { 454 452 xbc_get_info(&ret, NULL); 455 - pr_info("Load bootconfig: %d bytes %d nodes\n", size, ret); 453 + pr_info("Load bootconfig: %ld bytes %d nodes\n", (long)size, ret); 456 454 /* keys starting with "kernel." are passed via cmdline */ 457 455 extra_command_line = xbc_make_cmdline("kernel"); 458 456 /* Also, "init." keys are init arguments */
+1
lib/.gitignore
··· 1 1 # SPDX-License-Identifier: GPL-2.0-only 2 2 /crc32table.h 3 3 /crc64table.h 4 + /default.bconf 4 5 /gen_crc32table 5 6 /gen_crc64table 6 7 /oid_registry_data.c
+8
lib/Makefile
··· 280 280 lib-$(CONFIG_LIBFDT) += $(libfdt_files) 281 281 282 282 obj-$(CONFIG_BOOT_CONFIG) += bootconfig.o 283 + obj-$(CONFIG_BOOT_CONFIG_EMBED) += bootconfig-data.o 284 + 285 + $(obj)/bootconfig-data.o: $(obj)/default.bconf 286 + 287 + targets += default.bconf 288 + filechk_defbconf = cat $(or $(real-prereqs), /dev/null) 289 + $(obj)/default.bconf: $(CONFIG_BOOT_CONFIG_EMBED_FILE) FORCE 290 + $(call filechk,defbconf) 283 291 284 292 obj-$(CONFIG_RBTREE_TEST) += rbtree_test.o 285 293 obj-$(CONFIG_INTERVAL_TREE_TEST) += interval_tree_test.o
+10
lib/bootconfig-data.S
··· 1 + /* SPDX-License-Identifier: GPL-2.0 */ 2 + /* 3 + * Embed default bootconfig in the kernel. 4 + */ 5 + .section .init.rodata, "aw" 6 + .global embedded_bootconfig_data 7 + embedded_bootconfig_data: 8 + .incbin "lib/default.bconf" 9 + .global embedded_bootconfig_data_end 10 + embedded_bootconfig_data_end:
+13
lib/bootconfig.c
··· 12 12 #include <linux/kernel.h> 13 13 #include <linux/memblock.h> 14 14 #include <linux/string.h> 15 + 16 + #ifdef CONFIG_BOOT_CONFIG_EMBED 17 + /* embedded_bootconfig_data is defined in bootconfig-data.S */ 18 + extern __visible const char embedded_bootconfig_data[]; 19 + extern __visible const char embedded_bootconfig_data_end[]; 20 + 21 + const char * __init xbc_get_embedded_bootconfig(size_t *size) 22 + { 23 + *size = embedded_bootconfig_data_end - embedded_bootconfig_data; 24 + return (*size) ? embedded_bootconfig_data : NULL; 25 + } 26 + #endif 27 + 15 28 #else /* !__KERNEL__ */ 16 29 /* 17 30 * NOTE: This is only for tools/bootconfig, because tools/bootconfig will