ipq806x: replace ARM bootloader patch with pending upstream version
authorChristian Marangi <ansuelsmth@gmail.com>
Fri, 23 Feb 2024 16:54:52 +0000 (17:54 +0100)
committerChristian Marangi <ansuelsmth@gmail.com>
Fri, 23 Feb 2024 17:04:48 +0000 (18:04 +0100)
Replace ARM bootloader patch with pending upstream version. The patch
got reviewed upstream and tested on a Netgear R7800.

This fix a problem with the ARM decompressor and permits to use
AUTO_ZRELADDR without having to hardcode PHYS_OFFSET as the bootloader
now correctly parse the memory modes in the appended DTB.

Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
target/linux/ipq806x/config-6.1
target/linux/ipq806x/patches-6.1/0060-ARM-mach-qcom-fix-support-for-ipq806x.patch [deleted file]
target/linux/ipq806x/patches-6.1/0067-generic-Mangle-bootloader-s-kernel-arguments.patch [deleted file]
target/linux/ipq806x/patches-6.1/900-arm-add-cmdline-override.patch
target/linux/ipq806x/patches-6.1/901-01-ARM-decompressor-support-memory-start-validation-.patch [new file with mode: 0644]
target/linux/ipq806x/patches-6.1/901-02-ARM-decompressor-add-option-to-ignore-MEM-ATAGs.patch [new file with mode: 0644]
target/linux/ipq806x/patches-6.1/902-ARM-decompressor-support-for-ATAGs-rootblock-parsing.patch [new file with mode: 0644]

index e6c9b930a2197c4317e1018c8f638dd3b0e21f1c..598ab305db9c680e4d29fe1a460a9fba8f76b320 100644 (file)
@@ -4,7 +4,6 @@ CONFIG_ALIGNMENT_TRAP=y
 CONFIG_ARCH_32BIT_OFF_T=y
 CONFIG_ARCH_HIBERNATION_POSSIBLE=y
 # CONFIG_ARCH_IPQ40XX is not set
-CONFIG_ARCH_IPQ806X=y
 CONFIG_ARCH_KEEP_MEMBLOCK=y
 # CONFIG_ARCH_MDM9615 is not set
 CONFIG_ARCH_MIGHT_HAVE_PC_PARPORT=y
@@ -31,6 +30,7 @@ CONFIG_ARM_ARCH_TIMER_EVTSTREAM=y
 CONFIG_ARM_ATAG_DTB_COMPAT=y
 # CONFIG_ARM_ATAG_DTB_COMPAT_CMDLINE_FROM_BOOTLOADER is not set
 CONFIG_ARM_ATAG_DTB_COMPAT_CMDLINE_MANGLE=y
+CONFIG_ARM_ATAG_DTB_COMPAT_IGNORE_MEM=y
 CONFIG_ARM_CPUIDLE=y
 CONFIG_ARM_CPU_SUSPEND=y
 # CONFIG_ARM_CPU_TOPOLOGY is not set
diff --git a/target/linux/ipq806x/patches-6.1/0060-ARM-mach-qcom-fix-support-for-ipq806x.patch b/target/linux/ipq806x/patches-6.1/0060-ARM-mach-qcom-fix-support-for-ipq806x.patch
deleted file mode 100644 (file)
index 4705326..0000000
+++ /dev/null
@@ -1,60 +0,0 @@
-From 9c896e9fc2ef1209e4a56d8c9fdd183847c2c814 Mon Sep 17 00:00:00 2001
-From: Christian Marangi <ansuelsmth@gmail.com>
-Date: Tue, 18 Oct 2022 22:02:46 +0200
-Subject: [PATCH] ARM: mach-qcom: fix support for ipq806x
-
-Add a specific config flag for Qcom IPQ806x as this SoC can't use
-AUTO_ZRELADDR and require the PHYS_OFFSET set to 0x42000000.
-
-This is needed as some legacy board (or some wrongly configured
-bootloader) pass the wrong memory map and doesn't exclude the first
-~20MB of RAM reserved for the hardware network accellerators.
-
-With this change we can correctly support each board and prevent any
-kind of misconfiguration done by the OEM.
-
-Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
----
- arch/arm/Kconfig           |  3 ++-
- arch/arm/mach-qcom/Kconfig | 13 +++++++++++++
- 2 files changed, 15 insertions(+), 1 deletion(-)
-
---- a/arch/arm/Kconfig
-+++ b/arch/arm/Kconfig
-@@ -285,6 +285,7 @@ config PHYS_OFFSET
-       default 0x30000000 if ARCH_S3C24XX
-       default 0xa0000000 if ARCH_IOP32X || ARCH_PXA
-       default 0xc0000000 if ARCH_EP93XX || ARCH_SA1100
-+      default 0x42000000 if ARCH_IPQ806X
-       default 0
-       help
-         Please provide the physical address corresponding to the
-@@ -1704,7 +1705,7 @@ config CRASH_DUMP
- config AUTO_ZRELADDR
-       bool "Auto calculation of the decompressed kernel image address" if !ARCH_MULTIPLATFORM
--      default !(ARCH_FOOTBRIDGE || ARCH_RPC || ARCH_SA1100)
-+      default !(ARCH_FOOTBRIDGE || ARCH_RPC || ARCH_SA1100 || ARCH_IPQ806X)
-       help
-         ZRELADDR is the physical address where the decompressed kernel
-         image will be placed. If AUTO_ZRELADDR is selected, the address
---- a/arch/arm/mach-qcom/Kconfig
-+++ b/arch/arm/mach-qcom/Kconfig
-@@ -46,4 +46,17 @@ config ARCH_MDM9615
-       bool "Enable support for MDM9615"
-       select CLKSRC_QCOM
-+config ARCH_IPQ806X
-+      bool "Enable support for IPQ806x"
-+      help
-+        Enable support for the Qualcomm IPQ806x.
-+
-+        IPQ806x require special PHYS_OFFSET and can't use AUTO_ZRELADDR.
-+        The first ~20MB of RAM is reserved for the hardware network accelerators,
-+        and the bootloader removes this section from the layout passed from the
-+        ATAGS (when used by some bootloader doesn't even do that).
-+
-+        To support every system and handle legacy systems, hardcode PHYS_OFFSET and
-+        disable AUTO_ZRELADDR.
-+
- endif
diff --git a/target/linux/ipq806x/patches-6.1/0067-generic-Mangle-bootloader-s-kernel-arguments.patch b/target/linux/ipq806x/patches-6.1/0067-generic-Mangle-bootloader-s-kernel-arguments.patch
deleted file mode 100644 (file)
index 4e47c39..0000000
+++ /dev/null
@@ -1,280 +0,0 @@
-From 71270226b14733a4b1f2cde58ea9265caa50b38d Mon Sep 17 00:00:00 2001
-From: Adrian Panella <ianchi74@outlook.com>
-Date: Thu, 9 Mar 2017 09:37:17 +0100
-Subject: [PATCH 67/69] generic: Mangle bootloader's kernel arguments
-
-The command-line arguments provided by the boot loader will be
-appended to a new device tree property: bootloader-args.
-If there is a property "append-rootblock" in DT under /chosen
-and a root= option in bootloaders command line it will be parsed
-and added to DT bootargs with the form: <append-rootblock>XX.
-Only command line ATAG will be processed, the rest of the ATAGs
-sent by bootloader will be ignored.
-This is usefull in dual boot systems, to get the current root partition
-without afecting the rest of the system.
-
-Signed-off-by: Adrian Panella <ianchi74@outlook.com>
----
- arch/arm/Kconfig                        | 11 +++++
- arch/arm/boot/compressed/atags_to_fdt.c | 72 ++++++++++++++++++++++++++++++++-
- init/main.c                             | 16 ++++++++
- 3 files changed, 98 insertions(+), 1 deletion(-)
-
---- a/arch/arm/Kconfig
-+++ b/arch/arm/Kconfig
-@@ -1588,6 +1588,17 @@ config ARM_ATAG_DTB_COMPAT_CMDLINE_EXTEN
-         The command-line arguments provided by the boot loader will be
-         appended to the the device tree bootargs property.
-+config ARM_ATAG_DTB_COMPAT_CMDLINE_MANGLE
-+      bool "Append rootblock parsing bootloader's kernel arguments"
-+      help
-+        The command-line arguments provided by the boot loader will be
-+        appended to a new device tree property: bootloader-args.
-+        If there is a property "append-rootblock" in DT under /chosen
-+        and a root= option in bootloaders command line it will be parsed
-+        and added to DT bootargs with the form: <append-rootblock>XX.
-+        Only command line ATAG will be processed, the rest of the ATAGs
-+        sent by bootloader will be ignored.
-+
- endchoice
- config CMDLINE
---- a/arch/arm/boot/compressed/atags_to_fdt.c
-+++ b/arch/arm/boot/compressed/atags_to_fdt.c
-@@ -5,6 +5,8 @@
- #if defined(CONFIG_ARM_ATAG_DTB_COMPAT_CMDLINE_EXTEND)
- #define do_extend_cmdline 1
-+#elif defined(CONFIG_ARM_ATAG_DTB_COMPAT_CMDLINE_MANGLE)
-+#define do_extend_cmdline 1
- #else
- #define do_extend_cmdline 0
- #endif
-@@ -20,6 +22,7 @@ static int node_offset(void *fdt, const
-       return offset;
- }
-+#ifndef CONFIG_ARM_ATAG_DTB_COMPAT_CMDLINE_MANGLE
- static int setprop(void *fdt, const char *node_path, const char *property,
-                  void *val_array, int size)
- {
-@@ -28,6 +31,7 @@ static int setprop(void *fdt, const char
-               return offset;
-       return fdt_setprop(fdt, offset, property, val_array, size);
- }
-+#endif
- static int setprop_string(void *fdt, const char *node_path,
-                         const char *property, const char *string)
-@@ -38,6 +42,7 @@ static int setprop_string(void *fdt, con
-       return fdt_setprop_string(fdt, offset, property, string);
- }
-+#ifndef CONFIG_ARM_ATAG_DTB_COMPAT_CMDLINE_MANGLE
- static int setprop_cell(void *fdt, const char *node_path,
-                       const char *property, uint32_t val)
- {
-@@ -46,6 +51,7 @@ static int setprop_cell(void *fdt, const
-               return offset;
-       return fdt_setprop_cell(fdt, offset, property, val);
- }
-+#endif
- static const void *getprop(const void *fdt, const char *node_path,
-                          const char *property, int *len)
-@@ -58,6 +64,7 @@ static const void *getprop(const void *f
-       return fdt_getprop(fdt, offset, property, len);
- }
-+#ifndef CONFIG_ARM_ATAG_DTB_COMPAT_CMDLINE_MANGLE
- static uint32_t get_cell_size(const void *fdt)
- {
-       int len;
-@@ -68,6 +75,81 @@ static uint32_t get_cell_size(const void
-               cell_size = fdt32_to_cpu(*size_len);
-       return cell_size;
- }
-+#endif
-+
-+#if defined(CONFIG_ARM_ATAG_DTB_COMPAT_CMDLINE_MANGLE)
-+/**
-+ * taken from arch/x86/boot/string.c
-+ * local_strstr - Find the first substring in a %NUL terminated string
-+ * @s1: The string to be searched
-+ * @s2: The string to search for
-+ */
-+static char *local_strstr(const char *s1, const char *s2)
-+{
-+      size_t l1, l2;
-+
-+      l2 = strlen(s2);
-+      if (!l2)
-+              return (char *)s1;
-+      l1 = strlen(s1);
-+      while (l1 >= l2) {
-+              l1--;
-+              if (!memcmp(s1, s2, l2))
-+                      return (char *)s1;
-+              s1++;
-+      }
-+      return NULL;
-+}
-+
-+static char *append_rootblock(char *dest, const char *str, int len, void *fdt)
-+{
-+      char *ptr, *end, *tmp;
-+      const char *root="root=";
-+      const char *find_rootblock;
-+      int i, l;
-+      const char *rootblock;
-+
-+      find_rootblock = getprop(fdt, "/chosen", "find-rootblock", &l);
-+      if (!find_rootblock)
-+              find_rootblock = root;
-+
-+      //ARM doesn't have __HAVE_ARCH_STRSTR, so it was copied from x86
-+      ptr = local_strstr(str, find_rootblock);
-+
-+      if(!ptr)
-+              return dest;
-+
-+      end = strchr(ptr, ' ');
-+      end = end ? (end - 1) : (strchr(ptr, 0) - 1);
-+
-+      // Some boards ubi.mtd=XX,ZZZZ, so let's check for '," too.
-+      tmp = strchr(ptr, ',');
-+
-+      if(tmp)
-+              end = end < tmp ? end : tmp - 1;
-+
-+      //find partition number (assumes format root=/dev/mtdXX | /dev/mtdblockXX | yy:XX | ubi.mtd=XX,ZZZZ )
-+      for( i = 0; end >= ptr && *end >= '0' && *end <= '9'; end--, i++);
-+      ptr = end + 1;
-+
-+      /* if append-rootblock property is set use it to append to command line */
-+      rootblock = getprop(fdt, "/chosen", "append-rootblock", &l);
-+      if(rootblock != NULL) {
-+              if(*dest != ' ') {
-+                      *dest = ' ';
-+                      dest++;
-+                      len++;
-+              }
-+              if (len + l + i <= COMMAND_LINE_SIZE) {
-+                      memcpy(dest, rootblock, l);
-+                      dest += l - 1;
-+                      memcpy(dest, ptr, i);
-+                      dest += i;
-+              }
-+      }
-+      return dest;
-+}
-+#endif
- static void merge_fdt_bootargs(void *fdt, const char *fdt_cmdline)
- {
-@@ -88,18 +170,28 @@ static void merge_fdt_bootargs(void *fdt
-       /* and append the ATAG_CMDLINE */
-       if (fdt_cmdline) {
-+
-+#if defined(CONFIG_ARM_ATAG_DTB_COMPAT_CMDLINE_MANGLE)
-+              //save original bootloader args
-+              //and append ubi.mtd with root partition number to current cmdline
-+              setprop_string(fdt, "/chosen", "bootloader-args", fdt_cmdline);
-+              ptr = append_rootblock(ptr, fdt_cmdline, len, fdt);
-+
-+#else
-               len = strlen(fdt_cmdline);
-               if (ptr - cmdline + len + 2 < COMMAND_LINE_SIZE) {
-                       *ptr++ = ' ';
-                       memcpy(ptr, fdt_cmdline, len);
-                       ptr += len;
-               }
-+#endif
-       }
-       *ptr = '\0';
-       setprop_string(fdt, "/chosen", "bootargs", cmdline);
- }
-+#ifndef CONFIG_ARM_ATAG_DTB_COMPAT_CMDLINE_MANGLE
- static void hex_str(char *out, uint32_t value)
- {
-       uint32_t digit;
-@@ -117,6 +209,7 @@ static void hex_str(char *out, uint32_t
-       }
-       *out = '\0';
- }
-+#endif
- /*
-  * Convert and fold provided ATAGs into the provided FDT.
-@@ -131,9 +224,11 @@ int atags_to_fdt(void *atag_list, void *
-       struct tag *atag = atag_list;
-       /* In the case of 64 bits memory size, need to reserve 2 cells for
-        * address and size for each bank */
-+#ifndef CONFIG_ARM_ATAG_DTB_COMPAT_CMDLINE_MANGLE
-       __be32 mem_reg_property[2 * 2 * NR_BANKS];
--      int memcount = 0;
--      int ret, memsize;
-+      int memsize, memcount = 0;
-+#endif
-+      int ret;
-       /* make sure we've got an aligned pointer */
-       if ((u32)atag_list & 0x3)
-@@ -168,7 +263,9 @@ int atags_to_fdt(void *atag_list, void *
-                       else
-                               setprop_string(fdt, "/chosen", "bootargs",
-                                              atag->u.cmdline.cmdline);
--              } else if (atag->hdr.tag == ATAG_MEM) {
-+              }
-+#ifndef CONFIG_ARM_ATAG_DTB_COMPAT_CMDLINE_MANGLE
-+              else if (atag->hdr.tag == ATAG_MEM) {
-                       if (memcount >= sizeof(mem_reg_property)/4)
-                               continue;
-                       if (!atag->u.mem.size)
-@@ -212,6 +309,10 @@ int atags_to_fdt(void *atag_list, void *
-               setprop(fdt, "/memory", "reg", mem_reg_property,
-                       4 * memcount * memsize);
-       }
-+#else
-+
-+      }
-+#endif
-       return fdt_pack(fdt);
- }
---- a/init/main.c
-+++ b/init/main.c
-@@ -112,6 +112,10 @@
- #include <kunit/test.h>
-+#if defined(CONFIG_ARM_ATAG_DTB_COMPAT_CMDLINE_MANGLE)
-+#include <linux/of.h>
-+#endif
-+
- static int kernel_init(void *);
- extern void init_IRQ(void);
-@@ -995,6 +999,18 @@ asmlinkage __visible void __init __no_sa
-       pr_notice("Kernel command line: %s\n", saved_command_line);
-       /* parameters may set static keys */
-       jump_label_init();
-+
-+#if defined(CONFIG_ARM_ATAG_DTB_COMPAT_CMDLINE_MANGLE)
-+      //Show bootloader's original command line for reference
-+      if(of_chosen) {
-+              const char *prop = of_get_property(of_chosen, "bootloader-args", NULL);
-+              if(prop)
-+                      pr_notice("Bootloader command line (ignored): %s\n", prop);
-+              else
-+                      pr_notice("Bootloader command line not present\n");
-+      }
-+#endif
-+
-       parse_early_param();
-       after_dashes = parse_args("Booting kernel",
-                                 static_command_line, __start___param,
index 20046325136071bfaa9538e8db0793e8840ac942..c9583549d0c39b925043d62c0f2a445c157e9315 100644 (file)
@@ -1,6 +1,6 @@
 --- a/arch/arm/Kconfig
 +++ b/arch/arm/Kconfig
-@@ -1601,6 +1601,14 @@ config ARM_ATAG_DTB_COMPAT_CMDLINE_MANGL
+@@ -1589,6 +1589,14 @@ config ARM_ATAG_DTB_COMPAT_CMDLINE_EXTEN
  
  endchoice
  
diff --git a/target/linux/ipq806x/patches-6.1/901-01-ARM-decompressor-support-memory-start-validation-.patch b/target/linux/ipq806x/patches-6.1/901-01-ARM-decompressor-support-memory-start-validation-.patch
new file mode 100644 (file)
index 0000000..04e2a0c
--- /dev/null
@@ -0,0 +1,75 @@
+From 2f86b9b71a11f86e3d850214ab781ebb17d7260e Mon Sep 17 00:00:00 2001
+From: Christian Marangi <ansuelsmth@gmail.com>
+Date: Fri, 19 Jan 2024 19:48:30 +0100
+Subject: [PATCH v2 1/2] ARM: decompressor: support memory start validation for
+ appended DTB
+
+There is currently a problem with a very specific sets of kernel config
+and AUTO_ZRELADDR.
+
+For the most common case AUTO_ZRELADDR check the PC register and
+calculate the start of the physical memory. Then fdt_check_mem_start is
+called to make sure the detected value makes sense by comparing it with
+what is present in DTB in the memory nodes and if additional fixup are
+required with the use of linux,usable-memory-range in the chosen node to
+hardcode usable memory range in case some reserved space needs to be
+addressed. With the help of this function the right address is
+calculated and the kernel correctly decompress and loads.
+
+Things starts to become problematic when in the mix,
+CONFIG_ARM_APPENDED_DTB is used. This is a particular kernel config is
+used when legacy systems doesn't support passing a DTB directly and a
+DTB is appended at the end of the image.
+
+In such case, fdt_check_mem_start is skipped in AUTO_ZRELADDR iteration
+as the appended DTB can be augumented later with ATAGS passed from the
+bootloader (if CONFIG_ARM_ATAG_DTB_COMPAT is enabled).
+
+The main problem and what this patch address is the fact that
+fdt_check_mem_start is never called later when the appended DTB is
+augumented, hence any fixup and validation is not done making AUTO_ZRELADDR
+detection inconsistent and most of the time wrong.
+
+Add support in head.S for this by checking if AUTO_ZRELADDR is enabled
+and calling fdt_check_mem_start with the appended DTB and the augumented
+values permitting legacy device to provide info in DTB instead of
+disabling AUTO_ZRELADDR and hardcoding the physical address offsets.
+
+Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
+Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>
+Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
+---
+ arch/arm/boot/compressed/head.S | 22 ++++++++++++++++++++++
+ 1 file changed, 22 insertions(+)
+
+--- a/arch/arm/boot/compressed/head.S
++++ b/arch/arm/boot/compressed/head.S
+@@ -443,6 +443,28 @@ restart:  adr     r0, LC1
+               add     r6, r6, r5
+               add     r10, r10, r5
+               add     sp, sp, r5
++
++#ifdef CONFIG_AUTO_ZRELADDR
++              /*
++               * Validate calculated start of physical memory with appended DTB.
++               * In the first iteration for physical memory start calculation,
++               * we skipped validating it as it could have been augumented by
++               * ATAGS stored at an offset from the same start of physical memory.
++               *
++               * We now have parsed them and augumented the appended DTB if asked
++               * so we can finally validate the start of physical memory.
++               *
++               * This is needed to apply additional fixup with
++               * linux,usable-memory-range or to make sure AUTO_ZRELADDR detected
++               * the correct value.
++               */
++              sub     r0, r4, #TEXT_OFFSET    @ revert to base address
++              mov     r1, r8                  @ use appended DTB
++              bl      fdt_check_mem_start
++
++              /* Determine final kernel image address. */
++              add     r4, r0, #TEXT_OFFSET
++#endif
+ dtb_check_done:
+ #endif
diff --git a/target/linux/ipq806x/patches-6.1/901-02-ARM-decompressor-add-option-to-ignore-MEM-ATAGs.patch b/target/linux/ipq806x/patches-6.1/901-02-ARM-decompressor-add-option-to-ignore-MEM-ATAGs.patch
new file mode 100644 (file)
index 0000000..2e4c4de
--- /dev/null
@@ -0,0 +1,54 @@
+From 781d7cd4c3364e9d38fa12a342c5ad4c7e33a5ba Mon Sep 17 00:00:00 2001
+From: Christian Marangi <ansuelsmth@gmail.com>
+Date: Fri, 19 Jan 2024 20:33:10 +0100
+Subject: [PATCH v2 2/2] ARM: decompressor: add option to ignore MEM ATAGs
+
+Some bootloaders can pass broken MEM ATAGs that provide hardcoded
+information about mounted RAM size and physical location.
+Example booloader provide RAM of size 1.7Gb but actual mounted RAM
+size is 512Mb causing kernel panic.
+
+Add option CONFIG_ARM_ATAG_DTB_COMPAT_IGNORE_MEM to ignore these ATAG
+and not augument appended DTB memory node.
+
+Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
+Acked-by: Linus Walleij <linus.walleij@linaro.org>
+---
+ arch/arm/Kconfig                        | 12 ++++++++++++
+ arch/arm/boot/compressed/atags_to_fdt.c |  4 ++++
+ 2 files changed, 16 insertions(+)
+
+--- a/arch/arm/Kconfig
++++ b/arch/arm/Kconfig
+@@ -1570,6 +1570,18 @@ config ARM_ATAG_DTB_COMPAT
+         bootloaders, this option allows zImage to extract the information
+         from the ATAG list and store it at run time into the appended DTB.
++config ARM_ATAG_DTB_COMPAT_IGNORE_MEM
++      bool "Ignore MEM ATAG information from bootloader"
++      depends on ARM_ATAG_DTB_COMPAT
++      help
++        Some bootloaders can pass broken MEM ATAGs that provide hardcoded
++        information about mounted RAM size and physical location.
++        Example booloader provide RAM of size 1.7Gb but actual mounted RAM
++        size is 512Mb causing kernel panic.
++
++        Enable this option if MEM ATAGs should be ignored and the memory
++        node in the appended DTB should NOT be augumented.
++
+ choice
+       prompt "Kernel command line type" if ARM_ATAG_DTB_COMPAT
+       default ARM_ATAG_DTB_COMPAT_CMDLINE_FROM_BOOTLOADER
+--- a/arch/arm/boot/compressed/atags_to_fdt.c
++++ b/arch/arm/boot/compressed/atags_to_fdt.c
+@@ -169,6 +169,10 @@ int atags_to_fdt(void *atag_list, void *
+                               setprop_string(fdt, "/chosen", "bootargs",
+                                              atag->u.cmdline.cmdline);
+               } else if (atag->hdr.tag == ATAG_MEM) {
++                      /* Bootloader MEM ATAG are broken and should be ignored */
++                      if (IS_ENABLED(CONFIG_ARM_ATAG_DTB_COMPAT_IGNORE_MEM))
++                              continue;
++
+                       if (memcount >= sizeof(mem_reg_property)/4)
+                               continue;
+                       if (!atag->u.mem.size)
diff --git a/target/linux/ipq806x/patches-6.1/902-ARM-decompressor-support-for-ATAGs-rootblock-parsing.patch b/target/linux/ipq806x/patches-6.1/902-ARM-decompressor-support-for-ATAGs-rootblock-parsing.patch
new file mode 100644 (file)
index 0000000..60b80fe
--- /dev/null
@@ -0,0 +1,197 @@
+From 13bb6d8dd9138927950a520a288401db82871dc9 Mon Sep 17 00:00:00 2001
+From: Christian Marangi <ansuelsmth@gmail.com>
+Date: Sun, 21 Jan 2024 23:36:57 +0100
+Subject: [PATCH] ARM: decompressor: support for ATAGs rootblock parsing
+
+The command-line arguments provided by the boot loader will be
+appended to a new device tree property: bootloader-args.
+
+If there is a property "append-rootblock" in DT under /chosen
+and a root= option in bootloaders command line it will be parsed
+and added to DT bootargs with the form: <append-rootblock>XX.
+
+This is usefull in dual boot systems, to get the current root partition
+without afecting the rest of the system.
+
+Signed-off-by: Adrian Panella <ianchi74@outlook.com>
+[ reworked to a cleaner patch ]
+Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
+---
+ arch/arm/Kconfig                        |  10 +++
+ arch/arm/boot/compressed/atags_to_fdt.c | 102 ++++++++++++++++++++++--
+ init/main.c                             |  12 +++
+ 3 files changed, 117 insertions(+), 7 deletions(-)
+
+--- a/arch/arm/Kconfig
++++ b/arch/arm/Kconfig
+@@ -1599,6 +1599,16 @@ config ARM_ATAG_DTB_COMPAT_CMDLINE_EXTEN
+         The command-line arguments provided by the boot loader will be
+         appended to the the device tree bootargs property.
++config ARM_ATAG_DTB_COMPAT_CMDLINE_MANGLE
++      bool "Append rootblock parsing bootloader's kernel arguments"
++      help
++        The command-line arguments provided by the boot loader will be
++        appended to a new device tree property: bootloader-args.
++
++        If there is a property "append-rootblock" in DT under /chosen
++        and a root= option in bootloaders command line it will be parsed
++        and added to DT bootargs with the form: <append-rootblock>XX.
++
+ endchoice
+ config CMDLINE_OVERRIDE
+--- a/arch/arm/boot/compressed/atags_to_fdt.c
++++ b/arch/arm/boot/compressed/atags_to_fdt.c
+@@ -3,7 +3,8 @@
+ #include <asm/setup.h>
+ #include <libfdt.h>
+-#if defined(CONFIG_ARM_ATAG_DTB_COMPAT_CMDLINE_EXTEND)
++#if defined(CONFIG_ARM_ATAG_DTB_COMPAT_CMDLINE_EXTEND) || \
++      defined(CONFIG_ARM_ATAG_DTB_COMPAT_CMDLINE_MANGLE)
+ #define do_extend_cmdline 1
+ #else
+ #define do_extend_cmdline 0
+@@ -69,6 +70,83 @@ static uint32_t get_cell_size(const void
+       return cell_size;
+ }
++/**
++ * taken from arch/x86/boot/string.c
++ * local_strstr - Find the first substring in a %NUL terminated string
++ * @s1: The string to be searched
++ * @s2: The string to search for
++ */
++static char *local_strstr(const char *s1, const char *s2)
++{
++      size_t l1, l2;
++
++      l2 = strlen(s2);
++      if (!l2)
++              return (char *)s1;
++      l1 = strlen(s1);
++      while (l1 >= l2) {
++              l1--;
++              if (!memcmp(s1, s2, l2))
++                      return (char *)s1;
++              s1++;
++      }
++      return NULL;
++}
++
++static char *append_rootblock(char *dest, const char *str, int len, void *fdt)
++{
++      char *ptr, *end, *tmp;
++      const char *root="root=";
++      const char *find_rootblock;
++      int i, l;
++      const char *rootblock;
++
++      find_rootblock = getprop(fdt, "/chosen", "find-rootblock", &l);
++      if (!find_rootblock)
++              find_rootblock = root;
++
++      /* ARM doesn't have __HAVE_ARCH_STRSTR, so it was copied from x86 */
++      ptr = local_strstr(str, find_rootblock);
++      if (!ptr)
++              return dest;
++
++      end = strchr(ptr, ' ');
++      end = end ? (end - 1) : (strchr(ptr, 0) - 1);
++
++      /* Some boards ubi.mtd=XX,ZZZZ, so let's check for '," too. */
++      tmp = strchr(ptr, ',');
++      if (tmp)
++              end = end < tmp ? end : tmp - 1;
++
++      /*
++       * find partition number
++       * (assumes format root=/dev/mtdXX | /dev/mtdblockXX | yy:XX | ubi.mtd=XX,ZZZZ )
++       */
++      for (i = 0; end >= ptr && *end >= '0' && *end <= '9'; end--, i++);
++
++      ptr = end + 1;
++
++      /* if append-rootblock property is set use it to append to command line */
++      rootblock = getprop(fdt, "/chosen", "append-rootblock", &l);
++      if (rootblock != NULL) {
++              if (*dest != ' ') {
++                      *dest = ' ';
++                      dest++;
++                      len++;
++              }
++
++              if (len + l + i <= COMMAND_LINE_SIZE) {
++                      memcpy(dest, rootblock, l);
++                      dest += l - 1;
++
++                      memcpy(dest, ptr, i);
++                      dest += i;
++              }
++      }
++
++      return dest;
++}
++
+ static void merge_fdt_bootargs(void *fdt, const char *fdt_cmdline)
+ {
+       char cmdline[COMMAND_LINE_SIZE];
+@@ -86,13 +164,23 @@ static void merge_fdt_bootargs(void *fdt
+                       ptr += len - 1;
+               }
+-      /* and append the ATAG_CMDLINE */
+       if (fdt_cmdline) {
+-              len = strlen(fdt_cmdline);
+-              if (ptr - cmdline + len + 2 < COMMAND_LINE_SIZE) {
+-                      *ptr++ = ' ';
+-                      memcpy(ptr, fdt_cmdline, len);
+-                      ptr += len;
++              if (IS_ENABLED(CONFIG_ARM_ATAG_DTB_COMPAT_CMDLINE_MANGLE)) {
++                      /*
++                      * save original bootloader args
++                      * and append ubi.mtd with root partition number
++                      * to current cmdline
++                      */
++                      setprop_string(fdt, "/chosen", "bootloader-args", fdt_cmdline);
++                      ptr = append_rootblock(ptr, fdt_cmdline, len, fdt);
++              } else {
++                      /* and append the ATAG_CMDLINE */
++                      len = strlen(fdt_cmdline);
++                      if (ptr - cmdline + len + 2 < COMMAND_LINE_SIZE) {
++                              *ptr++ = ' ';
++                              memcpy(ptr, fdt_cmdline, len);
++                              ptr += len;
++                      }
+               }
+       }
+       *ptr = '\0';
+--- a/init/main.c
++++ b/init/main.c
+@@ -28,6 +28,7 @@
+ #include <linux/initrd.h>
+ #include <linux/memblock.h>
+ #include <linux/acpi.h>
++#include <linux/of.h>
+ #include <linux/bootconfig.h>
+ #include <linux/console.h>
+ #include <linux/nmi.h>
+@@ -995,6 +996,17 @@ asmlinkage __visible void __init __no_sa
+       pr_notice("Kernel command line: %s\n", saved_command_line);
+       /* parameters may set static keys */
+       jump_label_init();
++
++      /* Show bootloader's original command line for reference */
++      if (IS_ENABLED(CONFIG_ARM_ATAG_DTB_COMPAT_CMDLINE_MANGLE) && of_chosen) {
++              const char *prop = of_get_property(of_chosen, "bootloader-args", NULL);
++
++              if(prop)
++                      pr_notice("Bootloader command line (ignored): %s\n", prop);
++              else
++                      pr_notice("Bootloader command line not present\n");
++      }
++
+       parse_early_param();
+       after_dashes = parse_args("Booting kernel",
+                                 static_command_line, __start___param,