b.liu | e958203 | 2025-04-17 19:18:16 +0800 | [diff] [blame^] | 1 | From: Paul Burton <paul.burton@mips.com> |
| 2 | Date: Wed, 9 Oct 2019 23:09:45 +0000 |
| 3 | Subject: MIPS: cmdline: Clean up boot_command_line initialization |
| 4 | |
| 5 | Our current code to initialize boot_command_line is a mess. Some of this |
| 6 | is due to the addition of too many options over the years, and some of |
| 7 | this is due to workarounds for early_init_dt_scan_chosen() performing |
| 8 | actions specific to options from other architectures that probably |
| 9 | shouldn't be in generic code. |
| 10 | |
| 11 | Clean this up by introducing a new bootcmdline_init() function that |
| 12 | simplifies the initialization somewhat. The major changes are: |
| 13 | |
| 14 | - Because bootcmdline_init() is a function it can return early in the |
| 15 | CONFIG_CMDLINE_OVERRIDE case. |
| 16 | |
| 17 | - We clear boot_command_line rather than inheriting whatever |
| 18 | early_init_dt_scan_chosen() may have left us. This means we no longer |
| 19 | need to set boot_command_line to a space character in an attempt to |
| 20 | prevent early_init_dt_scan_chosen() from copying CONFIG_CMDLINE into |
| 21 | boot_command_line without us knowing about it. |
| 22 | |
| 23 | - Indirection via USE_PROM_CMDLINE, USE_DTB_CMDLINE, EXTEND_WITH_PROM & |
| 24 | BUILTIN_EXTEND_WITH_PROM macros is removed; they seemingly served only |
| 25 | to obfuscate the code. |
| 26 | |
| 27 | - The logic is cleaner, clearer & commented. |
| 28 | |
| 29 | Two minor drawbacks of this approach are: |
| 30 | |
| 31 | 1) We call of_scan_flat_dt(), which means we scan through the DT again. |
| 32 | The overhead is fairly minimal & shouldn't be noticeable. |
| 33 | |
| 34 | 2) cmdline_scan_chosen() duplicates a small amount of the logic from |
| 35 | early_init_dt_scan_chosen(). Alternatives might be to allow the |
| 36 | generic FDT code to keep & expose a copy of the arguments taken from |
| 37 | the /chosen node's bootargs property, or to introduce a function like |
| 38 | early_init_dt_scan_chosen() that retrieves them without modification |
| 39 | to handle CONFIG_CMDLINE. Neither of these sounds particularly |
| 40 | cleaner though, and this way we at least keep the extra work in |
| 41 | arch/mips. |
| 42 | |
| 43 | Origin: upstream, https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=7784cac697351f0cc0a4bb619594c0c99348c5aa |
| 44 | Signed-off-by: Paul Burton <paul.burton@mips.com> |
| 45 | Cc: linux-mips@vger.kernel.org |
| 46 | |
| 47 | --- a/arch/mips/kernel/setup.c |
| 48 | +++ b/arch/mips/kernel/setup.c |
| 49 | @@ -538,11 +538,88 @@ static void __init check_kernel_sections |
| 50 | } |
| 51 | } |
| 52 | |
| 53 | -#define USE_PROM_CMDLINE IS_ENABLED(CONFIG_MIPS_CMDLINE_FROM_BOOTLOADER) |
| 54 | -#define USE_DTB_CMDLINE IS_ENABLED(CONFIG_MIPS_CMDLINE_FROM_DTB) |
| 55 | -#define EXTEND_WITH_PROM IS_ENABLED(CONFIG_MIPS_CMDLINE_DTB_EXTEND) |
| 56 | -#define BUILTIN_EXTEND_WITH_PROM \ |
| 57 | - IS_ENABLED(CONFIG_MIPS_CMDLINE_BUILTIN_EXTEND) |
| 58 | +static void __init bootcmdline_append(const char *s, size_t max) |
| 59 | +{ |
| 60 | + if (!s[0] || !max) |
| 61 | + return; |
| 62 | + |
| 63 | + if (boot_command_line[0]) |
| 64 | + strlcat(boot_command_line, " ", COMMAND_LINE_SIZE); |
| 65 | + |
| 66 | + strlcat(boot_command_line, s, max); |
| 67 | +} |
| 68 | + |
| 69 | +static int __init bootcmdline_scan_chosen(unsigned long node, const char *uname, |
| 70 | + int depth, void *data) |
| 71 | +{ |
| 72 | + bool *dt_bootargs = data; |
| 73 | + const char *p; |
| 74 | + int l; |
| 75 | + |
| 76 | + if (depth != 1 || !data || |
| 77 | + (strcmp(uname, "chosen") != 0 && strcmp(uname, "chosen@0") != 0)) |
| 78 | + return 0; |
| 79 | + |
| 80 | + p = of_get_flat_dt_prop(node, "bootargs", &l); |
| 81 | + if (p != NULL && l > 0) { |
| 82 | + bootcmdline_append(p, min(l, COMMAND_LINE_SIZE)); |
| 83 | + *dt_bootargs = true; |
| 84 | + } |
| 85 | + |
| 86 | + return 1; |
| 87 | +} |
| 88 | + |
| 89 | +static void __init bootcmdline_init(char **cmdline_p) |
| 90 | +{ |
| 91 | + bool dt_bootargs = false; |
| 92 | + |
| 93 | + /* |
| 94 | + * If CMDLINE_OVERRIDE is enabled then initializing the command line is |
| 95 | + * trivial - we simply use the built-in command line unconditionally & |
| 96 | + * unmodified. |
| 97 | + */ |
| 98 | + if (IS_ENABLED(CONFIG_CMDLINE_OVERRIDE)) { |
| 99 | + strlcpy(boot_command_line, builtin_cmdline, COMMAND_LINE_SIZE); |
| 100 | + return; |
| 101 | + } |
| 102 | + |
| 103 | + /* |
| 104 | + * If the user specified a built-in command line & |
| 105 | + * MIPS_CMDLINE_BUILTIN_EXTEND, then the built-in command line is |
| 106 | + * prepended to arguments from the bootloader or DT so we'll copy them |
| 107 | + * to the start of boot_command_line here. Otherwise, empty |
| 108 | + * boot_command_line to undo anything early_init_dt_scan_chosen() did. |
| 109 | + */ |
| 110 | + if (IS_ENABLED(CONFIG_MIPS_CMDLINE_BUILTIN_EXTEND)) |
| 111 | + strlcpy(boot_command_line, builtin_cmdline, COMMAND_LINE_SIZE); |
| 112 | + else |
| 113 | + boot_command_line[0] = 0; |
| 114 | + |
| 115 | + /* |
| 116 | + * If we're configured to take boot arguments from DT, look for those |
| 117 | + * now. |
| 118 | + */ |
| 119 | + if (IS_ENABLED(CONFIG_MIPS_CMDLINE_FROM_DTB)) |
| 120 | + of_scan_flat_dt(bootcmdline_scan_chosen, &dt_bootargs); |
| 121 | + |
| 122 | + /* |
| 123 | + * If we didn't get any arguments from DT (regardless of whether that's |
| 124 | + * because we weren't configured to look for them, or because we looked |
| 125 | + * & found none) then we'll take arguments from the bootloader. |
| 126 | + * plat_mem_setup() should have filled arcs_cmdline with arguments from |
| 127 | + * the bootloader. |
| 128 | + */ |
| 129 | + if (IS_ENABLED(CONFIG_MIPS_CMDLINE_DTB_EXTEND) || !dt_bootargs) |
| 130 | + bootcmdline_append(arcs_cmdline, COMMAND_LINE_SIZE); |
| 131 | + |
| 132 | + /* |
| 133 | + * If the user specified a built-in command line & we didn't already |
| 134 | + * prepend it, we append it to boot_command_line here. |
| 135 | + */ |
| 136 | + if (IS_ENABLED(CONFIG_CMDLINE_BOOL) && |
| 137 | + !IS_ENABLED(CONFIG_MIPS_CMDLINE_BUILTIN_EXTEND)) |
| 138 | + bootcmdline_append(builtin_cmdline, COMMAND_LINE_SIZE); |
| 139 | +} |
| 140 | |
| 141 | /* |
| 142 | * arch_mem_init - initialize memory management subsystem |
| 143 | @@ -570,48 +647,12 @@ static void __init arch_mem_init(char ** |
| 144 | { |
| 145 | extern void plat_mem_setup(void); |
| 146 | |
| 147 | - /* |
| 148 | - * Initialize boot_command_line to an innocuous but non-empty string in |
| 149 | - * order to prevent early_init_dt_scan_chosen() from copying |
| 150 | - * CONFIG_CMDLINE into it without our knowledge. We handle |
| 151 | - * CONFIG_CMDLINE ourselves below & don't want to duplicate its |
| 152 | - * content because repeating arguments can be problematic. |
| 153 | - */ |
| 154 | - strlcpy(boot_command_line, " ", COMMAND_LINE_SIZE); |
| 155 | - |
| 156 | /* call board setup routine */ |
| 157 | plat_mem_setup(); |
| 158 | memblock_set_bottom_up(true); |
| 159 | |
| 160 | -#if defined(CONFIG_CMDLINE_BOOL) && defined(CONFIG_CMDLINE_OVERRIDE) |
| 161 | - strlcpy(boot_command_line, builtin_cmdline, COMMAND_LINE_SIZE); |
| 162 | -#else |
| 163 | - if ((USE_PROM_CMDLINE && arcs_cmdline[0]) || |
| 164 | - (USE_DTB_CMDLINE && !boot_command_line[0])) |
| 165 | - strlcpy(boot_command_line, arcs_cmdline, COMMAND_LINE_SIZE); |
| 166 | - |
| 167 | - if (EXTEND_WITH_PROM && arcs_cmdline[0]) { |
| 168 | - if (boot_command_line[0]) |
| 169 | - strlcat(boot_command_line, " ", COMMAND_LINE_SIZE); |
| 170 | - strlcat(boot_command_line, arcs_cmdline, COMMAND_LINE_SIZE); |
| 171 | - } |
| 172 | - |
| 173 | -#if defined(CONFIG_CMDLINE_BOOL) |
| 174 | - if (builtin_cmdline[0]) { |
| 175 | - if (boot_command_line[0]) |
| 176 | - strlcat(boot_command_line, " ", COMMAND_LINE_SIZE); |
| 177 | - strlcat(boot_command_line, builtin_cmdline, COMMAND_LINE_SIZE); |
| 178 | - } |
| 179 | - |
| 180 | - if (BUILTIN_EXTEND_WITH_PROM && arcs_cmdline[0]) { |
| 181 | - if (boot_command_line[0]) |
| 182 | - strlcat(boot_command_line, " ", COMMAND_LINE_SIZE); |
| 183 | - strlcat(boot_command_line, arcs_cmdline, COMMAND_LINE_SIZE); |
| 184 | - } |
| 185 | -#endif |
| 186 | -#endif |
| 187 | + bootcmdline_init(cmdline_p); |
| 188 | strlcpy(command_line, boot_command_line, COMMAND_LINE_SIZE); |
| 189 | - |
| 190 | *cmdline_p = command_line; |
| 191 | |
| 192 | parse_early_param(); |