linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v6 0/4] bootconfig: Support embedding a bootconfig in kernel for non initrd boot
@ 2022-03-31  5:55 Masami Hiramatsu
  2022-03-31  5:56 ` [PATCH v6 1/4] bootconfig: Make the bootconfig.o as a normal object file Masami Hiramatsu
                   ` (3 more replies)
  0 siblings, 4 replies; 9+ messages in thread
From: Masami Hiramatsu @ 2022-03-31  5:55 UTC (permalink / raw)
  To: Steven Rostedt
  Cc: Masami Hiramatsu, Padmanabha Srinivasaiah, LKML, Jonathan Corbet,
	linux-doc, Randy Dunlap, Nick Desaulniers, Sami Tolvanen,
	Nathan Chancellor, llvm, Masahiro Yamada,
	Linux Kbuild mailing list

Hi,

Here are the 6th version of the patchset to enable kernel embedded bootconfig
for non-initrd kernel boot environment. This version adds a new patch to use
obj-y instead of lib-y for bootconfig([1/4]) and split the inline asm code into
independent asm file for incremental build with LTO THIN mode issue(*), which
was reported in the previous version [1].

[1] https://lore.kernel.org/all/164847778869.3060675.8115416881394543419.stgit@devnote2/T/#u

You can embed a bootconfig file into the kernel as a default bootconfig,
which will be used if there is no initrd or no bootconfig is attached to initrd. 

This needs 2 options: CONFIG_EMBED_BOOT_CONFIG=y and set the file
path to CONFIG_EMBED_BOOT_CONFIG_FILE. Even if you embed the bootconfig file
to the kernel, it will not be enabled unless you pass "bootconfig" kernel
command line option at boot. Moreover, since this is just a "default"
bootconfig, you can override it with a new bootconfig if you attach another
bootconfig to the initrd (if possible).
CONFIG_EMBED_BOOT_CONFIG_FILE can take both absolute and relative path, but
to simplify and make it independent from the build environment, I recommend
you to use an absolute path for that.

This is requested by Padmanabha at the below thread[2];

[2] https://lore.kernel.org/all/20220307184011.GA2570@pswork/T/#u

(*) this issue has been reported to github ClangBuiltLinux project [3]

[3] https://github.com/ClangBuiltLinux/linux/issues/1618

and Nick told me that we can avoid this by disabling LTO on that file.

CFLAGS_REMOVE_<file>.o := $(CC_FLAGS_LTO)

But I chose Masahiro's idea to split the inline asm into an independent
asm file, since that can also simplify the Makefile.
The above mitigation should be applied to kernel/configs.c and kernel/kheaders.c
but that should be another story (maybe LTO bugfix?).


Thank you,

---

Masami Hiramatsu (4):
      bootconfig: Make the bootconfig.o as a normal object file
      bootconfig: Check the checksum before removing the bootconfig from initrd
      bootconfig: Support embedding a bootconfig file in kernel
      docs: bootconfig: Add how to embed the bootconfig into kernel


 Documentation/admin-guide/bootconfig.rst |   31 +++++++++++++++++++++++++++---
 MAINTAINERS                              |    1 +
 include/linux/bootconfig.h               |   10 ++++++++++
 init/Kconfig                             |   21 ++++++++++++++++++++
 init/main.c                              |   31 +++++++++++++++---------------
 lib/.gitignore                           |    1 +
 lib/Makefile                             |   10 +++++++++-
 lib/bootconfig-data.S                    |   11 +++++++++++
 lib/bootconfig.c                         |   13 +++++++++++++
 9 files changed, 110 insertions(+), 19 deletions(-)
 create mode 100644 lib/bootconfig-data.S

--
Masami Hiramatsu (Linaro) <mhiramat@kernel.org>

^ permalink raw reply	[flat|nested] 9+ messages in thread

* [PATCH v6 1/4] bootconfig: Make the bootconfig.o as a normal object file
  2022-03-31  5:55 [PATCH v6 0/4] bootconfig: Support embedding a bootconfig in kernel for non initrd boot Masami Hiramatsu
@ 2022-03-31  5:56 ` Masami Hiramatsu
  2022-03-31  5:56 ` [PATCH v6 2/4] bootconfig: Check the checksum before removing the bootconfig from initrd Masami Hiramatsu
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 9+ messages in thread
From: Masami Hiramatsu @ 2022-03-31  5:56 UTC (permalink / raw)
  To: Steven Rostedt
  Cc: Masami Hiramatsu, Padmanabha Srinivasaiah, LKML, Jonathan Corbet,
	linux-doc, Randy Dunlap, Nick Desaulniers, Sami Tolvanen,
	Nathan Chancellor, llvm, Masahiro Yamada,
	Linux Kbuild mailing list

Since the APIs defined in the bootconfig.o are not individually used,
it is meaningless to build it as library by lib-y. Use obj-y for that.

Reported-by: Masahiro Yamada <masahiroy@kernel.org>
Signed-off-by: Masami Hiramatsu <mhiramat@kernel.org>
---
 Changes in v6:
  - Newly added.
---
 lib/Makefile |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/lib/Makefile b/lib/Makefile
index 6b9ffc1bd1ee..08053df16c7c 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -279,7 +279,7 @@ $(foreach file, $(libfdt_files), \
 	$(eval CFLAGS_$(file) = -I $(srctree)/scripts/dtc/libfdt))
 lib-$(CONFIG_LIBFDT) += $(libfdt_files)
 
-lib-$(CONFIG_BOOT_CONFIG) += bootconfig.o
+obj-$(CONFIG_BOOT_CONFIG) += bootconfig.o
 
 obj-$(CONFIG_RBTREE_TEST) += rbtree_test.o
 obj-$(CONFIG_INTERVAL_TREE_TEST) += interval_tree_test.o


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH v6 2/4] bootconfig: Check the checksum before removing the bootconfig from initrd
  2022-03-31  5:55 [PATCH v6 0/4] bootconfig: Support embedding a bootconfig in kernel for non initrd boot Masami Hiramatsu
  2022-03-31  5:56 ` [PATCH v6 1/4] bootconfig: Make the bootconfig.o as a normal object file Masami Hiramatsu
@ 2022-03-31  5:56 ` Masami Hiramatsu
  2022-03-31  5:56 ` [PATCH v6 3/4] bootconfig: Support embedding a bootconfig file in kernel Masami Hiramatsu
  2022-03-31  5:56 ` [PATCH v6 4/4] docs: bootconfig: Add how to embed the bootconfig into kernel Masami Hiramatsu
  3 siblings, 0 replies; 9+ messages in thread
From: Masami Hiramatsu @ 2022-03-31  5:56 UTC (permalink / raw)
  To: Steven Rostedt
  Cc: Masami Hiramatsu, Padmanabha Srinivasaiah, LKML, Jonathan Corbet,
	linux-doc, Randy Dunlap, Nick Desaulniers, Sami Tolvanen,
	Nathan Chancellor, llvm, Masahiro Yamada,
	Linux Kbuild mailing list

Check the bootconfig's checksum before removing the bootcinfig data
from initrd to avoid modifying initrd by mistake.
This will also simplifies the get_boot_config_from_initrd() interface.

Signed-off-by: Masami Hiramatsu <mhiramat@kernel.org>
---
 init/main.c |   22 ++++++++++------------
 1 file changed, 10 insertions(+), 12 deletions(-)

diff --git a/init/main.c b/init/main.c
index 98182c3c2c4b..266d61bc67b0 100644
--- a/init/main.c
+++ b/init/main.c
@@ -266,7 +266,7 @@ static int __init loglevel(char *str)
 early_param("loglevel", loglevel);
 
 #ifdef CONFIG_BLK_DEV_INITRD
-static void * __init get_boot_config_from_initrd(u32 *_size, u32 *_csum)
+static void * __init get_boot_config_from_initrd(u32 *_size)
 {
 	u32 size, csum;
 	char *data;
@@ -300,17 +300,20 @@ static void * __init get_boot_config_from_initrd(u32 *_size, u32 *_csum)
 		return NULL;
 	}
 
+	if (xbc_calc_checksum(data, size) != csum) {
+		pr_err("bootconfig checksum failed\n");
+		return NULL;
+	}
+
 	/* Remove bootconfig from initramfs/initrd */
 	initrd_end = (unsigned long)data;
 	if (_size)
 		*_size = size;
-	if (_csum)
-		*_csum = csum;
 
 	return data;
 }
 #else
-static void * __init get_boot_config_from_initrd(u32 *_size, u32 *_csum)
+static void * __init get_boot_config_from_initrd(u32 *_size)
 {
 	return NULL;
 }
@@ -409,12 +412,12 @@ static void __init setup_boot_config(void)
 	static char tmp_cmdline[COMMAND_LINE_SIZE] __initdata;
 	const char *msg;
 	int pos;
-	u32 size, csum;
+	u32 size;
 	char *data, *err;
 	int ret;
 
 	/* Cut out the bootconfig data even if we have no bootconfig option */
-	data = get_boot_config_from_initrd(&size, &csum);
+	data = get_boot_config_from_initrd(&size);
 
 	strlcpy(tmp_cmdline, boot_command_line, COMMAND_LINE_SIZE);
 	err = parse_args("bootconfig", tmp_cmdline, NULL, 0, 0, 0, NULL,
@@ -438,11 +441,6 @@ static void __init setup_boot_config(void)
 		return;
 	}
 
-	if (xbc_calc_checksum(data, size) != csum) {
-		pr_err("bootconfig checksum failed\n");
-		return;
-	}
-
 	ret = xbc_init(data, size, &msg, &pos);
 	if (ret < 0) {
 		if (pos < 0)
@@ -471,7 +469,7 @@ static void __init exit_boot_config(void)
 static void __init setup_boot_config(void)
 {
 	/* Remove bootconfig data from initrd */
-	get_boot_config_from_initrd(NULL, NULL);
+	get_boot_config_from_initrd(NULL);
 }
 
 static int __init warn_bootconfig(char *str)


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH v6 3/4] bootconfig: Support embedding a bootconfig file in kernel
  2022-03-31  5:55 [PATCH v6 0/4] bootconfig: Support embedding a bootconfig in kernel for non initrd boot Masami Hiramatsu
  2022-03-31  5:56 ` [PATCH v6 1/4] bootconfig: Make the bootconfig.o as a normal object file Masami Hiramatsu
  2022-03-31  5:56 ` [PATCH v6 2/4] bootconfig: Check the checksum before removing the bootconfig from initrd Masami Hiramatsu
@ 2022-03-31  5:56 ` Masami Hiramatsu
  2022-03-31  6:27   ` Masahiro Yamada
  2022-03-31  5:56 ` [PATCH v6 4/4] docs: bootconfig: Add how to embed the bootconfig into kernel Masami Hiramatsu
  3 siblings, 1 reply; 9+ messages in thread
From: Masami Hiramatsu @ 2022-03-31  5:56 UTC (permalink / raw)
  To: Steven Rostedt
  Cc: Masami Hiramatsu, Padmanabha Srinivasaiah, LKML, Jonathan Corbet,
	linux-doc, Randy Dunlap, Nick Desaulniers, Sami Tolvanen,
	Nathan Chancellor, llvm, Masahiro Yamada,
	Linux Kbuild mailing list

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_EMBED_BOOT_CONFIG=y and set
the file path to CONFIG_EMBED_BOOT_CONFIG_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.

Signed-off-by: Masami Hiramatsu <mhiramat@kernel.org>
---
 Changes in v6:
  - Split out the .incbin asm part as bootconfig-data.S according to
    Masahiro's comment.
 Changes in v5:
  - Fix .gitignore to be sorted alphabetically.
  - Make default.bconf is cleaned up correctly.
  - Allow user to specify relative path to CONFIG_EMBED_BOOT_CONFIG_FILE.
    (Thanks Masahiro!)
 Changes in v4:
  - Avoid updating the default.bconf if the file is not changed.
---
 MAINTAINERS                |    1 +
 include/linux/bootconfig.h |   10 ++++++++++
 init/Kconfig               |   21 +++++++++++++++++++++
 init/main.c                |   13 ++++++++-----
 lib/.gitignore             |    1 +
 lib/Makefile               |    8 ++++++++
 lib/bootconfig-data.S      |   11 +++++++++++
 lib/bootconfig.c           |   13 +++++++++++++
 8 files changed, 73 insertions(+), 5 deletions(-)
 create mode 100644 lib/bootconfig-data.S

diff --git a/MAINTAINERS b/MAINTAINERS
index b555a5e8704f..9b4910685412 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -7350,6 +7350,7 @@ S:	Maintained
 F:	Documentation/admin-guide/bootconfig.rst
 F:	fs/proc/bootconfig.c
 F:	include/linux/bootconfig.h
+F:	lib/bootconfig-data.S
 F:	lib/bootconfig.c
 F:	tools/bootconfig/*
 F:	tools/bootconfig/scripts/*
diff --git a/include/linux/bootconfig.h b/include/linux/bootconfig.h
index a4665c7ab07c..5dbda5e3e9bb 100644
--- a/include/linux/bootconfig.h
+++ b/include/linux/bootconfig.h
@@ -289,4 +289,14 @@ int __init xbc_get_info(int *node_size, size_t *data_size);
 /* XBC cleanup data structures */
 void __init xbc_exit(void);
 
+/* XBC embedded bootconfig data in kernel */
+#ifdef CONFIG_EMBED_BOOT_CONFIG
+char * __init xbc_get_embedded_bootconfig(size_t *size);
+#else
+static inline char *xbc_get_embedded_bootconfig(size_t *size)
+{
+	return NULL;
+}
+#endif
+
 #endif
diff --git a/init/Kconfig b/init/Kconfig
index 97463a33baa7..f5d14a78cfce 100644
--- a/init/Kconfig
+++ b/init/Kconfig
@@ -1361,6 +1361,27 @@ config BOOT_CONFIG
 
 	  If unsure, say Y.
 
+config EMBED_BOOT_CONFIG
+	bool "Embed bootconfig file in the kernel"
+	depends on BOOT_CONFIG
+	default n
+	help
+	  Embed a bootconfig file given by EMBED_BOOT_CONFIG_FILE in the
+	  kernel. Usually, the bootconfig file is loaded with the initrd
+	  image. But if the system doesn't support initrd, this option will
+	  help you by embedding a bootconfig file while building the kernel.
+
+	  If unsure, say N.
+
+config EMBED_BOOT_CONFIG_FILE
+	string "Embedded bootconfig file path"
+	default ""
+	depends on EMBED_BOOT_CONFIG
+	help
+	  Specify a bootconfig file which will be embedded to the kernel.
+	  This bootconfig will be used if there is no initrd or no other
+	  bootconfig in the initrd.
+
 choice
 	prompt "Compiler optimization level"
 	default CC_OPTIMIZE_FOR_PERFORMANCE
diff --git a/init/main.c b/init/main.c
index 266d61bc67b0..a5db3e36b809 100644
--- a/init/main.c
+++ b/init/main.c
@@ -266,7 +266,7 @@ static int __init loglevel(char *str)
 early_param("loglevel", loglevel);
 
 #ifdef CONFIG_BLK_DEV_INITRD
-static void * __init get_boot_config_from_initrd(u32 *_size)
+static void * __init get_boot_config_from_initrd(size_t *_size)
 {
 	u32 size, csum;
 	char *data;
@@ -412,12 +412,15 @@ static void __init setup_boot_config(void)
 	static char tmp_cmdline[COMMAND_LINE_SIZE] __initdata;
 	const char *msg;
 	int pos;
-	u32 size;
+	size_t size;
 	char *data, *err;
 	int ret;
 
 	/* Cut out the bootconfig data even if we have no bootconfig option */
 	data = get_boot_config_from_initrd(&size);
+	/* If there is no bootconfig in initrd, try embedded one. */
+	if (!data)
+		data = xbc_get_embedded_bootconfig(&size);
 
 	strlcpy(tmp_cmdline, boot_command_line, COMMAND_LINE_SIZE);
 	err = parse_args("bootconfig", tmp_cmdline, NULL, 0, 0, 0, NULL,
@@ -436,8 +439,8 @@ static void __init setup_boot_config(void)
 	}
 
 	if (size >= XBC_DATA_MAX) {
-		pr_err("bootconfig size %d greater than max size %d\n",
-			size, XBC_DATA_MAX);
+		pr_err("bootconfig size %ld greater than max size %d\n",
+			(long)size, XBC_DATA_MAX);
 		return;
 	}
 
@@ -450,7 +453,7 @@ static void __init setup_boot_config(void)
 				msg, pos);
 	} else {
 		xbc_get_info(&ret, NULL);
-		pr_info("Load bootconfig: %d bytes %d nodes\n", size, ret);
+		pr_info("Load bootconfig: %ld bytes %d nodes\n", (long)size, ret);
 		/* keys starting with "kernel." are passed via cmdline */
 		extra_command_line = xbc_make_cmdline("kernel");
 		/* Also, "init." keys are init arguments */
diff --git a/lib/.gitignore b/lib/.gitignore
index e5e217b8307b..54596b634ecb 100644
--- a/lib/.gitignore
+++ b/lib/.gitignore
@@ -1,6 +1,7 @@
 # SPDX-License-Identifier: GPL-2.0-only
 /crc32table.h
 /crc64table.h
+/default.bconf
 /gen_crc32table
 /gen_crc64table
 /oid_registry_data.c
diff --git a/lib/Makefile b/lib/Makefile
index 08053df16c7c..2a82cc324f91 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -280,6 +280,14 @@ $(foreach file, $(libfdt_files), \
 lib-$(CONFIG_LIBFDT) += $(libfdt_files)
 
 obj-$(CONFIG_BOOT_CONFIG) += bootconfig.o
+obj-$(CONFIG_EMBED_BOOT_CONFIG) += bootconfig-data.o
+
+$(obj)/bootconfig-data.o: $(obj)/default.bconf
+
+targets += default.bconf
+filechk_defbconf = cat $(or $(real-prereqs), /dev/null)
+$(obj)/default.bconf: $(CONFIG_EMBED_BOOT_CONFIG_FILE) FORCE
+	$(call filechk,defbconf)
 
 obj-$(CONFIG_RBTREE_TEST) += rbtree_test.o
 obj-$(CONFIG_INTERVAL_TREE_TEST) += interval_tree_test.o
diff --git a/lib/bootconfig-data.S b/lib/bootconfig-data.S
new file mode 100644
index 000000000000..df674ea7d8be
--- /dev/null
+++ b/lib/bootconfig-data.S
@@ -0,0 +1,11 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Embed default bootconfig in the kernel.
+ */
+	.pushsection .init.data, "aw"
+	.global embedded_bootconfig_data
+embedded_bootconfig_data:
+	.incbin "lib/default.bconf"
+	.global embedded_bootconfig_data_end
+embedded_bootconfig_data_end:
+	.popsection
diff --git a/lib/bootconfig.c b/lib/bootconfig.c
index 74f3201ab8e5..6d30aee85ebe 100644
--- a/lib/bootconfig.c
+++ b/lib/bootconfig.c
@@ -12,6 +12,19 @@
 #include <linux/kernel.h>
 #include <linux/memblock.h>
 #include <linux/string.h>
+
+#ifdef CONFIG_EMBED_BOOT_CONFIG
+/* embedded_bootconfig_data is defined in bootconfig-data.S */
+extern __visible char embedded_bootconfig_data[];
+extern __visible char embedded_bootconfig_data_end[];
+
+char * __init xbc_get_embedded_bootconfig(size_t *size)
+{
+	*size = embedded_bootconfig_data_end - embedded_bootconfig_data;
+	return (*size) ? embedded_bootconfig_data : NULL;
+}
+#endif
+
 #else /* !__KERNEL__ */
 /*
  * NOTE: This is only for tools/bootconfig, because tools/bootconfig will


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH v6 4/4] docs: bootconfig: Add how to embed the bootconfig into kernel
  2022-03-31  5:55 [PATCH v6 0/4] bootconfig: Support embedding a bootconfig in kernel for non initrd boot Masami Hiramatsu
                   ` (2 preceding siblings ...)
  2022-03-31  5:56 ` [PATCH v6 3/4] bootconfig: Support embedding a bootconfig file in kernel Masami Hiramatsu
@ 2022-03-31  5:56 ` Masami Hiramatsu
  3 siblings, 0 replies; 9+ messages in thread
From: Masami Hiramatsu @ 2022-03-31  5:56 UTC (permalink / raw)
  To: Steven Rostedt
  Cc: Masami Hiramatsu, Padmanabha Srinivasaiah, LKML, Jonathan Corbet,
	linux-doc, Randy Dunlap, Nick Desaulniers, Sami Tolvanen,
	Nathan Chancellor, llvm, Masahiro Yamada,
	Linux Kbuild mailing list

Add a description how to embed the bootconfig file into kernel.

Signed-off-by: Masami Hiramatsu <mhiramat@kernel.org>
---
 Changes in v5:
  - Update CONFIG_EMBED_BOOT_CONFIG_FILE which can accept relative path.
 Changes in v3:
  - Fix typos.
 Changes in v2:
  - Corrected the text accoding to Randy's suggestion.
  - Do not reccomend to use relative path for CONFIG_EMBED_BOOT_CONFIG_FILE.
---
 Documentation/admin-guide/bootconfig.rst |   31 +++++++++++++++++++++++++++---
 1 file changed, 28 insertions(+), 3 deletions(-)

diff --git a/Documentation/admin-guide/bootconfig.rst b/Documentation/admin-guide/bootconfig.rst
index a1860fc0ca88..83a2a0cc9afa 100644
--- a/Documentation/admin-guide/bootconfig.rst
+++ b/Documentation/admin-guide/bootconfig.rst
@@ -158,9 +158,15 @@ Each key-value pair is shown in each line with following style::
 Boot Kernel With a Boot Config
 ==============================
 
-Since the boot configuration file is loaded with initrd, it will be added
-to the end of the initrd (initramfs) image file with padding, size,
-checksum and 12-byte magic word as below.
+There are two options to boot the kernel with bootconfig: attaching the
+bootconfig to the initrd image or embedding it in the kernel itself.
+
+Attaching a Boot Config to Initrd
+---------------------------------
+
+Since the boot configuration file is loaded with initrd by default,
+it will be added to the end of the initrd (initramfs) image file with
+padding, size, checksum and 12-byte magic word as below.
 
 [initrd][bootconfig][padding][size(le32)][checksum(le32)][#BOOTCONFIG\n]
 
@@ -196,6 +202,25 @@ To remove the config from the image, you can use -d option as below::
 Then add "bootconfig" on the normal kernel command line to tell the
 kernel to look for the bootconfig at the end of the initrd file.
 
+Embedding a Boot Config into Kernel
+-----------------------------------
+
+If you can not use initrd, you can also embed the bootconfig file in the
+kernel by Kconfig options. In this case, you need to recompile the kernel
+with the following configs::
+
+ CONFIG_EMBED_BOOT_CONFIG=y
+ CONFIG_EMBED_BOOT_CONFIG_FILE="/PATH/TO/BOOTCONFIG/FILE"
+
+``CONFIG_EMBED_BOOT_CONFIG_FILE`` requires an absolute path or a relative
+path to the bootconfig file from source tree or object tree.
+The kernel will embed it as the default bootconfig.
+
+Just as when attaching the bootconfig to the initrd, you need ``bootconfig``
+option on the kernel command line to enable the embedded bootconfig.
+
+Note that even if you set this option, you can override the embedded
+bootconfig by another bootconfig which attached to the initrd.
 
 Kernel parameters via Boot Config
 =================================


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* Re: [PATCH v6 3/4] bootconfig: Support embedding a bootconfig file in kernel
  2022-03-31  5:56 ` [PATCH v6 3/4] bootconfig: Support embedding a bootconfig file in kernel Masami Hiramatsu
@ 2022-03-31  6:27   ` Masahiro Yamada
  2022-03-31  6:49     ` Masami Hiramatsu
  0 siblings, 1 reply; 9+ messages in thread
From: Masahiro Yamada @ 2022-03-31  6:27 UTC (permalink / raw)
  To: Masami Hiramatsu
  Cc: Steven Rostedt, Padmanabha Srinivasaiah, LKML, Jonathan Corbet,
	open list:DOCUMENTATION, Randy Dunlap, Nick Desaulniers,
	Sami Tolvanen, Nathan Chancellor, llvm,
	Linux Kbuild mailing list

On Thu, Mar 31, 2022 at 2:56 PM Masami Hiramatsu <mhiramat@kernel.org> wrote:
>
> 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_EMBED_BOOT_CONFIG=y and set
> the file path to CONFIG_EMBED_BOOT_CONFIG_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.
>
> Signed-off-by: Masami Hiramatsu <mhiramat@kernel.org>
> ---
>  Changes in v6:
>   - Split out the .incbin asm part as bootconfig-data.S according to
>     Masahiro's comment.
>  Changes in v5:
>   - Fix .gitignore to be sorted alphabetically.
>   - Make default.bconf is cleaned up correctly.
>   - Allow user to specify relative path to CONFIG_EMBED_BOOT_CONFIG_FILE.
>     (Thanks Masahiro!)
>  Changes in v4:
>   - Avoid updating the default.bconf if the file is not changed.
> ---
>  MAINTAINERS                |    1 +
>  include/linux/bootconfig.h |   10 ++++++++++
>  init/Kconfig               |   21 +++++++++++++++++++++
>  init/main.c                |   13 ++++++++-----
>  lib/.gitignore             |    1 +
>  lib/Makefile               |    8 ++++++++
>  lib/bootconfig-data.S      |   11 +++++++++++
>  lib/bootconfig.c           |   13 +++++++++++++
>  8 files changed, 73 insertions(+), 5 deletions(-)
>  create mode 100644 lib/bootconfig-data.S
>
> diff --git a/MAINTAINERS b/MAINTAINERS
> index b555a5e8704f..9b4910685412 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -7350,6 +7350,7 @@ S:        Maintained
>  F:     Documentation/admin-guide/bootconfig.rst
>  F:     fs/proc/bootconfig.c
>  F:     include/linux/bootconfig.h
> +F:     lib/bootconfig-data.S
>  F:     lib/bootconfig.c
>  F:     tools/bootconfig/*
>  F:     tools/bootconfig/scripts/*
> diff --git a/include/linux/bootconfig.h b/include/linux/bootconfig.h
> index a4665c7ab07c..5dbda5e3e9bb 100644
> --- a/include/linux/bootconfig.h
> +++ b/include/linux/bootconfig.h
> @@ -289,4 +289,14 @@ int __init xbc_get_info(int *node_size, size_t *data_size);
>  /* XBC cleanup data structures */
>  void __init xbc_exit(void);
>
> +/* XBC embedded bootconfig data in kernel */
> +#ifdef CONFIG_EMBED_BOOT_CONFIG
> +char * __init xbc_get_embedded_bootconfig(size_t *size);
> +#else
> +static inline char *xbc_get_embedded_bootconfig(size_t *size)
> +{
> +       return NULL;
> +}
> +#endif
> +
>  #endif
> diff --git a/init/Kconfig b/init/Kconfig
> index 97463a33baa7..f5d14a78cfce 100644
> --- a/init/Kconfig
> +++ b/init/Kconfig
> @@ -1361,6 +1361,27 @@ config BOOT_CONFIG
>
>           If unsure, say Y.
>
> +config EMBED_BOOT_CONFIG
> +       bool "Embed bootconfig file in the kernel"
> +       depends on BOOT_CONFIG
> +       default n
> +       help
> +         Embed a bootconfig file given by EMBED_BOOT_CONFIG_FILE in the
> +         kernel. Usually, the bootconfig file is loaded with the initrd
> +         image. But if the system doesn't support initrd, this option will
> +         help you by embedding a bootconfig file while building the kernel.
> +
> +         If unsure, say N.
> +
> +config EMBED_BOOT_CONFIG_FILE
> +       string "Embedded bootconfig file path"
> +       default ""
> +       depends on EMBED_BOOT_CONFIG
> +       help
> +         Specify a bootconfig file which will be embedded to the kernel.
> +         This bootconfig will be used if there is no initrd or no other
> +         bootconfig in the initrd.
> +
>  choice
>         prompt "Compiler optimization level"
>         default CC_OPTIMIZE_FOR_PERFORMANCE
> diff --git a/init/main.c b/init/main.c
> index 266d61bc67b0..a5db3e36b809 100644
> --- a/init/main.c
> +++ b/init/main.c
> @@ -266,7 +266,7 @@ static int __init loglevel(char *str)
>  early_param("loglevel", loglevel);
>
>  #ifdef CONFIG_BLK_DEV_INITRD
> -static void * __init get_boot_config_from_initrd(u32 *_size)
> +static void * __init get_boot_config_from_initrd(size_t *_size)
>  {
>         u32 size, csum;
>         char *data;
> @@ -412,12 +412,15 @@ static void __init setup_boot_config(void)
>         static char tmp_cmdline[COMMAND_LINE_SIZE] __initdata;
>         const char *msg;
>         int pos;
> -       u32 size;
> +       size_t size;
>         char *data, *err;
>         int ret;
>
>         /* Cut out the bootconfig data even if we have no bootconfig option */
>         data = get_boot_config_from_initrd(&size);
> +       /* If there is no bootconfig in initrd, try embedded one. */
> +       if (!data)
> +               data = xbc_get_embedded_bootconfig(&size);
>
>         strlcpy(tmp_cmdline, boot_command_line, COMMAND_LINE_SIZE);
>         err = parse_args("bootconfig", tmp_cmdline, NULL, 0, 0, 0, NULL,
> @@ -436,8 +439,8 @@ static void __init setup_boot_config(void)
>         }
>
>         if (size >= XBC_DATA_MAX) {
> -               pr_err("bootconfig size %d greater than max size %d\n",
> -                       size, XBC_DATA_MAX);
> +               pr_err("bootconfig size %ld greater than max size %d\n",
> +                       (long)size, XBC_DATA_MAX);
>                 return;
>         }
>
> @@ -450,7 +453,7 @@ static void __init setup_boot_config(void)
>                                 msg, pos);
>         } else {
>                 xbc_get_info(&ret, NULL);
> -               pr_info("Load bootconfig: %d bytes %d nodes\n", size, ret);
> +               pr_info("Load bootconfig: %ld bytes %d nodes\n", (long)size, ret);
>                 /* keys starting with "kernel." are passed via cmdline */
>                 extra_command_line = xbc_make_cmdline("kernel");
>                 /* Also, "init." keys are init arguments */
> diff --git a/lib/.gitignore b/lib/.gitignore
> index e5e217b8307b..54596b634ecb 100644
> --- a/lib/.gitignore
> +++ b/lib/.gitignore
> @@ -1,6 +1,7 @@
>  # SPDX-License-Identifier: GPL-2.0-only
>  /crc32table.h
>  /crc64table.h
> +/default.bconf
>  /gen_crc32table
>  /gen_crc64table
>  /oid_registry_data.c
> diff --git a/lib/Makefile b/lib/Makefile
> index 08053df16c7c..2a82cc324f91 100644
> --- a/lib/Makefile
> +++ b/lib/Makefile
> @@ -280,6 +280,14 @@ $(foreach file, $(libfdt_files), \
>  lib-$(CONFIG_LIBFDT) += $(libfdt_files)
>
>  obj-$(CONFIG_BOOT_CONFIG) += bootconfig.o
> +obj-$(CONFIG_EMBED_BOOT_CONFIG) += bootconfig-data.o
> +
> +$(obj)/bootconfig-data.o: $(obj)/default.bconf
> +
> +targets += default.bconf
> +filechk_defbconf = cat $(or $(real-prereqs), /dev/null)
> +$(obj)/default.bconf: $(CONFIG_EMBED_BOOT_CONFIG_FILE) FORCE
> +       $(call filechk,defbconf)
>
>  obj-$(CONFIG_RBTREE_TEST) += rbtree_test.o
>  obj-$(CONFIG_INTERVAL_TREE_TEST) += interval_tree_test.o
> diff --git a/lib/bootconfig-data.S b/lib/bootconfig-data.S
> new file mode 100644
> index 000000000000..df674ea7d8be
> --- /dev/null
> +++ b/lib/bootconfig-data.S
> @@ -0,0 +1,11 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +/*
> + * Embed default bootconfig in the kernel.
> + */
> +       .pushsection .init.data, "aw"
> +       .global embedded_bootconfig_data
> +embedded_bootconfig_data:
> +       .incbin "lib/default.bconf"
> +       .global embedded_bootconfig_data_end
> +embedded_bootconfig_data_end:
> +       .popsection



You used  .pushsection / .popsection because it was
previously located in bootconfig.c, where there are
functions, which should go to the ".text" section.


Now that you split this into a separate compilation unit,
there is only one ".init.data" section in the file.


     .section  .init.data, "aw"

should be enough.



BTW, is it reasonable/possible to make it explicitly read-only?

I have not tested this patch at all. Nor do I have enough insight.

     .section  .init.rodata, "a"

I am not sure whether this is possible or not.



Some more nits:

    default n

    default ""

are the redundant defaults in Kconfig.





Personally, I prefer seeing the common prefix
for options that belong to the same group,
for example,

   CONFIG_BOOT_CONFIG
   CONFIG_BOOT_CONFIG_EMBED
   CONFIG_BOOT_CONFIG_EMBEDDED_FILE


But, this is something like "up to you" things.







> diff --git a/lib/bootconfig.c b/lib/bootconfig.c
> index 74f3201ab8e5..6d30aee85ebe 100644
> --- a/lib/bootconfig.c
> +++ b/lib/bootconfig.c
> @@ -12,6 +12,19 @@
>  #include <linux/kernel.h>
>  #include <linux/memblock.h>
>  #include <linux/string.h>
> +
> +#ifdef CONFIG_EMBED_BOOT_CONFIG
> +/* embedded_bootconfig_data is defined in bootconfig-data.S */
> +extern __visible char embedded_bootconfig_data[];
> +extern __visible char embedded_bootconfig_data_end[];
> +
> +char * __init xbc_get_embedded_bootconfig(size_t *size)
> +{
> +       *size = embedded_bootconfig_data_end - embedded_bootconfig_data;
> +       return (*size) ? embedded_bootconfig_data : NULL;
> +}
> +#endif
> +
>  #else /* !__KERNEL__ */
>  /*
>   * NOTE: This is only for tools/bootconfig, because tools/bootconfig will
>


-- 
Best Regards
Masahiro Yamada

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH v6 3/4] bootconfig: Support embedding a bootconfig file in kernel
  2022-03-31  6:27   ` Masahiro Yamada
@ 2022-03-31  6:49     ` Masami Hiramatsu
  2022-03-31  6:54       ` Masahiro Yamada
  0 siblings, 1 reply; 9+ messages in thread
From: Masami Hiramatsu @ 2022-03-31  6:49 UTC (permalink / raw)
  To: Masahiro Yamada
  Cc: Steven Rostedt, Padmanabha Srinivasaiah, LKML, Jonathan Corbet,
	open list:DOCUMENTATION, Randy Dunlap, Nick Desaulniers,
	Sami Tolvanen, Nathan Chancellor, llvm,
	Linux Kbuild mailing list

On Thu, 31 Mar 2022 15:27:56 +0900
Masahiro Yamada <masahiroy@kernel.org> wrote:

> On Thu, Mar 31, 2022 at 2:56 PM Masami Hiramatsu <mhiramat@kernel.org> wrote:
> >
> > 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_EMBED_BOOT_CONFIG=y and set
> > the file path to CONFIG_EMBED_BOOT_CONFIG_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.
> >
> > Signed-off-by: Masami Hiramatsu <mhiramat@kernel.org>
> > ---
> >  Changes in v6:
> >   - Split out the .incbin asm part as bootconfig-data.S according to
> >     Masahiro's comment.
> >  Changes in v5:
> >   - Fix .gitignore to be sorted alphabetically.
> >   - Make default.bconf is cleaned up correctly.
> >   - Allow user to specify relative path to CONFIG_EMBED_BOOT_CONFIG_FILE.
> >     (Thanks Masahiro!)
> >  Changes in v4:
> >   - Avoid updating the default.bconf if the file is not changed.
> > ---
> >  MAINTAINERS                |    1 +
> >  include/linux/bootconfig.h |   10 ++++++++++
> >  init/Kconfig               |   21 +++++++++++++++++++++
> >  init/main.c                |   13 ++++++++-----
> >  lib/.gitignore             |    1 +
> >  lib/Makefile               |    8 ++++++++
> >  lib/bootconfig-data.S      |   11 +++++++++++
> >  lib/bootconfig.c           |   13 +++++++++++++
> >  8 files changed, 73 insertions(+), 5 deletions(-)
> >  create mode 100644 lib/bootconfig-data.S
> >
> > diff --git a/MAINTAINERS b/MAINTAINERS
> > index b555a5e8704f..9b4910685412 100644
> > --- a/MAINTAINERS
> > +++ b/MAINTAINERS
> > @@ -7350,6 +7350,7 @@ S:        Maintained
> >  F:     Documentation/admin-guide/bootconfig.rst
> >  F:     fs/proc/bootconfig.c
> >  F:     include/linux/bootconfig.h
> > +F:     lib/bootconfig-data.S
> >  F:     lib/bootconfig.c
> >  F:     tools/bootconfig/*
> >  F:     tools/bootconfig/scripts/*
> > diff --git a/include/linux/bootconfig.h b/include/linux/bootconfig.h
> > index a4665c7ab07c..5dbda5e3e9bb 100644
> > --- a/include/linux/bootconfig.h
> > +++ b/include/linux/bootconfig.h
> > @@ -289,4 +289,14 @@ int __init xbc_get_info(int *node_size, size_t *data_size);
> >  /* XBC cleanup data structures */
> >  void __init xbc_exit(void);
> >
> > +/* XBC embedded bootconfig data in kernel */
> > +#ifdef CONFIG_EMBED_BOOT_CONFIG
> > +char * __init xbc_get_embedded_bootconfig(size_t *size);
> > +#else
> > +static inline char *xbc_get_embedded_bootconfig(size_t *size)
> > +{
> > +       return NULL;
> > +}
> > +#endif
> > +
> >  #endif
> > diff --git a/init/Kconfig b/init/Kconfig
> > index 97463a33baa7..f5d14a78cfce 100644
> > --- a/init/Kconfig
> > +++ b/init/Kconfig
> > @@ -1361,6 +1361,27 @@ config BOOT_CONFIG
> >
> >           If unsure, say Y.
> >
> > +config EMBED_BOOT_CONFIG
> > +       bool "Embed bootconfig file in the kernel"
> > +       depends on BOOT_CONFIG
> > +       default n
> > +       help
> > +         Embed a bootconfig file given by EMBED_BOOT_CONFIG_FILE in the
> > +         kernel. Usually, the bootconfig file is loaded with the initrd
> > +         image. But if the system doesn't support initrd, this option will
> > +         help you by embedding a bootconfig file while building the kernel.
> > +
> > +         If unsure, say N.
> > +
> > +config EMBED_BOOT_CONFIG_FILE
> > +       string "Embedded bootconfig file path"
> > +       default ""
> > +       depends on EMBED_BOOT_CONFIG
> > +       help
> > +         Specify a bootconfig file which will be embedded to the kernel.
> > +         This bootconfig will be used if there is no initrd or no other
> > +         bootconfig in the initrd.
> > +
> >  choice
> >         prompt "Compiler optimization level"
> >         default CC_OPTIMIZE_FOR_PERFORMANCE
> > diff --git a/init/main.c b/init/main.c
> > index 266d61bc67b0..a5db3e36b809 100644
> > --- a/init/main.c
> > +++ b/init/main.c
> > @@ -266,7 +266,7 @@ static int __init loglevel(char *str)
> >  early_param("loglevel", loglevel);
> >
> >  #ifdef CONFIG_BLK_DEV_INITRD
> > -static void * __init get_boot_config_from_initrd(u32 *_size)
> > +static void * __init get_boot_config_from_initrd(size_t *_size)
> >  {
> >         u32 size, csum;
> >         char *data;
> > @@ -412,12 +412,15 @@ static void __init setup_boot_config(void)
> >         static char tmp_cmdline[COMMAND_LINE_SIZE] __initdata;
> >         const char *msg;
> >         int pos;
> > -       u32 size;
> > +       size_t size;
> >         char *data, *err;
> >         int ret;
> >
> >         /* Cut out the bootconfig data even if we have no bootconfig option */
> >         data = get_boot_config_from_initrd(&size);
> > +       /* If there is no bootconfig in initrd, try embedded one. */
> > +       if (!data)
> > +               data = xbc_get_embedded_bootconfig(&size);
> >
> >         strlcpy(tmp_cmdline, boot_command_line, COMMAND_LINE_SIZE);
> >         err = parse_args("bootconfig", tmp_cmdline, NULL, 0, 0, 0, NULL,
> > @@ -436,8 +439,8 @@ static void __init setup_boot_config(void)
> >         }
> >
> >         if (size >= XBC_DATA_MAX) {
> > -               pr_err("bootconfig size %d greater than max size %d\n",
> > -                       size, XBC_DATA_MAX);
> > +               pr_err("bootconfig size %ld greater than max size %d\n",
> > +                       (long)size, XBC_DATA_MAX);
> >                 return;
> >         }
> >
> > @@ -450,7 +453,7 @@ static void __init setup_boot_config(void)
> >                                 msg, pos);
> >         } else {
> >                 xbc_get_info(&ret, NULL);
> > -               pr_info("Load bootconfig: %d bytes %d nodes\n", size, ret);
> > +               pr_info("Load bootconfig: %ld bytes %d nodes\n", (long)size, ret);
> >                 /* keys starting with "kernel." are passed via cmdline */
> >                 extra_command_line = xbc_make_cmdline("kernel");
> >                 /* Also, "init." keys are init arguments */
> > diff --git a/lib/.gitignore b/lib/.gitignore
> > index e5e217b8307b..54596b634ecb 100644
> > --- a/lib/.gitignore
> > +++ b/lib/.gitignore
> > @@ -1,6 +1,7 @@
> >  # SPDX-License-Identifier: GPL-2.0-only
> >  /crc32table.h
> >  /crc64table.h
> > +/default.bconf
> >  /gen_crc32table
> >  /gen_crc64table
> >  /oid_registry_data.c
> > diff --git a/lib/Makefile b/lib/Makefile
> > index 08053df16c7c..2a82cc324f91 100644
> > --- a/lib/Makefile
> > +++ b/lib/Makefile
> > @@ -280,6 +280,14 @@ $(foreach file, $(libfdt_files), \
> >  lib-$(CONFIG_LIBFDT) += $(libfdt_files)
> >
> >  obj-$(CONFIG_BOOT_CONFIG) += bootconfig.o
> > +obj-$(CONFIG_EMBED_BOOT_CONFIG) += bootconfig-data.o
> > +
> > +$(obj)/bootconfig-data.o: $(obj)/default.bconf
> > +
> > +targets += default.bconf
> > +filechk_defbconf = cat $(or $(real-prereqs), /dev/null)
> > +$(obj)/default.bconf: $(CONFIG_EMBED_BOOT_CONFIG_FILE) FORCE
> > +       $(call filechk,defbconf)
> >
> >  obj-$(CONFIG_RBTREE_TEST) += rbtree_test.o
> >  obj-$(CONFIG_INTERVAL_TREE_TEST) += interval_tree_test.o
> > diff --git a/lib/bootconfig-data.S b/lib/bootconfig-data.S
> > new file mode 100644
> > index 000000000000..df674ea7d8be
> > --- /dev/null
> > +++ b/lib/bootconfig-data.S
> > @@ -0,0 +1,11 @@
> > +/* SPDX-License-Identifier: GPL-2.0 */
> > +/*
> > + * Embed default bootconfig in the kernel.
> > + */
> > +       .pushsection .init.data, "aw"
> > +       .global embedded_bootconfig_data
> > +embedded_bootconfig_data:
> > +       .incbin "lib/default.bconf"
> > +       .global embedded_bootconfig_data_end
> > +embedded_bootconfig_data_end:
> > +       .popsection
> 
> 
> 
> You used  .pushsection / .popsection because it was
> previously located in bootconfig.c, where there are
> functions, which should go to the ".text" section.

Oops, yes. I have made a dumb copy from the inline asm...

> Now that you split this into a separate compilation unit,
> there is only one ".init.data" section in the file.
> 
> 
>      .section  .init.data, "aw"
> 
> should be enough.

OK.

> BTW, is it reasonable/possible to make it explicitly read-only?
> 
> I have not tested this patch at all. Nor do I have enough insight.
> 
>      .section  .init.rodata, "a"
> 
> I am not sure whether this is possible or not.

Yes, it can be. The data is passed via 'const char *'.

> 
> 
> 
> Some more nits:
> 
>     default n
> 
>     default ""
> 
> are the redundant defaults in Kconfig.

Thanks for that information. Let me remove those lines. :)

> 
> 
> 
> 
> Personally, I prefer seeing the common prefix
> for options that belong to the same group,
> for example,
> 
>    CONFIG_BOOT_CONFIG
>    CONFIG_BOOT_CONFIG_EMBED
>    CONFIG_BOOT_CONFIG_EMBEDDED_FILE
> 
> 
> But, this is something like "up to you" things.

Good comment. OK, I'll change it next version.

Thank you!

> 
> 
> 
> 
> 
> 
> 
> > diff --git a/lib/bootconfig.c b/lib/bootconfig.c
> > index 74f3201ab8e5..6d30aee85ebe 100644
> > --- a/lib/bootconfig.c
> > +++ b/lib/bootconfig.c
> > @@ -12,6 +12,19 @@
> >  #include <linux/kernel.h>
> >  #include <linux/memblock.h>
> >  #include <linux/string.h>
> > +
> > +#ifdef CONFIG_EMBED_BOOT_CONFIG
> > +/* embedded_bootconfig_data is defined in bootconfig-data.S */
> > +extern __visible char embedded_bootconfig_data[];
> > +extern __visible char embedded_bootconfig_data_end[];
> > +
> > +char * __init xbc_get_embedded_bootconfig(size_t *size)
> > +{
> > +       *size = embedded_bootconfig_data_end - embedded_bootconfig_data;
> > +       return (*size) ? embedded_bootconfig_data : NULL;
> > +}
> > +#endif
> > +
> >  #else /* !__KERNEL__ */
> >  /*
> >   * NOTE: This is only for tools/bootconfig, because tools/bootconfig will
> >
> 
> 
> -- 
> Best Regards
> Masahiro Yamada


-- 
Masami Hiramatsu <mhiramat@kernel.org>

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH v6 3/4] bootconfig: Support embedding a bootconfig file in kernel
  2022-03-31  6:49     ` Masami Hiramatsu
@ 2022-03-31  6:54       ` Masahiro Yamada
  2022-03-31  7:20         ` Masami Hiramatsu
  0 siblings, 1 reply; 9+ messages in thread
From: Masahiro Yamada @ 2022-03-31  6:54 UTC (permalink / raw)
  To: Masami Hiramatsu
  Cc: Steven Rostedt, Padmanabha Srinivasaiah, LKML, Jonathan Corbet,
	open list:DOCUMENTATION, Randy Dunlap, Nick Desaulniers,
	Sami Tolvanen, Nathan Chancellor, llvm,
	Linux Kbuild mailing list

On Thu, Mar 31, 2022 at 3:49 PM Masami Hiramatsu <mhiramat@kernel.org> wrote:
>
> On Thu, 31 Mar 2022 15:27:56 +0900
> Masahiro Yamada <masahiroy@kernel.org> wrote:
>
> > On Thu, Mar 31, 2022 at 2:56 PM Masami Hiramatsu <mhiramat@kernel.org> wrote:
> > >
> > > 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_EMBED_BOOT_CONFIG=y and set
> > > the file path to CONFIG_EMBED_BOOT_CONFIG_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.
> > >
> > > Signed-off-by: Masami Hiramatsu <mhiramat@kernel.org>
> > > ---
> > >  Changes in v6:
> > >   - Split out the .incbin asm part as bootconfig-data.S according to
> > >     Masahiro's comment.
> > >  Changes in v5:
> > >   - Fix .gitignore to be sorted alphabetically.
> > >   - Make default.bconf is cleaned up correctly.
> > >   - Allow user to specify relative path to CONFIG_EMBED_BOOT_CONFIG_FILE.
> > >     (Thanks Masahiro!)
> > >  Changes in v4:
> > >   - Avoid updating the default.bconf if the file is not changed.
> > > ---
> > >  MAINTAINERS                |    1 +
> > >  include/linux/bootconfig.h |   10 ++++++++++
> > >  init/Kconfig               |   21 +++++++++++++++++++++
> > >  init/main.c                |   13 ++++++++-----
> > >  lib/.gitignore             |    1 +
> > >  lib/Makefile               |    8 ++++++++
> > >  lib/bootconfig-data.S      |   11 +++++++++++
> > >  lib/bootconfig.c           |   13 +++++++++++++
> > >  8 files changed, 73 insertions(+), 5 deletions(-)
> > >  create mode 100644 lib/bootconfig-data.S
> > >
> > > diff --git a/MAINTAINERS b/MAINTAINERS
> > > index b555a5e8704f..9b4910685412 100644
> > > --- a/MAINTAINERS
> > > +++ b/MAINTAINERS
> > > @@ -7350,6 +7350,7 @@ S:        Maintained
> > >  F:     Documentation/admin-guide/bootconfig.rst
> > >  F:     fs/proc/bootconfig.c
> > >  F:     include/linux/bootconfig.h
> > > +F:     lib/bootconfig-data.S
> > >  F:     lib/bootconfig.c
> > >  F:     tools/bootconfig/*
> > >  F:     tools/bootconfig/scripts/*
> > > diff --git a/include/linux/bootconfig.h b/include/linux/bootconfig.h
> > > index a4665c7ab07c..5dbda5e3e9bb 100644
> > > --- a/include/linux/bootconfig.h
> > > +++ b/include/linux/bootconfig.h
> > > @@ -289,4 +289,14 @@ int __init xbc_get_info(int *node_size, size_t *data_size);
> > >  /* XBC cleanup data structures */
> > >  void __init xbc_exit(void);
> > >
> > > +/* XBC embedded bootconfig data in kernel */
> > > +#ifdef CONFIG_EMBED_BOOT_CONFIG
> > > +char * __init xbc_get_embedded_bootconfig(size_t *size);
> > > +#else
> > > +static inline char *xbc_get_embedded_bootconfig(size_t *size)
> > > +{
> > > +       return NULL;
> > > +}
> > > +#endif
> > > +
> > >  #endif
> > > diff --git a/init/Kconfig b/init/Kconfig
> > > index 97463a33baa7..f5d14a78cfce 100644
> > > --- a/init/Kconfig
> > > +++ b/init/Kconfig
> > > @@ -1361,6 +1361,27 @@ config BOOT_CONFIG
> > >
> > >           If unsure, say Y.
> > >
> > > +config EMBED_BOOT_CONFIG
> > > +       bool "Embed bootconfig file in the kernel"
> > > +       depends on BOOT_CONFIG
> > > +       default n
> > > +       help
> > > +         Embed a bootconfig file given by EMBED_BOOT_CONFIG_FILE in the
> > > +         kernel. Usually, the bootconfig file is loaded with the initrd
> > > +         image. But if the system doesn't support initrd, this option will
> > > +         help you by embedding a bootconfig file while building the kernel.
> > > +
> > > +         If unsure, say N.
> > > +
> > > +config EMBED_BOOT_CONFIG_FILE
> > > +       string "Embedded bootconfig file path"
> > > +       default ""
> > > +       depends on EMBED_BOOT_CONFIG
> > > +       help
> > > +         Specify a bootconfig file which will be embedded to the kernel.
> > > +         This bootconfig will be used if there is no initrd or no other
> > > +         bootconfig in the initrd.
> > > +
> > >  choice
> > >         prompt "Compiler optimization level"
> > >         default CC_OPTIMIZE_FOR_PERFORMANCE
> > > diff --git a/init/main.c b/init/main.c
> > > index 266d61bc67b0..a5db3e36b809 100644
> > > --- a/init/main.c
> > > +++ b/init/main.c
> > > @@ -266,7 +266,7 @@ static int __init loglevel(char *str)
> > >  early_param("loglevel", loglevel);
> > >
> > >  #ifdef CONFIG_BLK_DEV_INITRD
> > > -static void * __init get_boot_config_from_initrd(u32 *_size)
> > > +static void * __init get_boot_config_from_initrd(size_t *_size)
> > >  {
> > >         u32 size, csum;
> > >         char *data;
> > > @@ -412,12 +412,15 @@ static void __init setup_boot_config(void)
> > >         static char tmp_cmdline[COMMAND_LINE_SIZE] __initdata;
> > >         const char *msg;
> > >         int pos;
> > > -       u32 size;
> > > +       size_t size;
> > >         char *data, *err;
> > >         int ret;
> > >
> > >         /* Cut out the bootconfig data even if we have no bootconfig option */
> > >         data = get_boot_config_from_initrd(&size);
> > > +       /* If there is no bootconfig in initrd, try embedded one. */
> > > +       if (!data)
> > > +               data = xbc_get_embedded_bootconfig(&size);
> > >
> > >         strlcpy(tmp_cmdline, boot_command_line, COMMAND_LINE_SIZE);
> > >         err = parse_args("bootconfig", tmp_cmdline, NULL, 0, 0, 0, NULL,
> > > @@ -436,8 +439,8 @@ static void __init setup_boot_config(void)
> > >         }
> > >
> > >         if (size >= XBC_DATA_MAX) {
> > > -               pr_err("bootconfig size %d greater than max size %d\n",
> > > -                       size, XBC_DATA_MAX);
> > > +               pr_err("bootconfig size %ld greater than max size %d\n",
> > > +                       (long)size, XBC_DATA_MAX);
> > >                 return;
> > >         }
> > >
> > > @@ -450,7 +453,7 @@ static void __init setup_boot_config(void)
> > >                                 msg, pos);
> > >         } else {
> > >                 xbc_get_info(&ret, NULL);
> > > -               pr_info("Load bootconfig: %d bytes %d nodes\n", size, ret);
> > > +               pr_info("Load bootconfig: %ld bytes %d nodes\n", (long)size, ret);
> > >                 /* keys starting with "kernel." are passed via cmdline */
> > >                 extra_command_line = xbc_make_cmdline("kernel");
> > >                 /* Also, "init." keys are init arguments */
> > > diff --git a/lib/.gitignore b/lib/.gitignore
> > > index e5e217b8307b..54596b634ecb 100644
> > > --- a/lib/.gitignore
> > > +++ b/lib/.gitignore
> > > @@ -1,6 +1,7 @@
> > >  # SPDX-License-Identifier: GPL-2.0-only
> > >  /crc32table.h
> > >  /crc64table.h
> > > +/default.bconf
> > >  /gen_crc32table
> > >  /gen_crc64table
> > >  /oid_registry_data.c
> > > diff --git a/lib/Makefile b/lib/Makefile
> > > index 08053df16c7c..2a82cc324f91 100644
> > > --- a/lib/Makefile
> > > +++ b/lib/Makefile
> > > @@ -280,6 +280,14 @@ $(foreach file, $(libfdt_files), \
> > >  lib-$(CONFIG_LIBFDT) += $(libfdt_files)
> > >
> > >  obj-$(CONFIG_BOOT_CONFIG) += bootconfig.o
> > > +obj-$(CONFIG_EMBED_BOOT_CONFIG) += bootconfig-data.o
> > > +
> > > +$(obj)/bootconfig-data.o: $(obj)/default.bconf
> > > +
> > > +targets += default.bconf
> > > +filechk_defbconf = cat $(or $(real-prereqs), /dev/null)
> > > +$(obj)/default.bconf: $(CONFIG_EMBED_BOOT_CONFIG_FILE) FORCE
> > > +       $(call filechk,defbconf)
> > >
> > >  obj-$(CONFIG_RBTREE_TEST) += rbtree_test.o
> > >  obj-$(CONFIG_INTERVAL_TREE_TEST) += interval_tree_test.o
> > > diff --git a/lib/bootconfig-data.S b/lib/bootconfig-data.S
> > > new file mode 100644
> > > index 000000000000..df674ea7d8be
> > > --- /dev/null
> > > +++ b/lib/bootconfig-data.S
> > > @@ -0,0 +1,11 @@
> > > +/* SPDX-License-Identifier: GPL-2.0 */
> > > +/*
> > > + * Embed default bootconfig in the kernel.
> > > + */
> > > +       .pushsection .init.data, "aw"
> > > +       .global embedded_bootconfig_data
> > > +embedded_bootconfig_data:
> > > +       .incbin "lib/default.bconf"
> > > +       .global embedded_bootconfig_data_end
> > > +embedded_bootconfig_data_end:
> > > +       .popsection
> >
> >
> >
> > You used  .pushsection / .popsection because it was
> > previously located in bootconfig.c, where there are
> > functions, which should go to the ".text" section.
>
> Oops, yes. I have made a dumb copy from the inline asm...
>
> > Now that you split this into a separate compilation unit,
> > there is only one ".init.data" section in the file.
> >
> >
> >      .section  .init.data, "aw"
> >
> > should be enough.
>
> OK.
>
> > BTW, is it reasonable/possible to make it explicitly read-only?
> >
> > I have not tested this patch at all. Nor do I have enough insight.
> >
> >      .section  .init.rodata, "a"
> >
> > I am not sure whether this is possible or not.
>
> Yes, it can be. The data is passed via 'const char *'.

But, you didn't add "const" in the C code:

extern __visible char embedded_bootconfig_data[];
extern __visible char embedded_bootconfig_data_end[];


Is it possible to use "const char" ?



-- 
Best Regards
Masahiro Yamada

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH v6 3/4] bootconfig: Support embedding a bootconfig file in kernel
  2022-03-31  6:54       ` Masahiro Yamada
@ 2022-03-31  7:20         ` Masami Hiramatsu
  0 siblings, 0 replies; 9+ messages in thread
From: Masami Hiramatsu @ 2022-03-31  7:20 UTC (permalink / raw)
  To: Masahiro Yamada
  Cc: Steven Rostedt, Padmanabha Srinivasaiah, LKML, Jonathan Corbet,
	open list:DOCUMENTATION, Randy Dunlap, Nick Desaulniers,
	Sami Tolvanen, Nathan Chancellor, llvm,
	Linux Kbuild mailing list

On Thu, 31 Mar 2022 15:54:40 +0900
Masahiro Yamada <masahiroy@kernel.org> wrote:

> On Thu, Mar 31, 2022 at 3:49 PM Masami Hiramatsu <mhiramat@kernel.org> wrote:
> >
> > On Thu, 31 Mar 2022 15:27:56 +0900
> > Masahiro Yamada <masahiroy@kernel.org> wrote:
> >
> > > On Thu, Mar 31, 2022 at 2:56 PM Masami Hiramatsu <mhiramat@kernel.org> wrote:
> > > >
> > > > 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_EMBED_BOOT_CONFIG=y and set
> > > > the file path to CONFIG_EMBED_BOOT_CONFIG_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.
> > > >
> > > > Signed-off-by: Masami Hiramatsu <mhiramat@kernel.org>
> > > > ---
> > > >  Changes in v6:
> > > >   - Split out the .incbin asm part as bootconfig-data.S according to
> > > >     Masahiro's comment.
> > > >  Changes in v5:
> > > >   - Fix .gitignore to be sorted alphabetically.
> > > >   - Make default.bconf is cleaned up correctly.
> > > >   - Allow user to specify relative path to CONFIG_EMBED_BOOT_CONFIG_FILE.
> > > >     (Thanks Masahiro!)
> > > >  Changes in v4:
> > > >   - Avoid updating the default.bconf if the file is not changed.
> > > > ---
> > > >  MAINTAINERS                |    1 +
> > > >  include/linux/bootconfig.h |   10 ++++++++++
> > > >  init/Kconfig               |   21 +++++++++++++++++++++
> > > >  init/main.c                |   13 ++++++++-----
> > > >  lib/.gitignore             |    1 +
> > > >  lib/Makefile               |    8 ++++++++
> > > >  lib/bootconfig-data.S      |   11 +++++++++++
> > > >  lib/bootconfig.c           |   13 +++++++++++++
> > > >  8 files changed, 73 insertions(+), 5 deletions(-)
> > > >  create mode 100644 lib/bootconfig-data.S
> > > >
> > > > diff --git a/MAINTAINERS b/MAINTAINERS
> > > > index b555a5e8704f..9b4910685412 100644
> > > > --- a/MAINTAINERS
> > > > +++ b/MAINTAINERS
> > > > @@ -7350,6 +7350,7 @@ S:        Maintained
> > > >  F:     Documentation/admin-guide/bootconfig.rst
> > > >  F:     fs/proc/bootconfig.c
> > > >  F:     include/linux/bootconfig.h
> > > > +F:     lib/bootconfig-data.S
> > > >  F:     lib/bootconfig.c
> > > >  F:     tools/bootconfig/*
> > > >  F:     tools/bootconfig/scripts/*
> > > > diff --git a/include/linux/bootconfig.h b/include/linux/bootconfig.h
> > > > index a4665c7ab07c..5dbda5e3e9bb 100644
> > > > --- a/include/linux/bootconfig.h
> > > > +++ b/include/linux/bootconfig.h
> > > > @@ -289,4 +289,14 @@ int __init xbc_get_info(int *node_size, size_t *data_size);
> > > >  /* XBC cleanup data structures */
> > > >  void __init xbc_exit(void);
> > > >
> > > > +/* XBC embedded bootconfig data in kernel */
> > > > +#ifdef CONFIG_EMBED_BOOT_CONFIG
> > > > +char * __init xbc_get_embedded_bootconfig(size_t *size);
> > > > +#else
> > > > +static inline char *xbc_get_embedded_bootconfig(size_t *size)
> > > > +{
> > > > +       return NULL;
> > > > +}
> > > > +#endif
> > > > +
> > > >  #endif
> > > > diff --git a/init/Kconfig b/init/Kconfig
> > > > index 97463a33baa7..f5d14a78cfce 100644
> > > > --- a/init/Kconfig
> > > > +++ b/init/Kconfig
> > > > @@ -1361,6 +1361,27 @@ config BOOT_CONFIG
> > > >
> > > >           If unsure, say Y.
> > > >
> > > > +config EMBED_BOOT_CONFIG
> > > > +       bool "Embed bootconfig file in the kernel"
> > > > +       depends on BOOT_CONFIG
> > > > +       default n
> > > > +       help
> > > > +         Embed a bootconfig file given by EMBED_BOOT_CONFIG_FILE in the
> > > > +         kernel. Usually, the bootconfig file is loaded with the initrd
> > > > +         image. But if the system doesn't support initrd, this option will
> > > > +         help you by embedding a bootconfig file while building the kernel.
> > > > +
> > > > +         If unsure, say N.
> > > > +
> > > > +config EMBED_BOOT_CONFIG_FILE
> > > > +       string "Embedded bootconfig file path"
> > > > +       default ""
> > > > +       depends on EMBED_BOOT_CONFIG
> > > > +       help
> > > > +         Specify a bootconfig file which will be embedded to the kernel.
> > > > +         This bootconfig will be used if there is no initrd or no other
> > > > +         bootconfig in the initrd.
> > > > +
> > > >  choice
> > > >         prompt "Compiler optimization level"
> > > >         default CC_OPTIMIZE_FOR_PERFORMANCE
> > > > diff --git a/init/main.c b/init/main.c
> > > > index 266d61bc67b0..a5db3e36b809 100644
> > > > --- a/init/main.c
> > > > +++ b/init/main.c
> > > > @@ -266,7 +266,7 @@ static int __init loglevel(char *str)
> > > >  early_param("loglevel", loglevel);
> > > >
> > > >  #ifdef CONFIG_BLK_DEV_INITRD
> > > > -static void * __init get_boot_config_from_initrd(u32 *_size)
> > > > +static void * __init get_boot_config_from_initrd(size_t *_size)
> > > >  {
> > > >         u32 size, csum;
> > > >         char *data;
> > > > @@ -412,12 +412,15 @@ static void __init setup_boot_config(void)
> > > >         static char tmp_cmdline[COMMAND_LINE_SIZE] __initdata;
> > > >         const char *msg;
> > > >         int pos;
> > > > -       u32 size;
> > > > +       size_t size;
> > > >         char *data, *err;
> > > >         int ret;
> > > >
> > > >         /* Cut out the bootconfig data even if we have no bootconfig option */
> > > >         data = get_boot_config_from_initrd(&size);
> > > > +       /* If there is no bootconfig in initrd, try embedded one. */
> > > > +       if (!data)
> > > > +               data = xbc_get_embedded_bootconfig(&size);
> > > >
> > > >         strlcpy(tmp_cmdline, boot_command_line, COMMAND_LINE_SIZE);
> > > >         err = parse_args("bootconfig", tmp_cmdline, NULL, 0, 0, 0, NULL,
> > > > @@ -436,8 +439,8 @@ static void __init setup_boot_config(void)
> > > >         }
> > > >
> > > >         if (size >= XBC_DATA_MAX) {
> > > > -               pr_err("bootconfig size %d greater than max size %d\n",
> > > > -                       size, XBC_DATA_MAX);
> > > > +               pr_err("bootconfig size %ld greater than max size %d\n",
> > > > +                       (long)size, XBC_DATA_MAX);
> > > >                 return;
> > > >         }
> > > >
> > > > @@ -450,7 +453,7 @@ static void __init setup_boot_config(void)
> > > >                                 msg, pos);
> > > >         } else {
> > > >                 xbc_get_info(&ret, NULL);
> > > > -               pr_info("Load bootconfig: %d bytes %d nodes\n", size, ret);
> > > > +               pr_info("Load bootconfig: %ld bytes %d nodes\n", (long)size, ret);
> > > >                 /* keys starting with "kernel." are passed via cmdline */
> > > >                 extra_command_line = xbc_make_cmdline("kernel");
> > > >                 /* Also, "init." keys are init arguments */
> > > > diff --git a/lib/.gitignore b/lib/.gitignore
> > > > index e5e217b8307b..54596b634ecb 100644
> > > > --- a/lib/.gitignore
> > > > +++ b/lib/.gitignore
> > > > @@ -1,6 +1,7 @@
> > > >  # SPDX-License-Identifier: GPL-2.0-only
> > > >  /crc32table.h
> > > >  /crc64table.h
> > > > +/default.bconf
> > > >  /gen_crc32table
> > > >  /gen_crc64table
> > > >  /oid_registry_data.c
> > > > diff --git a/lib/Makefile b/lib/Makefile
> > > > index 08053df16c7c..2a82cc324f91 100644
> > > > --- a/lib/Makefile
> > > > +++ b/lib/Makefile
> > > > @@ -280,6 +280,14 @@ $(foreach file, $(libfdt_files), \
> > > >  lib-$(CONFIG_LIBFDT) += $(libfdt_files)
> > > >
> > > >  obj-$(CONFIG_BOOT_CONFIG) += bootconfig.o
> > > > +obj-$(CONFIG_EMBED_BOOT_CONFIG) += bootconfig-data.o
> > > > +
> > > > +$(obj)/bootconfig-data.o: $(obj)/default.bconf
> > > > +
> > > > +targets += default.bconf
> > > > +filechk_defbconf = cat $(or $(real-prereqs), /dev/null)
> > > > +$(obj)/default.bconf: $(CONFIG_EMBED_BOOT_CONFIG_FILE) FORCE
> > > > +       $(call filechk,defbconf)
> > > >
> > > >  obj-$(CONFIG_RBTREE_TEST) += rbtree_test.o
> > > >  obj-$(CONFIG_INTERVAL_TREE_TEST) += interval_tree_test.o
> > > > diff --git a/lib/bootconfig-data.S b/lib/bootconfig-data.S
> > > > new file mode 100644
> > > > index 000000000000..df674ea7d8be
> > > > --- /dev/null
> > > > +++ b/lib/bootconfig-data.S
> > > > @@ -0,0 +1,11 @@
> > > > +/* SPDX-License-Identifier: GPL-2.0 */
> > > > +/*
> > > > + * Embed default bootconfig in the kernel.
> > > > + */
> > > > +       .pushsection .init.data, "aw"
> > > > +       .global embedded_bootconfig_data
> > > > +embedded_bootconfig_data:
> > > > +       .incbin "lib/default.bconf"
> > > > +       .global embedded_bootconfig_data_end
> > > > +embedded_bootconfig_data_end:
> > > > +       .popsection
> > >
> > >
> > >
> > > You used  .pushsection / .popsection because it was
> > > previously located in bootconfig.c, where there are
> > > functions, which should go to the ".text" section.
> >
> > Oops, yes. I have made a dumb copy from the inline asm...
> >
> > > Now that you split this into a separate compilation unit,
> > > there is only one ".init.data" section in the file.
> > >
> > >
> > >      .section  .init.data, "aw"
> > >
> > > should be enough.
> >
> > OK.
> >
> > > BTW, is it reasonable/possible to make it explicitly read-only?
> > >
> > > I have not tested this patch at all. Nor do I have enough insight.
> > >
> > >      .section  .init.rodata, "a"
> > >
> > > I am not sure whether this is possible or not.
> >
> > Yes, it can be. The data is passed via 'const char *'.
> 
> But, you didn't add "const" in the C code:
> 
> extern __visible char embedded_bootconfig_data[];
> extern __visible char embedded_bootconfig_data_end[];
> 
> 
> Is it possible to use "const char" ?

Yes, I need to update C part too, and that is not a problem. :)

Thank you!

> 
> 
> 
> -- 
> Best Regards
> Masahiro Yamada


-- 
Masami Hiramatsu <mhiramat@kernel.org>

^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2022-03-31  7:21 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-03-31  5:55 [PATCH v6 0/4] bootconfig: Support embedding a bootconfig in kernel for non initrd boot Masami Hiramatsu
2022-03-31  5:56 ` [PATCH v6 1/4] bootconfig: Make the bootconfig.o as a normal object file Masami Hiramatsu
2022-03-31  5:56 ` [PATCH v6 2/4] bootconfig: Check the checksum before removing the bootconfig from initrd Masami Hiramatsu
2022-03-31  5:56 ` [PATCH v6 3/4] bootconfig: Support embedding a bootconfig file in kernel Masami Hiramatsu
2022-03-31  6:27   ` Masahiro Yamada
2022-03-31  6:49     ` Masami Hiramatsu
2022-03-31  6:54       ` Masahiro Yamada
2022-03-31  7:20         ` Masami Hiramatsu
2022-03-31  5:56 ` [PATCH v6 4/4] docs: bootconfig: Add how to embed the bootconfig into kernel Masami Hiramatsu

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).