[PATCH 2/2] LoongArch: Refactor command line processing
Dave Young
dyoung at redhat.com
Thu Sep 25 02:22:38 PDT 2025
On Thu, 25 Sept 2025 at 14:33, Youling Tang <youling.tang at linux.dev> wrote:
>
> From: Youling Tang <tangyouling at kylinos.cn>
>
> Refactor the cmdline_add_xxx code flow, and simultaneously display
> the content of parameters such as initrd in hexadecimal format to
> improve readability.
>
> Signed-off-by: Youling Tang <tangyouling at kylinos.cn>
> ---
> kexec/arch/loongarch/kexec-loongarch.c | 138 ++++++++++---------------
> 1 file changed, 55 insertions(+), 83 deletions(-)
>
> diff --git a/kexec/arch/loongarch/kexec-loongarch.c b/kexec/arch/loongarch/kexec-loongarch.c
> index 240202f..c2503de 100644
> --- a/kexec/arch/loongarch/kexec-loongarch.c
> +++ b/kexec/arch/loongarch/kexec-loongarch.c
> @@ -35,83 +35,49 @@
> #define _O_BINARY 0
> #endif
>
> -#define CMDLINE_PREFIX "kexec "
> -static char cmdline[COMMAND_LINE_SIZE] = CMDLINE_PREFIX;
> +/* Add the "kexec" command line parameter to command line. */
> +static void cmdline_add_loader(unsigned long *cmdline_tmplen, char *modified_cmdline)
> +{
> + int loader_strlen;
> +
> + loader_strlen = sprintf(modified_cmdline + (*cmdline_tmplen), "kexec ");
> + *cmdline_tmplen += loader_strlen;
> +}
Not sure why this is needed, I guess it is to distinguish the new
kernel and original kernel? As replied in another reply I would
suggest adding an extra cmdline in scripts instead of hard coded here,
you need to remove the fake param each time otherwise it will make
the cmdline longer and longer after many kexec reboot cycles.
>
> -/* Adds "initrd=start,size" parameters to command line. */
> -static int cmdline_add_initrd(char *cmdline, unsigned long addr,
> - unsigned long size)
> +/* Add the "initrd=start,size" command line parameter to command line. */
> +static void cmdline_add_initrd(unsigned long *cmdline_tmplen, char *modified_cmdline,
> + unsigned long initrd_base, unsigned long initrd_size)
> {
> - int cmdlen, len;
> - char str[50], *ptr;
> -
> - ptr = str;
> - strcpy(str, " initrd=");
> - ptr += strlen(str);
> - ultoa(addr, ptr);
> - strcat(str, ",");
> - ptr = str + strlen(str);
> - ultoa(size, ptr);
> - len = strlen(str);
> - cmdlen = strlen(cmdline) + len;
> - if (cmdlen > (COMMAND_LINE_SIZE - 1))
> - die("Command line overflow\n");
> - strcat(cmdline, str);
> + int initrd_strlen;
>
> - return 0;
> + initrd_strlen = sprintf(modified_cmdline + (*cmdline_tmplen), "initrd=0x%lx,0x%lx ",
> + initrd_base, initrd_size);
> + *cmdline_tmplen += initrd_strlen;
> }
>
> -/* Adds the appropriate "mem=size at start" options to command line, indicating the
> - * memory region the new kernel can use to boot into. */
> -static int cmdline_add_mem(char *cmdline, unsigned long addr,
> - unsigned long size)
> +/*
> + * Add the "mem=size at start" command line parameter to command line, indicating the
> + * memory region the new kernel can use to boot into.
> + */
> +static void cmdline_add_mem(unsigned long *cmdline_tmplen, char *modified_cmdline,
> + unsigned long mem_start, unsigned long mem_sz)
> {
> - int cmdlen, len;
> - char str[50], *ptr;
> -
> - addr = addr/1024;
> - size = size/1024;
> - ptr = str;
> - strcpy(str, " mem=");
> - ptr += strlen(str);
> - ultoa(size, ptr);
> - strcat(str, "K@");
> - ptr = str + strlen(str);
> - ultoa(addr, ptr);
> - strcat(str, "K");
> - len = strlen(str);
> - cmdlen = strlen(cmdline) + len;
> - if (cmdlen > (COMMAND_LINE_SIZE - 1))
> - die("Command line overflow\n");
> - strcat(cmdline, str);
> + int mem_strlen = 0;
>
> - return 0;
> + mem_strlen = sprintf(modified_cmdline + (*cmdline_tmplen), "mem=0x%lx at 0x%lx ",
> + mem_sz, mem_start);
> + *cmdline_tmplen += mem_strlen;
> }
Ditto for the mem= param and other similar cases, can this be done out
of the kexec-tools c code? it will be more flexible.
>
> -/* Adds the "elfcorehdr=size at start" command line parameter to command line. */
> -static int cmdline_add_elfcorehdr(char *cmdline, unsigned long addr,
> - unsigned long size)
> +/* Add the "elfcorehdr=size at start" command line parameter to command line. */
> +static void cmdline_add_elfcorehdr(unsigned long *cmdline_tmplen, char *modified_cmdline,
> + unsigned long elfcorehdr_start, unsigned long elfcorehdr_sz)
> {
> - int cmdlen, len;
> - char str[50], *ptr;
> -
> - addr = addr/1024;
> - size = size/1024;
> - ptr = str;
> - strcpy(str, " elfcorehdr=");
> - ptr += strlen(str);
> - ultoa(size, ptr);
> - strcat(str, "K@");
> - ptr = str + strlen(str);
> - ultoa(addr, ptr);
> - strcat(str, "K");
> - len = strlen(str);
> - cmdlen = strlen(cmdline) + len;
> - if (cmdlen > (COMMAND_LINE_SIZE - 1))
> - die("Command line overflow\n");
> - strcat(cmdline, str);
> + int elfcorehdr_strlen = 0;
>
> - return 0;
> + elfcorehdr_strlen = sprintf(modified_cmdline + (*cmdline_tmplen), "elfcorehdr=0x%lx at 0x%lx ",
> + elfcorehdr_sz, elfcorehdr_start);
> + *cmdline_tmplen += elfcorehdr_strlen;
> }
>
> /* Return a sorted list of memory ranges. */
> @@ -329,18 +295,17 @@ int loongarch_load_other_segments(struct kexec_info *info, unsigned long hole_mi
> unsigned long initrd_min, hole_max;
> char *initrd_buf = NULL;
> unsigned long pagesize = getpagesize();
> + unsigned long cmdline_tmplen = 0;
> + char *cmdline = NULL;
> int i;
>
> - if (arch_options.command_line) {
> - if (strlen(arch_options.command_line) >
> - sizeof(cmdline) - 1) {
> - fprintf(stderr,
> - "Kernel command line too long for kernel!\n");
> - return EFAILED;
> - }
> + cmdline = calloc(1, COMMAND_LINE_SIZE);
> + if (!cmdline)
> + return EFAILED;
>
> - strncat(cmdline, arch_options.command_line, sizeof(cmdline) - 1);
> - }
> + /* Ensure it's null terminated */
> + cmdline_add_loader(&cmdline_tmplen, cmdline);
> + cmdline[COMMAND_LINE_SIZE - 1] = '\0';
>
> /* Put the other segments after the image. */
>
> @@ -360,21 +325,29 @@ int loongarch_load_other_segments(struct kexec_info *info, unsigned long hole_mi
> pagesize), hole_max, -1);
> dbgprintf("initrd_base: %lx, initrd_size: %lx\n", initrd_base, initrd_size);
>
> - cmdline_add_initrd(cmdline, initrd_base, initrd_size);
> + cmdline_add_initrd(&cmdline_tmplen, cmdline, initrd_base, initrd_size);
> }
>
> if (info->kexec_flags & KEXEC_ON_CRASH) {
> - cmdline_add_elfcorehdr(cmdline, elfcorehdr_mem.start,
> - elfcorehdr_mem.end - elfcorehdr_mem.start + 1);
> + cmdline_add_elfcorehdr(&cmdline_tmplen, cmdline, elfcorehdr_mem.start,
> + elfcorehdr_mem.end - elfcorehdr_mem.start + 1);
>
> for(i = 0;i < usablemem_rgns.size; i++) {
> - cmdline_add_mem(cmdline, crash_reserved_mem[i].start,
> - crash_reserved_mem[i].end -
> - crash_reserved_mem[i].start + 1);
> + cmdline_add_mem(&cmdline_tmplen, cmdline, crash_reserved_mem[i].start,
> + crash_reserved_mem[i].end - crash_reserved_mem[i].start + 1);
> + }
> + }
> +
> + if (arch_options.command_line) {
> + if (strlen(arch_options.command_line) + cmdline_tmplen > COMMAND_LINE_SIZE) {
> + fprintf(stderr, "Kernel command line too long for kernel!\n");
> + free(cmdline);
> + return EFAILED;
> }
> + memcpy(cmdline + cmdline_tmplen, arch_options.command_line,
> + strlen(arch_options.command_line));
> }
>
> - cmdline[sizeof(cmdline) - 1] = '\0';
> add_buffer(info, cmdline, sizeof(cmdline), sizeof(cmdline),
> sizeof(void *), _ALIGN_UP(hole_min, getpagesize()),
> hole_max, 1);
> @@ -382,7 +355,6 @@ int loongarch_load_other_segments(struct kexec_info *info, unsigned long hole_mi
> dbgprintf("%s:%d: command_line: %s\n", __func__, __LINE__, cmdline);
>
> return 0;
> -
> }
>
> int arch_compat_trampoline(struct kexec_info *UNUSED(info))
> --
> 2.48.1
>
>
More information about the kexec
mailing list