[openwrt/openwrt] ath79: Fix fallback to bootloader cmdline on empty DT bootargs

LEDE Commits lede-commits at lists.infradead.org
Tue Dec 22 13:13:44 EST 2020


ynezz pushed a commit to openwrt/openwrt.git, branch master:
https://git.openwrt.org/727eebbad1b9dea91174ea675cb64ea13484f790

commit 727eebbad1b9dea91174ea675cb64ea13484f790
Author: Sven Eckelmann <sven at narfation.org>
AuthorDate: Mon Nov 23 16:57:31 2020 +0100

    ath79: Fix fallback to bootloader cmdline on empty DT bootargs
    
    The MIPS code is supposed to fall back to u-boots bootargs whenever the
    /chosen/bootargs property is missing. But this feature was accidentally
    disabled when the boot_command_line was initialized with an empty space
    just to work around problems with early_init_dt_scan_chosen.
    
    But this feature is necessary for some boards which have a dualboot
    mechanism and whose u-boot is calculating the correct partition at runtime
    without writing this information back to the u-boot-env.
    
    Signed-off-by: Sven Eckelmann <sven at narfation.org>
---
 ...e-Clean-up-boot_command_line-initializati.patch | 194 +++++++++++++++++++++
 1 file changed, 194 insertions(+)

diff --git a/target/linux/ath79/patches-5.4/0001-MIPS-cmdline-Clean-up-boot_command_line-initializati.patch b/target/linux/ath79/patches-5.4/0001-MIPS-cmdline-Clean-up-boot_command_line-initializati.patch
new file mode 100644
index 0000000000..4cadd5a86f
--- /dev/null
+++ b/target/linux/ath79/patches-5.4/0001-MIPS-cmdline-Clean-up-boot_command_line-initializati.patch
@@ -0,0 +1,194 @@
+From: Paul Burton <paul.burton at mips.com>
+Date: Wed, 9 Oct 2019 23:09:45 +0000
+Subject: MIPS: cmdline: Clean up boot_command_line initialization
+
+Our current code to initialize boot_command_line is a mess. Some of this
+is due to the addition of too many options over the years, and some of
+this is due to workarounds for early_init_dt_scan_chosen() performing
+actions specific to options from other architectures that probably
+shouldn't be in generic code.
+
+Clean this up by introducing a new bootcmdline_init() function that
+simplifies the initialization somewhat. The major changes are:
+
+- Because bootcmdline_init() is a function it can return early in the
+  CONFIG_CMDLINE_OVERRIDE case.
+
+- We clear boot_command_line rather than inheriting whatever
+  early_init_dt_scan_chosen() may have left us. This means we no longer
+  need to set boot_command_line to a space character in an attempt to
+  prevent early_init_dt_scan_chosen() from copying CONFIG_CMDLINE into
+  boot_command_line without us knowing about it.
+
+- Indirection via USE_PROM_CMDLINE, USE_DTB_CMDLINE, EXTEND_WITH_PROM &
+  BUILTIN_EXTEND_WITH_PROM macros is removed; they seemingly served only
+  to obfuscate the code.
+
+- The logic is cleaner, clearer & commented.
+
+Two minor drawbacks of this approach are:
+
+1) We call of_scan_flat_dt(), which means we scan through the DT again.
+   The overhead is fairly minimal & shouldn't be noticeable.
+
+2) cmdline_scan_chosen() duplicates a small amount of the logic from
+   early_init_dt_scan_chosen(). Alternatives might be to allow the
+   generic FDT code to keep & expose a copy of the arguments taken from
+   the /chosen node's bootargs property, or to introduce a function like
+   early_init_dt_scan_chosen() that retrieves them without modification
+   to handle CONFIG_CMDLINE. Neither of these sounds particularly
+   cleaner though, and this way we at least keep the extra work in
+   arch/mips.
+
+Origin: upstream, https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=7784cac697351f0cc0a4bb619594c0c99348c5aa
+Signed-off-by: Paul Burton <paul.burton at mips.com>
+Cc: linux-mips at vger.kernel.org
+
+diff --git a/arch/mips/kernel/setup.c b/arch/mips/kernel/setup.c
+index b8884de89c81e1b444b218a15519556b4a374089..e56dd6c25d46336fcb9af21326f697d0c37aac1c 100644
+--- a/arch/mips/kernel/setup.c
++++ b/arch/mips/kernel/setup.c
+@@ -538,11 +538,88 @@ static void __init check_kernel_sections_mem(void)
+ 	}
+ }
+ 
+-#define USE_PROM_CMDLINE	IS_ENABLED(CONFIG_MIPS_CMDLINE_FROM_BOOTLOADER)
+-#define USE_DTB_CMDLINE		IS_ENABLED(CONFIG_MIPS_CMDLINE_FROM_DTB)
+-#define EXTEND_WITH_PROM	IS_ENABLED(CONFIG_MIPS_CMDLINE_DTB_EXTEND)
+-#define BUILTIN_EXTEND_WITH_PROM	\
+-	IS_ENABLED(CONFIG_MIPS_CMDLINE_BUILTIN_EXTEND)
++static void __init bootcmdline_append(const char *s, size_t max)
++{
++	if (!s[0] || !max)
++		return;
++
++	if (boot_command_line[0])
++		strlcat(boot_command_line, " ", COMMAND_LINE_SIZE);
++
++	strlcat(boot_command_line, s, max);
++}
++
++static int __init bootcmdline_scan_chosen(unsigned long node, const char *uname,
++					  int depth, void *data)
++{
++	bool *dt_bootargs = data;
++	const char *p;
++	int l;
++
++	if (depth != 1 || !data ||
++	    (strcmp(uname, "chosen") != 0 && strcmp(uname, "chosen at 0") != 0))
++		return 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;
++	}
++
++	return 1;
++}
++
++static void __init bootcmdline_init(char **cmdline_p)
++{
++	bool dt_bootargs = false;
++
++	/*
++	 * If CMDLINE_OVERRIDE is enabled then initializing the command line is
++	 * trivial - we simply use the built-in command line unconditionally &
++	 * unmodified.
++	 */
++	if (IS_ENABLED(CONFIG_CMDLINE_OVERRIDE)) {
++		strlcpy(boot_command_line, builtin_cmdline, COMMAND_LINE_SIZE);
++		return;
++	}
++
++	/*
++	 * If the user specified a built-in command line &
++	 * MIPS_CMDLINE_BUILTIN_EXTEND, then the built-in command line is
++	 * prepended to arguments from the bootloader or DT so we'll copy them
++	 * to the start of boot_command_line here. Otherwise, empty
++	 * boot_command_line to undo anything early_init_dt_scan_chosen() did.
++	 */
++	if (IS_ENABLED(CONFIG_MIPS_CMDLINE_BUILTIN_EXTEND))
++		strlcpy(boot_command_line, builtin_cmdline, COMMAND_LINE_SIZE);
++	else
++		boot_command_line[0] = 0;
++
++	/*
++	 * If we're configured to take boot arguments from DT, look for those
++	 * now.
++	 */
++	if (IS_ENABLED(CONFIG_MIPS_CMDLINE_FROM_DTB))
++		of_scan_flat_dt(bootcmdline_scan_chosen, &dt_bootargs);
++
++	/*
++	 * If we didn't get any arguments from DT (regardless of whether that's
++	 * because we weren't configured to look for them, or because we looked
++	 * & found none) then we'll take arguments from the bootloader.
++	 * plat_mem_setup() should have filled arcs_cmdline with arguments from
++	 * the bootloader.
++	 */
++	if (IS_ENABLED(CONFIG_MIPS_CMDLINE_DTB_EXTEND) || !dt_bootargs)
++		bootcmdline_append(arcs_cmdline, COMMAND_LINE_SIZE);
++
++	/*
++	 * If the user specified a built-in command line & we didn't already
++	 * prepend it, we append it to boot_command_line here.
++	 */
++	if (IS_ENABLED(CONFIG_CMDLINE_BOOL) &&
++	    !IS_ENABLED(CONFIG_MIPS_CMDLINE_BUILTIN_EXTEND))
++		bootcmdline_append(builtin_cmdline, COMMAND_LINE_SIZE);
++}
+ 
+ /*
+  * arch_mem_init - initialize memory management subsystem
+@@ -570,48 +647,12 @@ static void __init arch_mem_init(char **cmdline_p)
+ {
+ 	extern void plat_mem_setup(void);
+ 
+-	/*
+-	 * Initialize boot_command_line to an innocuous but non-empty string in
+-	 * order to prevent early_init_dt_scan_chosen() from copying
+-	 * CONFIG_CMDLINE into it without our knowledge. We handle
+-	 * CONFIG_CMDLINE ourselves below & don't want to duplicate its
+-	 * content because repeating arguments can be problematic.
+-	 */
+-	strlcpy(boot_command_line, " ", COMMAND_LINE_SIZE);
+-
+ 	/* call board setup routine */
+ 	plat_mem_setup();
+ 	memblock_set_bottom_up(true);
+ 
+-#if defined(CONFIG_CMDLINE_BOOL) && defined(CONFIG_CMDLINE_OVERRIDE)
+-	strlcpy(boot_command_line, builtin_cmdline, COMMAND_LINE_SIZE);
+-#else
+-	if ((USE_PROM_CMDLINE && arcs_cmdline[0]) ||
+-	    (USE_DTB_CMDLINE && !boot_command_line[0]))
+-		strlcpy(boot_command_line, arcs_cmdline, COMMAND_LINE_SIZE);
+-
+-	if (EXTEND_WITH_PROM && arcs_cmdline[0]) {
+-		if (boot_command_line[0])
+-			strlcat(boot_command_line, " ", COMMAND_LINE_SIZE);
+-		strlcat(boot_command_line, arcs_cmdline, COMMAND_LINE_SIZE);
+-	}
+-
+-#if defined(CONFIG_CMDLINE_BOOL)
+-	if (builtin_cmdline[0]) {
+-		if (boot_command_line[0])
+-			strlcat(boot_command_line, " ", COMMAND_LINE_SIZE);
+-		strlcat(boot_command_line, builtin_cmdline, COMMAND_LINE_SIZE);
+-	}
+-
+-	if (BUILTIN_EXTEND_WITH_PROM && arcs_cmdline[0]) {
+-		if (boot_command_line[0])
+-			strlcat(boot_command_line, " ", COMMAND_LINE_SIZE);
+-		strlcat(boot_command_line, arcs_cmdline, COMMAND_LINE_SIZE);
+-	}
+-#endif
+-#endif
++	bootcmdline_init(cmdline_p);
+ 	strlcpy(command_line, boot_command_line, COMMAND_LINE_SIZE);
+-
+ 	*cmdline_p = command_line;
+ 
+ 	parse_early_param();



More information about the lede-commits mailing list