From 4f96023afd9c6ff97634e334e8f536837c42ea78 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 5 Sep 2020 14:50:51 -0600 Subject: [PATCH] x86: zboot: Allow overriding the command line When booting Chrome OS images the command line is stored separately from the kernel. Add a way to specify this address so that images boot correctly. Also add comments to the zimage.h header. Signed-off-by: Simon Glass Reviewed-by: Wolfgang Wallner Reviewed-by: Bin Meng [bmeng: adjust maxargs to 8 for 'zboot start'] Signed-off-by: Bin Meng --- arch/x86/include/asm/zimage.h | 30 +++++++++++++++++++++++++++++- arch/x86/lib/bootm.c | 2 +- arch/x86/lib/zimage.c | 25 ++++++++++++++++++------- 3 files changed, 48 insertions(+), 9 deletions(-) diff --git a/arch/x86/include/asm/zimage.h b/arch/x86/include/asm/zimage.h index 80e128c..64c0e6e 100644 --- a/arch/x86/include/asm/zimage.h +++ b/arch/x86/include/asm/zimage.h @@ -30,10 +30,38 @@ #define BZIMAGE_LOAD_ADDR 0x100000 #define ZIMAGE_LOAD_ADDR 0x10000 +/** + * load_zimage() - Load a zImage or bzImage + * + * This copies an image into the standard location ready for setup + * + * @image: Address of image to load + * @kernel_size: Size of kernel including setup block (or 0 if the kernel is + * new enough to have a 'syssize' value) + * @load_addressp: Returns the address where the kernel has been loaded + * @return address of setup block, or NULL if something went wrong + */ struct boot_params *load_zimage(char *image, unsigned long kernel_size, ulong *load_addressp); + +/** + * setup_zimage() - Set up a loaded zImage or bzImage ready for booting + * + * @setup_base: Pointer to the boot parameters, typically at address + * DEFAULT_SETUP_BASE + * @cmd_line: Place to put the command line, or NULL to use the one in the setup + * block + * @initrd_addr: Address of the initial ramdisk, or 0 if none + * @initrd_size: Size of the initial ramdisk, or 0 if none + * @load_address: Address where the bzImage is moved before booting, either + * BZIMAGE_LOAD_ADDR or ZIMAGE_LOAD_ADDR + * @cmdline_force: Address of 'override' command line, or 0 to use the one in + * the * setup block + * @return 0 (always) + */ int setup_zimage(struct boot_params *setup_base, char *cmd_line, int auto_boot, - unsigned long initrd_addr, unsigned long initrd_size); + ulong initrd_addr, ulong initrd_size, ulong cmdline_force); + void setup_video(struct screen_info *screen_info); void setup_efi_info(struct efi_info *efi_info); diff --git a/arch/x86/lib/bootm.c b/arch/x86/lib/bootm.c index 1198a52..da6b8ce 100644 --- a/arch/x86/lib/bootm.c +++ b/arch/x86/lib/bootm.c @@ -136,7 +136,7 @@ static int boot_prep_linux(bootm_headers_t *images) printf("Setup at %#08lx\n", images->ep); ret = setup_zimage((void *)images->ep, cmd_line_dest, 0, images->rd_start, - images->rd_end - images->rd_start); + images->rd_end - images->rd_start, 0); if (ret) { printf("## Setting up boot parameters failed ...\n"); diff --git a/arch/x86/lib/zimage.c b/arch/x86/lib/zimage.c index 1a4094a..a00964c 100644 --- a/arch/x86/lib/zimage.c +++ b/arch/x86/lib/zimage.c @@ -56,6 +56,8 @@ * BZIMAGE_LOAD_ADDR or ZIMAGE_LOAD_ADDR * @base_ptr: Pointer to the boot parameters, typically at address * DEFAULT_SETUP_BASE + * @cmdline: Address of 'override' command line, or 0 to use the one in the + * setup block */ struct zboot_state { ulong bzimage_addr; @@ -64,6 +66,7 @@ struct zboot_state { ulong initrd_size; ulong load_address; struct boot_params *base_ptr; + ulong cmdline; } state; enum { @@ -284,7 +287,7 @@ struct boot_params *load_zimage(char *image, unsigned long kernel_size, } int setup_zimage(struct boot_params *setup_base, char *cmd_line, int auto_boot, - unsigned long initrd_addr, unsigned long initrd_size) + ulong initrd_addr, ulong initrd_size, ulong cmdline_force) { struct setup_header *hdr = &setup_base->hdr; int bootproto = get_boot_protocol(hdr, false); @@ -325,7 +328,10 @@ int setup_zimage(struct boot_params *setup_base, char *cmd_line, int auto_boot, } /* build command line at COMMAND_LINE_OFFSET */ - build_command_line(cmd_line, auto_boot); + if (cmdline_force) + strcpy(cmd_line, (char *)cmdline_force); + else + build_command_line(cmd_line, auto_boot); } if (IS_ENABLED(CONFIG_INTEL_MID) && bootproto >= 0x0207) @@ -384,6 +390,8 @@ static int do_zboot_start(struct cmd_tbl *cmdtp, int flag, int argc, state.load_address = state.bzimage_addr; state.bzimage_addr = 0; } + if (argc >= 7) + state.cmdline = simple_strtoul(argv[6], NULL, 16); return 0; } @@ -427,7 +435,8 @@ static int do_zboot_setup(struct cmd_tbl *cmdtp, int flag, int argc, return CMD_RET_FAILURE; } ret = setup_zimage(base_ptr, (char *)base_ptr + COMMAND_LINE_OFFSET, - 0, state.initrd_addr, state.initrd_size); + 0, state.initrd_addr, state.initrd_size, + state.cmdline); if (ret) { puts("Setting up boot parameters failed ...\n"); return CMD_RET_FAILURE; @@ -627,7 +636,7 @@ int do_zboot_dump(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) if (hdr->cmd_line_ptr) { printf(" "); /* Use puts() to avoid limits from CONFIG_SYS_PBSIZE */ - puts((char *)hdr->cmd_line_ptr); + puts((char *)(ulong)hdr->cmd_line_ptr); printf("\n"); } print_num("Initrd addr max", hdr->initrd_addr_max); @@ -655,7 +664,7 @@ int do_zboot_dump(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) /* Note: This defines the complete_zboot() function */ U_BOOT_SUBCMDS(zboot, - U_BOOT_CMD_MKENT(start, 7, 1, do_zboot_start, "", ""), + U_BOOT_CMD_MKENT(start, 8, 1, do_zboot_start, "", ""), U_BOOT_CMD_MKENT(load, 1, 1, do_zboot_load, "", ""), U_BOOT_CMD_MKENT(setup, 1, 1, do_zboot_setup, "", ""), U_BOOT_CMD_MKENT(info, 1, 1, do_zboot_info, "", ""), @@ -707,8 +716,8 @@ int do_zboot_parent(struct cmd_tbl *cmdtp, int flag, int argc, } U_BOOT_CMDREP_COMPLETE( - zboot, 7, do_zboot_parent, "Boot bzImage", - "[addr] [size] [initrd addr] [initrd size] [setup]\n" + zboot, 8, do_zboot_parent, "Boot bzImage", + "[addr] [size] [initrd addr] [initrd size] [setup] [cmdline]\n" " addr - The optional starting address of the bzimage.\n" " If not set it defaults to the environment\n" " variable \"fileaddr\".\n" @@ -718,6 +727,8 @@ U_BOOT_CMDREP_COMPLETE( " initrd size - The size of the initrd image to use, if any.\n" " setup - The address of the kernel setup region, if this\n" " is not at addr\n" + " cmdline - The address of the kernel command line, to\n" + " override U-Boot's normal cmdline generation\n" "\n" "Sub-commands to do part of the zboot sequence:\n" "\tstart [addr [arg ...]] - specify arguments\n" -- 2.7.4