diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index a091bd7a57..c55dc521d2 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -1146,6 +1146,7 @@ config ARCH_ROCKCHIP select SYS_NS16550 select SPI select DEBUG_UART_BOARD_INIT + select PANIC_HANG imply CMD_FASTBOOT imply FASTBOOT imply FAT_WRITE diff --git a/arch/arm/mach-rockchip/board.c b/arch/arm/mach-rockchip/board.c index c8ffb9681a..f008072716 100644 --- a/arch/arm/mach-rockchip/board.c +++ b/arch/arm/mach-rockchip/board.c @@ -311,6 +311,9 @@ static void board_debug_init(void) if (gd->console_evt <= 0x1a) /* 'z' */ printf("Hotkey: ctrl+%c\n", gd->console_evt + 'a' - 1); } + + if (IS_ENABLED(CONFIG_CONSOLE_DISABLE_CLI)) + printf("CLI: off\n"); } int board_init(void) @@ -754,3 +757,15 @@ int board_do_bootm(int argc, char * const argv[]) return 0; } #endif + +void autoboot_command_fail_handle(void) +{ +#ifdef CONFIG_AVB_VBMETA_PUBLIC_KEY_VALIDATE +#ifdef CONFIG_ANDROID_AB + run_command("fastboot usb 0;", 0); /* use fastboot to ative slot */ +#else + run_command("rockusb 0 ${devtype} ${devnum}", 0); + run_command("fastboot usb 0;", 0); +#endif +#endif +} diff --git a/arch/arm/mach-rockchip/fit.c b/arch/arm/mach-rockchip/fit.c index fbfda43d1a..1e442df05c 100644 --- a/arch/arm/mach-rockchip/fit.c +++ b/arch/arm/mach-rockchip/fit.c @@ -13,7 +13,7 @@ DECLARE_GLOBAL_DATA_PTR; -#define FIT_PLACEHOLDER_ADDR 0xffffffff +#define FIT_PLACEHOLDER_ADDR 0xffffff00 /* * Must use args '-E -p' for mkimage to generate FIT image, 4K as max assumption. @@ -30,6 +30,11 @@ static int fit_is_signed(void *fit, const void *sig_blob) return fdt_subnode_offset(sig_blob, 0, FIT_SIG_NODENAME) < 0 ? 0 : 1; } +static inline int fit_is_placeholder_addr(ulong addr) +{ + return (addr & 0xffffff00) == FIT_PLACEHOLDER_ADDR; +} + static int fit_is_required(void *fit, const void *sig_blob) { int sig_node; @@ -84,7 +89,7 @@ int fit_fixup_load_entry(void *fit, int images, int defconf, int uname_cfg; int err; - if ((*load != FIT_PLACEHOLDER_ADDR) || + if (!fit_is_placeholder_addr(*load) || fit_is_required(fit, gd_fdt_blob())) return 0; diff --git a/arch/arm/mach-rockchip/hotkey.c b/arch/arm/mach-rockchip/hotkey.c index 2bed1cc188..37a03df862 100644 --- a/arch/arm/mach-rockchip/hotkey.c +++ b/arch/arm/mach-rockchip/hotkey.c @@ -34,10 +34,9 @@ bool is_hotkey(enum hotkey_t id) return gd->console_evt == CTRL_R; case HK_SYSMEM: return gd->console_evt == CTRL_M; -#if defined(CONFIG_CONSOLE_DISABLE_CTRLC) && \ - defined(CONFIG_BOOTDELAY) && (CONFIG_BOOTDELAY <= 0) case HK_BROM_DNL: return gd->console_evt == CTRL_B; +#ifndef CONFIG_CONSOLE_DISABLE_CLI case HK_ROCKUSB_DNL: return gd->console_evt == CTRL_D; case HK_FASTBOOT: @@ -71,8 +70,6 @@ void hotkey_run(enum hotkey_t id) if (gd->console_evt == CTRL_T) run_command("fdt print", 0); break; -#if defined(CONFIG_CONSOLE_DISABLE_CTRLC) && \ - defined(CONFIG_BOOTDELAY) && (CONFIG_BOOTDELAY <= 0) case HK_CLI_OS_PRE: if (gd->console_evt == CTRL_A) cli_loop(); @@ -81,7 +78,6 @@ void hotkey_run(enum hotkey_t id) if (gd->console_evt == CTRL_S) cli_loop(); break; -#endif default: break; } diff --git a/arch/arm/mach-rockchip/kernel_arm.its b/arch/arm/mach-rockchip/kernel_arm.its new file mode 100644 index 0000000000..e717ccea08 --- /dev/null +++ b/arch/arm/mach-rockchip/kernel_arm.its @@ -0,0 +1,82 @@ +/* + * Copyright (C) 2020 Fuzhou Rockchip Electronics Co., Ltd + * + * Minimal dts for a FIT image. + * + * SPDX-License-Identifier: GPL-2.0 + */ + +/dts-v1/; +/ { + description = "U-Boot FIT source file for arm"; + #address-cells = <1>; + + images { + fdt@1 { + description = "Device tree blob for arm"; + data = /incbin/("images/rk-kernel.dtb"); + type = "flat_dt"; + arch = "arm"; + compression = "none"; + load = <0xffffff00>; + hash@1 { + algo = "sha256"; + }; + }; + + kernel@1 { + description = "Kernel for arm"; + data = /incbin/("images/kernel.img"); + type = "kernel"; + arch = "arm"; + os = "linux"; + compression = "none"; + entry = <0xffffff01>; + load = <0xffffff01>; + hash@1 { + algo = "sha256"; + }; + }; + + ramdisk@1 { + description = "Ramdisk for arm"; + data = /incbin/("images/ramdisk.img"); + type = "ramdisk"; + arch = "arm"; + os = "linux"; + compression = "none"; + load = <0xffffff02>; + hash@1 { + algo = "sha256"; + }; + }; + + resource@1 { + description = "Resource for arm"; + data = /incbin/("images/resource.img"); + type = "multi"; + arch = "arm"; + compression = "none"; + hash@1 { + algo = "sha256"; + }; + }; + }; + + configurations { + default = "conf@1"; + conf@1 { + description = "Boot Linux kernel with FDT blob"; + conf-version = <1>; + fdt = "fdt@1"; + kernel = "kernel@1"; + ramdisk = "ramdisk@1"; + multi = "resource@1"; + signature@1 { + algo = "sha256,rsa2048"; + key-name-hint = "dev"; + sign-images = "fdt", "kernel", "ramdisk", "multi"; + }; + }; + }; +}; diff --git a/arch/arm/mach-rockchip/kernel_arm64.its b/arch/arm/mach-rockchip/kernel_arm64.its new file mode 100644 index 0000000000..06ee7997d4 --- /dev/null +++ b/arch/arm/mach-rockchip/kernel_arm64.its @@ -0,0 +1,83 @@ +/* + * Copyright (C) 2020 Fuzhou Rockchip Electronics Co., Ltd + * + * Minimal dts for a FIT image. + * + * SPDX-License-Identifier: GPL-2.0 + */ + +/dts-v1/; +/ { + description = "U-Boot FIT source file for arm64"; + #address-cells = <1>; + + images { + fdt@1 { + description = "Device tree blob for arm64"; + data = /incbin/("images/rk-kernel.dtb"); + type = "flat_dt"; + arch = "arm64"; + compression = "none"; + load = <0xffffff00>; + hash@1 { + algo = "sha256"; + }; + }; + + kernel@1 { + description = "Kernel for arm64"; + kernel-version = <1>; + data = /incbin/("images/kernel.img"); + type = "kernel"; + arch = "arm64"; + os = "linux"; + compression = "none"; + entry = <0xffffff01>; + load = <0xffffff01>; + hash@1 { + algo = "sha256"; + }; + }; + + ramdisk@1 { + description = "Ramdisk for arm64"; + data = /incbin/("images/ramdisk.img"); + type = "ramdisk"; + arch = "arm64"; + os = "linux"; + compression = "none"; + load = <0xffffff02>; + hash@1 { + algo = "sha256"; + }; + }; + + resource@1 { + description = "Resource for arm64"; + data = /incbin/("images/resource.img"); + type = "multi"; + arch = "arm64"; + compression = "none"; + hash@1 { + algo = "sha256"; + }; + }; + }; + + configurations { + default = "conf@1"; + conf@1 { + description = "Boot Linux kernel with FDT blob"; + conf-version = <1>; + fdt = "fdt@1"; + kernel = "kernel@1"; + ramdisk = "ramdisk@1"; + multi = "resource@1"; + signature@1 { + algo = "sha256,rsa2048"; + key-name-hint = "dev"; + sign-images = "fdt", "kernel", "ramdisk", "multi"; + }; + }; + }; +}; diff --git a/arch/arm/mach-rockchip/make_fit_atf.py b/arch/arm/mach-rockchip/make_fit_atf.py index 5f832e7538..9f54fcbb82 100755 --- a/arch/arm/mach-rockchip/make_fit_atf.py +++ b/arch/arm/mach-rockchip/make_fit_atf.py @@ -91,6 +91,7 @@ def append_fdt_node(file, dtbs): print >> file, '\t\t\tdescription = "U-Boot device tree blob";' print >> file, '\t\t\tdata = /incbin/("u-boot.dtb");' print >> file, '\t\t\ttype = "flat_dt";' + print >> file, '\t\t\tarch = "arm64";' print >> file, '\t\t\tcompression = "none";' print >> file, '\t\t\thash@1 {' print >> file, '\t\t\t\talgo = "sha256";' @@ -101,7 +102,7 @@ def append_fdt_node(file, dtbs): def append_conf_section(file, cnt, dtname, atf_cnt): print >> file, '\t\tconfig@%d {' % cnt - print >> file, '\t\t\tdescription = "%s";' % dtname + print >> file, '\t\t\tdescription = "Rockchip armv8 with ATF";' print >> file, '\t\t\tfirmware = "atf@1";' print >> file, '\t\t\tloadables = "uboot@1",', for i in range(1, atf_cnt): diff --git a/arch/arm/mach-rockchip/make_fit_optee.sh b/arch/arm/mach-rockchip/make_fit_optee.sh index f91c31e544..94dd87f54f 100755 --- a/arch/arm/mach-rockchip/make_fit_optee.sh +++ b/arch/arm/mach-rockchip/make_fit_optee.sh @@ -25,12 +25,14 @@ EOF OUTDIR=$PWD DARM_BASE=`sed -n "/CONFIG_SYS_SDRAM_BASE=/s/CONFIG_SYS_SDRAM_BASE=//p" ${OUTDIR}/include/autoconf.mk|tr -d '\r'` -UBOOT_OFFSET=0x00200000 +UBOOT_OFFSET=`sed -n "/CONFIG_SYS_TEXT_BASE=/s/CONFIG_SYS_TEXT_BASE=//p" ${OUTDIR}/include/autoconf.mk|tr -d '\r'` UBOOT_BASE=$((DARM_BASE+UBOOT_OFFSET)) UBOOT_BASE=$(echo "obase=16;${UBOOT_BASE}"|bc) echo " load = <0x"$UBOOT_BASE">;" - cat << EOF + hash@1 { + algo = "sha256"; + }; }; optee@1 { description = "OP-TEE"; @@ -46,14 +48,19 @@ TEE_LOAD_ADDR=$((DARM_BASE+TEE_OFFSET)) TEE_LOAD_ADDR=$(echo "obase=16;${TEE_LOAD_ADDR}"|bc) echo " load = <0x"$TEE_LOAD_ADDR">;" echo " entry = <0x"$TEE_LOAD_ADDR">;" - cat << EOF + hash@1 { + algo = "sha256"; + }; }; fdt@1 { - description = "dtb"; + description = "U-Boot dtb"; data = /incbin/("./u-boot.dtb"); type = "flat_dt"; compression = "none"; + hash@1 { + algo = "sha256"; + }; }; }; @@ -64,6 +71,11 @@ cat << EOF firmware = "optee@1"; loadables = "uboot@1"; fdt = "fdt@1"; + signature@1 { + algo = "sha256,rsa2048"; + key-name-hint = "dev"; + sign-images = "fdt", "firmware", "loadables"; + }; }; }; }; diff --git a/cmd/bootfit.c b/cmd/bootfit.c index 8bbf8b114a..c3250a8392 100644 --- a/cmd/bootfit.c +++ b/cmd/bootfit.c @@ -75,17 +75,17 @@ static int do_boot_fit(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]) if (!fit) { FIT_I("No FIT image\n"); - return -EBADF; + goto out; } if (fdt_check_header(fit)) { FIT_I("Invalid FIT format\n"); - return -EBADF; + goto out; } /* reserve memory to avoid memory overlap and fixup entry & load !! */ if (fit_image_fixup_and_sysmem_rsv(fit)) - return -ENOMEM; + goto out; env_set("bootm-no-reloc", "y"); snprintf(fit_addr, sizeof(fit_addr), "0x%lx", (ulong)fit); @@ -103,10 +103,14 @@ static int do_boot_fit(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]) BOOTM_STATE_OS_PREP | BOOTM_STATE_OS_FAKE_GO | BOOTM_STATE_OS_GO, &images, 1); - if (ret && argc != 1) + if (ret && argc != 1) { fit_sysmem_free_each(fit); + ret = -1; + } return ret; +out: + return -1; } U_BOOT_CMD( diff --git a/cmd/bootuimage.c b/cmd/bootuimage.c index 4be0cf1c68..1b4122c02d 100644 --- a/cmd/bootuimage.c +++ b/cmd/bootuimage.c @@ -70,11 +70,11 @@ static int do_boot_uimage(cmd_tbl_t *cmdtp, int flag, if (!img) { UIMG_I("Failed to load multi images\n"); - return -EINVAL; + goto out; } if (uimage_sysmem_reserve_each(img, &ramdisk_sz)) - return -ENOMEM; + goto out; snprintf(uimg_addr, sizeof(uimg_addr), "0x%lx", (ulong)img); bootm_args[0] = uimg_addr; @@ -91,10 +91,14 @@ static int do_boot_uimage(cmd_tbl_t *cmdtp, int flag, BOOTM_STATE_OS_PREP | BOOTM_STATE_OS_FAKE_GO | BOOTM_STATE_OS_GO, &images, 1); - if (ret && argc != 1) + if (ret && argc != 1) { uimage_sysmem_free_each(img, ramdisk_sz); + ret = -1; + } return ret; +out: + return -1; } U_BOOT_CMD( diff --git a/common/Kconfig b/common/Kconfig index 1a005b1722..4a76d02ad5 100644 --- a/common/Kconfig +++ b/common/Kconfig @@ -250,10 +250,12 @@ config CONSOLE_RECORD_IN_SIZE The buffer is allocated immediately after the malloc() region is ready. -config CONSOLE_DISABLE_CTRLC +config CONSOLE_DISABLE_CLI bool "disable ctrlc" + depends on BOOTDELAY = 0 + default y if AVB_VBMETA_PUBLIC_KEY_VALIDATE || FIT_SIGNATURE help - This disable ctrl+c when CONFIG_BOOTDELAY is 0. + This disable CLI interactive in verified-boot. config DISABLE_CONSOLE bool "disable console in & out" diff --git a/common/autoboot.c b/common/autoboot.c index d30d4e6701..760f44cf34 100644 --- a/common/autoboot.c +++ b/common/autoboot.c @@ -220,7 +220,7 @@ static int __abortboot(int bootdelay) #endif #ifdef CONFIG_ARCH_ROCKCHIP - if (ctrlc()) { /* we press ctrl+c ? */ + if (!IS_ENABLED(CONFIG_CONSOLE_DISABLE_CLI) && ctrlc()) { /* we press ctrl+c ? */ #else /* * Check if key already pressed diff --git a/common/bootm.c b/common/bootm.c index 79ea87bb94..afb01b9238 100644 --- a/common/bootm.c +++ b/common/bootm.c @@ -30,6 +30,10 @@ #include #include +#ifdef USE_HOSTCC +#define CONFIG_SYS_BOOTM_LEN 0x4000000 +#endif + #ifndef CONFIG_SYS_BOOTM_LEN /* use 8MByte as default max gunzip size */ #define CONFIG_SYS_BOOTM_LEN 0x800000 @@ -350,7 +354,8 @@ static int handle_decomp_error(int comp_type, size_t uncomp_size, const char *name = genimg_get_comp_name(comp_type); if (uncomp_size >= unc_len) - printf("Image too large: increase CONFIG_SYS_BOOTM_LEN\n"); + printf("Image too large(0x%lx >= 0x%lx): increase CONFIG_SYS_BOOTM_LEN\n", + (ulong)uncomp_size, (ulong)unc_len); else printf("%s: uncompress error %d\n", name, ret); @@ -978,7 +983,7 @@ void memmove_wd(void *to, void *from, size_t len, ulong chunksz) memmove(to, from, len); } -static int bootm_host_load_image(const void *fit, int req_image_type) +static int bootm_host_load_image(const void *fit, int req_image_type, int index) { const char *fit_uname_config = NULL; ulong data, len; @@ -992,9 +997,9 @@ static int bootm_host_load_image(const void *fit, int req_image_type) memset(&images, '\0', sizeof(images)); images.verify = 1; - noffset = fit_image_load(&images, (ulong)fit, + noffset = fit_image_load_index(&images, (ulong)fit, NULL, &fit_uname_config, - IH_ARCH_DEFAULT, req_image_type, -1, + IH_ARCH_DEFAULT, req_image_type, index, -1, FIT_LOAD_IGNORED, &data, &len); if (noffset < 0) return noffset; @@ -1021,20 +1026,42 @@ static int bootm_host_load_image(const void *fit, int req_image_type) return 0; } -int bootm_host_load_images(const void *fit, int cfg_noffset) +int bootm_host_load_images(const void *fit, int cfg_noffset, int is_spl) { static uint8_t image_types[] = { IH_TYPE_KERNEL, IH_TYPE_FLATDT, IH_TYPE_RAMDISK, }; + static uint8_t image_types_spl[] = { + IH_TYPE_FLATDT, + IH_TYPE_FIRMWARE, + IH_TYPE_LOADABLE, + IH_TYPE_LOADABLE, + IH_TYPE_LOADABLE, + }; + int loadable_index = 0; int err = 0; + int index; int i; - for (i = 0; i < ARRAY_SIZE(image_types); i++) { + for (i = 0; !is_spl && i < ARRAY_SIZE(image_types); i++) { int ret; - ret = bootm_host_load_image(fit, image_types[i]); + ret = bootm_host_load_image(fit, image_types[i], 0); + if (!err && ret && ret != -ENOENT) + err = ret; + } + + for (i = 0; is_spl && i < ARRAY_SIZE(image_types_spl); i++) { + int ret; + + if (image_types_spl[i] == IH_TYPE_LOADABLE) + index = loadable_index++; + else + index = 0; + + ret = bootm_host_load_image(fit, image_types_spl[i], index); if (!err && ret && ret != -ENOENT) err = ret; } diff --git a/common/cli.c b/common/cli.c index 57874d8797..a96db7e3e1 100644 --- a/common/cli.c +++ b/common/cli.c @@ -212,6 +212,7 @@ err: } #endif /* CONFIG_IS_ENABLED(OF_CONTROL) */ +#ifndef CONFIG_CONSOLE_DISABLE_CLI void cli_loop(void) { #ifdef CONFIG_HUSH_PARSER @@ -224,6 +225,9 @@ void cli_loop(void) printf("## U-Boot command line is disabled. Please enable CONFIG_CMDLINE\n"); #endif /*CONFIG_HUSH_PARSER*/ } +#else +void cli_loop(void) { } +#endif void cli_init(void) { diff --git a/common/console.c b/common/console.c index 3e96261ad7..f399024397 100644 --- a/common/console.c +++ b/common/console.c @@ -655,11 +655,6 @@ static int ctrlc_disabled = 0; /* see disable_ctrl() */ static int ctrlc_was_pressed = 0; int ctrlc(void) { -#if defined(CONFIG_CONSOLE_DISABLE_CTRLC) && \ - defined(CONFIG_BOOTDELAY) && (CONFIG_BOOTDELAY <= 0) - return 0; -#endif - #ifndef CONFIG_SANDBOX if (!ctrlc_disabled && gd->have_console) { if (tstc()) { diff --git a/common/image-fit.c b/common/image-fit.c index 40035c765b..1834950505 100644 --- a/common/image-fit.c +++ b/common/image-fit.c @@ -1799,6 +1799,8 @@ static const char *fit_get_image_type_property(int type) return FIT_KERNEL_PROP; case IH_TYPE_RAMDISK: return FIT_RAMDISK_PROP; + case IH_TYPE_FIRMWARE: + return FIT_FIRMWARE_PROP; case IH_TYPE_X86_SETUP: return FIT_SETUP_PROP; case IH_TYPE_LOADABLE: @@ -1810,10 +1812,10 @@ static const char *fit_get_image_type_property(int type) return "unknown"; } -int fit_image_load(bootm_headers_t *images, ulong addr, - const char **fit_unamep, const char **fit_uname_configp, - int arch, int image_type, int bootstage_id, - enum fit_load_op load_op, ulong *datap, ulong *lenp) +int fit_image_load_index(bootm_headers_t *images, ulong addr, + const char **fit_unamep, const char **fit_uname_configp, + int arch, int image_type, int image_index, int bootstage_id, + enum fit_load_op load_op, ulong *datap, ulong *lenp) { int cfg_noffset, noffset; const char *fit_uname; @@ -1886,8 +1888,8 @@ int fit_image_load(bootm_headers_t *images, ulong addr, bootstage_mark(BOOTSTAGE_ID_FIT_CONFIG); } - noffset = fit_conf_get_prop_node(fit, cfg_noffset, - prop_name); + noffset = fit_conf_get_prop_node_index(fit, cfg_noffset, + prop_name, image_index); fit_uname = fit_get_name(fit, noffset, NULL); } if (noffset < 0) { @@ -1933,6 +1935,8 @@ int fit_image_load(bootm_headers_t *images, ulong addr, os_ok = image_type == IH_TYPE_FLATDT || image_type == IH_TYPE_FPGA || fit_image_check_os(fit, noffset, IH_OS_LINUX) || + fit_image_check_os(fit, noffset, IH_OS_ARM_TRUSTED_FIRMWARE) || + fit_image_check_os(fit, noffset, IH_OS_OP_TEE) || fit_image_check_os(fit, noffset, IH_OS_U_BOOT) || fit_image_check_os(fit, noffset, IH_OS_OPENRTOS); @@ -2034,6 +2038,16 @@ int fit_image_load(bootm_headers_t *images, ulong addr, return noffset; } +int fit_image_load(bootm_headers_t *images, ulong addr, + const char **fit_unamep, const char **fit_uname_configp, + int arch, int image_type, int bootstage_id, + enum fit_load_op load_op, ulong *datap, ulong *lenp) +{ + return fit_image_load_index(images, addr,fit_unamep, fit_uname_configp, + arch, image_type, 0, bootstage_id, + load_op, datap, lenp); +} + int boot_get_setup_fit(bootm_headers_t *images, uint8_t arch, ulong *setup_start, ulong *setup_len) { diff --git a/common/image.c b/common/image.c index 985127f8ea..4134ac80d7 100644 --- a/common/image.c +++ b/common/image.c @@ -192,6 +192,26 @@ static const struct table_info table_info[IH_COUNT] = { /*****************************************************************************/ /* Legacy format routines */ /*****************************************************************************/ +#ifndef USE_HOSTCC +#ifndef CONFIG_SPL_BUILD +uint32_t image_get_load(const image_header_t *hdr) +{ + uint32_t load = uimage_to_cpu(hdr->ih_load); + + return (load == IMAGE_PARAM_INVAL) ? + env_get_ulong("kernel_addr_r", 16, 0) : load; +} + +uint32_t image_get_ep(const image_header_t *hdr) +{ + uint32_t ep = uimage_to_cpu(hdr->ih_ep); + + return (ep == IMAGE_PARAM_INVAL) ? + env_get_ulong("kernel_addr_r", 16, 0) : ep; +} +#endif +#endif + int image_check_hcrc(const image_header_t *hdr) { ulong hcrc; @@ -239,7 +259,7 @@ ulong image_multi_count(const image_header_t *hdr) size = (uint32_t *)image_get_data(hdr); /* count non empty slots */ - for (i = 0; size[i]; ++i) + for (i = 0; size[i] != IMAGE_PARAM_INVAL; ++i) count++; return count; diff --git a/common/main.c b/common/main.c index 6a1159879e..225d06967b 100644 --- a/common/main.c +++ b/common/main.c @@ -20,6 +20,12 @@ DECLARE_GLOBAL_DATA_PTR; */ __weak void show_boot_progress(int val) {} +/* + * Board-specific Platform code can reimplement autoboot_command_fail_handle () + * if needed + */ +__weak void autoboot_command_fail_handle(void) {} + static void run_preboot_environment_command(void) { #ifdef CONFIG_PREBOOT @@ -64,6 +70,7 @@ void main_loop(void) cli_secure_boot_cmd(s); autoboot_command(s); + autoboot_command_fail_handle(); cli_loop(); panic("No CLI available"); diff --git a/include/bootm.h b/include/bootm.h index 19c3ad9d8a..2274ab5350 100644 --- a/include/bootm.h +++ b/include/bootm.h @@ -41,7 +41,7 @@ void lynxkdi_boot(image_header_t *hdr); boot_os_fn *bootm_os_get_boot_func(int os); -int bootm_host_load_images(const void *fit, int cfg_noffset); +int bootm_host_load_images(const void *fit, int cfg_noffset, int is_spl); int boot_selected_os(int argc, char * const argv[], int state, bootm_headers_t *images, boot_os_fn *boot_fn); diff --git a/include/common.h b/include/common.h index 9a2e2c8b4b..b6b8c374fe 100644 --- a/include/common.h +++ b/include/common.h @@ -103,6 +103,7 @@ int cpu_init(void); /* common/main.c */ void main_loop (void); +void autoboot_command_fail_handle(void); int run_command(const char *cmd, int flag); int run_command_repeatable(const char *cmd, int flag); diff --git a/include/configs/rockchip-common.h b/include/configs/rockchip-common.h index 16b63a2266..591bcb46d3 100644 --- a/include/configs/rockchip-common.h +++ b/include/configs/rockchip-common.h @@ -133,33 +133,17 @@ "setenv devtype spinor; setenv devnum 1;" \ "fi; \0" -#ifdef CONFIG_AVB_VBMETA_PUBLIC_KEY_VALIDATE -#ifndef CONFIG_ANDROID_AB -#define RKIMG_BOOTCOMMAND \ - "boot_android ${devtype} ${devnum};" \ - "echo AVB boot failed and enter rockusb or fastboot!;" \ - "rockusb 0 ${devtype} ${devnum};" \ - "fastboot usb 0;" +#if defined(CONFIG_AVB_VBMETA_PUBLIC_KEY_VALIDATE) +#define RKIMG_BOOTCOMMAND \ + "boot_android ${devtype} ${devnum};" #else -/* - * Update images a/b and active slot with fastboot - * when avb+ab system boot failed. - * Remove rockusb since it unable to active slot. - */ -#define RKIMG_BOOTCOMMAND \ - "boot_android ${devtype} ${devnum};" \ - "echo AVB boot failed and enter fastboot!;" \ - "fastboot usb 0;" -#endif /* CONFIG_ANDROID_AB */ -#else /* CONFIG_AVB_VBMETA_PUBLIC_KEY_VALIDATE */ -#define RKIMG_BOOTCOMMAND \ - "boot_android ${devtype} ${devnum};" \ - "bootrkp;" \ - "boot_fit;" \ - "boot_uimage;" \ +#define RKIMG_BOOTCOMMAND \ + "boot_android ${devtype} ${devnum};" \ + "bootrkp;" \ "run distro_bootcmd;" #endif -#endif + +#endif /* CONFIG_SPL_BUILD */ #define CONFIG_DISPLAY_BOARDINFO_LATE diff --git a/include/image.h b/include/image.h index c0e6b1a727..4d877b84d1 100644 --- a/include/image.h +++ b/include/image.h @@ -656,6 +656,11 @@ int fit_image_load(bootm_headers_t *images, ulong addr, int arch, int image_type, int bootstage_id, enum fit_load_op load_op, ulong *datap, ulong *lenp); +int fit_image_load_index(bootm_headers_t *images, ulong addr, + const char **fit_unamep, const char **fit_uname_configp, + int arch, int image_type, int image_index, int bootstage_id, + enum fit_load_op load_op, ulong *datap, ulong *lenp); + #ifndef USE_HOSTCC /** * fit_get_node_from_config() - Look up an image a FIT by type @@ -709,6 +714,8 @@ int boot_get_kbd(struct lmb *lmb, bd_t **kbd); /*******************************************************************/ /* Legacy format specific code (prefixed with image_) */ /*******************************************************************/ +#define IMAGE_PARAM_INVAL 0xffffffff + static inline uint32_t image_get_header_size(void) { return (sizeof(image_header_t)); @@ -723,9 +730,17 @@ image_get_hdr_l(magic) /* image_get_magic */ image_get_hdr_l(hcrc) /* image_get_hcrc */ image_get_hdr_l(time) /* image_get_time */ image_get_hdr_l(size) /* image_get_size */ +image_get_hdr_l(dcrc) /* image_get_dcrc */ +#ifdef USE_HOSTCC image_get_hdr_l(load) /* image_get_load */ image_get_hdr_l(ep) /* image_get_ep */ -image_get_hdr_l(dcrc) /* image_get_dcrc */ +#elif defined(CONFIG_SPL_BUILD) +image_get_hdr_l(load) /* image_get_load */ +image_get_hdr_l(ep) /* image_get_ep */ +#else +uint32_t image_get_load(const image_header_t *hdr); +uint32_t image_get_ep(const image_header_t *hdr); +#endif #define image_get_hdr_b(f) \ static inline uint8_t image_get_##f(const image_header_t *hdr) \ diff --git a/include/u-boot/rsa.h b/include/u-boot/rsa.h index 0e96c38711..a7d361ef83 100644 --- a/include/u-boot/rsa.h +++ b/include/u-boot/rsa.h @@ -82,7 +82,7 @@ static inline int rsa_add_verify_data(struct image_sign_info *info, } #endif -#if IMAGE_ENABLE_VERIFY +#if IMAGE_ENABLE_VERIFY || defined(CONFIG_SPL_FIT_SIGNATURE) /** * rsa_verify() - Verify a signature against some data * diff --git a/lib/avb/libavb_user/Kconfig b/lib/avb/libavb_user/Kconfig index 6a5a307d4a..33dff1bc79 100755 --- a/lib/avb/libavb_user/Kconfig +++ b/lib/avb/libavb_user/Kconfig @@ -9,7 +9,6 @@ config AVB_LIBAVB_USER config AVB_VBMETA_PUBLIC_KEY_VALIDATE bool "Support vbmeta public key validate" depends on AVB_LIBAVB_USER - select CONSOLE_DISABLE_CTRLC help support vbmeta public key validate, system bootflow would be uninterruptale when it is enabled: diff --git a/scripts/setlocalversion b/scripts/setlocalversion index 8564bedd1a..a3014ca5b6 100755 --- a/scripts/setlocalversion +++ b/scripts/setlocalversion @@ -59,7 +59,9 @@ scm_version() # If we are past a tagged commit (like # "v2.6.30-rc5-302-g72357d5"), we pretty print it. if atag="`git describe 2>/dev/null`"; then - echo "$atag" | awk -F- '{printf("-%05d-%s", $(NF-1),$(NF))}' + echo "$atag" | awk -F- '{printf("-%s", $(NF))}' + date=`git log -1 --author='@rock-chips' --date=format:%y%m%d | sed -n '/Date:/p' | awk '{ print "-"$2 }'` + printf '%s' $date # If we don't have a tag at all we print -g{commitish}. else @@ -77,6 +79,8 @@ scm_version() printf '%s' -dirty fi + printf ' \#%s' $USER + # All done with git return fi diff --git a/tools/fdt_host.h b/tools/fdt_host.h index 98acf278a3..d962368c12 100644 --- a/tools/fdt_host.h +++ b/tools/fdt_host.h @@ -28,6 +28,6 @@ */ int fdt_remove_unused_strings(const void *old, void *new); -int fit_check_sign(const void *working_fdt, const void *key); +int fit_check_sign(const void *working_fdt, const void *key, int is_spl); #endif /* __FDT_HOST_H__ */ diff --git a/tools/fit_check_sign.c b/tools/fit_check_sign.c index d9361b0095..06d3f08b3e 100644 --- a/tools/fit_check_sign.c +++ b/tools/fit_check_sign.c @@ -46,10 +46,11 @@ int main(int argc, char **argv) int ret; void *key_blob; int c; + int is_spl = 0; strncpy(cmdname, *argv, sizeof(cmdname) - 1); cmdname[sizeof(cmdname) - 1] = '\0'; - while ((c = getopt(argc, argv, "f:k:")) != -1) + while ((c = getopt(argc, argv, "f:k:s")) != -1) switch (c) { case 'f': fdtfile = optarg; @@ -57,6 +58,9 @@ int main(int argc, char **argv) case 'k': keyfile = optarg; break; + case 's': + is_spl = 1; + break; default: usage(cmdname); break; @@ -79,7 +83,7 @@ int main(int argc, char **argv) return EXIT_FAILURE; image_set_host_blob(key_blob); - ret = fit_check_sign(fit_blob, key_blob); + ret = fit_check_sign(fit_blob, key_blob, is_spl); if (!ret) { ret = EXIT_SUCCESS; fprintf(stderr, "Signature check OK\n"); diff --git a/tools/image-host.c b/tools/image-host.c index 5d31044558..7208df5c16 100644 --- a/tools/image-host.c +++ b/tools/image-host.c @@ -728,7 +728,7 @@ int fit_add_verification_data(const char *keydir, void *keydest, void *fit, } #ifdef CONFIG_FIT_SIGNATURE -int fit_check_sign(const void *fit, const void *key) +int fit_check_sign(const void *fit, const void *key, int is_spl) { int cfg_noffset; int ret; @@ -741,7 +741,7 @@ int fit_check_sign(const void *fit, const void *key) ret = fit_config_verify(fit, cfg_noffset); if (ret) return ret; - ret = bootm_host_load_images(fit, cfg_noffset); + ret = bootm_host_load_images(fit, cfg_noffset, is_spl); return ret; } diff --git a/tools/imagetool.h b/tools/imagetool.h index ac8f7d71ec..e4765af490 100644 --- a/tools/imagetool.h +++ b/tools/imagetool.h @@ -233,6 +233,7 @@ time_t imagetool_get_source_date( void pbl_load_uboot(int fd, struct image_tool_params *mparams); +int rockchip_copy_image(int fd, struct image_tool_params *mparams); #define ___cat(a, b) a ## b #define __cat(a, b) ___cat(a, b) diff --git a/tools/mkimage.c b/tools/mkimage.c index ffc91d2319..fce304f400 100644 --- a/tools/mkimage.c +++ b/tools/mkimage.c @@ -479,7 +479,7 @@ int main(int argc, char **argv) } size = cpu_to_uimage (sbuf.st_size); } else { - size = 0; + size = IMAGE_PARAM_INVAL; } if (write(ifd, (char *)&size, sizeof(size)) != sizeof(size)) { @@ -518,6 +518,15 @@ int main(int argc, char **argv) } else if (params.type == IH_TYPE_PBLIMAGE) { /* PBL has special Image format, implements its' own */ pbl_load_uboot(ifd, ¶ms); + } else if ((params.type == IH_TYPE_RKSD) || + (params.type == IH_TYPE_RKSPI) || + (params.type == IH_TYPE_RKNAND)) { + /* Rockchip has special Image format */ + int ret; + + ret = rockchip_copy_image(ifd, ¶ms); + if (ret) + return ret; } else { copy_file(ifd, params.datafile, pad_len); } @@ -650,6 +659,11 @@ copy_file (int ifd, const char *datafile, int pad) exit (EXIT_FAILURE); } + if (sbuf.st_size == 0) { + (void) close (dfd); + return; + } + ptr = mmap(0, sbuf.st_size, PROT_READ, MAP_SHARED, dfd, 0); if (ptr == MAP_FAILED) { fprintf (stderr, "%s: Can't read %s: %s\n", diff --git a/tools/rkcommon.c b/tools/rkcommon.c index d502607202..b4b0021146 100644 --- a/tools/rkcommon.c +++ b/tools/rkcommon.c @@ -15,8 +15,6 @@ #include "mkimage.h" #include "rkcommon.h" -#define DIV_ROUND_UP(n, d) (((n) + (d) - 1) / (d)) - enum { RK_SIGNATURE = 0x0ff0aa55, }; @@ -83,6 +81,24 @@ static struct spl_info spl_infos[] = { { "rk1808", "RK18", 0x200000 - 0x2000, false}, }; +/** + * struct spl_params - spl params parsed in check_params() + * + * @init_file: Init data file path + * @init_size: Aligned size of init data in bytes + * @boot_file: Boot data file path + * @boot_size: Aligned size of boot data in bytes + */ + +struct spl_params { + char *init_file; + uint32_t init_size; + char *boot_file; + uint32_t boot_size; +}; + +static struct spl_params spl_params = { 0 }; + static unsigned char rc4_key[16] = { 124, 78, 3, 4, 85, 5, 9, 7, 45, 44, 123, 56, 23, 13, 23, 17 @@ -102,13 +118,26 @@ static struct spl_info *rkcommon_get_spl_info(char *imagename) return NULL; } +static int rkcommon_get_aligned_size(struct image_tool_params *params, + const char *fname) +{ + int size; + + size = imagetool_get_filesize(params, fname); + if (size < 0) + return -1; + + /* + * Pad to a 2KB alignment, as required for init/boot size by the ROM + * (see https://lists.denx.de/pipermail/u-boot/2017-May/293268.html) + */ + return ROUND(size, RK_SIZE_ALIGN); +} + int rkcommon_check_params(struct image_tool_params *params) { int i; - if (rkcommon_get_spl_info(params->imagename) != NULL) - return EXIT_SUCCESS; - /* * If this is a operation (list or extract), the don't require * imagename to be set. @@ -116,6 +145,40 @@ int rkcommon_check_params(struct image_tool_params *params) if (params->lflag || params->iflag) return EXIT_SUCCESS; + if (!rkcommon_get_spl_info(params->imagename)) + goto err_spl_info; + + spl_params.init_file = params->datafile; + + spl_params.boot_file = strchr(spl_params.init_file, ':'); + if (spl_params.boot_file) { + *spl_params.boot_file = '\0'; + spl_params.boot_file += 1; + } + + spl_params.init_size = + rkcommon_get_aligned_size(params, spl_params.init_file); + if (spl_params.init_size < 0) + return EXIT_FAILURE; + + /* Boot file is optional, and only for back-to-bootrom functionality. */ + if (spl_params.boot_file) { + spl_params.boot_size = + rkcommon_get_aligned_size(params, spl_params.boot_file); + if (spl_params.boot_size < 0) + return EXIT_FAILURE; + } + + if (spl_params.init_size > rkcommon_get_spl_size(params)) { + fprintf(stderr, + "Error: SPL image is too large (size %#x than %#x)\n", + spl_params.init_size, rkcommon_get_spl_size(params)); + return EXIT_FAILURE; + } + + return EXIT_SUCCESS; + +err_spl_info: fprintf(stderr, "ERROR: imagename (%s) is not supported!\n", params->imagename ? params->imagename : "NULL"); @@ -158,8 +221,7 @@ bool rkcommon_need_rc4_spl(struct image_tool_params *params) return info->spl_rc4; } -static void rkcommon_set_header0(void *buf, uint file_size, uint max_size, - struct image_tool_params *params) +static void rkcommon_set_header0(void *buf, struct image_tool_params *params) { struct header0_info *hdr = buf; @@ -167,16 +229,8 @@ static void rkcommon_set_header0(void *buf, uint file_size, uint max_size, hdr->signature = RK_SIGNATURE; hdr->disable_rc4 = !rkcommon_need_rc4_spl(params); hdr->init_offset = RK_INIT_OFFSET; + hdr->init_size = spl_params.init_size / RK_BLK_SIZE; - hdr->init_size = DIV_ROUND_UP(file_size, RK_BLK_SIZE); - /* - * The init_size has to be a multiple of 4 blocks (i.e. of 2K) - * or the BootROM will not boot the image. - * - * Note: To verify that this is not a legacy constraint, we - * rechecked this against the RK3399 BootROM. - */ - hdr->init_size = ROUND(hdr->init_size, 4); /* * init_boot_size needs to be set, as it is read by the BootROM * to determine the size of the next-stage bootloader (e.g. U-Boot @@ -185,21 +239,22 @@ static void rkcommon_set_header0(void *buf, uint file_size, uint max_size, * see https://lists.denx.de/pipermail/u-boot/2017-May/293267.html * for a more detailed explanation by Andy Yan */ - hdr->init_boot_size = hdr->init_size + DIV_ROUND_UP(max_size, RK_BLK_SIZE); - hdr->init_boot_size = ROUND(hdr->init_boot_size, 4); + if (spl_params.boot_file) + hdr->init_boot_size = + hdr->init_size + spl_params.boot_size / RK_BLK_SIZE; + else + hdr->init_boot_size = + hdr->init_size + RK_MAX_BOOT_SIZE / RK_BLK_SIZE; rc4_encode(buf, RK_BLK_SIZE, rc4_key); } -int rkcommon_set_header(void *buf, uint file_size, uint max_size, - struct image_tool_params *params) +void rkcommon_set_header(void *buf, struct stat *sbuf, int ifd, + struct image_tool_params *params) { struct header1_info *hdr = buf + RK_SPL_HDR_START; - if (file_size > rkcommon_get_spl_size(params)) - return -ENOSPC; - - rkcommon_set_header0(buf, file_size, max_size, params); + rkcommon_set_header0(buf, params); /* Set up the SPL name (i.e. copy spl_hdr over) */ if (memcmp(&hdr->magic, "RSAK", 4)) @@ -207,9 +262,14 @@ int rkcommon_set_header(void *buf, uint file_size, uint max_size, if (rkcommon_need_rc4_spl(params)) rkcommon_rc4_encode_spl(buf, RK_SPL_HDR_START, - params->file_size - RK_SPL_HDR_START); + spl_params.init_size); - return 0; + if (spl_params.boot_file) { + if (rkcommon_need_rc4_spl(params)) + rkcommon_rc4_encode_spl(buf + RK_SPL_HDR_START, + spl_params.init_size, + spl_params.boot_size); + } } static inline unsigned rkcommon_offset_to_spi(unsigned offset) @@ -301,7 +361,7 @@ void rkcommon_print_header(const void *buf) struct header0_info header0; struct spl_info *spl_info; uint8_t image_type; - int ret; + int ret, boot_size; ret = rkcommon_parse_header(buf, &header0, &spl_info); @@ -319,7 +379,11 @@ void rkcommon_print_header(const void *buf) printf("Image Type: Rockchip %s (%s) boot image\n", spl_info->spl_hdr, (image_type == IH_TYPE_RKSD) ? "SD/MMC" : "SPI"); - printf("Data Size: %d bytes\n", header0.init_size * RK_BLK_SIZE); + printf("Init Data Size: %d bytes\n", header0.init_size * RK_BLK_SIZE); + + boot_size = (header0.init_boot_size - header0.init_size) * RK_BLK_SIZE; + if (boot_size != RK_MAX_BOOT_SIZE) + printf("Boot Data Size: %d bytes\n", boot_size); } void rkcommon_rc4_encode_spl(void *buf, unsigned int offset, unsigned int size) @@ -336,12 +400,8 @@ void rkcommon_rc4_encode_spl(void *buf, unsigned int offset, unsigned int size) } int rkcommon_vrec_header(struct image_tool_params *params, - struct image_type_params *tparams, - unsigned int alignment) + struct image_type_params *tparams) { - unsigned int unpadded_size; - unsigned int padded_size; - /* * The SPL image looks as follows: * @@ -367,19 +427,118 @@ int rkcommon_vrec_header(struct image_tool_params *params, /* Allocate, clear and install the header */ tparams->hdr = malloc(tparams->header_size); - if (!tparams->hdr) - return -ENOMEM; + if (!tparams->hdr) { + fprintf(stderr, "%s: Can't alloc header: %s\n", + params->cmdname, strerror(errno)); + exit(EXIT_FAILURE); + } memset(tparams->hdr, 0, tparams->header_size); /* - * If someone passed in 0 for the alignment, we'd better handle - * it correctly... + * We need to store the original file-size (i.e. before padding), as + * imagetool does not set this during its adjustment of file_size. */ - if (!alignment) - alignment = 1; + params->orig_file_size = tparams->header_size + + spl_params.init_size + spl_params.boot_size; - unpadded_size = tparams->header_size + params->file_size; - padded_size = ROUND(unpadded_size, alignment); + params->file_size = ROUND(params->orig_file_size, RK_SIZE_ALIGN); - return padded_size - unpadded_size; + /* Ignoring pad len, since we are using our own copy_image() */ + return 0; +} + +static int pad_file(struct image_tool_params *params, int ifd, int pad) +{ + uint8_t zeros[4096]; + + memset(zeros, 0, sizeof(zeros)); + + while (pad > 0) { + int todo = sizeof(zeros); + + if (todo > pad) + todo = pad; + if (write(ifd, (char *)&zeros, todo) != todo) { + fprintf(stderr, "%s: Write error on %s: %s\n", + params->cmdname, params->imagefile, + strerror(errno)); + return -1; + } + pad -= todo; + } + + return 0; +} + +static int copy_file(struct image_tool_params *params, int ifd, + const char *file, int padded_size) +{ + int dfd; + struct stat sbuf; + unsigned char *ptr; + int size; + + if (params->vflag) + fprintf(stderr, "Adding Image %s\n", file); + + dfd = open(file, O_RDONLY | O_BINARY); + if (dfd < 0) { + fprintf(stderr, "%s: Can't open %s: %s\n", + params->cmdname, file, strerror(errno)); + return -1; + } + + if (fstat(dfd, &sbuf) < 0) { + fprintf(stderr, "%s: Can't stat %s: %s\n", + params->cmdname, file, strerror(errno)); + goto err_close; + } + + if (params->vflag) + fprintf(stderr, "Size %u(pad to %u)\n", + (int)sbuf.st_size, padded_size); + + ptr = mmap(0, sbuf.st_size, PROT_READ, MAP_SHARED, dfd, 0); + if (ptr == MAP_FAILED) { + fprintf(stderr, "%s: Can't read %s: %s\n", + params->cmdname, file, strerror(errno)); + goto err_munmap; + } + + size = sbuf.st_size; + if (write(ifd, ptr, size) != size) { + fprintf(stderr, "%s: Write error on %s: %s\n", + params->cmdname, params->imagefile, strerror(errno)); + goto err_munmap; + } + + munmap((void *)ptr, sbuf.st_size); + close(dfd); + return pad_file(params, ifd, padded_size - size); + +err_munmap: + munmap((void *)ptr, sbuf.st_size); +err_close: + close(dfd); + return -1; +} + +int rockchip_copy_image(int ifd, struct image_tool_params *params) +{ + int ret; + + ret = copy_file(params, ifd, spl_params.init_file, + spl_params.init_size); + if (ret) + return ret; + + if (spl_params.boot_file) { + ret = copy_file(params, ifd, spl_params.boot_file, + spl_params.boot_size); + if (ret) + return ret; + } + + return pad_file(params, ifd, + params->file_size - params->orig_file_size); } diff --git a/tools/rkcommon.h b/tools/rkcommon.h index 8fd147a4e0..97019c01b2 100644 --- a/tools/rkcommon.h +++ b/tools/rkcommon.h @@ -10,13 +10,11 @@ enum { RK_BLK_SIZE = 512, - RK_INIT_SIZE_ALIGN = 2048, + RK_SIZE_ALIGN = 2048, RK_INIT_OFFSET = 4, RK_MAX_BOOT_SIZE = 512 << 10, RK_SPL_HDR_START = RK_INIT_OFFSET * RK_BLK_SIZE, RK_SPL_HDR_SIZE = 4, - RK_SPL_START = RK_SPL_HDR_START + RK_SPL_HDR_SIZE, - RK_IMAGE_HEADER_LEN = RK_SPL_START, }; /** @@ -50,11 +48,9 @@ int rkcommon_get_spl_size(struct image_tool_params *params); * This sets up a 2KB header which can be interpreted by the Rockchip boot ROM. * * @buf: Pointer to header place (must be at least 2KB in size) - * @file_size: Size of the file we want the boot ROM to load, in bytes - * @return 0 if OK, -ENOSPC if too large */ -int rkcommon_set_header(void *buf, uint file_size, uint max_size, - struct image_tool_params *params); +void rkcommon_set_header(void *buf, struct stat *sbuf, int ifd, + struct image_tool_params *params); /** * rkcommon_verify_header() - verify the header for a Rockchip boot image @@ -103,14 +99,10 @@ void rkcommon_rc4_encode_spl(void *buf, unsigned int offset, unsigned int size); * @params: Pointer to the tool params structure * @tparams: Pointer tot the image type structure (for setting * the header and header_size) - * @alignment: Alignment (a power of two) that the image should be - * padded to (e.g. 512 if we want to align with SD/MMC - * blocksizes or 2048 for the SPI format) * - * @return bytes of padding required/added (does not include the header_size) + * @return 0 (always) */ int rkcommon_vrec_header(struct image_tool_params *params, - struct image_type_params *tparams, - unsigned int alignment); + struct image_type_params *tparams); #endif diff --git a/tools/rknand.c b/tools/rknand.c index c93f053203..99fcf6f268 100644 --- a/tools/rknand.c +++ b/tools/rknand.c @@ -10,113 +10,52 @@ #include "mkimage.h" #include "rkcommon.h" +#define DIV_ROUND_UP(n, d) (((n) + (d) - 1) / (d)) + enum { RKNAND_SECT_LEN = RK_BLK_SIZE * 4, }; struct rknand_info { uint32_t pagesize; - uint32_t skippages; - uint32_t tplsize; - uint32_t splsize; - uint32_t tplpaddedsize; - uint32_t splpaddedsize; uint32_t itersize; uint32_t tplsplsize; - char *tplfile; - char *splfile; }; struct rknand_info ninfo; -static uint32_t rknand_get_file_size(char *filename) -{ - int dfd; - struct stat sbuf; - - dfd = open(filename, O_RDONLY | O_BINARY); - if (dfd < 0) { - fprintf(stderr, "Can't open %s: %s\n", filename, strerror(errno)); - exit(EXIT_FAILURE); - } - - if (fstat(dfd, &sbuf) < 0) { - fprintf(stderr, "Can't stat %s: %s\n", filename, strerror(errno)); - exit(EXIT_FAILURE); - } - - close(dfd); - - return sbuf.st_size; -} - -static void rknand_fill_ninfo(struct image_tool_params *params) -{ - sscanf(params->extraparams, "%u,%u", &ninfo.pagesize, &ninfo.skippages); - - ninfo.tplfile = params->datafile; - if ((ninfo.splfile = strchr(params->datafile, ':')) != NULL) { - *ninfo.splfile = '\0'; - ninfo.splfile += 1; - } - - ninfo.tplsize = rknand_get_file_size(ninfo.tplfile); - ninfo.splsize = rknand_get_file_size(ninfo.splfile); - - ninfo.tplpaddedsize = ROUND(ninfo.tplsize, RKNAND_SECT_LEN); - - ninfo.splpaddedsize = ROUND(ninfo.splsize, RKNAND_SECT_LEN); - - ninfo.itersize = ninfo.pagesize * (ninfo.skippages + 1); - ninfo.tplsplsize = ((ninfo.tplpaddedsize + ninfo.splpaddedsize) / - RKNAND_SECT_LEN) * ninfo.itersize; -} - static void rknand_set_header(void *buf, struct stat *sbuf, int ifd, struct image_tool_params *params) { - int sector, sploffset, splfd, ret; + int sector; + unsigned int size; - ret = rkcommon_set_header(buf, ninfo.tplsize, ninfo.splsize, params); - if (ret) { - printf("Warning: TPL image is too large (size %#x) and will " - "not boot\n", ninfo.tplsize); - } + size = params->orig_file_size; - if ((splfd = open(ninfo.splfile, O_RDONLY | O_BINARY)) < 0) { - fprintf (stderr, "%s: Can't open %s: %s\n", - params->cmdname, ninfo.splfile, strerror(errno)); - exit (EXIT_FAILURE); - } - - sploffset = RKNAND_SECT_LEN + ninfo.tplpaddedsize; - if (read(splfd, buf + sploffset, ninfo.splsize) != ninfo.splsize) { - fprintf (stderr, "%s: Read error on %s: %s\n", - params->cmdname, ninfo.splfile, strerror(errno)); - exit (EXIT_FAILURE); - } - close(splfd); - - if (rkcommon_need_rc4_spl(params)) - rkcommon_rc4_encode_spl(buf, sploffset, ninfo.splpaddedsize); + rkcommon_set_header(buf, sbuf, ifd, params); /* * Spread the image out so we only use the first 2KB of each pagesize * region. This is a feature of the NAND format required by the Rockchip * boot ROM. */ - for (sector = ninfo.tplsplsize / ninfo.itersize - 1; sector >= 0; sector--) { - memmove(buf + sector * ninfo.itersize + ninfo.pagesize, - buf + (sector + 1) * RKNAND_SECT_LEN, RKNAND_SECT_LEN); + if (params->vflag) + fprintf(stderr, "Spreading nand image from %u to %u\n", + size, params->file_size); - if (sector < (ninfo.tplsplsize / ninfo.itersize - 1)) - memset(buf + sector * ninfo.itersize + ninfo.pagesize + - RKNAND_SECT_LEN, 0xFF, ninfo.itersize - - RKNAND_SECT_LEN); + for (sector = ninfo.tplsplsize / ninfo.itersize - 1; sector >= 0; + sector--) { + memmove(buf + ninfo.pagesize + sector * ninfo.itersize, + buf + RK_SPL_HDR_START + sector * RKNAND_SECT_LEN, + RKNAND_SECT_LEN); + + memset(buf + ninfo.pagesize + sector * ninfo.itersize + + RKNAND_SECT_LEN, 0xFF, + ninfo.itersize - RKNAND_SECT_LEN); } - memset(buf + RKNAND_SECT_LEN, 0xFF, ninfo.pagesize - RKNAND_SECT_LEN); - memset(buf + ninfo.tplsplsize - ninfo.pagesize + RKNAND_SECT_LEN, 0xFF, - ninfo.pagesize - RKNAND_SECT_LEN); + + /* Fill up padded area of the header. */ + memset(buf + RK_SPL_HDR_START, 0xFF, ninfo.pagesize - RK_SPL_HDR_START); } static int rknand_check_image_type(uint8_t type) @@ -130,10 +69,28 @@ static int rknand_check_image_type(uint8_t type) static int rknand_vrec_header(struct image_tool_params *params, struct image_type_params *tparams) { - rknand_fill_ninfo(params); - rkcommon_vrec_header(params, tparams, RKNAND_SECT_LEN); + int tplsplsize; + uint32_t skippages; + int ret; - return ninfo.tplsplsize - tparams->header_size - ninfo.tplsize; + rkcommon_vrec_header(params, tparams); + + ret = sscanf(params->extraparams, "%u,%u", &ninfo.pagesize, &skippages); + if (ret != 2 || (ninfo.pagesize % RKNAND_SECT_LEN)) { + fprintf(stderr, "%s: Wrong nand params\n", params->cmdname); + exit(EXIT_FAILURE); + } + + ninfo.itersize = ninfo.pagesize * (skippages + 1); + + tplsplsize = params->file_size - RK_SPL_HDR_START; + ninfo.tplsplsize = + DIV_ROUND_UP(tplsplsize, RKNAND_SECT_LEN) * ninfo.itersize; + + /* Padded file size = padded header + padded tpl & spl. */ + params->file_size = ninfo.pagesize + ninfo.tplsplsize; + + return 0; } /* @@ -145,8 +102,9 @@ U_BOOT_IMAGE_TYPE( 0, NULL, rkcommon_check_params, - rkcommon_verify_header, - rkcommon_print_header, + /* TODO: Support rknand in there helpers */ + NULL, //rkcommon_verify_header, + NULL, //rkcommon_print_header, rknand_set_header, NULL, rknand_check_image_type, diff --git a/tools/rksd.c b/tools/rksd.c index 164c1fbcb7..25119b22c6 100644 --- a/tools/rksd.c +++ b/tools/rksd.c @@ -13,27 +13,6 @@ #include "mkimage.h" #include "rkcommon.h" -static void rksd_set_header(void *buf, struct stat *sbuf, int ifd, - struct image_tool_params *params) -{ - unsigned int size; - int ret; - - /* - * We need to calculate this using 'RK_SPL_HDR_START' and not using - * 'tparams->header_size', as the additional byte inserted when - * 'is_boot0' is true counts towards the payload (and not towards the - * header). - */ - size = params->file_size - RK_SPL_HDR_START; - ret = rkcommon_set_header(buf, size, RK_MAX_BOOT_SIZE, params); - if (ret) { - /* TODO(sjg@chromium.org): This method should return an error */ - printf("Warning: SPL image is too large (size %#x) and will " - "not boot\n", size); - } -} - static int rksd_check_image_type(uint8_t type) { if (type == IH_TYPE_RKSD) @@ -42,16 +21,6 @@ static int rksd_check_image_type(uint8_t type) return EXIT_FAILURE; } -static int rksd_vrec_header(struct image_tool_params *params, - struct image_type_params *tparams) -{ - /* - * Pad to a 2KB alignment, as required for init_size by the ROM - * (see https://lists.denx.de/pipermail/u-boot/2017-May/293268.html) - */ - return rkcommon_vrec_header(params, tparams, RK_INIT_SIZE_ALIGN); -} - /* * rk_sd parameters */ @@ -63,9 +32,9 @@ U_BOOT_IMAGE_TYPE( rkcommon_check_params, rkcommon_verify_header, rkcommon_print_header, - rksd_set_header, + rkcommon_set_header, NULL, rksd_check_image_type, NULL, - rksd_vrec_header + rkcommon_vrec_header ); diff --git a/tools/rkspi.c b/tools/rkspi.c index 5005051d39..15e283851e 100644 --- a/tools/rkspi.c +++ b/tools/rkspi.c @@ -22,22 +22,20 @@ static void rkspi_set_header(void *buf, struct stat *sbuf, int ifd, { int sector; unsigned int size; - int ret; size = params->orig_file_size; - ret = rkcommon_set_header(buf, size, RK_MAX_BOOT_SIZE, params); - debug("size %x\n", size); - if (ret) { - /* TODO(sjg@chromium.org): This method should return an error */ - printf("Warning: SPL image is too large (size %#x) and will " - "not boot\n", size); - } + + rkcommon_set_header(buf, sbuf, ifd, params); /* * Spread the image out so we only use the first 2KB of each 4KB * region. This is a feature of the SPI format required by the Rockchip * boot ROM. Its rationale is unknown. */ + if (params->vflag) + fprintf(stderr, "Spreading spi image from %u to %u\n", + size, params->file_size); + for (sector = size / RKSPI_SECT_LEN - 1; sector >= 0; sector--) { debug("sector %u\n", sector); memmove(buf + sector * RKSPI_SECT_LEN * 2, @@ -57,35 +55,23 @@ static int rkspi_check_image_type(uint8_t type) } /* - * The SPI payload needs to be padded out to make space for odd half-sector - * layout used in flash (i.e. only the first 2K of each 4K sector is used). + * The SPI payload needs to make space for odd half-sector layout used in flash + * (i.e. only the first 2K of each 4K sector is used). */ static int rkspi_vrec_header(struct image_tool_params *params, struct image_type_params *tparams) { - int padding = rkcommon_vrec_header(params, tparams, RK_INIT_SIZE_ALIGN); - /* - * The file size has not been adjusted at this point (our caller will - * eventually add the header/padding to the file_size), so we need to - * add up the header_size, file_size and padding ourselves. - */ - int padded_size = tparams->header_size + params->file_size + padding; - - /* - * We need to store the original file-size (i.e. before padding), as - * imagetool does not set this during its adjustment of file_size. - */ - params->orig_file_size = padded_size; + rkcommon_vrec_header(params, tparams); /* * Converting to the SPI format (i.e. splitting each 4K page into two * 2K subpages and then padding these 2K pages up to take a complete - * 4K sector again) will will double the image size. - * - * Thus we return the padded_size as an additional padding requirement - * (be sure to add this to the padding returned from the common code). + * 4K sector again) which will double the image size. */ - return padded_size + padding; + params->file_size = ROUND(params->file_size, RKSPI_SECT_LEN) << 1; + + /* Ignoring pad len, since we are using our own copy_image() */ + return 0; } /*