[PATCH 2/2] LoongArch: Refactor command line processing

Youling Tang youling.tang at linux.dev
Wed Sep 24 23:32:41 PDT 2025


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;
+}
 
-/* 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;
 }
 
-/* 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