ipq806x: 6.6: refresh kernel patches
[openwrt/openwrt.git] / target / linux / ipq806x / patches-6.6 / 902-ARM-decompressor-support-for-ATAGs-rootblock-parsing.patch
1 From 13bb6d8dd9138927950a520a288401db82871dc9 Mon Sep 17 00:00:00 2001
2 From: Christian Marangi <ansuelsmth@gmail.com>
3 Date: Sun, 21 Jan 2024 23:36:57 +0100
4 Subject: [PATCH] ARM: decompressor: support for ATAGs rootblock parsing
5
6 The command-line arguments provided by the boot loader will be
7 appended to a new device tree property: bootloader-args.
8
9 If there is a property "append-rootblock" in DT under /chosen
10 and a root= option in bootloaders command line it will be parsed
11 and added to DT bootargs with the form: <append-rootblock>XX.
12
13 This is usefull in dual boot systems, to get the current root partition
14 without afecting the rest of the system.
15
16 Signed-off-by: Adrian Panella <ianchi74@outlook.com>
17 [ reworked to a cleaner patch ]
18 Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
19 ---
20 arch/arm/Kconfig | 10 +++
21 arch/arm/boot/compressed/atags_to_fdt.c | 102 ++++++++++++++++++++++--
22 init/main.c | 12 +++
23 3 files changed, 117 insertions(+), 7 deletions(-)
24
25 --- a/arch/arm/Kconfig
26 +++ b/arch/arm/Kconfig
27 @@ -1578,6 +1578,16 @@ config ARM_ATAG_DTB_COMPAT_CMDLINE_EXTEN
28 The command-line arguments provided by the boot loader will be
29 appended to the the device tree bootargs property.
30
31 +config ARM_ATAG_DTB_COMPAT_CMDLINE_MANGLE
32 + bool "Append rootblock parsing bootloader's kernel arguments"
33 + help
34 + The command-line arguments provided by the boot loader will be
35 + appended to a new device tree property: bootloader-args.
36 +
37 + If there is a property "append-rootblock" in DT under /chosen
38 + and a root= option in bootloaders command line it will be parsed
39 + and added to DT bootargs with the form: <append-rootblock>XX.
40 +
41 endchoice
42
43 config CMDLINE_OVERRIDE
44 --- a/arch/arm/boot/compressed/atags_to_fdt.c
45 +++ b/arch/arm/boot/compressed/atags_to_fdt.c
46 @@ -4,7 +4,8 @@
47 #include <libfdt.h>
48 #include "misc.h"
49
50 -#if defined(CONFIG_ARM_ATAG_DTB_COMPAT_CMDLINE_EXTEND)
51 +#if defined(CONFIG_ARM_ATAG_DTB_COMPAT_CMDLINE_EXTEND) || \
52 + defined(CONFIG_ARM_ATAG_DTB_COMPAT_CMDLINE_MANGLE)
53 #define do_extend_cmdline 1
54 #else
55 #define do_extend_cmdline 0
56 @@ -70,6 +71,83 @@ static uint32_t get_cell_size(const void
57 return cell_size;
58 }
59
60 +/**
61 + * taken from arch/x86/boot/string.c
62 + * local_strstr - Find the first substring in a %NUL terminated string
63 + * @s1: The string to be searched
64 + * @s2: The string to search for
65 + */
66 +static char *local_strstr(const char *s1, const char *s2)
67 +{
68 + size_t l1, l2;
69 +
70 + l2 = strlen(s2);
71 + if (!l2)
72 + return (char *)s1;
73 + l1 = strlen(s1);
74 + while (l1 >= l2) {
75 + l1--;
76 + if (!memcmp(s1, s2, l2))
77 + return (char *)s1;
78 + s1++;
79 + }
80 + return NULL;
81 +}
82 +
83 +static char *append_rootblock(char *dest, const char *str, int len, void *fdt)
84 +{
85 + char *ptr, *end, *tmp;
86 + const char *root="root=";
87 + const char *find_rootblock;
88 + int i, l;
89 + const char *rootblock;
90 +
91 + find_rootblock = getprop(fdt, "/chosen", "find-rootblock", &l);
92 + if (!find_rootblock)
93 + find_rootblock = root;
94 +
95 + /* ARM doesn't have __HAVE_ARCH_STRSTR, so it was copied from x86 */
96 + ptr = local_strstr(str, find_rootblock);
97 + if (!ptr)
98 + return dest;
99 +
100 + end = strchr(ptr, ' ');
101 + end = end ? (end - 1) : (strchr(ptr, 0) - 1);
102 +
103 + /* Some boards ubi.mtd=XX,ZZZZ, so let's check for '," too. */
104 + tmp = strchr(ptr, ',');
105 + if (tmp)
106 + end = end < tmp ? end : tmp - 1;
107 +
108 + /*
109 + * find partition number
110 + * (assumes format root=/dev/mtdXX | /dev/mtdblockXX | yy:XX | ubi.mtd=XX,ZZZZ )
111 + */
112 + for (i = 0; end >= ptr && *end >= '0' && *end <= '9'; end--, i++);
113 +
114 + ptr = end + 1;
115 +
116 + /* if append-rootblock property is set use it to append to command line */
117 + rootblock = getprop(fdt, "/chosen", "append-rootblock", &l);
118 + if (rootblock != NULL) {
119 + if (*dest != ' ') {
120 + *dest = ' ';
121 + dest++;
122 + len++;
123 + }
124 +
125 + if (len + l + i <= COMMAND_LINE_SIZE) {
126 + memcpy(dest, rootblock, l);
127 + dest += l - 1;
128 +
129 + memcpy(dest, ptr, i);
130 + dest += i;
131 + }
132 + }
133 +
134 + return dest;
135 +}
136 +
137 static void merge_fdt_bootargs(void *fdt, const char *fdt_cmdline)
138 {
139 char cmdline[COMMAND_LINE_SIZE];
140 @@ -87,13 +165,23 @@ static void merge_fdt_bootargs(void *fdt
141 ptr += len - 1;
142 }
143
144 - /* and append the ATAG_CMDLINE */
145 if (fdt_cmdline) {
146 - len = strlen(fdt_cmdline);
147 - if (ptr - cmdline + len + 2 < COMMAND_LINE_SIZE) {
148 - *ptr++ = ' ';
149 - memcpy(ptr, fdt_cmdline, len);
150 - ptr += len;
151 + if (IS_ENABLED(CONFIG_ARM_ATAG_DTB_COMPAT_CMDLINE_MANGLE)) {
152 + /*
153 + * save original bootloader args
154 + * and append ubi.mtd with root partition number
155 + * to current cmdline
156 + */
157 + setprop_string(fdt, "/chosen", "bootloader-args", fdt_cmdline);
158 + ptr = append_rootblock(ptr, fdt_cmdline, len, fdt);
159 + } else {
160 + /* and append the ATAG_CMDLINE */
161 + len = strlen(fdt_cmdline);
162 + if (ptr - cmdline + len + 2 < COMMAND_LINE_SIZE) {
163 + *ptr++ = ' ';
164 + memcpy(ptr, fdt_cmdline, len);
165 + ptr += len;
166 + }
167 }
168 }
169 *ptr = '\0';
170 --- a/init/main.c
171 +++ b/init/main.c
172 @@ -28,6 +28,7 @@
173 #include <linux/initrd.h>
174 #include <linux/memblock.h>
175 #include <linux/acpi.h>
176 +#include <linux/of.h>
177 #include <linux/bootconfig.h>
178 #include <linux/console.h>
179 #include <linux/nmi.h>
180 @@ -929,6 +930,17 @@ void start_kernel(void)
181 pr_notice("Kernel command line: %s\n", saved_command_line);
182 /* parameters may set static keys */
183 jump_label_init();
184 +
185 + /* Show bootloader's original command line for reference */
186 + if (IS_ENABLED(CONFIG_ARM_ATAG_DTB_COMPAT_CMDLINE_MANGLE) && of_chosen) {
187 + const char *prop = of_get_property(of_chosen, "bootloader-args", NULL);
188 +
189 + if(prop)
190 + pr_notice("Bootloader command line (ignored): %s\n", prop);
191 + else
192 + pr_notice("Bootloader command line not present\n");
193 + }
194 +
195 parse_early_param();
196 after_dashes = parse_args("Booting kernel",
197 static_command_line, __start___param,