ipq806x: replace ARM bootloader patch with pending upstream version
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>
This commit is contained in:
parent
68968fc981
commit
b2bb4b0f0a
7 changed files with 328 additions and 342 deletions
|
@ -4,7 +4,6 @@ CONFIG_ALIGNMENT_TRAP=y
|
||||||
CONFIG_ARCH_32BIT_OFF_T=y
|
CONFIG_ARCH_32BIT_OFF_T=y
|
||||||
CONFIG_ARCH_HIBERNATION_POSSIBLE=y
|
CONFIG_ARCH_HIBERNATION_POSSIBLE=y
|
||||||
# CONFIG_ARCH_IPQ40XX is not set
|
# CONFIG_ARCH_IPQ40XX is not set
|
||||||
CONFIG_ARCH_IPQ806X=y
|
|
||||||
CONFIG_ARCH_KEEP_MEMBLOCK=y
|
CONFIG_ARCH_KEEP_MEMBLOCK=y
|
||||||
# CONFIG_ARCH_MDM9615 is not set
|
# CONFIG_ARCH_MDM9615 is not set
|
||||||
CONFIG_ARCH_MIGHT_HAVE_PC_PARPORT=y
|
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=y
|
||||||
# CONFIG_ARM_ATAG_DTB_COMPAT_CMDLINE_FROM_BOOTLOADER is not set
|
# CONFIG_ARM_ATAG_DTB_COMPAT_CMDLINE_FROM_BOOTLOADER is not set
|
||||||
CONFIG_ARM_ATAG_DTB_COMPAT_CMDLINE_MANGLE=y
|
CONFIG_ARM_ATAG_DTB_COMPAT_CMDLINE_MANGLE=y
|
||||||
|
CONFIG_ARM_ATAG_DTB_COMPAT_IGNORE_MEM=y
|
||||||
CONFIG_ARM_CPUIDLE=y
|
CONFIG_ARM_CPUIDLE=y
|
||||||
CONFIG_ARM_CPU_SUSPEND=y
|
CONFIG_ARM_CPU_SUSPEND=y
|
||||||
# CONFIG_ARM_CPU_TOPOLOGY is not set
|
# CONFIG_ARM_CPU_TOPOLOGY is not set
|
||||||
|
|
|
@ -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
|
|
|
@ -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,
|
|
|
@ -1,6 +1,6 @@
|
||||||
--- a/arch/arm/Kconfig
|
--- a/arch/arm/Kconfig
|
||||||
+++ b/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
|
endchoice
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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)
|
|
@ -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,
|
Loading…
Reference in a new issue