Skip to contentSkip to conversation

of: bootargs handling improvement

PATCH In review Christian Marangi 2 participants 6 messages May 12, 2024 – May 20, 2024

Subsystems (3)
lore
Share & tools
lore
#0 lore raw

cover of: bootargs handling improvement

This is a very simple series that try to solve a very simple problem.

Many emebedded devices have very hacked (by OEMS) bootloader that do all kind of modification and makes the kernel unbootable with the very first small modification. And also many times these broken bootloader have hardcoded values that can't be modified and would require risky procedure that can brick the device.

One of the common modification done is hardcoding bootargs in the appended kernel DT trashing the bootargs set in the /chosen.

The main usage of this is to have dynamic stuff to support dual partition scheme and make the kernel load a dedicated rootfs. But the other usage of this is to effectively lockup the device and cause kernel panic on modification like using squashfs instead of legacy jffs2.

The simple solution to this is to let the bootloader override the bootargs in /chosen and make the kernel parse a different property.

From long time on OpenWRT we use bootargs-override as the alternative property for this task fixing the problem of overridden bootargs.

The second feature is bootargs-append. This is self-explanatory, sometimes bootargs from bootloader might be good but lack of some crucial things that needs to be appended, like rootfstype or rootfs path.

This feature is different than hardcoding the CMDLINE since that is usable only with some specific case and is really problematic if the same kernel is used for multiple devices that share a common kernel and .dtsi

Christian Marangi (3):
docs: dt: Document new bootargs chosen property
of: add support for bootargs-override chosen property
of: add support for bootargs-append chosen property

David Bauer (1):
MIPS: add bootargs-override property

 Documentation/devicetree/usage-model.rst |  9 +++++++++
 arch/mips/kernel/setup.c                 | 14 +++++++++++++-
 drivers/of/fdt.c                         | 15 +++++++++++++--
 3 files changed, 35 insertions(+), 3 deletions(-)
Signature · 1 line
2.43.0
#1 lore raw

PATCH 1/4 docs: dt: Document new bootargs chosen property

The bootargs property might be overridden by bootloaders on kernel load, in such scenario, bootargs-override might be used instead. With bootargs-override set, any value set in bootargs will be ignored.

The bootargs-append can be used to append additional kernel arguments to the bootargs property. This can be useful in the context of a bootargs overridden by the bootloader that contains correct that but the kernel require additional one to be correctly setup.

---
 Documentation/devicetree/usage-model.rst | 9 +++++++++
 1 file changed, 9 insertions(+)
Documentation/devicetree/usage-model.rst +9 -0
index 0717426856b2..885be3e582fc 100644
@@ -217,6 +217,15 @@ On ARM, the function setup_machine_fdt() is responsible for early
 scanning of the device tree after selecting the correct machine_desc
 that supports the board.
 
+The bootargs property might be overridden by bootloaders on kernel load,
+in such scenario, bootargs-override might be used instead. With
+bootargs-override set, any value set in bootargs will be ignored.
+
+The bootargs-append can be used to append additional kernel arguments
+to the bootargs property. This can be useful in the context of a
+bootargs overridden by the bootloader that contains correct that but
+the kernel require additional one to be correctly setup.
+
 2.4 Device population
 ---------------------
 After the board has been identified, and after the early configuration data
Signature · 1 line
2.43.0
#2 lore raw

PATCH 2/4 of: add support for bootargs-override chosen property

In reply to Christian Marangi

On some devices bootloader may hardcoded and overwrite the bootargs DT property passed in "/chosen" when the kernel is loaded resulting in the value dropped.

While CMDLINE_FORCE can be used, this is not a good option for kernels that are shared across devices.

This setting enables using "/chosen/bootargs-override" as the cmdline if it exists in the device tree.

This broken behaviour was found in various devices from ipq806x Soc, to Mediatek and even PowerPC.

---
 drivers/of/fdt.c | 12 ++++++++++--
 1 file changed, 10 insertions(+), 2 deletions(-)
drivers/of/fdt.c +10 -2
index a8a04f27915b..253315421591 100644
@@ -1068,8 +1068,16 @@ int __init early_init_dt_scan_chosen(char *cmdline)
 				fdt_totalsize(initial_boot_params));
 	}
 
-	/* Retrieve command line */
-	p = of_get_flat_dt_prop(node, "bootargs", &l);
+	/*
+	 * Retrieve command line
+	 * bootargs might be hardcoded and overwrite by bootloader on
+	 * kernel load.
+	 * Check if alternative bootargs-override is present instead
+	 * first.
+	 */
+	p = of_get_flat_dt_prop(node, "bootargs-override", &l);
+	if (p == NULL || l == 0)
+		p = of_get_flat_dt_prop(node, "bootargs", &l);
 	if (p != NULL && l > 0)
 		strscpy(cmdline, p, min(l, COMMAND_LINE_SIZE));
 
Signature · 1 line
2.43.0
#3 lore raw

PATCH 3/4 of: add support for bootargs-append chosen property

In reply to Christian Marangi

Add support for bootargs-append chosen property.

The bootargs-append can be used to append additional kernel arguments to the bootargs property. This can be useful in the context of a bootargs overridden by the bootloader that contains correct that but the kernel require additional one to be correctly setup.

---
 drivers/of/fdt.c | 3 +++
 1 file changed, 3 insertions(+)
drivers/of/fdt.c +3 -0
index 253315421591..cc99958872e4 100644
@@ -1080,6 +1080,9 @@ int __init early_init_dt_scan_chosen(char *cmdline)
 		p = of_get_flat_dt_prop(node, "bootargs", &l);
 	if (p != NULL && l > 0)
 		strscpy(cmdline, p, min(l, COMMAND_LINE_SIZE));
+	p = of_get_flat_dt_prop(node, "bootargs-append", &l);
+	if (p != NULL && l > 0)
+		strlcat(cmdline, p, min_t(int, strlen(cmdline) + l, COMMAND_LINE_SIZE));
 
 handle_cmdline:
 	/*
Signature · 1 line
2.43.0
#4 lore raw

PATCH 4/4 MIPS: add bootargs-override property

In reply to Christian Marangi

From: David Bauer <[email protected]>

Add support for the bootargs-override and bootargs-append property to the chosen node similar to the one used on ipq806x or mpc85xx.

This is necessary, as the U-Boot used on some boards, notably the Ubiquiti UniFi 6 Lite, overwrite the bootargs property of the chosen node leading to a kernel panic on kernel loading (hardcoded root path or other not compatible thing).

[ rework and simplify implementation, add support for bootargs-append ]
---
 arch/mips/kernel/setup.c | 14 +++++++++++++-
 1 file changed, 13 insertions(+), 1 deletion(-)
arch/mips/kernel/setup.c +13 -1
index 12a1a4ffb602..725e3f19f342 100644
@@ -538,11 +538,23 @@ static int __init bootcmdline_scan_chosen(unsigned long node, const char *uname,
 	    (strcmp(uname, "chosen") != 0 && strcmp(uname, "chosen@0") != 0))
 		return 0;
 
-	p = of_get_flat_dt_prop(node, "bootargs", &l);
+	/*
+	 * Retrieve command line
+	 * bootargs might be hardcoded and overwrite by bootloader on
+	 * kernel load.
+	 * Check if alternative bootargs-override is present instead
+	 * first.
+	 */
+	p = of_get_flat_dt_prop(node, "bootargs-override", &l);
+	if (p == NULL || l == 0)
+		p = of_get_flat_dt_prop(node, "bootargs", &l);
 	if (p != NULL && l > 0) {
 		bootcmdline_append(p, min(l, COMMAND_LINE_SIZE));
 		*dt_bootargs = true;
 	}
+	p = of_get_flat_dt_prop(node, "bootargs-append", &l);
+	if (p != NULL && l > 0)
+		bootcmdline_append(p, min_t(int, strlen(boot_command_line) + l, COMMAND_LINE_SIZE));
 
 	return 1;
 }
Signature · 1 line
2.43.0
maintainer
#5 lore raw
In reply to Christian Marangi
Quoted 11 lines · Christian Marangi

This is a very simple series that try to solve a very simple problem.

Many emebedded devices have very hacked (by OEMS) bootloader that do all kind of modification and makes the kernel unbootable with the very first small modification. And also many times these broken bootloader have hardcoded values that can't be modified and would require risky procedure that can brick the device.

One of the common modification done is hardcoding bootargs in the appended kernel DT trashing the bootargs set in the /chosen.

Quoted 7 lines

The main usage of this is to have dynamic stuff to support dual partition scheme and make the kernel load a dedicated rootfs. But the other usage of this is to effectively lockup the device and cause kernel panic on modification like using squashfs instead of legacy jffs2.

The simple solution to this is to let the bootloader override the bootargs in /chosen and make the kernel parse a different property.

What happens when bootloaders start using these new "standard" bootarg properties and you need to override them? Perhaps name it something the OEM wouldn't use (maybe):
"use-this-bootargs-instead-for-the-broken-bootloader"

Quoted 7 lines
Quoted 1 line

From long time on OpenWRT we use bootargs-override as the alternative

property for this task fixing the problem of overridden bootargs.

The second feature is bootargs-append. This is self-explanatory, sometimes bootargs from bootloader might be good but lack of some crucial things that needs to be appended, like rootfstype or rootfs path.

It is unfortunate that the kernel's handling of appending or prepending to bootargs is ambiguous. And MIPS is a further mess with handling cmdline from multiple sources.

I'm not really interested in adding any more complexity to the cmdline handling until it is made common. There's been at least 2 approaches to doing that.

Rob