Commit 2c840c82b3558267650b98735790ac7151644ae1
1 parent
4ec81a0b07
Exists in
smarc_8mm-imx_v2018.03_4.14.98_2.0.0_ga
and in
5 other branches
MLK-18591-3 android: Add FSL android fastboot support
Porting the FSL android fastboot features from imx u-boot v2017.03 to support all SoCs: imx6/imx7/imx7ulp/imx8/imx8m Signed-off-by: Ye Li <ye.li@nxp.com>
Showing 34 changed files with 4476 additions and 138 deletions Side-by-side Diff
- arch/arm/include/asm/arch-imx8/sys_proto.h
- arch/arm/include/asm/arch-mx6/sys_proto.h
- arch/arm/mach-imx/Kconfig
- arch/arm/mach-imx/imx8/cpu.c
- arch/arm/mach-imx/imx8m/soc.c
- arch/arm/mach-imx/mx6/soc.c
- arch/arm/mach-imx/mx7/soc.c
- arch/arm/mach-imx/mx7ulp/soc.c
- board/freescale/common/Makefile
- board/freescale/common/recovery_keypad.c
- board/freescale/common/recovery_keypad.h
- cmd/fastboot.c
- cmd/fastboot/Kconfig
- cmd/read.c
- common/autoboot.c
- common/board_r.c
- common/image-android.c
- common/image-fdt.c
- disk/part_efi.c
- drivers/usb/gadget/Makefile
- drivers/usb/gadget/bcb.c
- drivers/usb/gadget/bcb.h
- drivers/usb/gadget/command.c
- drivers/usb/gadget/f_fastboot.c
- drivers/usb/gadget/fastboot_lock_unlock.c
- drivers/usb/gadget/fastboot_lock_unlock.h
- include/android_image.h
- include/common.h
- include/fsl_fastboot.h
- include/image.h
- include/mmc.h
- include/part.h
- include/recovery.h
- scripts/config_whitelist.txt
arch/arm/include/asm/arch-imx8/sys_proto.h
arch/arm/include/asm/arch-mx6/sys_proto.h
arch/arm/mach-imx/Kconfig
... | ... | @@ -100,4 +100,10 @@ |
100 | 100 | NXP boards based on i.MX6/7 contain the board revision information |
101 | 101 | stored in the fuses. Select this option if you want to be able to |
102 | 102 | retrieve the board revision information. |
103 | + | |
104 | +config FLASH_MCUFIRMWARE_SUPPORT | |
105 | + bool "Enable mcu firmware flash support" | |
106 | + depends on ARCH_MX7ULP || ARCH_IMX8M | |
107 | + help | |
108 | + This enables the mcu firmware flash support for some SOCs. |
arch/arm/mach-imx/imx8/cpu.c
arch/arm/mach-imx/imx8m/soc.c
... | ... | @@ -20,6 +20,7 @@ |
20 | 20 | #include <fsl_wdog.h> |
21 | 21 | #include <imx_sip.h> |
22 | 22 | #include <generated/version_autogenerated.h> |
23 | +#include <asm/setup.h> | |
23 | 24 | |
24 | 25 | DECLARE_GLOBAL_DATA_PTR; |
25 | 26 | |
... | ... | @@ -196,6 +197,18 @@ |
196 | 197 | { |
197 | 198 | return get_boot_device() == USB_BOOT; |
198 | 199 | } |
200 | +#ifdef CONFIG_SERIAL_TAG | |
201 | +void get_board_serial(struct tag_serialnr *serialnr) | |
202 | +{ | |
203 | + struct ocotp_regs *ocotp = (struct ocotp_regs *)OCOTP_BASE_ADDR; | |
204 | + struct fuse_bank *bank = &ocotp->bank[0]; | |
205 | + struct fuse_bank0_regs *fuse = | |
206 | + (struct fuse_bank0_regs *)bank->fuse_regs; | |
207 | + | |
208 | + serialnr->low = fuse->uid_low; | |
209 | + serialnr->high = fuse->uid_high; | |
210 | +} | |
211 | +#endif | |
199 | 212 | |
200 | 213 | #ifdef CONFIG_OF_SYSTEM_SETUP |
201 | 214 | static int ft_add_optee_node(void *fdt, bd_t *bd) |
arch/arm/mach-imx/mx6/soc.c
... | ... | @@ -23,6 +23,7 @@ |
23 | 23 | #include <dm.h> |
24 | 24 | #include <imx_thermal.h> |
25 | 25 | #include <mmc.h> |
26 | +#include <asm/setup.h> | |
26 | 27 | |
27 | 28 | enum ldo_reg { |
28 | 29 | LDO_ARM, |
... | ... | @@ -805,6 +806,10 @@ |
805 | 806 | u32 mask528; |
806 | 807 | u32 reg, periph1, periph2; |
807 | 808 | |
809 | +#if defined(CONFIG_ANDROID_SUPPORT) | |
810 | + /* Enable RTC */ | |
811 | + writel(0x21, 0x020cc038); | |
812 | +#endif | |
808 | 813 | if (is_mx6sx() || is_mx6ul() || is_mx6ull() || is_mx6sll()) |
809 | 814 | return; |
810 | 815 |
arch/arm/mach-imx/mx7/soc.c
... | ... | @@ -20,6 +20,7 @@ |
20 | 20 | #include <imx_thermal.h> |
21 | 21 | #include <fsl_sec.h> |
22 | 22 | #include <fsl_wdog.h> |
23 | +#include <asm/setup.h> | |
23 | 24 | |
24 | 25 | #if defined(CONFIG_IMX_THERMAL) |
25 | 26 | static const struct imx_thermal_plat imx7_thermal_plat = { |
... | ... | @@ -293,6 +294,10 @@ |
293 | 294 | /* clock configuration. */ |
294 | 295 | clock_init(); |
295 | 296 | |
297 | +#if defined(CONFIG_ANDROID_SUPPORT) | |
298 | + /* Enable RTC */ | |
299 | + writel(0x21, 0x30370038); | |
300 | +#endif | |
296 | 301 | return; |
297 | 302 | } |
298 | 303 |
arch/arm/mach-imx/mx7ulp/soc.c
... | ... | @@ -12,6 +12,7 @@ |
12 | 12 | #include <asm/mach-imx/hab.h> |
13 | 13 | #include <asm/mach-imx/boot_mode.h> |
14 | 14 | #include <fdt_support.h> |
15 | +#include <asm/setup.h> | |
15 | 16 | |
16 | 17 | static char *get_reset_cause(char *); |
17 | 18 | |
... | ... | @@ -155,6 +156,11 @@ |
155 | 156 | if (soc_rev() < CHIP_REV_2_0) { |
156 | 157 | /* enable dumb pmic */ |
157 | 158 | writel((readl(SNVS_LP_LPCR) | SNVS_LPCR_DPEN), SNVS_LP_LPCR); |
159 | + | |
160 | +#if defined(CONFIG_ANDROID_SUPPORT) | |
161 | + /* Enable RTC */ | |
162 | + writel((readl(SNVS_LP_LPCR) | SNVS_LPCR_SRTC_ENV), SNVS_LP_LPCR); | |
163 | +#endif | |
158 | 164 | } |
159 | 165 | return; |
160 | 166 | } |
... | ... | @@ -370,4 +376,19 @@ |
370 | 376 | |
371 | 377 | return boot_dev; |
372 | 378 | } |
379 | + | |
380 | +#ifdef CONFIG_FSL_FASTBOOT | |
381 | +#ifdef CONFIG_SERIAL_TAG | |
382 | +void get_board_serial(struct tag_serialnr *serialnr) | |
383 | +{ | |
384 | + | |
385 | + struct ocotp_regs *ocotp = (struct ocotp_regs *)OCOTP_BASE_ADDR; | |
386 | + struct fuse_bank *bank = &ocotp->bank[1]; | |
387 | + struct fuse_bank1_regs *fuse = | |
388 | + (struct fuse_bank1_regs *)bank->fuse_regs; | |
389 | + serialnr->low = (fuse->cfg0 & 0xFFFF) + ((fuse->cfg1 & 0xFFFF) << 16); | |
390 | + serialnr->high = (fuse->cfg2 & 0xFFFF) + ((fuse->cfg3 & 0xFFFF) << 16); | |
391 | +} | |
392 | +#endif /*CONFIG_SERIAL_TAG*/ | |
393 | +#endif /*CONFIG_FSL_FASTBOOT*/ |
board/freescale/common/Makefile
... | ... | @@ -65,6 +65,9 @@ |
65 | 65 | obj-$(CONFIG_POWER_MC34VR500) += mc34vr500.o |
66 | 66 | obj-$(CONFIG_MXC_EPDC) += epdc_setup.o |
67 | 67 | obj-y += mmc.o |
68 | +ifdef CONFIG_FSL_FASTBOOT | |
69 | +obj-${CONFIG_ANDROID_RECOVERY} += recovery_keypad.o | |
70 | +endif | |
68 | 71 | |
69 | 72 | obj-$(CONFIG_LS102XA_STREAM_ID) += ls102xa_stream_id.o |
70 | 73 |
board/freescale/common/recovery_keypad.c
1 | +/* | |
2 | + * Copyright (C) 2010-2016 Freescale Semiconductor, Inc. All Rights Reserved. | |
3 | + * Copyright 2017 NXP | |
4 | + * | |
5 | + * SPDX-License-Identifier: GPL-2.0+ | |
6 | + */ | |
7 | +#include <common.h> | |
8 | +#include <malloc.h> | |
9 | +#include <recovery.h> | |
10 | +#ifdef CONFIG_MXC_KPD | |
11 | +#include <mxc_keyb.h> | |
12 | +#endif | |
13 | +#include <asm/mach-imx/boot_mode.h> | |
14 | + | |
15 | +#ifdef CONFIG_MXC_KPD | |
16 | +#define PRESSED_VOL_DOWN 0x01 | |
17 | +#define PRESSED_POWER 0x02 | |
18 | +#define RECOVERY_KEY_MASK (PRESSED_VOL_DOWN | PRESSED_POWER) | |
19 | + | |
20 | +inline int test_key(int value, struct kpp_key_info *ki) | |
21 | +{ | |
22 | + return (ki->val == value) && (ki->evt == KDepress); | |
23 | +} | |
24 | + | |
25 | +int is_recovery_keypad_pressing(void) | |
26 | +{ | |
27 | + struct kpp_key_info *key_info = NULL; | |
28 | + int state = 0, keys, i; | |
29 | + | |
30 | + int ret = 0; | |
31 | + | |
32 | + mxc_kpp_init(); | |
33 | + /* due to glitch suppression circuit, | |
34 | + wait sometime to let all keys scanned. */ | |
35 | + udelay(1000); | |
36 | + keys = mxc_kpp_getc(&key_info); | |
37 | + | |
38 | + printf("Detecting VOL_DOWN+POWER key for recovery(%d:%d) ...\n", | |
39 | + keys, keys ? key_info->val : 0); | |
40 | + if (keys > 1) { | |
41 | + for (i = 0; i < keys; i++) { | |
42 | + if (test_key(CONFIG_POWER_KEY, &key_info[i])) | |
43 | + state |= PRESSED_POWER; | |
44 | + else if (test_key(CONFIG_VOL_DOWN_KEY, &key_info[i])) | |
45 | + state |= PRESSED_VOL_DOWN; | |
46 | + } | |
47 | + } | |
48 | + if ((state & RECOVERY_KEY_MASK) == RECOVERY_KEY_MASK) | |
49 | + ret = 1; | |
50 | + if (key_info) | |
51 | + free(key_info); | |
52 | + return ret; | |
53 | +} | |
54 | +#else | |
55 | +/* If not using mxc keypad, currently we will detect power key on board */ | |
56 | +int is_recovery_keypad_pressing(void) | |
57 | +{ | |
58 | + return 0; | |
59 | +} | |
60 | +#endif |
board/freescale/common/recovery_keypad.h
cmd/fastboot.c
... | ... | @@ -23,7 +23,11 @@ |
23 | 23 | return CMD_RET_USAGE; |
24 | 24 | |
25 | 25 | usb_controller = argv[1]; |
26 | +#ifdef CONFIG_FASTBOOT_USB_DEV | |
27 | + controller_index = CONFIG_FASTBOOT_USB_DEV; | |
28 | +#else | |
26 | 29 | controller_index = simple_strtoul(usb_controller, NULL, 0); |
30 | +#endif | |
27 | 31 | |
28 | 32 | ret = board_usb_init(controller_index, USB_INIT_DEVICE); |
29 | 33 | if (ret) { |
cmd/fastboot/Kconfig
... | ... | @@ -26,6 +26,48 @@ |
26 | 26 | |
27 | 27 | See doc/README.android-fastboot for more information. |
28 | 28 | |
29 | +config FSL_FASTBOOT | |
30 | + bool "Enable FSL fastboot support" | |
31 | + select BCB_SUPPORT | |
32 | + help | |
33 | + This enables FSL implementation for Android fastboot. | |
34 | + | |
35 | +if FSL_FASTBOOT | |
36 | + | |
37 | +config ANDROID_RECOVERY | |
38 | + bool "Enable the recovery boot function" | |
39 | + help | |
40 | + This enables the Android Recovery boot function. | |
41 | + | |
42 | +config CMD_BOOTA | |
43 | + bool "Enable the boota command" | |
44 | + help | |
45 | + This enables the boota command for booting android images. | |
46 | + | |
47 | +config BCB_SUPPORT | |
48 | + bool | |
49 | + | |
50 | +choice | |
51 | + prompt "Android Image Storage select" | |
52 | + default FASTBOOT_STORAGE_MMC | |
53 | + | |
54 | +config FASTBOOT_STORAGE_MMC | |
55 | + bool "Using eMMC/SD for Android fastboot storage media" | |
56 | + | |
57 | +config FASTBOOT_STORAGE_NAND | |
58 | + bool "Using NAND flash for Android fastboot storage media" | |
59 | + | |
60 | +config FASTBOOT_STORAGE_SATA | |
61 | + bool "Using SATA disk for Android fastboot storage media" | |
62 | + | |
63 | +endchoice | |
64 | + | |
65 | +config FASTBOOT_SATA_NO | |
66 | + int "Sata device index" | |
67 | + depends on FASTBOOT_STORAGE_SATA | |
68 | + | |
69 | +endif #FSL_FASTBOOT | |
70 | + | |
29 | 71 | if USB_FUNCTION_FASTBOOT |
30 | 72 | |
31 | 73 | config FASTBOOT_BUF_ADDR |
cmd/read.c
... | ... | @@ -12,7 +12,7 @@ |
12 | 12 | #include <command.h> |
13 | 13 | #include <part.h> |
14 | 14 | |
15 | -int do_read(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) | |
15 | +int do_raw_read(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) | |
16 | 16 | { |
17 | 17 | char *ep; |
18 | 18 | struct blk_desc *dev_desc = NULL; |
... | ... | @@ -75,7 +75,7 @@ |
75 | 75 | } |
76 | 76 | |
77 | 77 | U_BOOT_CMD( |
78 | - read, 6, 0, do_read, | |
78 | + read, 6, 0, do_raw_read, | |
79 | 79 | "Load binary data from a partition", |
80 | 80 | "<interface> <dev[:part]> addr blk# cnt" |
81 | 81 | ); |
common/autoboot.c
... | ... | @@ -311,7 +311,7 @@ |
311 | 311 | s = env_get("bootdelay"); |
312 | 312 | bootdelay = s ? (int)simple_strtol(s, NULL, 10) : CONFIG_BOOTDELAY; |
313 | 313 | |
314 | -#ifdef is_boot_from_usb | |
314 | +#if !defined(CONFIG_FSL_FASTBOOT) && defined(is_boot_from_usb) | |
315 | 315 | if (is_boot_from_usb()) { |
316 | 316 | disconnect_from_pc(); |
317 | 317 | printf("Boot from USB for mfgtools\n"); |
... | ... | @@ -349,7 +349,7 @@ |
349 | 349 | #endif /* CONFIG_BOOTCOUNT_LIMIT */ |
350 | 350 | s = env_get("bootcmd"); |
351 | 351 | |
352 | -#ifdef is_boot_from_usb | |
352 | +#if !defined(CONFIG_FSL_FASTBOOT) && defined(is_boot_from_usb) | |
353 | 353 | if (is_boot_from_usb()) { |
354 | 354 | s = env_get("bootcmd_mfg"); |
355 | 355 | printf("Run bootcmd_mfg: %s\n", s); |
common/board_r.c
... | ... | @@ -54,6 +54,9 @@ |
54 | 54 | #include <linux/compiler.h> |
55 | 55 | #include <linux/err.h> |
56 | 56 | #include <efi_loader.h> |
57 | +#ifdef CONFIG_FSL_FASTBOOT | |
58 | +#include <fsl_fastboot.h> | |
59 | +#endif | |
57 | 60 | |
58 | 61 | DECLARE_GLOBAL_DATA_PTR; |
59 | 62 | |
... | ... | @@ -659,6 +662,20 @@ |
659 | 662 | } |
660 | 663 | #endif |
661 | 664 | |
665 | +#ifdef CONFIG_FSL_FASTBOOT | |
666 | +static int initr_fastboot_setup(void) | |
667 | +{ | |
668 | + fastboot_setup(); | |
669 | + return 0; | |
670 | +} | |
671 | + | |
672 | +static int initr_check_fastboot(void) | |
673 | +{ | |
674 | + fastboot_run_bootmode(); | |
675 | + return 0; | |
676 | +} | |
677 | +#endif | |
678 | + | |
662 | 679 | static int run_main_loop(void) |
663 | 680 | { |
664 | 681 | #ifdef CONFIG_SANDBOX |
... | ... | @@ -831,6 +848,9 @@ |
831 | 848 | #ifdef CONFIG_BOARD_LATE_INIT |
832 | 849 | board_late_init, |
833 | 850 | #endif |
851 | +#ifdef CONFIG_FSL_FASTBOOT | |
852 | + initr_fastboot_setup, | |
853 | +#endif | |
834 | 854 | #if defined(CONFIG_SCSI) && !defined(CONFIG_DM_SCSI) |
835 | 855 | INIT_FUNC_WATCHDOG_RESET |
836 | 856 | initr_scsi, |
... | ... | @@ -872,6 +892,9 @@ |
872 | 892 | #endif |
873 | 893 | #ifdef AVB_RPMB |
874 | 894 | initr_avbkey, |
895 | +#endif | |
896 | +#ifdef CONFIG_FSL_FASTBOOT | |
897 | + initr_check_fastboot, | |
875 | 898 | #endif |
876 | 899 | run_main_loop, |
877 | 900 | }; |
common/image-android.c
1 | 1 | /* |
2 | 2 | * Copyright (c) 2011 Sebastian Andrzej Siewior <bigeasy@linutronix.de> |
3 | 3 | * |
4 | + * Copyright (C) 2015-2016 Freescale Semiconductor, Inc. | |
5 | + * Copyright 2017 NXP | |
6 | + * | |
4 | 7 | * SPDX-License-Identifier: GPL-2.0+ |
5 | 8 | */ |
6 | 9 | |
... | ... | @@ -9,6 +12,11 @@ |
9 | 12 | #include <android_image.h> |
10 | 13 | #include <malloc.h> |
11 | 14 | #include <errno.h> |
15 | +#include <asm/bootm.h> | |
16 | +#include <asm/mach-imx/boot_mode.h> | |
17 | +#include <asm/arch/sys_proto.h> | |
18 | +#include <fsl_fastboot.h> | |
19 | +#include <asm/setup.h> | |
12 | 20 | |
13 | 21 | #define ANDROID_IMAGE_DEFAULT_KERNEL_ADDR 0x10008000 |
14 | 22 | |
... | ... | @@ -51,6 +59,7 @@ |
51 | 59 | int android_image_get_kernel(const struct andr_img_hdr *hdr, int verify, |
52 | 60 | ulong *os_data, ulong *os_len) |
53 | 61 | { |
62 | + extern boot_metric metrics; | |
54 | 63 | u32 kernel_addr = android_image_get_kernel_addr(hdr); |
55 | 64 | |
56 | 65 | /* |
57 | 66 | |
58 | 67 | |
59 | 68 | |
60 | 69 | |
61 | 70 | |
62 | 71 | |
63 | 72 | |
... | ... | @@ -66,32 +75,111 @@ |
66 | 75 | printf("Kernel load addr 0x%08x size %u KiB\n", |
67 | 76 | kernel_addr, DIV_ROUND_UP(hdr->kernel_size, 1024)); |
68 | 77 | |
69 | - int len = 0; | |
70 | - if (*hdr->cmdline) { | |
71 | - printf("Kernel command line: %s\n", hdr->cmdline); | |
72 | - len += strlen(hdr->cmdline); | |
78 | + char newbootargs[512] = {0}; | |
79 | + char commandline[2048] = {0}; | |
80 | + char *bootargs = env_get("bootargs"); | |
81 | + | |
82 | + if (bootargs) { | |
83 | + if (strlen(bootargs) + 1 > sizeof(commandline)) { | |
84 | + printf("bootargs is too long!\n"); | |
85 | + return -1; | |
86 | + } | |
87 | + else | |
88 | + strncpy(commandline, bootargs, sizeof(commandline) - 1); | |
89 | + } else if (*hdr->cmdline) { | |
90 | + if (strlen(hdr->cmdline) + 1 > sizeof(commandline)) { | |
91 | + printf("cmdline in bootimg is too long!\n"); | |
92 | + return -1; | |
93 | + } | |
94 | + else | |
95 | + strncpy(commandline, hdr->cmdline, strlen(commandline) - 1); | |
73 | 96 | } |
74 | 97 | |
75 | - char *bootargs = env_get("bootargs"); | |
76 | - if (bootargs) | |
77 | - len += strlen(bootargs); | |
98 | +#ifdef CONFIG_SERIAL_TAG | |
99 | + struct tag_serialnr serialnr; | |
100 | + get_board_serial(&serialnr); | |
78 | 101 | |
79 | - char *newbootargs = malloc(len + 2); | |
80 | - if (!newbootargs) { | |
81 | - puts("Error: malloc in android_image_get_kernel failed!\n"); | |
82 | - return -ENOMEM; | |
102 | + sprintf(newbootargs, | |
103 | + " androidboot.serialno=%08x%08x", | |
104 | + serialnr.high, | |
105 | + serialnr.low); | |
106 | + strncat(commandline, newbootargs, sizeof(commandline) - strlen(commandline)); | |
107 | +#endif | |
108 | + | |
109 | + /* append soc type into bootargs */ | |
110 | + char *soc_type = env_get("soc_type"); | |
111 | + if (soc_type) { | |
112 | + sprintf(newbootargs, | |
113 | + " androidboot.soc_type=%s", | |
114 | + soc_type); | |
115 | + strncat(commandline, newbootargs, sizeof(commandline) - strlen(commandline)); | |
83 | 116 | } |
84 | - *newbootargs = '\0'; | |
85 | 117 | |
86 | - if (bootargs) { | |
87 | - strcpy(newbootargs, bootargs); | |
88 | - strcat(newbootargs, " "); | |
118 | + int bootdev = get_boot_device(); | |
119 | + if (bootdev == SD1_BOOT || bootdev == SD2_BOOT || | |
120 | + bootdev == SD3_BOOT || bootdev == SD4_BOOT) { | |
121 | + sprintf(newbootargs, | |
122 | + " androidboot.storage_type=sd"); | |
123 | + } else if (bootdev == MMC1_BOOT || bootdev == MMC2_BOOT || | |
124 | + bootdev == MMC3_BOOT || bootdev == MMC4_BOOT) { | |
125 | + sprintf(newbootargs, | |
126 | + " androidboot.storage_type=emmc"); | |
127 | + } else if (bootdev == NAND_BOOT) { | |
128 | + sprintf(newbootargs, | |
129 | + " androidboot.storage_type=nand"); | |
130 | + } else | |
131 | + printf("boot device type is incorrect.\n"); | |
132 | + strncat(commandline, newbootargs, sizeof(commandline) - strlen(commandline)); | |
133 | + if (bootloader_gpt_overlay()) { | |
134 | + sprintf(newbootargs, " gpt"); | |
135 | + strncat(commandline, newbootargs, sizeof(commandline) - strlen(commandline)); | |
89 | 136 | } |
90 | - if (*hdr->cmdline) | |
91 | - strcat(newbootargs, hdr->cmdline); | |
92 | 137 | |
93 | - env_set("bootargs", newbootargs); | |
138 | + /* boot metric variables */ | |
139 | + metrics.ble_1 = get_timer(0); | |
140 | + sprintf(newbootargs, | |
141 | + " androidboot.boottime=1BLL:%d,1BLE:%d,KL:%d,KD:%d,AVB:%d,ODT:%d,SW:%d", | |
142 | + metrics.bll_1, metrics.ble_1, metrics.kl, metrics.kd, metrics.avb, | |
143 | + metrics.odt, metrics.sw); | |
144 | + strncat(commandline, newbootargs, sizeof(commandline) - strlen(commandline)); | |
94 | 145 | |
146 | +#ifdef CONFIG_AVB_SUPPORT | |
147 | + /* secondary cmdline added by avb */ | |
148 | + char *bootargs_sec = env_get("bootargs_sec"); | |
149 | + if (bootargs_sec) { | |
150 | + strncat(commandline, " ", sizeof(commandline) - strlen(commandline)); | |
151 | + strncat(commandline, bootargs_sec, sizeof(commandline) - strlen(commandline)); | |
152 | + } | |
153 | +#endif | |
154 | +#ifdef CONFIG_SYSTEM_RAMDISK_SUPPORT | |
155 | + /* Normal boot: | |
156 | + * cmdline to bypass ramdisk in boot.img, but use the system.img | |
157 | + * Recovery boot: | |
158 | + * Use the ramdisk in boot.img | |
159 | + */ | |
160 | + char *bootargs_3rd = env_get("bootargs_3rd"); | |
161 | + if (bootargs_3rd) { | |
162 | + strncat(commandline, " ", sizeof(commandline) - strlen(commandline)); | |
163 | + strncat(commandline, bootargs_3rd, sizeof(commandline) - strlen(commandline)); | |
164 | + } | |
165 | +#endif | |
166 | + | |
167 | + /* Add 'append_bootargs' to hold some paramemters which need to be appended | |
168 | + * to bootargs */ | |
169 | + char *append_bootargs = env_get("append_bootargs"); | |
170 | + if (append_bootargs) { | |
171 | + if (strlen(append_bootargs) + 2 > | |
172 | + (sizeof(commandline) - strlen(commandline))) { | |
173 | + printf("The 'append_bootargs' is too long to be appended to bootargs\n"); | |
174 | + } else { | |
175 | + strncat(commandline, " ", sizeof(commandline) - strlen(commandline)); | |
176 | + strncat(commandline, append_bootargs, sizeof(commandline) - strlen(commandline)); | |
177 | + } | |
178 | + } | |
179 | + | |
180 | + printf("Kernel command line: %s\n", commandline); | |
181 | + env_set("bootargs", commandline); | |
182 | + | |
95 | 183 | if (os_data) { |
96 | 184 | *os_data = (ulong)hdr; |
97 | 185 | *os_data += hdr->page_size; |
... | ... | @@ -202,4 +290,16 @@ |
202 | 290 | printf("%scmdline: %s\n", p, hdr->cmdline); |
203 | 291 | } |
204 | 292 | #endif |
293 | + | |
294 | +#define ARM64_IMAGE_MAGIC 0x644d5241 | |
295 | +bool image_arm64(void *images) | |
296 | +{ | |
297 | + struct header_image *ih; | |
298 | + | |
299 | + ih = (struct header_image *)images; | |
300 | + debug("image magic: %x\n", ih->magic); | |
301 | + if (ih->magic == le32_to_cpu(ARM64_IMAGE_MAGIC)) | |
302 | + return true; | |
303 | + return false; | |
304 | +} |
common/image-fdt.c
... | ... | @@ -6,6 +6,8 @@ |
6 | 6 | * (C) Copyright 2000-2006 |
7 | 7 | * Wolfgang Denk, DENX Software Engineering, wd@denx.de. |
8 | 8 | * |
9 | + * Copyright (C) 2015-2016 Freescale Semiconductor, Inc. | |
10 | + * | |
9 | 11 | * SPDX-License-Identifier: GPL-2.0+ |
10 | 12 | */ |
11 | 13 | |
... | ... | @@ -413,7 +415,34 @@ |
413 | 415 | debug("## No Flattened Device Tree\n"); |
414 | 416 | goto no_fdt; |
415 | 417 | } |
416 | - } else { | |
418 | + } | |
419 | +#ifdef CONFIG_ANDROID_BOOT_IMAGE | |
420 | + else if (genimg_get_format((void *)images->os.start) == | |
421 | + IMAGE_FORMAT_ANDROID) { | |
422 | + ulong fdt_data, fdt_len; | |
423 | + android_image_get_second((void *)images->os.start, | |
424 | + &fdt_data, &fdt_len); | |
425 | + | |
426 | + if (fdt_len) { | |
427 | + fdt_blob = (char *)fdt_data; | |
428 | + printf(" Booting using the fdt at 0x%p\n", fdt_blob); | |
429 | + | |
430 | + if (fdt_check_header(fdt_blob) != 0) { | |
431 | + fdt_error("image is not a fdt"); | |
432 | + goto error; | |
433 | + } | |
434 | + | |
435 | + if (fdt_totalsize(fdt_blob) != fdt_len) { | |
436 | + fdt_error("fdt size != image size"); | |
437 | + goto error; | |
438 | + } | |
439 | + } else { | |
440 | + debug("## No Flattened Device Tree\n"); | |
441 | + goto no_fdt; | |
442 | + } | |
443 | + } | |
444 | +#endif | |
445 | + else { | |
417 | 446 | debug("## No Flattened Device Tree\n"); |
418 | 447 | goto no_fdt; |
419 | 448 | } |
disk/part_efi.c
... | ... | @@ -135,6 +135,25 @@ |
135 | 135 | return 0; |
136 | 136 | } |
137 | 137 | |
138 | +static void prepare_last_lba_gpt_header(struct blk_desc *dev_desc, gpt_header *gpt_h) | |
139 | +{ | |
140 | + uint32_t calc_crc32; | |
141 | + uint64_t val; | |
142 | + | |
143 | + /* recalculate the values for the Backup GPT Header */ | |
144 | + val = le64_to_cpu(gpt_h->my_lba); | |
145 | + gpt_h->my_lba = cpu_to_le64(dev_desc->lba - 1);; | |
146 | + gpt_h->alternate_lba = cpu_to_le64(val); | |
147 | + gpt_h->last_usable_lba = cpu_to_le64(dev_desc->lba - 34); | |
148 | + gpt_h->partition_entry_lba = | |
149 | + cpu_to_le64(le64_to_cpu(gpt_h->last_usable_lba) + 1); | |
150 | + gpt_h->header_crc32 = 0; | |
151 | + | |
152 | + calc_crc32 = efi_crc32((const unsigned char *)gpt_h, | |
153 | + le32_to_cpu(gpt_h->header_size)); | |
154 | + gpt_h->header_crc32 = cpu_to_le32(calc_crc32); | |
155 | +} | |
156 | + | |
138 | 157 | static int validate_gpt_entries(gpt_header *gpt_h, gpt_entry *gpt_e) |
139 | 158 | { |
140 | 159 | uint32_t calc_crc32; |
... | ... | @@ -145,7 +164,7 @@ |
145 | 164 | le32_to_cpu(gpt_h->sizeof_partition_entry)); |
146 | 165 | |
147 | 166 | if (calc_crc32 != le32_to_cpu(gpt_h->partition_entry_array_crc32)) { |
148 | - printf("%s: 0x%x != 0x%x\n", | |
167 | + debug("%s: 0x%x != 0x%x\n", | |
149 | 168 | "GUID Partition Table Entry Array CRC is wrong", |
150 | 169 | le32_to_cpu(gpt_h->partition_entry_array_crc32), |
151 | 170 | calc_crc32); |
152 | 171 | |
... | ... | @@ -281,14 +300,14 @@ |
281 | 300 | /* This function validates AND fills in the GPT header and PTE */ |
282 | 301 | if (is_gpt_valid(dev_desc, GPT_PRIMARY_PARTITION_TABLE_LBA, |
283 | 302 | gpt_head, &gpt_pte) != 1) { |
284 | - printf("%s: *** ERROR: Invalid GPT ***\n", __func__); | |
303 | + debug("%s: *** ERROR: Invalid GPT ***\n", __func__); | |
285 | 304 | if (is_gpt_valid(dev_desc, (dev_desc->lba - 1), |
286 | 305 | gpt_head, &gpt_pte) != 1) { |
287 | 306 | printf("%s: *** ERROR: Invalid Backup GPT ***\n", |
288 | 307 | __func__); |
289 | 308 | return -1; |
290 | 309 | } else { |
291 | - printf("%s: *** Using Backup GPT ***\n", | |
310 | + debug("%s: *** Using Backup GPT ***\n", | |
292 | 311 | __func__); |
293 | 312 | } |
294 | 313 | } |
... | ... | @@ -849,6 +868,58 @@ |
849 | 868 | } |
850 | 869 | |
851 | 870 | prepare_backup_gpt_header(gpt_h); |
871 | + | |
872 | + /* write Backup GPT */ | |
873 | + lba = le64_to_cpu(gpt_h->partition_entry_lba); | |
874 | + cnt = gpt_e_blk_cnt; | |
875 | + if (blk_dwrite(dev_desc, lba, cnt, gpt_e) != cnt) { | |
876 | + printf("%s: failed writing '%s' (%d blks at 0x" LBAF ")\n", | |
877 | + __func__, "Backup GPT Entries", cnt, lba); | |
878 | + return 1; | |
879 | + } | |
880 | + | |
881 | + lba = le64_to_cpu(gpt_h->my_lba); | |
882 | + cnt = 1; /* GPT Header (1 block) */ | |
883 | + if (blk_dwrite(dev_desc, lba, cnt, gpt_h) != cnt) { | |
884 | + printf("%s: failed writing '%s' (%d blks at 0x" LBAF ")\n", | |
885 | + __func__, "Backup GPT Header", cnt, lba); | |
886 | + return 1; | |
887 | + } | |
888 | + | |
889 | + return 0; | |
890 | +} | |
891 | +int write_backup_gpt_partitions(struct blk_desc *dev_desc, void *buf) | |
892 | +{ | |
893 | + gpt_header *gpt_h; | |
894 | + gpt_entry *gpt_e; | |
895 | + int gpt_e_blk_cnt; | |
896 | + lbaint_t lba; | |
897 | + int cnt; | |
898 | + | |
899 | + if (is_valid_gpt_buf(dev_desc, buf)) | |
900 | + return -1; | |
901 | + | |
902 | + /* determine start of GPT Header in the buffer */ | |
903 | + gpt_h = buf + (GPT_PRIMARY_PARTITION_TABLE_LBA * | |
904 | + dev_desc->blksz); | |
905 | + | |
906 | + /* determine start of GPT Entries in the buffer */ | |
907 | + gpt_e = buf + (le64_to_cpu(gpt_h->partition_entry_lba) * | |
908 | + dev_desc->blksz); | |
909 | + gpt_e_blk_cnt = BLOCK_CNT((le32_to_cpu(gpt_h->num_partition_entries) * | |
910 | + le32_to_cpu(gpt_h->sizeof_partition_entry)), | |
911 | + dev_desc); | |
912 | + | |
913 | + /* write MBR */ | |
914 | + lba = 0; /* MBR is always at 0 */ | |
915 | + cnt = 1; /* MBR (1 block) */ | |
916 | + if (blk_dwrite(dev_desc, lba, cnt, buf) != cnt) { | |
917 | + printf("%s: failed writing '%s' (%d blks at 0x" LBAF ")\n", | |
918 | + __func__, "MBR", cnt, lba); | |
919 | + return 1; | |
920 | + } | |
921 | + | |
922 | + prepare_last_lba_gpt_header(dev_desc, gpt_h); | |
852 | 923 | |
853 | 924 | /* write Backup GPT */ |
854 | 925 | lba = le64_to_cpu(gpt_h->partition_entry_lba); |
drivers/usb/gadget/Makefile
... | ... | @@ -29,6 +29,8 @@ |
29 | 29 | obj-$(CONFIG_DFU_OVER_USB) += f_dfu.o |
30 | 30 | obj-$(CONFIG_USB_FUNCTION_MASS_STORAGE) += f_mass_storage.o |
31 | 31 | obj-$(CONFIG_USB_FUNCTION_FASTBOOT) += f_fastboot.o |
32 | +obj-$(CONFIG_FASTBOOT_LOCK) += fastboot_lock_unlock.o | |
33 | +obj-$(CONFIG_BCB_SUPPORT) += command.o bcb.o | |
32 | 34 | obj-$(CONFIG_USB_FUNCTION_SDP) += f_sdp.o |
33 | 35 | obj-$(CONFIG_USB_FUNCTION_ROCKUSB) += f_rockusb.o |
34 | 36 | endif |
drivers/usb/gadget/bcb.c
1 | +/* | |
2 | + * Copyright (C) 2015-2016 Freescale Semiconductor, Inc. | |
3 | + * Copyright 2017 NXP | |
4 | + * | |
5 | + * SPDX-License-Identifier: GPL-2.0+ | |
6 | + */ | |
7 | + | |
8 | +#include <fsl_fastboot.h> | |
9 | +#include <linux/stat.h> | |
10 | +#include <linux/types.h> | |
11 | +#include <common.h> | |
12 | +#include <g_dnl.h> | |
13 | +#include <mmc.h> | |
14 | +#include "bcb.h" | |
15 | +#define ALIGN_BYTES 64 /*armv7 cache line need 64 bytes aligned */ | |
16 | + | |
17 | +static ulong get_block_size(char *ifname, int dev) | |
18 | +{ | |
19 | + struct blk_desc *dev_desc = NULL; | |
20 | + | |
21 | + dev_desc = blk_get_dev(ifname, dev); | |
22 | + if (dev_desc == NULL) { | |
23 | + printf("Block device %s %d not supported\n", ifname, dev); | |
24 | + return 0; | |
25 | + } | |
26 | + | |
27 | + return dev_desc->blksz; | |
28 | +} | |
29 | + | |
30 | +static int do_write(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) | |
31 | +{ | |
32 | + char *ep; | |
33 | + struct blk_desc *dev_desc = NULL; | |
34 | + int dev; | |
35 | + int part = 0; | |
36 | + disk_partition_t part_info; | |
37 | + ulong offset = 0u; | |
38 | + ulong limit = 0u; | |
39 | + void *addr; | |
40 | + uint blk; | |
41 | + uint cnt; | |
42 | + | |
43 | + if (argc != 6) { | |
44 | + cmd_usage(cmdtp); | |
45 | + return 1; | |
46 | + } | |
47 | + | |
48 | + dev = (int)simple_strtoul(argv[2], &ep, 16); | |
49 | + if (*ep) { | |
50 | + if (*ep != ':') { | |
51 | + printf("Invalid block device %s\n", argv[2]); | |
52 | + return 1; | |
53 | + } | |
54 | + part = (int)simple_strtoul(++ep, NULL, 16); | |
55 | + } | |
56 | + | |
57 | + dev_desc = blk_get_dev(argv[1], dev); | |
58 | + if (dev_desc == NULL) { | |
59 | + printf("Block device %s %d not supported\n", argv[1], dev); | |
60 | + return 1; | |
61 | + } | |
62 | + | |
63 | + addr = (void *)simple_strtoul(argv[3], NULL, 16); | |
64 | + blk = simple_strtoul(argv[4], NULL, 16); | |
65 | + cnt = simple_strtoul(argv[5], NULL, 16); | |
66 | + | |
67 | + if (part != 0) { | |
68 | + if (part_get_info(dev_desc, part, &part_info)) { | |
69 | + printf("Cannot find partition %d\n", part); | |
70 | + return 1; | |
71 | + } | |
72 | + offset = part_info.start; | |
73 | + limit = part_info.size; | |
74 | + } else { | |
75 | + /* Largest address not available in block_dev_desc_t. */ | |
76 | + limit = ~0; | |
77 | + } | |
78 | + | |
79 | + if (cnt + blk > limit) { | |
80 | + printf("Write out of range\n"); | |
81 | + return 1; | |
82 | + } | |
83 | + | |
84 | + if (blk_dwrite(dev_desc, offset + blk, cnt, addr) != cnt) { | |
85 | + printf("Error writing blocks\n"); | |
86 | + return 1; | |
87 | + } | |
88 | + | |
89 | + return 0; | |
90 | +} | |
91 | + | |
92 | +U_BOOT_CMD( | |
93 | + write, 6, 0, do_write, | |
94 | + "write binary data to a partition", | |
95 | + "<interface> <dev[:part]> addr blk# cnt" | |
96 | +); | |
97 | + | |
98 | +int bcb_rw_block(bool bread, char **ppblock, | |
99 | + uint *pblksize, char *pblock_write, uint offset, uint size) | |
100 | +{ | |
101 | + int ret; | |
102 | + char *argv[6]; | |
103 | + char addr_str[20]; | |
104 | + char cnt_str[8]; | |
105 | + char devpart_str[8]; | |
106 | + char block_begin_str[8]; | |
107 | + ulong blk_size = 0; | |
108 | + uint blk_begin = 0; | |
109 | + uint blk_end = 0; | |
110 | + uint block_cnt = 0; | |
111 | + char *p_block = NULL; | |
112 | + unsigned int mmc_id; | |
113 | + | |
114 | + if (bread && ((ppblock == NULL) || (pblksize == NULL))) | |
115 | + return -1; | |
116 | + | |
117 | + if (!bread && (pblock_write == NULL)) | |
118 | + return -1; | |
119 | + | |
120 | + mmc_id = mmc_get_env_dev(); | |
121 | + blk_size = get_block_size("mmc", mmc_id); | |
122 | + if (blk_size == 0) { | |
123 | + printf("bcb_rw_block, get_block_size return 0\n"); | |
124 | + return -1; | |
125 | + } | |
126 | + | |
127 | + blk_begin = offset/blk_size; | |
128 | + blk_end = (offset + size)/blk_size; | |
129 | + block_cnt = 1 + (blk_end - blk_begin); | |
130 | + | |
131 | + sprintf(devpart_str, "0x%x:0x%x", mmc_id, | |
132 | + fastboot_flash_find_index(FASTBOOT_PARTITION_MISC)); | |
133 | + sprintf(block_begin_str, "0x%x", blk_begin); | |
134 | + sprintf(cnt_str, "0x%x", block_cnt); | |
135 | + | |
136 | + argv[0] = "rw"; /* not care */ | |
137 | + argv[1] = "mmc"; | |
138 | + argv[2] = devpart_str; | |
139 | + argv[3] = addr_str; | |
140 | + argv[4] = block_begin_str; | |
141 | + argv[5] = cnt_str; | |
142 | + | |
143 | + if (bread) { | |
144 | + p_block = (char *)memalign(ALIGN_BYTES, blk_size * block_cnt); | |
145 | + if (NULL == p_block) { | |
146 | + printf("bcb_rw_block, memalign %d bytes failed\n", | |
147 | + (int)(blk_size * block_cnt)); | |
148 | + return -1; | |
149 | + } | |
150 | + sprintf(addr_str, "0x%x", (unsigned int)(uintptr_t)p_block); | |
151 | + ret = do_raw_read(NULL, 0, 6, argv); | |
152 | + if (ret) { | |
153 | + free(p_block); | |
154 | + printf("do_raw_read failed, ret %d\n", ret); | |
155 | + return -1; | |
156 | + } | |
157 | + | |
158 | + *ppblock = p_block; | |
159 | + *pblksize = (uint)blk_size; | |
160 | + } else { | |
161 | + sprintf(addr_str, "0x%x", (unsigned int)(uintptr_t)pblock_write); | |
162 | + ret = do_write(NULL, 0, 6, argv); | |
163 | + if (ret) { | |
164 | + printf("do_write failed, ret %d\n", ret); | |
165 | + return -1; | |
166 | + } | |
167 | + } | |
168 | + return 0; | |
169 | +} |
drivers/usb/gadget/bcb.h
1 | +/* | |
2 | + * Copyright (C) 2015-2016 Freescale Semiconductor, Inc. | |
3 | + * | |
4 | + * SPDX-License-Identifier: GPL-2.0+ | |
5 | + */ | |
6 | + | |
7 | +#ifndef BCB_H | |
8 | +#define BCB_H | |
9 | +#include <linux/types.h> | |
10 | +#include <linux/stat.h> | |
11 | + | |
12 | +#define FASTBOOT_BCB_CMD "bootonce-bootloader" | |
13 | +#ifdef CONFIG_ANDROID_RECOVERY | |
14 | +#define RECOVERY_BCB_CMD "boot-recovery" | |
15 | +#endif | |
16 | +/* keep same as bootable/recovery/bootloader.h */ | |
17 | +struct bootloader_message { | |
18 | + char command[32]; | |
19 | + char status[32]; | |
20 | + char recovery[768]; | |
21 | + | |
22 | + /* The 'recovery' field used to be 1024 bytes. It has only ever | |
23 | + been used to store the recovery command line, so 768 bytes | |
24 | + should be plenty. We carve off the last 256 bytes to store the | |
25 | + stage string (for multistage packages) and possible future | |
26 | + expansion. */ | |
27 | + char stage[32]; | |
28 | + | |
29 | + /* The 'reserved' field used to be 224 bytes when it was initially | |
30 | + carved off from the 1024-byte recovery field. Bump it up to | |
31 | + 1184-byte so that the entire bootloader_message struct rounds up | |
32 | + to 2048-byte. | |
33 | + */ | |
34 | + char reserved[1184]; | |
35 | +}; | |
36 | + | |
37 | +struct bootloader_message_ab { | |
38 | + struct bootloader_message message; | |
39 | + char slot_suffix[32]; | |
40 | + | |
41 | + /* Round up the entire struct to 4096-byte. */ | |
42 | + char reserved[2016]; | |
43 | +}; | |
44 | + | |
45 | +/* start from bootloader_message_ab.slot_suffix[BOOTCTRL_IDX] */ | |
46 | +#define BOOTCTRL_IDX 0 | |
47 | +#define MISC_COMMAND_IDX 0 | |
48 | +#define BOOTCTRL_OFFSET \ | |
49 | + (u32)(&(((struct bootloader_message_ab *)0)->slot_suffix[BOOTCTRL_IDX])) | |
50 | +#define MISC_COMMAND \ | |
51 | + (u32)(uintptr_t)(&(((struct bootloader_message *)0)->command[MISC_COMMAND_IDX])) | |
52 | +int bcb_rw_block(bool bread, char **ppblock, | |
53 | + uint *pblksize, char *pblock_write, uint offset, uint size); | |
54 | + | |
55 | +int bcb_write_command(char *bcb_command); | |
56 | +int bcb_read_command(char *command); | |
57 | + | |
58 | +#endif |
drivers/usb/gadget/command.c
1 | +/* | |
2 | + * Copyright (C) 2015-2016 Freescale Semiconductor, Inc. | |
3 | + * | |
4 | + * SPDX-License-Identifier: GPL-2.0+ | |
5 | + */ | |
6 | + | |
7 | +#include <common.h> | |
8 | +#include <g_dnl.h> | |
9 | +#include "bcb.h" | |
10 | + | |
11 | +int bcb_read_command(char *command) | |
12 | +{ | |
13 | + int ret = 0; | |
14 | + char *p_block = NULL; | |
15 | + uint offset_in_block = 0; | |
16 | + uint blk_size = 0; | |
17 | + | |
18 | + if (command == NULL) | |
19 | + return -1; | |
20 | + | |
21 | + ret = bcb_rw_block(true, &p_block, &blk_size, NULL, MISC_COMMAND, 32); | |
22 | + if (ret) { | |
23 | + printf("read_bootctl, bcb_rw_block read failed\n"); | |
24 | + return -1; | |
25 | + } | |
26 | + | |
27 | + offset_in_block = MISC_COMMAND%blk_size; | |
28 | + memcpy(command, p_block + offset_in_block, 32); | |
29 | + free(p_block); | |
30 | + | |
31 | + return 0; | |
32 | +} | |
33 | +int bcb_write_command(char *bcb_command) | |
34 | +{ | |
35 | + int ret = 0; | |
36 | + char *p_block = NULL; | |
37 | + uint offset_in_block = 0; | |
38 | + uint blk_size = 0; | |
39 | + | |
40 | + if (bcb_command == NULL) | |
41 | + return -1; | |
42 | + | |
43 | + | |
44 | + ret = bcb_rw_block(true, &p_block, &blk_size, NULL, MISC_COMMAND, 32); | |
45 | + if (ret) { | |
46 | + printf("write_bootctl, bcb_rw_block read failed\n"); | |
47 | + return -1; | |
48 | + } | |
49 | + | |
50 | + offset_in_block = MISC_COMMAND%blk_size; | |
51 | + memcpy(p_block + offset_in_block, bcb_command, 32); | |
52 | + | |
53 | + ret = bcb_rw_block(false, NULL, NULL, p_block, MISC_COMMAND, 32); | |
54 | + if (ret) { | |
55 | + free(p_block); | |
56 | + printf("write_bootctl, bcb_rw_block write failed\n"); | |
57 | + return -1; | |
58 | + } | |
59 | + | |
60 | + free(p_block); | |
61 | + return 0; | |
62 | +} |
drivers/usb/gadget/f_fastboot.c
Changes suppressed. Click to show
... | ... | @@ -8,11 +8,15 @@ |
8 | 8 | * Copyright 2014 Linaro, Ltd. |
9 | 9 | * Rob Herring <robh@kernel.org> |
10 | 10 | * |
11 | + * Copyright (C) 2015-2016 Freescale Semiconductor, Inc. | |
12 | + * Copyright 2017 NXP | |
13 | + * | |
11 | 14 | * SPDX-License-Identifier: GPL-2.0+ |
12 | 15 | */ |
13 | 16 | #include <config.h> |
14 | 17 | #include <common.h> |
15 | 18 | #include <errno.h> |
19 | +#include <stdlib.h> | |
16 | 20 | #include <fastboot.h> |
17 | 21 | #include <malloc.h> |
18 | 22 | #include <linux/usb/ch9.h> |
... | ... | @@ -21,6 +25,7 @@ |
21 | 25 | #include <linux/compiler.h> |
22 | 26 | #include <version.h> |
23 | 27 | #include <g_dnl.h> |
28 | +#include "../lib/avb/fsl/utils.h" | |
24 | 29 | #ifdef CONFIG_FASTBOOT_FLASH_MMC_DEV |
25 | 30 | #include <fb_mmc.h> |
26 | 31 | #endif |
27 | 32 | |
... | ... | @@ -28,8 +33,43 @@ |
28 | 33 | #include <fb_nand.h> |
29 | 34 | #endif |
30 | 35 | |
36 | +#ifdef CONFIG_FSL_FASTBOOT | |
37 | +#include <asm/mach-imx/sys_proto.h> | |
38 | +#include <fsl_fastboot.h> | |
39 | +#include <mmc.h> | |
40 | +#include <android_image.h> | |
41 | +#include <asm/bootm.h> | |
42 | +#include <nand.h> | |
43 | +#include <part.h> | |
44 | +#include <sparse_format.h> | |
45 | +#include <image-sparse.h> | |
46 | +#include <image.h> | |
47 | +#include <asm/mach-imx/boot_mode.h> | |
48 | +#include <asm/arch/sys_proto.h> | |
49 | +#include <asm/setup.h> | |
50 | +#include <environment.h> | |
51 | +#ifdef CONFIG_ANDROID_RECOVERY | |
52 | +#include <recovery.h> | |
53 | +#endif | |
54 | + | |
55 | +#ifdef CONFIG_BCB_SUPPORT | |
56 | +#include "bcb.h" | |
57 | +#endif | |
58 | + | |
59 | +#ifdef CONFIG_AVB_SUPPORT | |
60 | +#include <fsl_avb.h> | |
61 | +#endif | |
62 | + | |
63 | +#ifdef CONFIG_FASTBOOT_LOCK | |
64 | +#include "fastboot_lock_unlock.h" | |
65 | +#endif | |
66 | +#endif | |
67 | + | |
31 | 68 | #define FASTBOOT_VERSION "0.4" |
32 | 69 | |
70 | +#define FASTBOOT_COMMON_VAR_NUM 13 | |
71 | +#define FASTBOOT_VAR_YES "yes" | |
72 | +#define FASTBOOT_VAR_NO "no" | |
33 | 73 | #define FASTBOOT_INTERFACE_CLASS 0xff |
34 | 74 | #define FASTBOOT_INTERFACE_SUB_CLASS 0x42 |
35 | 75 | #define FASTBOOT_INTERFACE_PROTOCOL 0x03 |
36 | 76 | |
37 | 77 | |
... | ... | @@ -39,18 +79,69 @@ |
39 | 79 | #define TX_ENDPOINT_MAXIMUM_PACKET_SIZE (0x0040) |
40 | 80 | |
41 | 81 | #define EP_BUFFER_SIZE 4096 |
82 | + | |
83 | +#ifdef CONFIG_FSL_FASTBOOT | |
84 | + | |
85 | +#define ANDROID_GPT_OFFSET 0 | |
86 | +#define ANDROID_GPT_SIZE 0x100000 | |
87 | +#define ANDROID_GPT_END 0x4400 | |
88 | + | |
89 | +#ifdef CONFIG_FLASH_MCUFIRMWARE_SUPPORT | |
90 | +struct fastboot_device_info fastboot_firmwareinfo; | |
91 | +#endif | |
92 | + | |
93 | +#if defined (CONFIG_ARCH_IMX8) || defined (CONFIG_ARCH_IMX8M) | |
94 | +#define DST_DECOMPRESS_LEN 1024*1024*32 | |
95 | +#endif | |
96 | + | |
97 | +#endif | |
42 | 98 | /* |
43 | 99 | * EP_BUFFER_SIZE must always be an integral multiple of maxpacket size |
44 | 100 | * (64 or 512 or 1024), else we break on certain controllers like DWC3 |
45 | 101 | * that expect bulk OUT requests to be divisible by maxpacket size. |
46 | 102 | */ |
47 | 103 | |
104 | +/* common variables of fastboot getvar command */ | |
105 | +char *fastboot_common_var[FASTBOOT_COMMON_VAR_NUM] = { | |
106 | + "version", | |
107 | + "version-bootloader", | |
108 | + "version-baseband", | |
109 | + "product", | |
110 | + "secure", | |
111 | + "max-download-size", | |
112 | + "erase-block-size", | |
113 | + "logical-block-size", | |
114 | + "unlocked", | |
115 | + "off-mode-charge", | |
116 | + "battery-voltage", | |
117 | + "variant", | |
118 | + "battery-soc-ok" | |
119 | +}; | |
120 | + | |
121 | +/* Boot metric variables */ | |
122 | +boot_metric metrics = { | |
123 | + .bll_1 = 0, | |
124 | + .ble_1 = 0, | |
125 | + .kl = 0, | |
126 | + .kd = 0, | |
127 | + .avb = 0, | |
128 | + .odt = 0, | |
129 | + .sw = 0 | |
130 | +}; | |
131 | + | |
132 | +typedef struct usb_req usb_req; | |
133 | +struct usb_req { | |
134 | + struct usb_request *in_req; | |
135 | + usb_req *next; | |
136 | +}; | |
137 | + | |
48 | 138 | struct f_fastboot { |
49 | 139 | struct usb_function usb_function; |
50 | 140 | |
51 | 141 | /* IN/OUT EP's and corresponding requests */ |
52 | 142 | struct usb_ep *in_ep, *out_ep; |
53 | 143 | struct usb_request *in_req, *out_req; |
144 | + usb_req *front, *rear; | |
54 | 145 | }; |
55 | 146 | |
56 | 147 | static inline struct f_fastboot *func_to_fastboot(struct usb_function *f) |
... | ... | @@ -153,6 +244,1960 @@ |
153 | 244 | |
154 | 245 | static char *fb_response_str; |
155 | 246 | |
247 | +#ifdef CONFIG_FSL_FASTBOOT | |
248 | + | |
249 | +#define ANDROID_MBR_OFFSET 0 | |
250 | +#define ANDROID_MBR_SIZE 0x200 | |
251 | +#ifdef CONFIG_BOOTLOADER_OFFSET_33K | |
252 | +#define ANDROID_BOOTLOADER_OFFSET 0x8400 | |
253 | +/* The Bootloader offset of imx8qxp B0 board is set to 32K */ | |
254 | +#elif defined(CONFIG_BOOTLOADER_OFFSET_32K) | |
255 | +#define ANDROID_BOOTLOADER_OFFSET 0x8000 | |
256 | +#else | |
257 | +#define ANDROID_BOOTLOADER_OFFSET 0x400 | |
258 | +#endif | |
259 | +#define ANDROID_BOOTLOADER_SIZE 0x1FFC00 | |
260 | + | |
261 | +#define MMC_SATA_BLOCK_SIZE 512 | |
262 | +#define FASTBOOT_FBPARTS_ENV_MAX_LEN 1024 | |
263 | +/* To support the Android-style naming of flash */ | |
264 | +#define MAX_PTN 32 | |
265 | +struct fastboot_ptentry g_ptable[MAX_PTN]; | |
266 | +unsigned int g_pcount; | |
267 | +struct fastboot_device_info fastboot_devinfo; | |
268 | + | |
269 | + | |
270 | +enum { | |
271 | + PTN_GPT_INDEX = 0, | |
272 | +#ifdef CONFIG_FLASH_MCUFIRMWARE_SUPPORT | |
273 | + PTN_M4_OS_INDEX, | |
274 | +#endif | |
275 | + PTN_BOOTLOADER_INDEX, | |
276 | +}; | |
277 | +static unsigned int download_bytes_unpadded; | |
278 | + | |
279 | +static struct cmd_fastboot_interface interface = { | |
280 | + .rx_handler = NULL, | |
281 | + .reset_handler = NULL, | |
282 | + .product_name = NULL, | |
283 | + .serial_no = NULL, | |
284 | + .nand_block_size = 0, | |
285 | + .transfer_buffer = (unsigned char *)0xffffffff, | |
286 | + .transfer_buffer_size = 0, | |
287 | +}; | |
288 | + | |
289 | +int read_from_partition_multi(const char* partition, | |
290 | + int64_t offset, size_t num_bytes, void* buffer, size_t* out_num_read) | |
291 | +{ | |
292 | + struct fastboot_ptentry *pte; | |
293 | + unsigned char *bdata; | |
294 | + unsigned char *out_buf = (unsigned char *)buffer; | |
295 | + unsigned char *dst, *dst64 = NULL; | |
296 | + unsigned long blksz; | |
297 | + unsigned long s, cnt; | |
298 | + size_t num_read = 0; | |
299 | + lbaint_t part_start, part_end, bs, be, bm, blk_num; | |
300 | + margin_pos_t margin; | |
301 | + struct blk_desc *fs_dev_desc = NULL; | |
302 | + int dev_no; | |
303 | + int ret; | |
304 | + | |
305 | + assert(buffer != NULL && out_num_read != NULL); | |
306 | + | |
307 | + dev_no = mmc_get_env_dev(); | |
308 | + if ((fs_dev_desc = blk_get_dev("mmc", dev_no)) == NULL) { | |
309 | + printf("mmc device not found\n"); | |
310 | + return -1; | |
311 | + } | |
312 | + | |
313 | + pte = fastboot_flash_find_ptn(partition); | |
314 | + if (!pte) { | |
315 | + printf("no %s partition\n", partition); | |
316 | + return -1; | |
317 | + } | |
318 | + | |
319 | + blksz = fs_dev_desc->blksz; | |
320 | + part_start = pte->start; | |
321 | + part_end = pte->start + pte->length - 1; | |
322 | + | |
323 | + if (get_margin_pos((uint64_t)part_start, (uint64_t)part_end, blksz, | |
324 | + &margin, offset, num_bytes, true)) | |
325 | + return -1; | |
326 | + | |
327 | + bs = (lbaint_t)margin.blk_start; | |
328 | + be = (lbaint_t)margin.blk_end; | |
329 | + s = margin.start; | |
330 | + bm = margin.multi; | |
331 | + | |
332 | + /* alloc a blksz mem */ | |
333 | + bdata = (unsigned char *)memalign(ALIGN_BYTES, blksz); | |
334 | + if (bdata == NULL) { | |
335 | + printf("Failed to allocate memory!\n"); | |
336 | + return -1; | |
337 | + } | |
338 | + | |
339 | + /* support multi blk read */ | |
340 | + while (bs <= be) { | |
341 | + if (!s && bm > 1) { | |
342 | + dst = out_buf; | |
343 | + dst64 = PTR_ALIGN(out_buf, 64); /* for mmc blk read alignment */ | |
344 | + if (dst64 != dst) { | |
345 | + dst = dst64; | |
346 | + bm--; | |
347 | + } | |
348 | + blk_num = bm; | |
349 | + cnt = bm * blksz; | |
350 | + bm = 0; /* no more multi blk */ | |
351 | + } else { | |
352 | + blk_num = 1; | |
353 | + cnt = blksz - s; | |
354 | + if (num_read + cnt > num_bytes) | |
355 | + cnt = num_bytes - num_read; | |
356 | + dst = bdata; | |
357 | + } | |
358 | + if (blk_dread(fs_dev_desc, bs, blk_num, dst) != blk_num) { | |
359 | + ret = -1; | |
360 | + goto fail; | |
361 | + } | |
362 | + | |
363 | + if (dst == bdata) | |
364 | + memcpy(out_buf, bdata + s, cnt); | |
365 | + else if (dst == dst64) | |
366 | + memcpy(out_buf, dst, cnt); /* internal copy */ | |
367 | + | |
368 | + s = 0; | |
369 | + bs += blk_num; | |
370 | + num_read += cnt; | |
371 | + out_buf += cnt; | |
372 | + } | |
373 | + *out_num_read = num_read; | |
374 | + ret = 0; | |
375 | + | |
376 | +fail: | |
377 | + free(bdata); | |
378 | + return ret; | |
379 | +} | |
380 | + | |
381 | +static void save_env(struct fastboot_ptentry *ptn, | |
382 | + char *var, char *val) | |
383 | +{ | |
384 | + env_set(var, val); | |
385 | + env_save(); | |
386 | +} | |
387 | + | |
388 | +/* When save = 0, just parse. The input is unchanged | |
389 | + When save = 1, parse and do the save. The input is changed */ | |
390 | +static int parse_env(void *ptn, char *err_string, int save, int debug) | |
391 | +{ | |
392 | + int ret = 1; | |
393 | + unsigned int sets = 0; | |
394 | + unsigned int comment_start = 0; | |
395 | + char *var = NULL; | |
396 | + char *var_end = NULL; | |
397 | + char *val = NULL; | |
398 | + char *val_end = NULL; | |
399 | + unsigned int i; | |
400 | + | |
401 | + char *buff = (char *)interface.transfer_buffer; | |
402 | + unsigned int size = download_bytes_unpadded; | |
403 | + | |
404 | + /* The input does not have to be null terminated. | |
405 | + This will cause a problem in the corner case | |
406 | + where the last line does not have a new line. | |
407 | + Put a null after the end of the input. | |
408 | + | |
409 | + WARNING : Input buffer is assumed to be bigger | |
410 | + than the size of the input */ | |
411 | + if (save) | |
412 | + buff[size] = 0; | |
413 | + | |
414 | + for (i = 0; i < size; i++) { | |
415 | + | |
416 | + if (NULL == var) { | |
417 | + | |
418 | + /* | |
419 | + * Check for comments, comment ok only on | |
420 | + * mostly empty lines | |
421 | + */ | |
422 | + if (buff[i] == '#') | |
423 | + comment_start = 1; | |
424 | + | |
425 | + if (comment_start) { | |
426 | + if ((buff[i] == '\r') || | |
427 | + (buff[i] == '\n')) { | |
428 | + comment_start = 0; | |
429 | + } | |
430 | + } else { | |
431 | + if (!((buff[i] == ' ') || | |
432 | + (buff[i] == '\t') || | |
433 | + (buff[i] == '\r') || | |
434 | + (buff[i] == '\n'))) { | |
435 | + /* | |
436 | + * Normal whitespace before the | |
437 | + * variable | |
438 | + */ | |
439 | + var = &buff[i]; | |
440 | + } | |
441 | + } | |
442 | + | |
443 | + } else if (((NULL == var_end) || (NULL == val)) && | |
444 | + ((buff[i] == '\r') || (buff[i] == '\n'))) { | |
445 | + | |
446 | + /* This is the case when a variable | |
447 | + is unset. */ | |
448 | + | |
449 | + if (save) { | |
450 | + /* Set the var end to null so the | |
451 | + normal string routines will work | |
452 | + | |
453 | + WARNING : This changes the input */ | |
454 | + buff[i] = '\0'; | |
455 | + | |
456 | + save_env(ptn, var, val); | |
457 | + | |
458 | + if (debug) | |
459 | + printf("Unsetting %s\n", var); | |
460 | + } | |
461 | + | |
462 | + /* Clear the variable so state is parse is back | |
463 | + to initial. */ | |
464 | + var = NULL; | |
465 | + var_end = NULL; | |
466 | + sets++; | |
467 | + } else if (NULL == var_end) { | |
468 | + if ((buff[i] == ' ') || | |
469 | + (buff[i] == '\t')) | |
470 | + var_end = &buff[i]; | |
471 | + } else if (NULL == val) { | |
472 | + if (!((buff[i] == ' ') || | |
473 | + (buff[i] == '\t'))) | |
474 | + val = &buff[i]; | |
475 | + } else if (NULL == val_end) { | |
476 | + if ((buff[i] == '\r') || | |
477 | + (buff[i] == '\n')) { | |
478 | + /* look for escaped cr or ln */ | |
479 | + if ('\\' == buff[i - 1]) { | |
480 | + /* check for dos */ | |
481 | + if ((buff[i] == '\r') && | |
482 | + (buff[i+1] == '\n')) | |
483 | + buff[i + 1] = ' '; | |
484 | + buff[i - 1] = buff[i] = ' '; | |
485 | + } else { | |
486 | + val_end = &buff[i]; | |
487 | + } | |
488 | + } | |
489 | + } else { | |
490 | + sprintf(err_string, "Internal Error"); | |
491 | + | |
492 | + if (debug) | |
493 | + printf("Internal error at %s %d\n", | |
494 | + __FILE__, __LINE__); | |
495 | + return 1; | |
496 | + } | |
497 | + /* Check if a var / val pair is ready */ | |
498 | + if (NULL != val_end) { | |
499 | + if (save) { | |
500 | + /* Set the end's with nulls so | |
501 | + normal string routines will | |
502 | + work. | |
503 | + | |
504 | + WARNING : This changes the input */ | |
505 | + *var_end = '\0'; | |
506 | + *val_end = '\0'; | |
507 | + | |
508 | + save_env(ptn, var, val); | |
509 | + | |
510 | + if (debug) | |
511 | + printf("Setting %s %s\n", var, val); | |
512 | + } | |
513 | + | |
514 | + /* Clear the variable so state is parse is back | |
515 | + to initial. */ | |
516 | + var = NULL; | |
517 | + var_end = NULL; | |
518 | + val = NULL; | |
519 | + val_end = NULL; | |
520 | + | |
521 | + sets++; | |
522 | + } | |
523 | + } | |
524 | + | |
525 | + /* Corner case | |
526 | + Check for the case that no newline at end of the input */ | |
527 | + if ((NULL != var) && | |
528 | + (NULL == val_end)) { | |
529 | + if (save) { | |
530 | + /* case of val / val pair */ | |
531 | + if (var_end) | |
532 | + *var_end = '\0'; | |
533 | + /* else case handled by setting 0 past | |
534 | + the end of buffer. | |
535 | + Similar for val_end being null */ | |
536 | + save_env(ptn, var, val); | |
537 | + | |
538 | + if (debug) { | |
539 | + if (var_end) | |
540 | + printf("Trailing Setting %s %s\n", var, val); | |
541 | + else | |
542 | + printf("Trailing Unsetting %s\n", var); | |
543 | + } | |
544 | + } | |
545 | + sets++; | |
546 | + } | |
547 | + /* Did we set anything ? */ | |
548 | + if (0 == sets) | |
549 | + sprintf(err_string, "No variables set"); | |
550 | + else | |
551 | + ret = 0; | |
552 | + | |
553 | + return ret; | |
554 | +} | |
555 | + | |
556 | +static int saveenv_to_ptn(struct fastboot_ptentry *ptn, char *err_string) | |
557 | +{ | |
558 | + int ret = 1; | |
559 | + int save = 0; | |
560 | + int debug = 0; | |
561 | + | |
562 | + /* err_string is only 32 bytes | |
563 | + Initialize with a generic error message. */ | |
564 | + sprintf(err_string, "%s", "Unknown Error"); | |
565 | + | |
566 | + /* Parse the input twice. | |
567 | + Only save to the enviroment if the entire input if correct */ | |
568 | + save = 0; | |
569 | + if (0 == parse_env(ptn, err_string, save, debug)) { | |
570 | + save = 1; | |
571 | + ret = parse_env(ptn, err_string, save, debug); | |
572 | + } | |
573 | + return ret; | |
574 | +} | |
575 | + | |
576 | +static int get_block_size(void); | |
577 | +#ifdef CONFIG_FLASH_MCUFIRMWARE_SUPPORT | |
578 | +static void process_flash_sf(const char *cmdbuf) | |
579 | +{ | |
580 | + int blksz = 0; | |
581 | + blksz = get_block_size(); | |
582 | + | |
583 | + if (download_bytes) { | |
584 | + struct fastboot_ptentry *ptn; | |
585 | + ptn = fastboot_flash_find_ptn(cmdbuf); | |
586 | + if (ptn == 0) { | |
587 | + fastboot_fail("partition does not exist"); | |
588 | + } else if ((download_bytes > ptn->length * blksz)) { | |
589 | + fastboot_fail("image too large for partition"); | |
590 | + /* TODO : Improve check for yaffs write */ | |
591 | + } else { | |
592 | + int ret; | |
593 | + char sf_command[128]; | |
594 | + /* Normal case */ | |
595 | + /* Probe device */ | |
596 | + sprintf(sf_command, "sf probe"); | |
597 | + ret = run_command(sf_command, 0); | |
598 | + if (ret){ | |
599 | + fastboot_fail("Probe sf failed"); | |
600 | + return; | |
601 | + } | |
602 | + /* Erase */ | |
603 | + sprintf(sf_command, "sf erase 0x%x 0x%x", ptn->start * blksz, /*start*/ | |
604 | + ptn->length * blksz /*size*/); | |
605 | + ret = run_command(sf_command, 0); | |
606 | + if (ret) { | |
607 | + fastboot_fail("Erasing sf failed"); | |
608 | + return; | |
609 | + } | |
610 | + /* Write image */ | |
611 | + sprintf(sf_command, "sf write 0x%x 0x%x 0x%x", | |
612 | + (unsigned int)(ulong)interface.transfer_buffer, /* source */ | |
613 | + ptn->start * blksz, /* start */ | |
614 | + download_bytes /*size*/); | |
615 | + printf("sf write '%s'\n", ptn->name); | |
616 | + ret = run_command(sf_command, 0); | |
617 | + if (ret){ | |
618 | + fastboot_fail("Writing sf failed"); | |
619 | + return; | |
620 | + } | |
621 | + printf("sf write finished '%s'\n", ptn->name); | |
622 | + fastboot_okay(""); | |
623 | + } | |
624 | + } else { | |
625 | + fastboot_fail("no image downloaded"); | |
626 | + } | |
627 | +} | |
628 | + | |
629 | +#ifdef CONFIG_ARCH_IMX8M | |
630 | +/* Check if the mcu image is built for running from TCM */ | |
631 | +static bool is_tcm_image(unsigned char *image_addr) | |
632 | +{ | |
633 | + u32 stack; | |
634 | + | |
635 | + stack = *(u32 *)image_addr; | |
636 | + | |
637 | + if ((stack != (u32)ANDROID_MCU_FIRMWARE_HEADER_STACK)) { | |
638 | + printf("Please flash mcu firmware images for running from TCM\n"); | |
639 | + return false; | |
640 | + } else | |
641 | + return true; | |
642 | +} | |
643 | + | |
644 | +static int do_bootmcu(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) | |
645 | +{ | |
646 | + int ret; | |
647 | + size_t out_num_read; | |
648 | + void *m4_base_addr = (void *)M4_BOOTROM_BASE_ADDR; | |
649 | + char command[32]; | |
650 | + | |
651 | + ret = read_from_partition_multi(FASTBOOT_MCU_FIRMWARE_PARTITION, | |
652 | + 0, ANDROID_MCU_FIRMWARE_SIZE, (void *)m4_base_addr, &out_num_read); | |
653 | + if ((ret != 0) || (out_num_read != ANDROID_MCU_FIRMWARE_SIZE)) { | |
654 | + printf("Read M4 images failed!\n"); | |
655 | + return 1; | |
656 | + } else { | |
657 | + printf("run command: 'bootaux 0x%x'\n",(unsigned int)(ulong)m4_base_addr); | |
658 | + | |
659 | + sprintf(command, "bootaux 0x%x", (unsigned int)(ulong)m4_base_addr); | |
660 | + ret = run_command(command, 0); | |
661 | + if (ret) { | |
662 | + printf("run 'bootaux' command failed!\n"); | |
663 | + return 1; | |
664 | + } | |
665 | + } | |
666 | + return 0; | |
667 | +} | |
668 | + | |
669 | +U_BOOT_CMD( | |
670 | + bootmcu, 1, 0, do_bootmcu, | |
671 | + "boot mcu images\n", | |
672 | + "boot mcu images from 'm4_os' partition, only support images run from TCM" | |
673 | +); | |
674 | +#endif | |
675 | +#endif /* CONFIG_FLASH_MCUFIRMWARE_SUPPORT */ | |
676 | + | |
677 | +#if defined(CONFIG_FASTBOOT_STORAGE_SATA) | |
678 | +static void process_flash_sata(const char *cmdbuf) | |
679 | +{ | |
680 | + if (download_bytes) { | |
681 | + struct fastboot_ptentry *ptn; | |
682 | + | |
683 | + /* Next is the partition name */ | |
684 | + ptn = fastboot_flash_find_ptn(cmdbuf); | |
685 | + if (ptn == NULL) { | |
686 | + fastboot_fail("partition does not exist"); | |
687 | + } else if ((download_bytes > | |
688 | + ptn->length * MMC_SATA_BLOCK_SIZE) && | |
689 | + !(ptn->flags & FASTBOOT_PTENTRY_FLAGS_WRITE_ENV)) { | |
690 | + printf("Image too large for the partition\n"); | |
691 | + fastboot_fail("image too large for partition"); | |
692 | + } else if (ptn->flags & FASTBOOT_PTENTRY_FLAGS_WRITE_ENV) { | |
693 | + /* Since the response can only be 64 bytes, | |
694 | + there is no point in having a large error message. */ | |
695 | + char err_string[32]; | |
696 | + if (saveenv_to_ptn(ptn, &err_string[0])) { | |
697 | + printf("savenv '%s' failed : %s\n", ptn->name, err_string); | |
698 | + fastboot_fail(err_string); | |
699 | + } else { | |
700 | + printf("partition '%s' saveenv-ed\n", ptn->name); | |
701 | + fastboot_okay(""); | |
702 | + } | |
703 | + } else { | |
704 | + unsigned int temp; | |
705 | + char sata_write[128]; | |
706 | + | |
707 | + /* block count */ | |
708 | + temp = (download_bytes + | |
709 | + MMC_SATA_BLOCK_SIZE - 1) / | |
710 | + MMC_SATA_BLOCK_SIZE; | |
711 | + | |
712 | + sprintf(sata_write, "sata write 0x%x 0x%x 0x%x", | |
713 | + (unsigned int)interface.transfer_buffer, | |
714 | + ptn->start, | |
715 | + temp); | |
716 | + | |
717 | + if (run_command(sata_write, 0)) { | |
718 | + printf("Writing '%s' FAILED!\n", | |
719 | + ptn->name); | |
720 | + fastboot_fail("Write partition failed"); | |
721 | + } else { | |
722 | + printf("Writing '%s' DONE!\n", | |
723 | + ptn->name); | |
724 | + fastboot_okay(""); | |
725 | + } | |
726 | + } | |
727 | + } else { | |
728 | + fastboot_fail("no image downloaded"); | |
729 | + } | |
730 | + | |
731 | +} | |
732 | +#endif | |
733 | + | |
734 | +#if defined(CONFIG_FASTBOOT_STORAGE_MMC) | |
735 | +static int is_raw_partition(struct fastboot_ptentry *ptn) | |
736 | +{ | |
737 | +#ifdef CONFIG_ANDROID_AB_SUPPORT | |
738 | + if (ptn && (!strncmp(ptn->name, FASTBOOT_PARTITION_BOOTLOADER, | |
739 | + strlen(FASTBOOT_PARTITION_BOOTLOADER)) || | |
740 | + !strncmp(ptn->name, FASTBOOT_PARTITION_GPT, | |
741 | + strlen(FASTBOOT_PARTITION_GPT)) || | |
742 | + !strncmp(ptn->name, FASTBOOT_PARTITION_BOOT_A, | |
743 | + strlen(FASTBOOT_PARTITION_BOOT_A)) || | |
744 | + !strncmp(ptn->name, FASTBOOT_PARTITION_BOOT_B, | |
745 | + strlen(FASTBOOT_PARTITION_BOOT_B)) || | |
746 | +#ifdef CONFIG_FASTBOOT_LOCK | |
747 | + !strncmp(ptn->name, FASTBOOT_PARTITION_FBMISC, | |
748 | + strlen(FASTBOOT_PARTITION_FBMISC)) || | |
749 | +#endif | |
750 | + !strncmp(ptn->name, FASTBOOT_PARTITION_MISC, | |
751 | + strlen(FASTBOOT_PARTITION_MISC)))) { | |
752 | +#else | |
753 | + if (ptn && (!strncmp(ptn->name, FASTBOOT_PARTITION_BOOTLOADER, | |
754 | + strlen(FASTBOOT_PARTITION_BOOTLOADER)) || | |
755 | + !strncmp(ptn->name, FASTBOOT_PARTITION_BOOT, | |
756 | + strlen(FASTBOOT_PARTITION_BOOT)) || | |
757 | +#ifdef CONFIG_FASTBOOT_LOCK | |
758 | + !strncmp(ptn->name, FASTBOOT_PARTITION_FBMISC, | |
759 | + strlen(FASTBOOT_PARTITION_FBMISC)) || | |
760 | +#endif | |
761 | + !strncmp(ptn->name, FASTBOOT_PARTITION_MISC, | |
762 | + strlen(FASTBOOT_PARTITION_MISC)))) { | |
763 | +#endif | |
764 | + printf("support sparse flash partition for %s\n", ptn->name); | |
765 | + return 1; | |
766 | + } else | |
767 | + return 0; | |
768 | +} | |
769 | + | |
770 | +static lbaint_t mmc_sparse_write(struct sparse_storage *info, | |
771 | + lbaint_t blk, lbaint_t blkcnt, const void *buffer) | |
772 | +{ | |
773 | +#define SPARSE_FILL_BUF_SIZE (2 * 1024 * 1024) | |
774 | + | |
775 | + struct blk_desc *dev_desc = (struct blk_desc *)info->priv; | |
776 | + ulong ret = 0; | |
777 | + void *data; | |
778 | + int fill_buf_num_blks, cnt; | |
779 | + | |
780 | + if ((unsigned long)buffer & (CONFIG_SYS_CACHELINE_SIZE - 1)) { | |
781 | + | |
782 | + fill_buf_num_blks = SPARSE_FILL_BUF_SIZE / info->blksz; | |
783 | + | |
784 | + data = memalign(CONFIG_SYS_CACHELINE_SIZE, fill_buf_num_blks * info->blksz); | |
785 | + | |
786 | + while (blkcnt) { | |
787 | + | |
788 | + if (blkcnt > fill_buf_num_blks) | |
789 | + cnt = fill_buf_num_blks; | |
790 | + else | |
791 | + cnt = blkcnt; | |
792 | + | |
793 | + memcpy(data, buffer, cnt * info->blksz); | |
794 | + | |
795 | + ret += blk_dwrite(dev_desc, blk, cnt, data); | |
796 | + | |
797 | + blk += cnt; | |
798 | + blkcnt -= cnt; | |
799 | + buffer = (void *)((unsigned long)buffer + cnt * info->blksz); | |
800 | + | |
801 | + } | |
802 | + | |
803 | + free(data); | |
804 | + } else { | |
805 | + ret = blk_dwrite(dev_desc, blk, blkcnt, buffer); | |
806 | + } | |
807 | + | |
808 | + return ret; | |
809 | +} | |
810 | + | |
811 | +static lbaint_t mmc_sparse_reserve(struct sparse_storage *info, | |
812 | + lbaint_t blk, lbaint_t blkcnt) | |
813 | +{ | |
814 | + return blkcnt; | |
815 | +} | |
816 | + | |
817 | +/*judge wether the gpt image and bootloader image are overlay*/ | |
818 | +bool bootloader_gpt_overlay(void) | |
819 | +{ | |
820 | + return (g_ptable[PTN_GPT_INDEX].partition_id == g_ptable[PTN_BOOTLOADER_INDEX].partition_id && | |
821 | + ANDROID_BOOTLOADER_OFFSET < ANDROID_GPT_END); | |
822 | +} | |
823 | + | |
824 | +int write_backup_gpt(void) | |
825 | +{ | |
826 | + int mmc_no = 0; | |
827 | + struct mmc *mmc; | |
828 | + struct blk_desc *dev_desc; | |
829 | + | |
830 | + mmc_no = fastboot_devinfo.dev_id; | |
831 | + mmc = find_mmc_device(mmc_no); | |
832 | + if (mmc == NULL) { | |
833 | + printf("invalid mmc device\n"); | |
834 | + return -1; | |
835 | + } | |
836 | + dev_desc = blk_get_dev("mmc", mmc_no); | |
837 | + | |
838 | + /* write backup get partition */ | |
839 | + if (write_backup_gpt_partitions(dev_desc, interface.transfer_buffer)) { | |
840 | + printf("writing GPT image fail\n"); | |
841 | + return -1; | |
842 | + } | |
843 | + | |
844 | + printf("flash backup gpt image successfully\n"); | |
845 | + return 0; | |
846 | +} | |
847 | + | |
848 | +static void process_flash_mmc(const char *cmdbuf) | |
849 | +{ | |
850 | + if (download_bytes) { | |
851 | + struct fastboot_ptentry *ptn; | |
852 | +#ifdef CONFIG_AVB_SUPPORT | |
853 | + if (!strcmp_l1(FASTBOOT_PARTITION_AVBKEY, cmdbuf)) { | |
854 | + printf("pubkey len %d\n", download_bytes); | |
855 | + if (avbkey_init(interface.transfer_buffer, download_bytes) != 0) { | |
856 | + fastboot_fail("fail to Write partition"); | |
857 | + } else { | |
858 | + printf("init 'avbkey' DONE!\n"); | |
859 | + fastboot_okay("OKAY"); | |
860 | + } | |
861 | + return; | |
862 | + } | |
863 | +#endif | |
864 | + | |
865 | + /* Next is the partition name */ | |
866 | + ptn = fastboot_flash_find_ptn(cmdbuf); | |
867 | + if (ptn == NULL) { | |
868 | + fastboot_fail("partition does not exist"); | |
869 | + } else if ((download_bytes > | |
870 | + ptn->length * MMC_SATA_BLOCK_SIZE) && | |
871 | + !(ptn->flags & FASTBOOT_PTENTRY_FLAGS_WRITE_ENV)) { | |
872 | + printf("Image too large for the partition\n"); | |
873 | + fastboot_fail("image too large for partition"); | |
874 | + } else if (ptn->flags & FASTBOOT_PTENTRY_FLAGS_WRITE_ENV) { | |
875 | + /* Since the response can only be 64 bytes, | |
876 | + there is no point in having a large error message. */ | |
877 | + char err_string[32]; | |
878 | + if (saveenv_to_ptn(ptn, &err_string[0])) { | |
879 | + printf("savenv '%s' failed : %s\n", ptn->name, err_string); | |
880 | + fastboot_fail(err_string); | |
881 | + } else { | |
882 | + printf("partition '%s' saveenv-ed\n", ptn->name); | |
883 | + fastboot_okay(""); | |
884 | + } | |
885 | + } else { | |
886 | + unsigned int temp; | |
887 | + | |
888 | + char mmc_dev[128]; | |
889 | + char mmc_write[128]; | |
890 | + int mmcret; | |
891 | + | |
892 | + printf("writing to partition '%s'\n", ptn->name); | |
893 | + | |
894 | + if (ptn->partition_id != FASTBOOT_MMC_NONE_PARTITION_ID) | |
895 | + sprintf(mmc_dev, "mmc dev %x %x", | |
896 | + fastboot_devinfo.dev_id, /*slot no*/ | |
897 | + ptn->partition_id /*part no*/); | |
898 | + else | |
899 | + sprintf(mmc_dev, "mmc dev %x", | |
900 | + fastboot_devinfo.dev_id /*slot no*/); | |
901 | + | |
902 | + if (!is_raw_partition(ptn) && | |
903 | + is_sparse_image(interface.transfer_buffer)) { | |
904 | + int mmc_no = 0; | |
905 | + struct mmc *mmc; | |
906 | + struct blk_desc *dev_desc; | |
907 | + disk_partition_t info; | |
908 | + struct sparse_storage sparse; | |
909 | + | |
910 | + mmc_no = fastboot_devinfo.dev_id; | |
911 | + | |
912 | + printf("sparse flash target is MMC:%d\n", mmc_no); | |
913 | + mmc = find_mmc_device(mmc_no); | |
914 | + if (mmc && mmc_init(mmc)) | |
915 | + printf("MMC card init failed!\n"); | |
916 | + | |
917 | + dev_desc = blk_get_dev("mmc", mmc_no); | |
918 | + if (!dev_desc || dev_desc->type == DEV_TYPE_UNKNOWN) { | |
919 | + printf("** Block device MMC %d not supported\n", | |
920 | + mmc_no); | |
921 | + return; | |
922 | + } | |
923 | + | |
924 | + if (part_get_info(dev_desc, | |
925 | + ptn->partition_index, &info)) { | |
926 | + printf("Bad partition index:%d for partition:%s\n", | |
927 | + ptn->partition_index, ptn->name); | |
928 | + return; | |
929 | + } | |
930 | + | |
931 | + printf("writing to partition '%s' for sparse, buffer size %d\n", | |
932 | + ptn->name, download_bytes); | |
933 | + | |
934 | + sparse.blksz = info.blksz; | |
935 | + sparse.start = info.start; | |
936 | + sparse.size = info.size; | |
937 | + sparse.write = mmc_sparse_write; | |
938 | + sparse.reserve = mmc_sparse_reserve; | |
939 | + printf("Flashing sparse image at offset " LBAFU "\n", | |
940 | + sparse.start); | |
941 | + | |
942 | + sparse.priv = dev_desc; | |
943 | + write_sparse_image(&sparse, ptn->name, interface.transfer_buffer, | |
944 | + download_bytes); | |
945 | + | |
946 | + } else { | |
947 | + /* Will flash images in below case: | |
948 | + * 1. Is not gpt partition. | |
949 | + * 2. Is gpt partition but no overlay detected. | |
950 | + * */ | |
951 | + if (strncmp(ptn->name, "gpt", 3) || !bootloader_gpt_overlay()) { | |
952 | + /* block count */ | |
953 | + if (strncmp(ptn->name, "gpt", 3) == 0) { | |
954 | + temp = (ANDROID_GPT_END + | |
955 | + MMC_SATA_BLOCK_SIZE - 1) / | |
956 | + MMC_SATA_BLOCK_SIZE; | |
957 | + } else { | |
958 | + temp = (download_bytes + | |
959 | + MMC_SATA_BLOCK_SIZE - 1) / | |
960 | + MMC_SATA_BLOCK_SIZE; | |
961 | + } | |
962 | + | |
963 | + sprintf(mmc_write, "mmc write 0x%x 0x%x 0x%x", | |
964 | + (unsigned int)(uintptr_t)interface.transfer_buffer, /*source*/ | |
965 | + ptn->start, /*dest*/ | |
966 | + temp /*length*/); | |
967 | + | |
968 | + printf("Initializing '%s'\n", ptn->name); | |
969 | + | |
970 | + mmcret = run_command(mmc_dev, 0); | |
971 | + if (mmcret) | |
972 | + fastboot_fail("Init of MMC card failed"); | |
973 | + else | |
974 | + fastboot_okay(""); | |
975 | + | |
976 | + printf("Writing '%s'\n", ptn->name); | |
977 | + if (run_command(mmc_write, 0)) { | |
978 | + printf("Writing '%s' FAILED!\n", ptn->name); | |
979 | + fastboot_fail("Write partition failed"); | |
980 | + } else { | |
981 | + printf("Writing '%s' DONE!\n", ptn->name); | |
982 | + fastboot_okay(""); | |
983 | + } | |
984 | + } | |
985 | + /* Write backup gpt image */ | |
986 | + if (strncmp(ptn->name, "gpt", 3) == 0) { | |
987 | + if (write_backup_gpt()) | |
988 | + fastboot_fail("write backup GPT image fail"); | |
989 | + else | |
990 | + fastboot_okay(""); | |
991 | + | |
992 | + /* will force scan the device, | |
993 | + * so dev_desc can be re-inited | |
994 | + * with the latest data */ | |
995 | + run_command(mmc_dev, 0); | |
996 | + } | |
997 | + } | |
998 | + } | |
999 | + } else { | |
1000 | + fastboot_fail("no image downloaded"); | |
1001 | + } | |
1002 | +} | |
1003 | + | |
1004 | +#endif | |
1005 | + | |
1006 | +#if defined(CONFIG_FASTBOOT_STORAGE_MMC) | |
1007 | +static void process_erase_mmc(const char *cmdbuf, char *response) | |
1008 | +{ | |
1009 | + int mmc_no = 0; | |
1010 | + lbaint_t blks, blks_start, blks_size, grp_size; | |
1011 | + struct mmc *mmc; | |
1012 | + struct blk_desc *dev_desc; | |
1013 | + struct fastboot_ptentry *ptn; | |
1014 | + disk_partition_t info; | |
1015 | + | |
1016 | + ptn = fastboot_flash_find_ptn(cmdbuf); | |
1017 | + if ((ptn == NULL) || (ptn->flags & FASTBOOT_PTENTRY_FLAGS_UNERASEABLE)) { | |
1018 | + sprintf(response, "FAILpartition does not exist or uneraseable"); | |
1019 | + return; | |
1020 | + } | |
1021 | + | |
1022 | + mmc_no = fastboot_devinfo.dev_id; | |
1023 | + printf("erase target is MMC:%d\n", mmc_no); | |
1024 | + | |
1025 | + mmc = find_mmc_device(mmc_no); | |
1026 | + if ((mmc == NULL) || mmc_init(mmc)) { | |
1027 | + printf("MMC card init failed!\n"); | |
1028 | + return; | |
1029 | + } | |
1030 | + | |
1031 | + dev_desc = blk_get_dev("mmc", mmc_no); | |
1032 | + if (NULL == dev_desc) { | |
1033 | + printf("Block device MMC %d not supported\n", | |
1034 | + mmc_no); | |
1035 | + sprintf(response, "FAILnot valid MMC card"); | |
1036 | + return; | |
1037 | + } | |
1038 | + | |
1039 | + if (part_get_info(dev_desc, | |
1040 | + ptn->partition_index, &info)) { | |
1041 | + printf("Bad partition index:%d for partition:%s\n", | |
1042 | + ptn->partition_index, ptn->name); | |
1043 | + sprintf(response, "FAILerasing of MMC card"); | |
1044 | + return; | |
1045 | + } | |
1046 | + | |
1047 | + /* Align blocks to erase group size to avoid erasing other partitions */ | |
1048 | + grp_size = mmc->erase_grp_size; | |
1049 | + blks_start = (info.start + grp_size - 1) & ~(grp_size - 1); | |
1050 | + if (info.size >= grp_size) | |
1051 | + blks_size = (info.size - (blks_start - info.start)) & | |
1052 | + (~(grp_size - 1)); | |
1053 | + else | |
1054 | + blks_size = 0; | |
1055 | + | |
1056 | + printf("Erasing blocks " LBAFU " to " LBAFU " due to alignment\n", | |
1057 | + blks_start, blks_start + blks_size); | |
1058 | + | |
1059 | + blks = blk_derase(dev_desc, blks_start, blks_size); | |
1060 | + if (blks != blks_size) { | |
1061 | + printf("failed erasing from device %d", dev_desc->devnum); | |
1062 | + sprintf(response, "FAILerasing of MMC card"); | |
1063 | + return; | |
1064 | + } | |
1065 | + | |
1066 | + printf("........ erased " LBAFU " bytes from '%s'\n", | |
1067 | + blks_size * info.blksz, cmdbuf); | |
1068 | + sprintf(response, "OKAY"); | |
1069 | + | |
1070 | + return; | |
1071 | +} | |
1072 | +#endif | |
1073 | + | |
1074 | +#if defined(CONFIG_FASTBOOT_STORAGE_SATA) | |
1075 | +static void process_erase_sata(const char *cmdbuf, char *response) | |
1076 | +{ | |
1077 | + return; | |
1078 | +} | |
1079 | +#endif | |
1080 | + | |
1081 | +static void rx_process_erase(const char *cmdbuf, char *response) | |
1082 | +{ | |
1083 | + switch (fastboot_devinfo.type) { | |
1084 | +#if defined(CONFIG_FASTBOOT_STORAGE_SATA) | |
1085 | + case DEV_SATA: | |
1086 | + process_erase_sata(cmdbuf, response); | |
1087 | + break; | |
1088 | +#endif | |
1089 | +#if defined(CONFIG_FASTBOOT_STORAGE_MMC) | |
1090 | + case DEV_MMC: | |
1091 | + process_erase_mmc(cmdbuf, response); | |
1092 | + break; | |
1093 | +#endif | |
1094 | + default: | |
1095 | + printf("Not support flash command for current device %d\n", | |
1096 | + fastboot_devinfo.type); | |
1097 | + sprintf(response, | |
1098 | + "FAILfailed to flash device"); | |
1099 | + break; | |
1100 | + } | |
1101 | +} | |
1102 | + | |
1103 | +static void rx_process_flash(const char *cmdbuf) | |
1104 | +{ | |
1105 | +/* Check if we need to flash mcu firmware */ | |
1106 | +#ifdef CONFIG_FLASH_MCUFIRMWARE_SUPPORT | |
1107 | + if (!strncmp(cmdbuf, FASTBOOT_MCU_FIRMWARE_PARTITION, | |
1108 | + sizeof(FASTBOOT_MCU_FIRMWARE_PARTITION))) { | |
1109 | + switch (fastboot_firmwareinfo.type) { | |
1110 | + case DEV_SF: | |
1111 | + process_flash_sf(cmdbuf); | |
1112 | + break; | |
1113 | +#ifdef CONFIG_ARCH_IMX8M | |
1114 | + case DEV_MMC: | |
1115 | + if (is_tcm_image(interface.transfer_buffer)) | |
1116 | + process_flash_mmc(cmdbuf); | |
1117 | + break; | |
1118 | +#endif | |
1119 | + default: | |
1120 | + printf("Don't support flash firmware\n"); | |
1121 | + } | |
1122 | + return; | |
1123 | + } | |
1124 | +#endif | |
1125 | + /* Normal case */ | |
1126 | + switch (fastboot_devinfo.type) { | |
1127 | +#if defined(CONFIG_FASTBOOT_STORAGE_SATA) | |
1128 | + case DEV_SATA: | |
1129 | + process_flash_sata(cmdbuf); | |
1130 | + break; | |
1131 | +#endif | |
1132 | +#if defined(CONFIG_FASTBOOT_STORAGE_MMC) | |
1133 | + case DEV_MMC: | |
1134 | + process_flash_mmc(cmdbuf); | |
1135 | + break; | |
1136 | +#endif | |
1137 | + default: | |
1138 | + printf("Not support flash command for current device %d\n", | |
1139 | + fastboot_devinfo.type); | |
1140 | + fastboot_fail("failed to flash device"); | |
1141 | + break; | |
1142 | + } | |
1143 | +} | |
1144 | + | |
1145 | + | |
1146 | +static void parameters_setup(void) | |
1147 | +{ | |
1148 | + interface.nand_block_size = 0; | |
1149 | + interface.transfer_buffer = | |
1150 | + (unsigned char *)CONFIG_FASTBOOT_BUF_ADDR; | |
1151 | + interface.transfer_buffer_size = | |
1152 | + CONFIG_FASTBOOT_BUF_SIZE; | |
1153 | +} | |
1154 | + | |
1155 | +static int _fastboot_setup_dev(void) | |
1156 | +{ | |
1157 | + char *fastboot_env; | |
1158 | + fastboot_env = env_get("fastboot_dev"); | |
1159 | + | |
1160 | + if (fastboot_env) { | |
1161 | + if (!strcmp(fastboot_env, "sata")) { | |
1162 | + fastboot_devinfo.type = DEV_SATA; | |
1163 | + fastboot_devinfo.dev_id = 0; | |
1164 | +#if defined(CONFIG_FASTBOOT_STORAGE_MMC) | |
1165 | + } else if (!strncmp(fastboot_env, "mmc", 3)) { | |
1166 | + fastboot_devinfo.type = DEV_MMC; | |
1167 | + fastboot_devinfo.dev_id = mmc_get_env_dev(); | |
1168 | +#endif | |
1169 | + } | |
1170 | + } else { | |
1171 | + return 1; | |
1172 | + } | |
1173 | +#ifdef CONFIG_FLASH_MCUFIRMWARE_SUPPORT | |
1174 | + /* For imx7ulp, flash m4 images directly to spi nor-flash, M4 will | |
1175 | + * run automatically after powered on. For imx8mq, flash m4 images to | |
1176 | + * physical partition 'm4_os', m4 will be kicked off by A core. */ | |
1177 | + fastboot_firmwareinfo.type = ANDROID_MCU_FRIMWARE_DEV_TYPE; | |
1178 | +#endif | |
1179 | + | |
1180 | + return 0; | |
1181 | +} | |
1182 | + | |
1183 | +#if defined(CONFIG_FASTBOOT_STORAGE_SATA) \ | |
1184 | + || defined(CONFIG_FASTBOOT_STORAGE_MMC) | |
1185 | +/** | |
1186 | + @mmc_dos_partition_index: the partition index in mbr. | |
1187 | + @mmc_partition_index: the boot partition or user partition index, | |
1188 | + not related to the partition table. | |
1189 | + */ | |
1190 | +static int _fastboot_parts_add_ptable_entry(int ptable_index, | |
1191 | + int mmc_dos_partition_index, | |
1192 | + int mmc_partition_index, | |
1193 | + const char *name, | |
1194 | + const char *fstype, | |
1195 | + struct blk_desc *dev_desc, | |
1196 | + struct fastboot_ptentry *ptable) | |
1197 | +{ | |
1198 | + disk_partition_t info; | |
1199 | + | |
1200 | + if (part_get_info(dev_desc, | |
1201 | + mmc_dos_partition_index, &info)) { | |
1202 | + debug("Bad partition index:%d for partition:%s\n", | |
1203 | + mmc_dos_partition_index, name); | |
1204 | + return -1; | |
1205 | + } | |
1206 | + ptable[ptable_index].start = info.start; | |
1207 | + ptable[ptable_index].length = info.size; | |
1208 | + ptable[ptable_index].partition_id = mmc_partition_index; | |
1209 | + ptable[ptable_index].partition_index = mmc_dos_partition_index; | |
1210 | + strncpy(ptable[ptable_index].name, (const char *)info.name, | |
1211 | + sizeof(ptable[ptable_index].name) - 1); | |
1212 | + | |
1213 | +#ifdef CONFIG_PARTITION_UUIDS | |
1214 | + strcpy(ptable[ptable_index].uuid, (const char *)info.uuid); | |
1215 | +#endif | |
1216 | +#ifdef CONFIG_ANDROID_AB_SUPPORT | |
1217 | + if (!strcmp((const char *)info.name, FASTBOOT_PARTITION_SYSTEM_A) || | |
1218 | + !strcmp((const char *)info.name, FASTBOOT_PARTITION_SYSTEM_B) || | |
1219 | + !strcmp((const char *)info.name, FASTBOOT_PARTITION_DATA)) | |
1220 | +#else | |
1221 | + if (!strcmp((const char *)info.name, FASTBOOT_PARTITION_SYSTEM) || | |
1222 | + !strcmp((const char *)info.name, FASTBOOT_PARTITION_DATA) || | |
1223 | + !strcmp((const char *)info.name, FASTBOOT_PARTITION_DEVICE) || | |
1224 | + !strcmp((const char *)info.name, FASTBOOT_PARTITION_CACHE)) | |
1225 | +#endif | |
1226 | + strcpy(ptable[ptable_index].fstype, "ext4"); | |
1227 | + else | |
1228 | + strcpy(ptable[ptable_index].fstype, "raw"); | |
1229 | + return 0; | |
1230 | +} | |
1231 | + | |
1232 | +static int _fastboot_parts_load_from_ptable(void) | |
1233 | +{ | |
1234 | + int i; | |
1235 | +#ifdef CONFIG_CMD_SATA | |
1236 | + int sata_device_no; | |
1237 | +#endif | |
1238 | + | |
1239 | + /* mmc boot partition: -1 means no partition, 0 user part., 1 boot part. | |
1240 | + * default is no partition, for emmc default user part, except emmc*/ | |
1241 | + int boot_partition = FASTBOOT_MMC_NONE_PARTITION_ID; | |
1242 | + int user_partition = FASTBOOT_MMC_NONE_PARTITION_ID; | |
1243 | + | |
1244 | + struct mmc *mmc; | |
1245 | + struct blk_desc *dev_desc; | |
1246 | + struct fastboot_ptentry ptable[MAX_PTN]; | |
1247 | + | |
1248 | + /* sata case in env */ | |
1249 | + if (fastboot_devinfo.type == DEV_SATA) { | |
1250 | +#ifdef CONFIG_CMD_SATA | |
1251 | + puts("flash target is SATA\n"); | |
1252 | + if (sata_initialize()) | |
1253 | + return -1; | |
1254 | + sata_device_no = CONFIG_FASTBOOT_SATA_NO; | |
1255 | + if (sata_device_no >= CONFIG_SYS_SATA_MAX_DEVICE) { | |
1256 | + printf("Unknown SATA(%d) device for fastboot\n", | |
1257 | + sata_device_no); | |
1258 | + return -1; | |
1259 | + } | |
1260 | + dev_desc = sata_get_dev(sata_device_no); | |
1261 | +#else /*! CONFIG_CMD_SATA*/ | |
1262 | + puts("SATA isn't buildin\n"); | |
1263 | + return -1; | |
1264 | +#endif /*! CONFIG_CMD_SATA*/ | |
1265 | + } else if (fastboot_devinfo.type == DEV_MMC) { | |
1266 | + int mmc_no = 0; | |
1267 | + mmc_no = fastboot_devinfo.dev_id; | |
1268 | + | |
1269 | + printf("flash target is MMC:%d\n", mmc_no); | |
1270 | + mmc = find_mmc_device(mmc_no); | |
1271 | + if (mmc && mmc_init(mmc)) | |
1272 | + printf("MMC card init failed!\n"); | |
1273 | + | |
1274 | + dev_desc = blk_get_dev("mmc", mmc_no); | |
1275 | + if (!dev_desc || dev_desc->type == DEV_TYPE_UNKNOWN) { | |
1276 | + printf("** Block device MMC %d not supported\n", | |
1277 | + mmc_no); | |
1278 | + return -1; | |
1279 | + } | |
1280 | + | |
1281 | + /* multiple boot paritions for eMMC 4.3 later */ | |
1282 | + if (mmc->part_config != MMCPART_NOAVAILABLE) { | |
1283 | + boot_partition = FASTBOOT_MMC_BOOT_PARTITION_ID; | |
1284 | + user_partition = FASTBOOT_MMC_USER_PARTITION_ID; | |
1285 | + } | |
1286 | + } else { | |
1287 | + printf("Can't setup partition table on this device %d\n", | |
1288 | + fastboot_devinfo.type); | |
1289 | + return -1; | |
1290 | + } | |
1291 | + | |
1292 | + memset((char *)ptable, 0, | |
1293 | + sizeof(struct fastboot_ptentry) * (MAX_PTN)); | |
1294 | + /* GPT */ | |
1295 | + strcpy(ptable[PTN_GPT_INDEX].name, FASTBOOT_PARTITION_GPT); | |
1296 | + ptable[PTN_GPT_INDEX].start = ANDROID_GPT_OFFSET / dev_desc->blksz; | |
1297 | + ptable[PTN_GPT_INDEX].length = ANDROID_GPT_SIZE / dev_desc->blksz; | |
1298 | + ptable[PTN_GPT_INDEX].partition_id = user_partition; | |
1299 | + ptable[PTN_GPT_INDEX].flags = FASTBOOT_PTENTRY_FLAGS_UNERASEABLE; | |
1300 | + strcpy(ptable[PTN_GPT_INDEX].fstype, "raw"); | |
1301 | + | |
1302 | + /* Add m4_os partition if we support mcu firmware image flash */ | |
1303 | +#ifdef CONFIG_FLASH_MCUFIRMWARE_SUPPORT | |
1304 | + strcpy(ptable[PTN_M4_OS_INDEX].name, FASTBOOT_MCU_FIRMWARE_PARTITION); | |
1305 | + ptable[PTN_M4_OS_INDEX].start = ANDROID_MCU_FIRMWARE_START / dev_desc->blksz; | |
1306 | + ptable[PTN_M4_OS_INDEX].length = ANDROID_MCU_FIRMWARE_SIZE / dev_desc->blksz; | |
1307 | + ptable[PTN_M4_OS_INDEX].flags = FASTBOOT_PTENTRY_FLAGS_UNERASEABLE; | |
1308 | + ptable[PTN_M4_OS_INDEX].partition_id = user_partition; | |
1309 | + strcpy(ptable[PTN_M4_OS_INDEX].fstype, "raw"); | |
1310 | +#endif | |
1311 | + | |
1312 | + /* Bootloader */ | |
1313 | + strcpy(ptable[PTN_BOOTLOADER_INDEX].name, FASTBOOT_PARTITION_BOOTLOADER); | |
1314 | + ptable[PTN_BOOTLOADER_INDEX].start = | |
1315 | + ANDROID_BOOTLOADER_OFFSET / dev_desc->blksz; | |
1316 | + ptable[PTN_BOOTLOADER_INDEX].length = | |
1317 | + ANDROID_BOOTLOADER_SIZE / dev_desc->blksz; | |
1318 | + ptable[PTN_BOOTLOADER_INDEX].partition_id = boot_partition; | |
1319 | + ptable[PTN_BOOTLOADER_INDEX].flags = FASTBOOT_PTENTRY_FLAGS_UNERASEABLE; | |
1320 | + strcpy(ptable[PTN_BOOTLOADER_INDEX].fstype, "raw"); | |
1321 | + | |
1322 | + int tbl_idx; | |
1323 | + int part_idx = 1; | |
1324 | + int ret; | |
1325 | + for (tbl_idx = PTN_BOOTLOADER_INDEX + 1; tbl_idx < MAX_PTN; tbl_idx++) { | |
1326 | + ret = _fastboot_parts_add_ptable_entry(tbl_idx, | |
1327 | + part_idx++, | |
1328 | + user_partition, | |
1329 | + NULL, | |
1330 | + NULL, | |
1331 | + dev_desc, ptable); | |
1332 | + if (ret) | |
1333 | + break; | |
1334 | + } | |
1335 | + for (i = 0; i < tbl_idx; i++) | |
1336 | + fastboot_flash_add_ptn(&ptable[i]); | |
1337 | + | |
1338 | + return 0; | |
1339 | +} | |
1340 | +#endif /*CONFIG_FASTBOOT_STORAGE_SATA || CONFIG_FASTBOOT_STORAGE_MMC*/ | |
1341 | + | |
1342 | +static void _fastboot_load_partitions(void) | |
1343 | +{ | |
1344 | + g_pcount = 0; | |
1345 | +#if defined(CONFIG_FASTBOOT_STORAGE_SATA) \ | |
1346 | + || defined(CONFIG_FASTBOOT_STORAGE_MMC) | |
1347 | + _fastboot_parts_load_from_ptable(); | |
1348 | +#endif | |
1349 | +} | |
1350 | + | |
1351 | +/* | |
1352 | + * Android style flash utilties */ | |
1353 | +void fastboot_flash_add_ptn(struct fastboot_ptentry *ptn) | |
1354 | +{ | |
1355 | + if (g_pcount < MAX_PTN) { | |
1356 | + memcpy(g_ptable + g_pcount, ptn, sizeof(struct fastboot_ptentry)); | |
1357 | + g_pcount++; | |
1358 | + } | |
1359 | +} | |
1360 | + | |
1361 | +void fastboot_flash_dump_ptn(void) | |
1362 | +{ | |
1363 | + unsigned int n; | |
1364 | + for (n = 0; n < g_pcount; n++) { | |
1365 | + struct fastboot_ptentry *ptn = g_ptable + n; | |
1366 | + printf("idx %d, ptn %d name='%s' start=%d len=%d\n", | |
1367 | + n, ptn->partition_index, ptn->name, ptn->start, ptn->length); | |
1368 | + } | |
1369 | +} | |
1370 | + | |
1371 | + | |
1372 | +struct fastboot_ptentry *fastboot_flash_find_ptn(const char *name) | |
1373 | +{ | |
1374 | + unsigned int n; | |
1375 | + | |
1376 | + for (n = 0; n < g_pcount; n++) { | |
1377 | + /* Make sure a substring is not accepted */ | |
1378 | + if (strlen(name) == strlen(g_ptable[n].name)) { | |
1379 | + if (0 == strcmp(g_ptable[n].name, name)) | |
1380 | + return g_ptable + n; | |
1381 | + } | |
1382 | + } | |
1383 | + | |
1384 | + printf("can't find partition: %s, dump the partition table\n", name); | |
1385 | + fastboot_flash_dump_ptn(); | |
1386 | + return 0; | |
1387 | +} | |
1388 | + | |
1389 | +int fastboot_flash_find_index(const char *name) | |
1390 | +{ | |
1391 | + struct fastboot_ptentry *ptentry = fastboot_flash_find_ptn(name); | |
1392 | + if (ptentry == NULL) { | |
1393 | + printf("cannot get the partion info for %s\n",name); | |
1394 | + return -1; | |
1395 | + } | |
1396 | + return ptentry->partition_index; | |
1397 | +} | |
1398 | + | |
1399 | +struct fastboot_ptentry *fastboot_flash_get_ptn(unsigned int n) | |
1400 | +{ | |
1401 | + if (n < g_pcount) | |
1402 | + return g_ptable + n; | |
1403 | + else | |
1404 | + return 0; | |
1405 | +} | |
1406 | + | |
1407 | +unsigned int fastboot_flash_get_ptn_count(void) | |
1408 | +{ | |
1409 | + return g_pcount; | |
1410 | +} | |
1411 | + | |
1412 | +#ifdef CONFIG_FSL_FASTBOOT | |
1413 | +void board_fastboot_setup(void) | |
1414 | +{ | |
1415 | +#if defined(CONFIG_FASTBOOT_STORAGE_MMC) | |
1416 | + static char boot_dev_part[32]; | |
1417 | + u32 dev_no; | |
1418 | +#endif | |
1419 | + switch (get_boot_device()) { | |
1420 | +#if defined(CONFIG_FASTBOOT_STORAGE_MMC) | |
1421 | + case SD1_BOOT: | |
1422 | + case SD2_BOOT: | |
1423 | + case SD3_BOOT: | |
1424 | + case SD4_BOOT: | |
1425 | + case MMC1_BOOT: | |
1426 | + case MMC2_BOOT: | |
1427 | + case MMC3_BOOT: | |
1428 | + case MMC4_BOOT: | |
1429 | + dev_no = mmc_get_env_dev(); | |
1430 | + sprintf(boot_dev_part,"mmc%d",dev_no); | |
1431 | + if (!env_get("fastboot_dev")) | |
1432 | + env_set("fastboot_dev", boot_dev_part); | |
1433 | + sprintf(boot_dev_part, "boota mmc%d", dev_no); | |
1434 | + if (!env_get("bootcmd")) | |
1435 | + env_set("bootcmd", boot_dev_part); | |
1436 | + break; | |
1437 | +#endif /*CONFIG_FASTBOOT_STORAGE_MMC*/ | |
1438 | + default: | |
1439 | + printf("unsupported boot devices\n"); | |
1440 | + break; | |
1441 | + } | |
1442 | + | |
1443 | + /* add soc type into bootargs */ | |
1444 | + if (is_mx6dqp()) { | |
1445 | + if (!env_get("soc_type")) | |
1446 | + env_set("soc_type", "imx6qp"); | |
1447 | + } else if (is_mx6dq()) { | |
1448 | + if (!env_get("soc_type")) | |
1449 | + env_set("soc_type", "imx6q"); | |
1450 | + } else if (is_mx6sdl()) { | |
1451 | + if (!env_get("soc_type")) | |
1452 | + env_set("soc_type", "imx6dl"); | |
1453 | + } else if (is_mx6sx()) { | |
1454 | + if (!env_get("soc_type")) | |
1455 | + env_set("soc_type", "imx6sx"); | |
1456 | + } else if (is_mx6sl()) { | |
1457 | + if (!env_get("soc_type")) | |
1458 | + env_set("soc_type", "imx6sl"); | |
1459 | + } else if (is_mx6ul()) { | |
1460 | + if (!env_get("soc_type")) | |
1461 | + env_set("soc_type", "imx6ul"); | |
1462 | + } else if (is_mx7()) { | |
1463 | + if (!env_get("soc_type")) | |
1464 | + env_set("soc_type", "imx7d"); | |
1465 | + } else if (is_mx7ulp()) { | |
1466 | + if (!env_get("soc_type")) | |
1467 | + env_set("soc_type", "imx7ulp"); | |
1468 | + } else if (is_imx8qm()) { | |
1469 | + if (!env_get("soc_type")) | |
1470 | + env_set("soc_type", "imx8qm"); | |
1471 | + } else if (is_imx8qxp()) { | |
1472 | + if (!env_get("soc_type")) | |
1473 | + env_set("soc_type", "imx8qxp"); | |
1474 | + } else if (is_imx8mq()) { | |
1475 | + if (!env_get("soc_type")) | |
1476 | + env_set("soc_type", "imx8mq"); | |
1477 | + } else if (is_imx8mm()) { | |
1478 | + if (!env_get("soc_type")) | |
1479 | + env_set("soc_type", "imx8mm"); | |
1480 | + } | |
1481 | +} | |
1482 | + | |
1483 | +#ifdef CONFIG_ANDROID_RECOVERY | |
1484 | +void board_recovery_setup(void) | |
1485 | +{ | |
1486 | +/* boot from current mmc with avb verify */ | |
1487 | +#ifdef CONFIG_AVB_SUPPORT | |
1488 | + if (!env_get("bootcmd_android_recovery")) | |
1489 | + env_set("bootcmd_android_recovery", "boota recovery"); | |
1490 | +#else | |
1491 | +#if defined(CONFIG_FASTBOOT_STORAGE_MMC) | |
1492 | + static char boot_dev_part[32]; | |
1493 | + u32 dev_no; | |
1494 | +#endif | |
1495 | + int bootdev = get_boot_device(); | |
1496 | + switch (bootdev) { | |
1497 | +#if defined(CONFIG_FASTBOOT_STORAGE_MMC) | |
1498 | + case SD1_BOOT: | |
1499 | + case SD2_BOOT: | |
1500 | + case SD3_BOOT: | |
1501 | + case SD4_BOOT: | |
1502 | + case MMC1_BOOT: | |
1503 | + case MMC2_BOOT: | |
1504 | + case MMC3_BOOT: | |
1505 | + case MMC4_BOOT: | |
1506 | + dev_no = mmc_get_env_dev(); | |
1507 | + sprintf(boot_dev_part,"boota mmc%d recovery",dev_no); | |
1508 | + if (!env_get("bootcmd_android_recovery")) | |
1509 | + env_set("bootcmd_android_recovery", boot_dev_part); | |
1510 | + break; | |
1511 | +#endif /*CONFIG_FASTBOOT_STORAGE_MMC*/ | |
1512 | + default: | |
1513 | + printf("Unsupported bootup device for recovery: dev: %d\n", | |
1514 | + bootdev); | |
1515 | + return; | |
1516 | + } | |
1517 | +#endif /* CONFIG_AVB_SUPPORT */ | |
1518 | + printf("setup env for recovery..\n"); | |
1519 | + env_set("bootcmd", "run bootcmd_android_recovery"); | |
1520 | +} | |
1521 | +#endif /*CONFIG_ANDROID_RECOVERY*/ | |
1522 | +#endif /*CONFIG_FSL_FASTBOOT*/ | |
1523 | + | |
1524 | +#if defined(CONFIG_AVB_SUPPORT) && defined(CONFIG_MMC) | |
1525 | +static AvbABOps fsl_avb_ab_ops = { | |
1526 | + .read_ab_metadata = fsl_read_ab_metadata, | |
1527 | + .write_ab_metadata = fsl_write_ab_metadata, | |
1528 | + .ops = NULL | |
1529 | +}; | |
1530 | +#ifdef CONFIG_AVB_ATX | |
1531 | +static AvbAtxOps fsl_avb_atx_ops = { | |
1532 | + .ops = NULL, | |
1533 | + .read_permanent_attributes = fsl_read_permanent_attributes, | |
1534 | + .read_permanent_attributes_hash = fsl_read_permanent_attributes_hash | |
1535 | +}; | |
1536 | +#endif | |
1537 | +static AvbOps fsl_avb_ops = { | |
1538 | + .ab_ops = &fsl_avb_ab_ops, | |
1539 | +#ifdef CONFIG_AVB_ATX | |
1540 | + .atx_ops = &fsl_avb_atx_ops, | |
1541 | +#endif | |
1542 | + .read_from_partition = fsl_read_from_partition_multi, | |
1543 | + .write_to_partition = fsl_write_to_partition, | |
1544 | +#ifdef CONFIG_AVB_ATX | |
1545 | + .validate_vbmeta_public_key = avb_atx_validate_vbmeta_public_key, | |
1546 | +#else | |
1547 | + .validate_vbmeta_public_key = fsl_validate_vbmeta_public_key_rpmb, | |
1548 | +#endif | |
1549 | + .read_rollback_index = fsl_read_rollback_index_rpmb, | |
1550 | + .write_rollback_index = fsl_write_rollback_index_rpmb, | |
1551 | + .read_is_device_unlocked = fsl_read_is_device_unlocked, | |
1552 | + .get_unique_guid_for_partition = fsl_get_unique_guid_for_partition, | |
1553 | + .get_size_of_partition = fsl_get_size_of_partition | |
1554 | +}; | |
1555 | +#endif | |
1556 | + | |
1557 | +void fastboot_setup(void) | |
1558 | +{ | |
1559 | +#ifdef CONFIG_USB_GADGET | |
1560 | + struct tag_serialnr serialnr; | |
1561 | + char serial[17]; | |
1562 | + | |
1563 | + get_board_serial(&serialnr); | |
1564 | + sprintf(serial, "%08x%08x", serialnr.high, serialnr.low); | |
1565 | + g_dnl_set_serialnumber(serial); | |
1566 | +#endif | |
1567 | + /*execute board relevant initilizations for preparing fastboot */ | |
1568 | + board_fastboot_setup(); | |
1569 | + | |
1570 | + /*get the fastboot dev*/ | |
1571 | + _fastboot_setup_dev(); | |
1572 | + | |
1573 | + | |
1574 | + /*load partitions information for the fastboot dev*/ | |
1575 | + _fastboot_load_partitions(); | |
1576 | + | |
1577 | + parameters_setup(); | |
1578 | +#ifdef CONFIG_AVB_SUPPORT | |
1579 | + fsl_avb_ab_ops.ops = &fsl_avb_ops; | |
1580 | +#ifdef CONFIG_AVB_ATX | |
1581 | + fsl_avb_atx_ops.ops = &fsl_avb_ops; | |
1582 | +#endif | |
1583 | +#endif | |
1584 | +} | |
1585 | + | |
1586 | +/* Write the bcb with fastboot bootloader commands */ | |
1587 | +static void enable_fastboot_command(void) | |
1588 | +{ | |
1589 | + char fastboot_command[32] = {0}; | |
1590 | + strncpy(fastboot_command, FASTBOOT_BCB_CMD, 31); | |
1591 | + bcb_write_command(fastboot_command); | |
1592 | +} | |
1593 | + | |
1594 | +/* Get the Boot mode from BCB cmd or Key pressed */ | |
1595 | +static FbBootMode fastboot_get_bootmode(void) | |
1596 | +{ | |
1597 | + int ret = 0; | |
1598 | + int boot_mode = BOOTMODE_NORMAL; | |
1599 | + char command[32]; | |
1600 | +#ifdef CONFIG_ANDROID_RECOVERY | |
1601 | + if(is_recovery_key_pressing()) { | |
1602 | + boot_mode = BOOTMODE_RECOVERY_KEY_PRESSED; | |
1603 | + return boot_mode; | |
1604 | + } | |
1605 | +#endif | |
1606 | + ret = bcb_read_command(command); | |
1607 | + if (ret < 0) { | |
1608 | + printf("read command failed\n"); | |
1609 | + return boot_mode; | |
1610 | + } | |
1611 | + if (!strcmp(command, FASTBOOT_BCB_CMD)) { | |
1612 | + boot_mode = BOOTMODE_FASTBOOT_BCB_CMD; | |
1613 | + } | |
1614 | +#ifdef CONFIG_ANDROID_RECOVERY | |
1615 | + else if (!strcmp(command, RECOVERY_BCB_CMD)) { | |
1616 | + boot_mode = BOOTMODE_RECOVERY_BCB_CMD; | |
1617 | + } | |
1618 | +#endif | |
1619 | + | |
1620 | + /* Clean the mode once its read out, | |
1621 | + no matter what in the mode string */ | |
1622 | + memset(command, 0, 32); | |
1623 | + bcb_write_command(command); | |
1624 | + return boot_mode; | |
1625 | +} | |
1626 | + | |
1627 | +#ifdef CONFIG_SYSTEM_RAMDISK_SUPPORT | |
1628 | +/* Setup booargs for taking the system parition as ramdisk */ | |
1629 | +static void fastboot_setup_system_boot_args(const char *slot, bool append_root) | |
1630 | +{ | |
1631 | + const char *system_part_name = NULL; | |
1632 | + if(slot == NULL) | |
1633 | + return; | |
1634 | + if(!strncmp(slot, "_a", strlen("_a")) || !strncmp(slot, "boot_a", strlen("boot_a"))) { | |
1635 | + system_part_name = FASTBOOT_PARTITION_SYSTEM_A; | |
1636 | + } | |
1637 | + else if(!strncmp(slot, "_b", strlen("_b")) || !strncmp(slot, "boot_b", strlen("boot_b"))) { | |
1638 | + system_part_name = FASTBOOT_PARTITION_SYSTEM_B; | |
1639 | + } else { | |
1640 | + printf("slot invalid!\n"); | |
1641 | + return; | |
1642 | + } | |
1643 | + struct fastboot_ptentry *ptentry = fastboot_flash_find_ptn(system_part_name); | |
1644 | + if(ptentry != NULL) { | |
1645 | + char bootargs_3rd[ANDR_BOOT_ARGS_SIZE]; | |
1646 | +#if defined(CONFIG_FASTBOOT_STORAGE_MMC) | |
1647 | + if (append_root) { | |
1648 | + u32 dev_no = mmc_map_to_kernel_blk(mmc_get_env_dev()); | |
1649 | + sprintf(bootargs_3rd, "skip_initramfs root=/dev/mmcblk%dp%d", | |
1650 | + dev_no, | |
1651 | + ptentry->partition_index); | |
1652 | + } else { | |
1653 | + sprintf(bootargs_3rd, "skip_initramfs"); | |
1654 | + } | |
1655 | + strcat(bootargs_3rd, " rootwait"); | |
1656 | + env_set("bootargs_3rd", bootargs_3rd); | |
1657 | +#endif | |
1658 | + } | |
1659 | +} | |
1660 | +#endif | |
1661 | +/* export to lib_arm/board.c */ | |
1662 | +void fastboot_run_bootmode(void) | |
1663 | +{ | |
1664 | + FbBootMode boot_mode = fastboot_get_bootmode(); | |
1665 | + switch(boot_mode){ | |
1666 | + case BOOTMODE_FASTBOOT_BCB_CMD: | |
1667 | + /* Make the boot into fastboot mode*/ | |
1668 | + puts("Fastboot: Got bootloader commands!\n"); | |
1669 | + run_command("fastboot 0", 0); | |
1670 | + break; | |
1671 | +#ifdef CONFIG_ANDROID_RECOVERY | |
1672 | + case BOOTMODE_RECOVERY_BCB_CMD: | |
1673 | + case BOOTMODE_RECOVERY_KEY_PRESSED: | |
1674 | + /* Make the boot into recovery mode */ | |
1675 | + puts("Fastboot: Got Recovery key pressing or recovery commands!\n"); | |
1676 | + board_recovery_setup(); | |
1677 | + break; | |
1678 | +#endif | |
1679 | + default: | |
1680 | + /* skip special mode boot*/ | |
1681 | + puts("Fastboot: Normal\n"); | |
1682 | + break; | |
1683 | + } | |
1684 | +} | |
1685 | + | |
1686 | +#ifdef CONFIG_CMD_BOOTA | |
1687 | + /* Section for Android bootimage format support | |
1688 | + * Refer: | |
1689 | + * http://android.git.kernel.org/?p=platform/system/core.git;a=blob; | |
1690 | + * f=mkbootimg/bootimg.h | |
1691 | + */ | |
1692 | + | |
1693 | +void | |
1694 | +bootimg_print_image_hdr(struct andr_img_hdr *hdr) | |
1695 | +{ | |
1696 | +#ifdef DEBUG | |
1697 | + int i; | |
1698 | + printf(" Image magic: %s\n", hdr->magic); | |
1699 | + | |
1700 | + printf(" kernel_size: 0x%x\n", hdr->kernel_size); | |
1701 | + printf(" kernel_addr: 0x%x\n", hdr->kernel_addr); | |
1702 | + | |
1703 | + printf(" rdisk_size: 0x%x\n", hdr->ramdisk_size); | |
1704 | + printf(" rdisk_addr: 0x%x\n", hdr->ramdisk_addr); | |
1705 | + | |
1706 | + printf(" second_size: 0x%x\n", hdr->second_size); | |
1707 | + printf(" second_addr: 0x%x\n", hdr->second_addr); | |
1708 | + | |
1709 | + printf(" tags_addr: 0x%x\n", hdr->tags_addr); | |
1710 | + printf(" page_size: 0x%x\n", hdr->page_size); | |
1711 | + | |
1712 | + printf(" name: %s\n", hdr->name); | |
1713 | + printf(" cmdline: %s\n", hdr->cmdline); | |
1714 | + | |
1715 | + for (i = 0; i < 8; i++) | |
1716 | + printf(" id[%d]: 0x%x\n", i, hdr->id[i]); | |
1717 | +#endif | |
1718 | +} | |
1719 | + | |
1720 | +static struct andr_img_hdr boothdr __aligned(ARCH_DMA_MINALIGN); | |
1721 | + | |
1722 | +#if defined(CONFIG_AVB_SUPPORT) && defined(CONFIG_MMC) | |
1723 | + | |
1724 | +int do_boota(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { | |
1725 | + | |
1726 | + ulong addr = 0; | |
1727 | + struct andr_img_hdr *hdr = NULL; | |
1728 | + void *boot_buf = NULL; | |
1729 | + ulong image_size; | |
1730 | + u32 avb_metric; | |
1731 | + bool check_image_arm64 = false; | |
1732 | + bool is_recovery_mode = false; | |
1733 | + | |
1734 | +#if defined (CONFIG_ARCH_IMX8) || defined (CONFIG_ARCH_IMX8M) | |
1735 | + size_t lz4_len = DST_DECOMPRESS_LEN; | |
1736 | +#endif | |
1737 | + AvbABFlowResult avb_result; | |
1738 | + AvbSlotVerifyData *avb_out_data; | |
1739 | + AvbPartitionData *avb_loadpart; | |
1740 | + | |
1741 | + /* get bootmode, default to boot "boot" */ | |
1742 | + if (argc > 1) { | |
1743 | + is_recovery_mode = | |
1744 | + (strncmp(argv[1], "recovery", sizeof("recovery")) != 0) ? false: true; | |
1745 | + } | |
1746 | + | |
1747 | +#ifdef CONFIG_FASTBOOT_LOCK | |
1748 | + /* check lock state */ | |
1749 | + FbLockState lock_status = fastboot_get_lock_stat(); | |
1750 | + if (lock_status == FASTBOOT_LOCK_ERROR) { | |
1751 | + printf("In boota get fastboot lock status error. Set lock status\n"); | |
1752 | + fastboot_set_lock_stat(FASTBOOT_LOCK); | |
1753 | + lock_status = FASTBOOT_LOCK; | |
1754 | + } | |
1755 | + bool allow_fail = (lock_status == FASTBOOT_UNLOCK ? true : false); | |
1756 | + avb_metric = get_timer(0); | |
1757 | + /* For imx6 on Android, we don't have a/b slot and we want to verify | |
1758 | + * boot/recovery with AVB. For imx8 and Android Things we don't have | |
1759 | + * recovery and support a/b slot for boot */ | |
1760 | +#ifdef CONFIG_ANDROID_AB_SUPPORT | |
1761 | + /* we can use avb to verify Trusty if we want */ | |
1762 | + const char *requested_partitions[] = {"boot", 0}; | |
1763 | + avb_result = avb_ab_flow_fast(&fsl_avb_ab_ops, requested_partitions, allow_fail, | |
1764 | + AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE, &avb_out_data); | |
1765 | +#else /* CONFIG_ANDROID_AB_SUPPORT */ | |
1766 | + if (!is_recovery_mode) { | |
1767 | + const char *requested_partitions[] = {"boot", 0}; | |
1768 | + avb_result = avb_single_flow(&fsl_avb_ab_ops, requested_partitions, allow_fail, | |
1769 | + AVB_HASHTREE_ERROR_MODE_RESTART, &avb_out_data); | |
1770 | + } else { | |
1771 | + const char *requested_partitions[] = {"recovery", 0}; | |
1772 | + avb_result = avb_single_flow(&fsl_avb_ab_ops, requested_partitions, allow_fail, | |
1773 | + AVB_HASHTREE_ERROR_MODE_RESTART, &avb_out_data); | |
1774 | + } | |
1775 | +#endif /* CONFIG_ANDROID_AB_SUPPORT */ | |
1776 | + /* get the duration of avb */ | |
1777 | + metrics.avb = get_timer(avb_metric); | |
1778 | + | |
1779 | + if ((avb_result == AVB_AB_FLOW_RESULT_OK) || | |
1780 | + (avb_result == AVB_AB_FLOW_RESULT_OK_WITH_VERIFICATION_ERROR)) { | |
1781 | + assert(avb_out_data != NULL); | |
1782 | + /* load the first partition */ | |
1783 | + avb_loadpart = avb_out_data->loaded_partitions; | |
1784 | + assert(avb_loadpart != NULL); | |
1785 | + /* we should use avb_part_data->data as boot image */ | |
1786 | + /* boot image is already read by avb */ | |
1787 | + hdr = (struct andr_img_hdr *)avb_loadpart->data; | |
1788 | + if (android_image_check_header(hdr)) { | |
1789 | + printf("boota: bad boot image magic\n"); | |
1790 | + goto fail; | |
1791 | + } | |
1792 | + if (avb_result == AVB_AB_FLOW_RESULT_OK) | |
1793 | + printf(" verify OK, boot '%s%s'\n", | |
1794 | + avb_loadpart->partition_name, avb_out_data->ab_suffix); | |
1795 | + else { | |
1796 | + printf(" verify FAIL, state: UNLOCK\n"); | |
1797 | + printf(" boot '%s%s' still\n", | |
1798 | + avb_loadpart->partition_name, avb_out_data->ab_suffix); | |
1799 | + } | |
1800 | + char bootargs_sec[ANDR_BOOT_ARGS_SIZE]; | |
1801 | + if (lock_status == FASTBOOT_LOCK) { | |
1802 | + sprintf(bootargs_sec, | |
1803 | + "androidboot.verifiedbootstate=green androidboot.slot_suffix=%s %s", | |
1804 | + avb_out_data->ab_suffix, avb_out_data->cmdline); | |
1805 | + } else { | |
1806 | + sprintf(bootargs_sec, | |
1807 | + "androidboot.verifiedbootstate=orange androidboot.slot_suffix=%s %s", | |
1808 | + avb_out_data->ab_suffix, avb_out_data->cmdline); | |
1809 | + } | |
1810 | + env_set("bootargs_sec", bootargs_sec); | |
1811 | +#ifdef CONFIG_SYSTEM_RAMDISK_SUPPORT | |
1812 | + if(!is_recovery_mode) { | |
1813 | + if(avb_out_data->cmdline != NULL && strstr(avb_out_data->cmdline, "root=")) | |
1814 | + fastboot_setup_system_boot_args(avb_out_data->ab_suffix, false); | |
1815 | + else | |
1816 | + fastboot_setup_system_boot_args(avb_out_data->ab_suffix, true); | |
1817 | + } | |
1818 | +#endif /* CONFIG_SYSTEM_RAMDISK_SUPPORT */ | |
1819 | + image_size = avb_loadpart->data_size; | |
1820 | +#if defined (CONFIG_ARCH_IMX8) || defined (CONFIG_ARCH_IMX8M) | |
1821 | + /* If we are using uncompressed kernel image, copy it directly to | |
1822 | + * hdr->kernel_addr, if we are using compressed lz4 kernel image, | |
1823 | + * we need to decompress the kernel image first. */ | |
1824 | + if (image_arm64((void *)((ulong)hdr + hdr->page_size))) { | |
1825 | + memcpy((void *)(long)hdr->kernel_addr, | |
1826 | + (void *)((ulong)hdr + hdr->page_size), hdr->kernel_size); | |
1827 | + } else { | |
1828 | +#ifdef CONFIG_LZ4 | |
1829 | + if (ulz4fn((void *)((ulong)hdr + hdr->page_size), | |
1830 | + hdr->kernel_size, (void *)(ulong)hdr->kernel_addr, &lz4_len) != 0) { | |
1831 | + printf("Decompress kernel fail!\n"); | |
1832 | + goto fail; | |
1833 | + } | |
1834 | +#else /* CONFIG_LZ4 */ | |
1835 | + printf("please enable CONFIG_LZ4 if we're using compressed lz4 kernel image!\n"); | |
1836 | + goto fail; | |
1837 | +#endif /* CONFIG_LZ4 */ | |
1838 | + } | |
1839 | +#else /* CONFIG_ARCH_IMX8 || CONFIG_ARCH_IMX8M */ | |
1840 | + /* copy kernel image and boot header to hdr->kernel_addr - hdr->page_size */ | |
1841 | + memcpy((void *)(ulong)(hdr->kernel_addr - hdr->page_size), (void *)hdr, | |
1842 | + hdr->page_size + ALIGN(hdr->kernel_size, hdr->page_size)); | |
1843 | +#endif /* CONFIG_ARCH_IMX8 || CONFIG_ARCH_IMX8M */ | |
1844 | + } else if (lock_status == FASTBOOT_LOCK) { /* && verify fail */ | |
1845 | + /* if in lock state, verify enforce fail */ | |
1846 | + printf(" verify FAIL, state: LOCK\n"); | |
1847 | + goto fail; | |
1848 | + } else { /* lock_status == FASTBOOT_UNLOCK && get unacceptable verify fail */ | |
1849 | + /* if in unlock state, log the verify state */ | |
1850 | + printf(" verify FAIL, state: UNLOCK\n"); | |
1851 | +#endif | |
1852 | + /* if lock/unlock not enabled or verify fail | |
1853 | + * in unlock state, will try boot */ | |
1854 | + size_t num_read; | |
1855 | + hdr = &boothdr; | |
1856 | + | |
1857 | + char bootimg[10]; | |
1858 | + /* we don't have a/b slot for imx6 on normal Android*/ | |
1859 | +#ifndef CONFIG_ANDROID_AB_SUPPORT | |
1860 | + char *slot = ""; | |
1861 | + if (!is_recovery_mode) { | |
1862 | + sprintf(bootimg, "boot"); | |
1863 | + } else { | |
1864 | + sprintf(bootimg, "recovery"); | |
1865 | + } | |
1866 | + printf("boot '%s' still\n", bootimg); | |
1867 | +#else | |
1868 | + char *slot = select_slot(&fsl_avb_ab_ops); | |
1869 | + if (slot == NULL) { | |
1870 | + printf("boota: no bootable slot\n"); | |
1871 | + goto fail; | |
1872 | + } | |
1873 | + sprintf(bootimg, "boot%s", slot); | |
1874 | + printf(" boot '%s' still\n", bootimg); | |
1875 | +#endif | |
1876 | + /* maybe we should use bootctl to select a/b | |
1877 | + * but libavb doesn't export a/b select */ | |
1878 | + if (fsl_avb_ops.read_from_partition(&fsl_avb_ops, bootimg, | |
1879 | + 0, sizeof(boothdr), hdr, &num_read) != AVB_IO_RESULT_OK && | |
1880 | + num_read != sizeof(boothdr)) { | |
1881 | + printf("boota: read bootimage head error\n"); | |
1882 | + goto fail; | |
1883 | + } | |
1884 | + if (android_image_check_header(hdr)) { | |
1885 | + printf("boota: bad boot image magic\n"); | |
1886 | + goto fail; | |
1887 | + } | |
1888 | + image_size = android_image_get_end(hdr) - (ulong)hdr; | |
1889 | +#if defined (CONFIG_ARCH_IMX8) || defined (CONFIG_ARCH_IMX8M) | |
1890 | + boot_buf = malloc(image_size); | |
1891 | + /* Load boot image */ | |
1892 | + if (fsl_avb_ops.read_from_partition(&fsl_avb_ops, bootimg, | |
1893 | + 0, image_size, boot_buf, &num_read) != AVB_IO_RESULT_OK | |
1894 | + && num_read != image_size) { | |
1895 | + printf("boota: read boot image error\n"); | |
1896 | + goto fail; | |
1897 | + } | |
1898 | + /* If we are using uncompressed kernel image, copy it directly to | |
1899 | + * hdr->kernel_addr, if we are using compressed lz4 kernel image, | |
1900 | + * we need to decompress the kernel image first. */ | |
1901 | + if (image_arm64((void *)((ulong)boot_buf + hdr->page_size))) { | |
1902 | + memcpy((void *)(ulong)hdr->kernel_addr, | |
1903 | + (void *)((ulong)boot_buf + hdr->page_size), hdr->kernel_size); | |
1904 | + } else { | |
1905 | +#ifdef CONFIG_LZ4 | |
1906 | + if (ulz4fn((void *)((ulong)boot_buf + hdr->page_size), | |
1907 | + hdr->kernel_size, (void *)(ulong)hdr->kernel_addr, &lz4_len) != 0) { | |
1908 | + printf("Decompress kernel fail!\n"); | |
1909 | + goto fail; | |
1910 | + } | |
1911 | +#else /* CONFIG_LZ4 */ | |
1912 | + printf("please enable CONFIG_LZ4 if we're using compressed lz4 kernel image!\n"); | |
1913 | + goto fail; | |
1914 | +#endif /* CONFIG_LZ4 */ | |
1915 | + } | |
1916 | + hdr = (struct andr_img_hdr *)boot_buf; | |
1917 | +#else /* CONFIG_ARCH_IMX8 || CONFIG_ARCH_IMX8M */ | |
1918 | + if (fsl_avb_ops.read_from_partition(&fsl_avb_ops, bootimg, | |
1919 | + 0, image_size, (void *)(ulong)(hdr->kernel_addr - hdr->page_size), &num_read) != AVB_IO_RESULT_OK | |
1920 | + && num_read != image_size) { | |
1921 | + printf("boota: read boot image error\n"); | |
1922 | + goto fail; | |
1923 | + } | |
1924 | + hdr = (struct andr_img_hdr *)(ulong)(hdr->kernel_addr - hdr->page_size); | |
1925 | +#endif /* CONFIG_ARCH_IMX8 || CONFIG_ARCH_IMX8M */ | |
1926 | + char bootargs_sec[ANDR_BOOT_ARGS_SIZE]; | |
1927 | + sprintf(bootargs_sec, | |
1928 | + "androidboot.verifiedbootstate=orange androidboot.slot_suffix=%s", slot); | |
1929 | + env_set("bootargs_sec", bootargs_sec); | |
1930 | +#ifdef CONFIG_SYSTEM_RAMDISK_SUPPORT | |
1931 | + if(!is_recovery_mode) | |
1932 | + fastboot_setup_system_boot_args(slot, true); | |
1933 | +#endif /* CONFIG_SYSTEM_RAMDISK_SUPPORT */ | |
1934 | +#ifdef CONFIG_FASTBOOT_LOCK | |
1935 | + } | |
1936 | +#endif | |
1937 | + | |
1938 | + flush_cache((ulong)load_addr, image_size); | |
1939 | + check_image_arm64 = image_arm64((void *)(ulong)hdr->kernel_addr); | |
1940 | +#ifdef CONFIG_SYSTEM_RAMDISK_SUPPORT | |
1941 | + if (is_recovery_mode) | |
1942 | + memcpy((void *)(ulong)hdr->ramdisk_addr, (void *)(ulong)hdr + hdr->page_size | |
1943 | + + ALIGN(hdr->kernel_size, hdr->page_size), hdr->ramdisk_size); | |
1944 | +#else | |
1945 | + memcpy((void *)(ulong)hdr->ramdisk_addr, (void *)(ulong)hdr + hdr->page_size | |
1946 | + + ALIGN(hdr->kernel_size, hdr->page_size), hdr->ramdisk_size); | |
1947 | +#endif | |
1948 | +#ifdef CONFIG_OF_LIBFDT | |
1949 | + /* load the dtb file */ | |
1950 | + if (hdr->second_size && hdr->second_addr) { | |
1951 | + memcpy((void *)(ulong)hdr->second_addr, (void *)(ulong)hdr + hdr->page_size | |
1952 | + + ALIGN(hdr->kernel_size, hdr->page_size) | |
1953 | + + ALIGN(hdr->ramdisk_size, hdr->page_size), hdr->second_size); | |
1954 | + } | |
1955 | +#endif /*CONFIG_OF_LIBFDT*/ | |
1956 | + if (check_image_arm64) { | |
1957 | + android_image_get_kernel(hdr, 0, NULL, NULL); | |
1958 | + addr = hdr->kernel_addr; | |
1959 | + } else { | |
1960 | + addr = (ulong)(hdr->kernel_addr - hdr->page_size); | |
1961 | + } | |
1962 | + printf("kernel @ %08x (%d)\n", hdr->kernel_addr, hdr->kernel_size); | |
1963 | + printf("ramdisk @ %08x (%d)\n", hdr->ramdisk_addr, hdr->ramdisk_size); | |
1964 | +#ifdef CONFIG_OF_LIBFDT | |
1965 | + if (hdr->second_size) | |
1966 | + printf("fdt @ %08x (%d)\n", hdr->second_addr, hdr->second_size); | |
1967 | +#endif /*CONFIG_OF_LIBFDT*/ | |
1968 | + | |
1969 | + char boot_addr_start[12]; | |
1970 | + char ramdisk_addr[25]; | |
1971 | + char fdt_addr[12]; | |
1972 | + | |
1973 | + char *boot_args[] = { NULL, boot_addr_start, ramdisk_addr, fdt_addr}; | |
1974 | + if (check_image_arm64) | |
1975 | + boot_args[0] = "booti"; | |
1976 | + else | |
1977 | + boot_args[0] = "bootm"; | |
1978 | + | |
1979 | + sprintf(boot_addr_start, "0x%lx", addr); | |
1980 | + sprintf(ramdisk_addr, "0x%x:0x%x", hdr->ramdisk_addr, hdr->ramdisk_size); | |
1981 | + sprintf(fdt_addr, "0x%x", hdr->second_addr); | |
1982 | + | |
1983 | +/* no need to pass ramdisk addr for normal boot mode when enable CONFIG_SYSTEM_RAMDISK_SUPPORT*/ | |
1984 | +#ifdef CONFIG_SYSTEM_RAMDISK_SUPPORT | |
1985 | + if (!is_recovery_mode) | |
1986 | + boot_args[2] = NULL; | |
1987 | +#endif | |
1988 | + if (avb_out_data != NULL) | |
1989 | + avb_slot_verify_data_free(avb_out_data); | |
1990 | + if (boot_buf != NULL) | |
1991 | + free(boot_buf); | |
1992 | + | |
1993 | + if (check_image_arm64) { | |
1994 | +#ifdef CONFIG_CMD_BOOTI | |
1995 | + do_booti(NULL, 0, 4, boot_args); | |
1996 | +#else | |
1997 | + debug("please enable CONFIG_CMD_BOOTI when kernel are Image"); | |
1998 | +#endif | |
1999 | + } else { | |
2000 | + do_bootm(NULL, 0, 4, boot_args); | |
2001 | + } | |
2002 | + | |
2003 | + /* This only happens if image is somehow faulty so we start over */ | |
2004 | + do_reset(NULL, 0, 0, NULL); | |
2005 | + | |
2006 | + return 1; | |
2007 | + | |
2008 | +fail: | |
2009 | + /* avb has no recovery */ | |
2010 | + if (avb_out_data != NULL) | |
2011 | + avb_slot_verify_data_free(avb_out_data); | |
2012 | + if (boot_buf != NULL) | |
2013 | + free(boot_buf); | |
2014 | + | |
2015 | + return run_command("fastboot 0", 0); | |
2016 | +} | |
2017 | + | |
2018 | +U_BOOT_CMD( | |
2019 | + boota, 2, 1, do_boota, | |
2020 | + "boota - boot android bootimg \n", | |
2021 | + "boot from current mmc with avb verify\n" | |
2022 | +); | |
2023 | +#else /* CONFIG_AVB_SUPPORT */ | |
2024 | +/* boota <addr> [ mmc0 | mmc1 [ <partition> ] ] */ | |
2025 | +int do_boota(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) | |
2026 | +{ | |
2027 | + ulong addr = 0; | |
2028 | + char *ptn = "boot"; | |
2029 | + int mmcc = -1; | |
2030 | + struct andr_img_hdr *hdr = &boothdr; | |
2031 | + ulong image_size; | |
2032 | + bool check_image_arm64 = false; | |
2033 | + int i = 0; | |
2034 | + | |
2035 | + for (i = 0; i < argc; i++) | |
2036 | + printf("%s ", argv[i]); | |
2037 | + printf("\n"); | |
2038 | + | |
2039 | + if (argc < 2) | |
2040 | + return -1; | |
2041 | + | |
2042 | + mmcc = simple_strtoul(argv[1]+3, NULL, 10); | |
2043 | + | |
2044 | + if (argc > 2) | |
2045 | + ptn = argv[2]; | |
2046 | + | |
2047 | + if (mmcc != -1) { | |
2048 | +#ifdef CONFIG_MMC | |
2049 | + struct fastboot_ptentry *pte; | |
2050 | + struct mmc *mmc; | |
2051 | + disk_partition_t info; | |
2052 | + struct blk_desc *dev_desc = NULL; | |
2053 | + unsigned bootimg_sectors; | |
2054 | + | |
2055 | + memset((void *)&info, 0 , sizeof(disk_partition_t)); | |
2056 | + /* i.MX use MBR as partition table, so this will have | |
2057 | + to find the start block and length for the | |
2058 | + partition name and register the fastboot pte we | |
2059 | + define the partition number of each partition in | |
2060 | + config file | |
2061 | + */ | |
2062 | + mmc = find_mmc_device(mmcc); | |
2063 | + if (!mmc) { | |
2064 | + printf("boota: cannot find '%d' mmc device\n", mmcc); | |
2065 | + goto fail; | |
2066 | + } | |
2067 | + dev_desc = blk_get_dev("mmc", mmcc); | |
2068 | + if (!dev_desc || dev_desc->type == DEV_TYPE_UNKNOWN) { | |
2069 | + printf("** Block device MMC %d not supported\n", mmcc); | |
2070 | + goto fail; | |
2071 | + } | |
2072 | + | |
2073 | + /* below was i.MX mmc operation code */ | |
2074 | + if (mmc_init(mmc)) { | |
2075 | + printf("mmc%d init failed\n", mmcc); | |
2076 | + goto fail; | |
2077 | + } | |
2078 | + | |
2079 | + pte = fastboot_flash_find_ptn(ptn); | |
2080 | + if (!pte) { | |
2081 | + printf("boota: cannot find '%s' partition\n", ptn); | |
2082 | + goto fail; | |
2083 | + } | |
2084 | + | |
2085 | + if (blk_dread(dev_desc, pte->start, | |
2086 | + 1, (void *)hdr) < 0) { | |
2087 | + printf("boota: mmc failed to read bootimg header\n"); | |
2088 | + goto fail; | |
2089 | + } | |
2090 | + | |
2091 | + if (android_image_check_header(hdr)) { | |
2092 | + printf("boota: bad boot image magic\n"); | |
2093 | + goto fail; | |
2094 | + } | |
2095 | + | |
2096 | + image_size = android_image_get_end(hdr) - (ulong)hdr; | |
2097 | + bootimg_sectors = image_size/512; | |
2098 | + | |
2099 | + if (blk_dread(dev_desc, pte->start, | |
2100 | + bootimg_sectors, | |
2101 | + (void *)(hdr->kernel_addr - hdr->page_size)) < 0) { | |
2102 | + printf("boota: mmc failed to read bootimage\n"); | |
2103 | + goto fail; | |
2104 | + } | |
2105 | + check_image_arm64 = image_arm64((void *)hdr->kernel_addr); | |
2106 | +#ifdef CONFIG_FASTBOOT_LOCK | |
2107 | + int verifyresult = -1; | |
2108 | +#endif | |
2109 | + | |
2110 | +#ifdef CONFIG_FASTBOOT_LOCK | |
2111 | + int lock_status = fastboot_get_lock_stat(); | |
2112 | + if (lock_status == FASTBOOT_LOCK_ERROR) { | |
2113 | + printf("In boota get fastboot lock status error. Set lock status\n"); | |
2114 | + fastboot_set_lock_stat(FASTBOOT_LOCK); | |
2115 | + } | |
2116 | + display_lock(fastboot_get_lock_stat(), verifyresult); | |
2117 | +#endif | |
2118 | + /* load the ramdisk file */ | |
2119 | + memcpy((void *)hdr->ramdisk_addr, (void *)hdr->kernel_addr | |
2120 | + + ALIGN(hdr->kernel_size, hdr->page_size), hdr->ramdisk_size); | |
2121 | + | |
2122 | +#ifdef CONFIG_OF_LIBFDT | |
2123 | + /* load the dtb file */ | |
2124 | + if (hdr->second_size && hdr->second_addr) { | |
2125 | + memcpy((void *)hdr->second_addr, (void *)hdr->kernel_addr | |
2126 | + + ALIGN(hdr->kernel_size, hdr->page_size) | |
2127 | + + ALIGN(hdr->ramdisk_size, hdr->page_size), hdr->second_size); | |
2128 | + } | |
2129 | +#endif /*CONFIG_OF_LIBFDT*/ | |
2130 | + | |
2131 | +#else /*! CONFIG_MMC*/ | |
2132 | + return -1; | |
2133 | +#endif /*! CONFIG_MMC*/ | |
2134 | + } else { | |
2135 | + printf("boota: parameters is invalid. only support mmcX device\n"); | |
2136 | + return -1; | |
2137 | + } | |
2138 | + | |
2139 | + printf("kernel @ %08x (%d)\n", hdr->kernel_addr, hdr->kernel_size); | |
2140 | + printf("ramdisk @ %08x (%d)\n", hdr->ramdisk_addr, hdr->ramdisk_size); | |
2141 | +#ifdef CONFIG_OF_LIBFDT | |
2142 | + if (hdr->second_size) | |
2143 | + printf("fdt @ %08x (%d)\n", hdr->second_addr, hdr->second_size); | |
2144 | +#endif /*CONFIG_OF_LIBFDT*/ | |
2145 | + | |
2146 | + | |
2147 | + char boot_addr_start[12]; | |
2148 | + char ramdisk_addr[25]; | |
2149 | + char fdt_addr[12]; | |
2150 | + char *boot_args[] = { NULL, boot_addr_start, ramdisk_addr, fdt_addr}; | |
2151 | + if (check_image_arm64 ) { | |
2152 | + addr = hdr->kernel_addr; | |
2153 | + boot_args[0] = "booti"; | |
2154 | + } else { | |
2155 | + addr = hdr->kernel_addr - hdr->page_size; | |
2156 | + boot_args[0] = "bootm"; | |
2157 | + } | |
2158 | + | |
2159 | + sprintf(boot_addr_start, "0x%lx", addr); | |
2160 | + sprintf(ramdisk_addr, "0x%x:0x%x", hdr->ramdisk_addr, hdr->ramdisk_size); | |
2161 | + sprintf(fdt_addr, "0x%x", hdr->second_addr); | |
2162 | + if (check_image_arm64) { | |
2163 | + android_image_get_kernel(hdr, 0, NULL, NULL); | |
2164 | +#ifdef CONFIG_CMD_BOOTI | |
2165 | + do_booti(NULL, 0, 4, boot_args); | |
2166 | +#else | |
2167 | + debug("please enable CONFIG_CMD_BOOTI when kernel are Image"); | |
2168 | +#endif | |
2169 | + } else { | |
2170 | + do_bootm(NULL, 0, 4, boot_args); | |
2171 | + } | |
2172 | + /* This only happens if image is somehow faulty so we start over */ | |
2173 | + do_reset(NULL, 0, 0, NULL); | |
2174 | + | |
2175 | + return 1; | |
2176 | + | |
2177 | +fail: | |
2178 | +#if defined(CONFIG_FSL_FASTBOOT) | |
2179 | + return run_command("fastboot 0", 0); | |
2180 | +#else /*! CONFIG_FSL_FASTBOOT*/ | |
2181 | + return -1; | |
2182 | +#endif /*! CONFIG_FSL_FASTBOOT*/ | |
2183 | +} | |
2184 | + | |
2185 | +U_BOOT_CMD( | |
2186 | + boota, 3, 1, do_boota, | |
2187 | + "boota - boot android bootimg from memory\n", | |
2188 | + "[<addr> | mmc0 | mmc1 | mmc2 | mmcX] [<partition>]\n " | |
2189 | + "- boot application image stored in memory or mmc\n" | |
2190 | + "\t'addr' should be the address of boot image " | |
2191 | + "which is zImage+ramdisk.img\n" | |
2192 | + "\t'mmcX' is the mmc device you store your boot.img, " | |
2193 | + "which will read the boot.img from 1M offset('/boot' partition)\n" | |
2194 | + "\t 'partition' (optional) is the partition id of your device, " | |
2195 | + "if no partition give, will going to 'boot' partition\n" | |
2196 | +); | |
2197 | +#endif /* CONFIG_AVB_SUPPORT */ | |
2198 | +#endif /* CONFIG_CMD_BOOTA */ | |
2199 | +#endif | |
2200 | + | |
156 | 2201 | void fastboot_fail(const char *reason) |
157 | 2202 | { |
158 | 2203 | strncpy(fb_response_str, "FAIL\0", 5); |
... | ... | @@ -165,6 +2210,24 @@ |
165 | 2210 | strncat(fb_response_str, reason, FASTBOOT_RESPONSE_LEN - 4 - 1); |
166 | 2211 | } |
167 | 2212 | |
2213 | +static void fastboot_fifo_complete(struct usb_ep *ep, struct usb_request *req) | |
2214 | +{ | |
2215 | + int status = req->status; | |
2216 | + usb_req *request; | |
2217 | + | |
2218 | + if (!status) { | |
2219 | + if (fastboot_func->front != NULL) { | |
2220 | + request = fastboot_func->front; | |
2221 | + fastboot_func->front = fastboot_func->front->next; | |
2222 | + usb_ep_free_request(ep, request->in_req); | |
2223 | + free(request); | |
2224 | + } else { | |
2225 | + printf("fail free request\n"); | |
2226 | + } | |
2227 | + return; | |
2228 | + } | |
2229 | +} | |
2230 | + | |
168 | 2231 | static void fastboot_complete(struct usb_ep *ep, struct usb_request *req) |
169 | 2232 | { |
170 | 2233 | int status = req->status; |
... | ... | @@ -226,6 +2289,7 @@ |
226 | 2289 | |
227 | 2290 | static void fastboot_disable(struct usb_function *f) |
228 | 2291 | { |
2292 | + usb_req *req; | |
229 | 2293 | struct f_fastboot *f_fb = func_to_fastboot(f); |
230 | 2294 | |
231 | 2295 | usb_ep_disable(f_fb->out_ep); |
... | ... | @@ -239,6 +2303,17 @@ |
239 | 2303 | if (f_fb->in_req) { |
240 | 2304 | free(f_fb->in_req->buf); |
241 | 2305 | usb_ep_free_request(f_fb->in_ep, f_fb->in_req); |
2306 | + | |
2307 | + /* disable usb request FIFO */ | |
2308 | + while(f_fb->front != NULL) { | |
2309 | + req = f_fb->front; | |
2310 | + f_fb->front = f_fb->front->next; | |
2311 | + free(req->in_req->buf); | |
2312 | + usb_ep_free_request(f_fb->in_ep, req->in_req); | |
2313 | + free(req); | |
2314 | + } | |
2315 | + | |
2316 | + f_fb->rear = NULL; | |
242 | 2317 | f_fb->in_req = NULL; |
243 | 2318 | } |
244 | 2319 | } |
245 | 2320 | |
... | ... | @@ -302,8 +2377,19 @@ |
302 | 2377 | ret = -EINVAL; |
303 | 2378 | goto err; |
304 | 2379 | } |
2380 | +#ifdef CONFIG_ANDROID_THINGS_SUPPORT | |
2381 | + /* | |
2382 | + * fastboot host end implement to get data in one bulk package so need | |
2383 | + * large buffer for the "fastboot upload" and "fastboot get_staged". | |
2384 | + */ | |
2385 | + if (f_fb->in_req->buf) | |
2386 | + free(f_fb->in_req->buf); | |
2387 | + f_fb->in_req->buf = memalign(CONFIG_SYS_CACHELINE_SIZE, EP_BUFFER_SIZE * 32); | |
2388 | +#endif | |
305 | 2389 | f_fb->in_req->complete = fastboot_complete; |
306 | 2390 | |
2391 | + f_fb->front = f_fb->rear = NULL; | |
2392 | + | |
307 | 2393 | ret = usb_ep_queue(f_fb->out_ep, f_fb->out_req, 0); |
308 | 2394 | if (ret) |
309 | 2395 | goto err; |
310 | 2396 | |
... | ... | @@ -340,13 +2426,56 @@ |
340 | 2426 | status = usb_add_function(c, &f_fb->usb_function); |
341 | 2427 | if (status) { |
342 | 2428 | free(f_fb); |
343 | - fastboot_func = f_fb; | |
2429 | + fastboot_func = NULL; | |
344 | 2430 | } |
345 | 2431 | |
346 | 2432 | return status; |
347 | 2433 | } |
348 | 2434 | DECLARE_GADGET_BIND_CALLBACK(usb_dnl_fastboot, fastboot_add); |
349 | 2435 | |
2436 | +static int fastboot_tx_write_more(const char *buffer) | |
2437 | +{ | |
2438 | + int ret = 0; | |
2439 | + | |
2440 | + /* alloc usb request FIFO node */ | |
2441 | + usb_req *req = (usb_req *)malloc(sizeof(usb_req)); | |
2442 | + if (!req) { | |
2443 | + printf("failed alloc usb req!\n"); | |
2444 | + return -ENOMEM; | |
2445 | + } | |
2446 | + | |
2447 | + /* usb request node FIFO enquene */ | |
2448 | + if ((fastboot_func->front == NULL) && (fastboot_func->rear == NULL)) { | |
2449 | + fastboot_func->front = fastboot_func->rear = req; | |
2450 | + req->next = NULL; | |
2451 | + } else { | |
2452 | + fastboot_func->rear->next = req; | |
2453 | + fastboot_func->rear = req; | |
2454 | + req->next = NULL; | |
2455 | + } | |
2456 | + | |
2457 | + /* alloc in request for current node */ | |
2458 | + req->in_req = fastboot_start_ep(fastboot_func->in_ep); | |
2459 | + if (!req->in_req) { | |
2460 | + printf("failed alloc req in\n"); | |
2461 | + fastboot_disable(&(fastboot_func->usb_function)); | |
2462 | + return -EINVAL; | |
2463 | + } | |
2464 | + req->in_req->complete = fastboot_fifo_complete; | |
2465 | + | |
2466 | + memcpy(req->in_req->buf, buffer, strlen(buffer)); | |
2467 | + req->in_req->length = strlen(buffer); | |
2468 | + | |
2469 | + ret = usb_ep_queue(fastboot_func->in_ep, req->in_req, 0); | |
2470 | + if (ret) { | |
2471 | + printf("Error %d on queue\n", ret); | |
2472 | + return -EINVAL; | |
2473 | + } | |
2474 | + | |
2475 | + ret = 0; | |
2476 | + return ret; | |
2477 | +} | |
2478 | + | |
350 | 2479 | static int fastboot_tx_write(const char *buffer, unsigned int buffer_size) |
351 | 2480 | { |
352 | 2481 | struct usb_request *in_req = fastboot_func->in_req; |
353 | 2482 | |
354 | 2483 | |
355 | 2484 | |
... | ... | @@ -398,10 +2527,612 @@ |
398 | 2527 | return strncmp(s1, s2, strlen(s1)); |
399 | 2528 | } |
400 | 2529 | |
2530 | +#ifdef CONFIG_FSL_FASTBOOT | |
2531 | +static bool is_slotvar(char *cmd) | |
2532 | +{ | |
2533 | + assert(cmd != NULL); | |
2534 | + if (!strcmp_l1("has-slot:", cmd) || | |
2535 | + !strcmp_l1("slot-successful:", cmd) || | |
2536 | + !strcmp_l1("slot-count", cmd) || | |
2537 | + !strcmp_l1("slot-suffixes", cmd) || | |
2538 | + !strcmp_l1("current-slot", cmd) || | |
2539 | + !strcmp_l1("slot-unbootable:", cmd) || | |
2540 | + !strcmp_l1("slot-retry-count:", cmd)) | |
2541 | + return true; | |
2542 | + return false; | |
2543 | +} | |
2544 | + | |
2545 | +static char *get_serial(void) | |
2546 | +{ | |
2547 | +#ifdef CONFIG_SERIAL_TAG | |
2548 | + struct tag_serialnr serialnr; | |
2549 | + static char serial[32]; | |
2550 | + get_board_serial(&serialnr); | |
2551 | + sprintf(serial, "%08x%08x", serialnr.high, serialnr.low); | |
2552 | + return serial; | |
2553 | +#else | |
2554 | + return NULL; | |
2555 | +#endif | |
2556 | +} | |
2557 | + | |
2558 | +#if !defined(PRODUCT_NAME) | |
2559 | +#define PRODUCT_NAME "NXP i.MX" | |
2560 | +#endif | |
2561 | + | |
2562 | +#if !defined(VARIANT_NAME) | |
2563 | +#define VARIANT_NAME "NXP i.MX" | |
2564 | +#endif | |
2565 | + | |
2566 | +static int get_block_size(void) { | |
2567 | + int mmc_no = 0; | |
2568 | + struct blk_desc *dev_desc; | |
2569 | + mmc_no = fastboot_devinfo.dev_id; | |
2570 | + dev_desc = blk_get_dev("mmc", mmc_no); | |
2571 | + if (NULL == dev_desc) { | |
2572 | + printf("** Block device MMC %d not supported\n", | |
2573 | + mmc_no); | |
2574 | + return 0; | |
2575 | + } | |
2576 | + return dev_desc->blksz; | |
2577 | +} | |
2578 | + | |
2579 | +static bool is_exist(char (*partition_base_name)[16], char *buffer, int count) | |
2580 | +{ | |
2581 | + int n; | |
2582 | + | |
2583 | + for (n = 0; n < count; n++) { | |
2584 | + if (!strcmp(partition_base_name[n],buffer)) | |
2585 | + return true; | |
2586 | + } | |
2587 | + return false; | |
2588 | +} | |
2589 | +/*get partition base name from gpt without "_a/_b"*/ | |
2590 | +static int get_partition_base_name(char (*partition_base_name)[16]) | |
2591 | +{ | |
2592 | + int n = 0; | |
2593 | + int count = 0; | |
2594 | + char *ptr1, *ptr2; | |
2595 | + char buffer[16]; | |
2596 | + | |
2597 | + for (n = 0; n < g_pcount; n++) { | |
2598 | + strcpy(buffer,g_ptable[n].name); | |
2599 | + ptr1 = strstr(buffer, "_a"); | |
2600 | + ptr2 = strstr(buffer, "_b"); | |
2601 | + if (ptr1 != NULL) { | |
2602 | + *ptr1 = '\0'; | |
2603 | + if (!is_exist(partition_base_name,buffer,count)) { | |
2604 | + strcpy(partition_base_name[count++],buffer); | |
2605 | + } | |
2606 | + } else if (ptr2 != NULL) { | |
2607 | + *ptr2 = '\0'; | |
2608 | + if (!is_exist(partition_base_name,buffer,count)) { | |
2609 | + strcpy(partition_base_name[count++],buffer); | |
2610 | + } | |
2611 | + } else { | |
2612 | + strcpy(partition_base_name[count++],buffer); | |
2613 | + } | |
2614 | + } | |
2615 | + return count; | |
2616 | +} | |
2617 | + | |
2618 | +static bool is_slot(void) | |
2619 | +{ | |
2620 | + char slot_suffix[2][5] = {"_a","_b"}; | |
2621 | + int n; | |
2622 | + | |
2623 | + for (n = 0; n < g_pcount; n++) { | |
2624 | + if (strstr(g_ptable[n].name, slot_suffix[0]) || | |
2625 | + strstr(g_ptable[n].name, slot_suffix[1])) | |
2626 | + return true; | |
2627 | + } | |
2628 | + return false; | |
2629 | +} | |
2630 | + | |
2631 | +static int get_single_var(char *cmd, char *response) | |
2632 | +{ | |
2633 | + char *str = cmd; | |
2634 | + size_t chars_left; | |
2635 | + const char *s; | |
2636 | + struct mmc *mmc; | |
2637 | + int mmc_dev_no; | |
2638 | + int blksz; | |
2639 | + | |
2640 | + chars_left = FASTBOOT_RESPONSE_LEN - strlen(response) - 1; | |
2641 | + | |
2642 | + if ((str = strstr(cmd, "partition-size:"))) { | |
2643 | + str +=strlen("partition-size:"); | |
2644 | + struct fastboot_ptentry* fb_part; | |
2645 | + fb_part = fastboot_flash_find_ptn(str); | |
2646 | + if (!fb_part) { | |
2647 | + strncat(response, "Wrong partition name.", chars_left); | |
2648 | + return -1; | |
2649 | + } else { | |
2650 | + snprintf(response + strlen(response), chars_left, "0x%x", fb_part->length * get_block_size()); | |
2651 | + } | |
2652 | + } else if ((str = strstr(cmd, "partition-type:"))) { | |
2653 | + str +=strlen("partition-type:"); | |
2654 | + struct fastboot_ptentry* fb_part; | |
2655 | + fb_part = fastboot_flash_find_ptn(str); | |
2656 | + if (!fb_part) { | |
2657 | + strncat(response, "Wrong partition name.", chars_left); | |
2658 | + return -1; | |
2659 | + } else { | |
2660 | + strncat(response, fb_part->fstype, chars_left); | |
2661 | + } | |
2662 | + } else if (!strcmp_l1("version-baseband", cmd)) { | |
2663 | + strncat(response, "N/A", chars_left); | |
2664 | + } else if (!strcmp_l1("version-bootloader", cmd) || | |
2665 | + !strcmp_l1("bootloader-version", cmd)) { | |
2666 | + strncat(response, U_BOOT_VERSION, chars_left); | |
2667 | + } else if (!strcmp_l1("version", cmd)) { | |
2668 | + strncat(response, FASTBOOT_VERSION, chars_left); | |
2669 | + } else if (!strcmp_l1("battery-voltage", cmd)) { | |
2670 | + strncat(response, "0mV", chars_left); | |
2671 | + } else if (!strcmp_l1("battery-soc-ok", cmd)) { | |
2672 | + strncat(response, "yes", chars_left); | |
2673 | + } else if (!strcmp_l1("variant", cmd)) { | |
2674 | + strncat(response, VARIANT_NAME, chars_left); | |
2675 | + } else if (!strcmp_l1("off-mode-charge", cmd)) { | |
2676 | + strncat(response, "1", chars_left); | |
2677 | + } else if (!strcmp_l1("downloadsize", cmd) || | |
2678 | + !strcmp_l1("max-download-size", cmd)) { | |
2679 | + | |
2680 | + snprintf(response + strlen(response), chars_left, "0x%x", CONFIG_FASTBOOT_BUF_SIZE); | |
2681 | + } else if (!strcmp_l1("erase-block-size", cmd)) { | |
2682 | + mmc_dev_no = mmc_get_env_dev(); | |
2683 | + mmc = find_mmc_device(mmc_dev_no); | |
2684 | + blksz = get_block_size(); | |
2685 | + snprintf(response + strlen(response), chars_left, "0x%x", | |
2686 | + (blksz * mmc->erase_grp_size)); | |
2687 | + } else if (!strcmp_l1("logical-block-size", cmd)) { | |
2688 | + blksz = get_block_size(); | |
2689 | + snprintf(response + strlen(response), chars_left, "0x%x", blksz); | |
2690 | + } else if (!strcmp_l1("serialno", cmd)) { | |
2691 | + s = get_serial(); | |
2692 | + if (s) | |
2693 | + strncat(response, s, chars_left); | |
2694 | + else { | |
2695 | + strncat(response, "FAILValue not set", chars_left); | |
2696 | + return -1; | |
2697 | + } | |
2698 | + } else if (!strcmp_l1("product", cmd)) { | |
2699 | + strncat(response, PRODUCT_NAME, chars_left); | |
2700 | + } | |
2701 | +#ifdef CONFIG_FASTBOOT_LOCK | |
2702 | + else if (!strcmp_l1("secure", cmd)) { | |
2703 | + strncat(response, FASTBOOT_VAR_YES, chars_left); | |
2704 | + } else if (!strcmp_l1("unlocked",cmd)){ | |
2705 | + int status = fastboot_get_lock_stat(); | |
2706 | + if (status == FASTBOOT_UNLOCK) { | |
2707 | + strncat(response, FASTBOOT_VAR_YES, chars_left); | |
2708 | + } else { | |
2709 | + strncat(response, FASTBOOT_VAR_NO, chars_left); | |
2710 | + } | |
2711 | + } | |
2712 | +#else | |
2713 | + else if (!strcmp_l1("secure", cmd)) { | |
2714 | + strncat(response, FASTBOOT_VAR_NO, chars_left); | |
2715 | + } else if (!strcmp_l1("unlocked",cmd)) { | |
2716 | + strncat(response, FASTBOOT_VAR_NO, chars_left); | |
2717 | + } | |
2718 | +#endif | |
2719 | + else if (is_slotvar(cmd)) { | |
2720 | +#ifdef CONFIG_AVB_SUPPORT | |
2721 | + if (get_slotvar_avb(&fsl_avb_ab_ops, cmd, | |
2722 | + response + strlen(response), chars_left + 1) < 0) | |
2723 | + return -1; | |
2724 | +#else | |
2725 | + strncat(response, FASTBOOT_VAR_NO, chars_left); | |
2726 | +#endif | |
2727 | + } | |
2728 | + else { | |
2729 | + char envstr[32]; | |
2730 | + | |
2731 | + snprintf(envstr, sizeof(envstr) - 1, "fastboot.%s", cmd); | |
2732 | + s = env_get(envstr); | |
2733 | + if (s) { | |
2734 | + strncat(response, s, chars_left); | |
2735 | + } else { | |
2736 | + sprintf(response,"FAILunknow variable:%s",cmd); | |
2737 | + printf("WARNING: unknown variable: %s\n", cmd); | |
2738 | + return -1; | |
2739 | + } | |
2740 | + } | |
2741 | + return 0; | |
2742 | +} | |
2743 | + | |
401 | 2744 | static void cb_getvar(struct usb_ep *ep, struct usb_request *req) |
402 | 2745 | { |
2746 | + int n = 0; | |
2747 | + int status = 0; | |
2748 | + int count = 0; | |
403 | 2749 | char *cmd = req->buf; |
2750 | + char var_name[FASTBOOT_RESPONSE_LEN - 1]; | |
2751 | + char partition_base_name[MAX_PTN][16]; | |
2752 | + char slot_suffix[2][5] = {"a","b"}; | |
2753 | + char response[FASTBOOT_RESPONSE_LEN - 1]; | |
2754 | + | |
2755 | + strsep(&cmd, ":"); | |
2756 | + if (!cmd) { | |
2757 | + pr_err("missing variable"); | |
2758 | + fastboot_tx_write_str("FAILmissing var"); | |
2759 | + return; | |
2760 | + } | |
2761 | + | |
2762 | + if (!strcmp_l1("all", cmd)) { | |
2763 | + | |
2764 | + memset(response, '\0', FASTBOOT_RESPONSE_LEN - 1); | |
2765 | + | |
2766 | + | |
2767 | + /* get common variables */ | |
2768 | + for (n = 0; n < FASTBOOT_COMMON_VAR_NUM; n++) { | |
2769 | + snprintf(response, sizeof(response), "INFO%s:", fastboot_common_var[n]); | |
2770 | + get_single_var(fastboot_common_var[n], response); | |
2771 | + fastboot_tx_write_more(response); | |
2772 | + } | |
2773 | + | |
2774 | + /* get partition type */ | |
2775 | + for (n = 0; n < g_pcount; n++) { | |
2776 | + snprintf(response, sizeof(response), "INFOpartition-type:%s:", g_ptable[n].name); | |
2777 | + snprintf(var_name, sizeof(var_name), "partition-type:%s", g_ptable[n].name); | |
2778 | + get_single_var(var_name, response); | |
2779 | + fastboot_tx_write_more(response); | |
2780 | + } | |
2781 | + /* get partition size */ | |
2782 | + for (n = 0; n < g_pcount; n++) { | |
2783 | + snprintf(response, sizeof(response), "INFOpartition-size:%s:", g_ptable[n].name); | |
2784 | + snprintf(var_name, sizeof(var_name), "partition-size:%s", g_ptable[n].name); | |
2785 | + get_single_var(var_name,response); | |
2786 | + fastboot_tx_write_more(response); | |
2787 | + } | |
2788 | + /* slot related variables */ | |
2789 | + if (is_slot()) { | |
2790 | + /* get has-slot variables */ | |
2791 | + count = get_partition_base_name(partition_base_name); | |
2792 | + for (n = 0; n < count; n++) { | |
2793 | + snprintf(response, sizeof(response), "INFOhas-slot:%s:", partition_base_name[n]); | |
2794 | + snprintf(var_name, sizeof(var_name), "has-slot:%s", partition_base_name[n]); | |
2795 | + get_single_var(var_name,response); | |
2796 | + fastboot_tx_write_more(response); | |
2797 | + } | |
2798 | + /* get current slot */ | |
2799 | + strncpy(response, "INFOcurrent-slot:", sizeof(response)); | |
2800 | + get_single_var("current-slot", response); | |
2801 | + fastboot_tx_write_more(response); | |
2802 | + /* get slot count */ | |
2803 | + strncpy(response, "INFOslot-count:", sizeof(response)); | |
2804 | + get_single_var("slot-count", response); | |
2805 | + fastboot_tx_write_more(response); | |
2806 | + /* get slot-successful variable */ | |
2807 | + for (n = 0; n < 2; n++) { | |
2808 | + snprintf(response, sizeof(response), "INFOslot-successful:%s:", slot_suffix[n]); | |
2809 | + snprintf(var_name, sizeof(var_name), "slot-successful:%s", slot_suffix[n]); | |
2810 | + get_single_var(var_name, response); | |
2811 | + fastboot_tx_write_more(response); | |
2812 | + } | |
2813 | + /*get slot-unbootable variable*/ | |
2814 | + for (n = 0; n < 2; n++) { | |
2815 | + snprintf(response, sizeof(response), "INFOslot-unbootable:%s:", slot_suffix[n]); | |
2816 | + snprintf(var_name, sizeof(var_name), "slot-unbootable:%s", slot_suffix[n]); | |
2817 | + get_single_var(var_name, response); | |
2818 | + fastboot_tx_write_more(response); | |
2819 | + } | |
2820 | + /*get slot-retry-count variable*/ | |
2821 | + for (n = 0; n < 2; n++) { | |
2822 | + snprintf(response, sizeof(response), "INFOslot-retry-count:%s:", slot_suffix[n]); | |
2823 | + snprintf(var_name, sizeof(var_name), "slot-retry-count:%s", slot_suffix[n]); | |
2824 | + get_single_var(var_name, response); | |
2825 | + fastboot_tx_write_more(response); | |
2826 | + } | |
2827 | + } | |
2828 | + | |
2829 | + strncpy(response, "OKAYDone!", 10); | |
2830 | + fastboot_tx_write_more(response); | |
2831 | + | |
2832 | + return; | |
2833 | + } else { | |
2834 | + | |
2835 | + strncpy(response, "OKAY", 5); | |
2836 | + status = get_single_var(cmd, response); | |
2837 | + if (status != 0) { | |
2838 | + strncpy(response, "FAIL", 5); | |
2839 | + } | |
2840 | + fastboot_tx_write_str(response); | |
2841 | + return; | |
2842 | + } | |
2843 | +} | |
2844 | + | |
2845 | +#ifdef CONFIG_FASTBOOT_LOCK | |
2846 | + | |
2847 | +int do_lock_status(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { | |
2848 | + FbLockState status = fastboot_get_lock_stat(); | |
2849 | + if (status != FASTBOOT_LOCK_ERROR) { | |
2850 | + if (status == FASTBOOT_LOCK) | |
2851 | + printf("fastboot lock status: locked.\n"); | |
2852 | + else | |
2853 | + printf("fastboot lock status: unlocked.\n"); | |
2854 | + } else | |
2855 | + printf("fastboot lock status error!\n"); | |
2856 | + | |
2857 | + display_lock(status, -1); | |
2858 | + | |
2859 | + return 0; | |
2860 | + | |
2861 | +} | |
2862 | + | |
2863 | +U_BOOT_CMD( | |
2864 | + lock_status, 2, 1, do_lock_status, | |
2865 | + "lock_status", | |
2866 | + "lock_status"); | |
2867 | + | |
2868 | +static FbLockState do_fastboot_unlock(bool force) | |
2869 | +{ | |
2870 | + int status; | |
2871 | + if (force) | |
2872 | + set_fastboot_lock_disable(); | |
2873 | + if ((fastboot_lock_enable() == FASTBOOT_UL_ENABLE) || force) { | |
2874 | + printf("It is able to unlock device. %d\n",fastboot_lock_enable()); | |
2875 | + if (fastboot_get_lock_stat() == FASTBOOT_UNLOCK) { | |
2876 | + printf("The device is already unlocked\n"); | |
2877 | + return FASTBOOT_UNLOCK; | |
2878 | + } | |
2879 | + status = fastboot_set_lock_stat(FASTBOOT_UNLOCK); | |
2880 | + if (status < 0) | |
2881 | + return FASTBOOT_LOCK_ERROR; | |
2882 | + | |
2883 | + printf("Start /data wipe process....\n"); | |
2884 | + fastboot_wipe_data_partition(); | |
2885 | + printf("Wipe /data completed.\n"); | |
2886 | + | |
2887 | +#ifdef CONFIG_AVB_SUPPORT | |
2888 | + printf("Start stored_rollback_index wipe process....\n"); | |
2889 | + rbkidx_erase(); | |
2890 | + printf("Wipe stored_rollback_index completed.\n"); | |
2891 | +#endif | |
2892 | + } else { | |
2893 | + printf("It is not able to unlock device."); | |
2894 | + return FASTBOOT_LOCK_ERROR; | |
2895 | + } | |
2896 | + | |
2897 | + return FASTBOOT_UNLOCK; | |
2898 | +} | |
2899 | + | |
2900 | +static FbLockState do_fastboot_lock(void) | |
2901 | +{ | |
2902 | + int status; | |
2903 | + if (fastboot_get_lock_stat() == FASTBOOT_LOCK) { | |
2904 | + printf("The device is already locked\n"); | |
2905 | + return FASTBOOT_LOCK; | |
2906 | + } | |
2907 | + status = fastboot_set_lock_stat(FASTBOOT_LOCK); | |
2908 | + if (status < 0) | |
2909 | + return FASTBOOT_LOCK_ERROR; | |
2910 | + | |
2911 | + printf("Start /data wipe process....\n"); | |
2912 | + fastboot_wipe_data_partition(); | |
2913 | + printf("Wipe /data completed.\n"); | |
2914 | + | |
2915 | + return FASTBOOT_LOCK; | |
2916 | +} | |
2917 | + | |
2918 | +static void cb_flashing(struct usb_ep *ep, struct usb_request *req) | |
2919 | +{ | |
2920 | + char *cmd = req->buf; | |
404 | 2921 | char response[FASTBOOT_RESPONSE_LEN]; |
2922 | + unsigned char len = strlen(cmd); | |
2923 | + FbLockState status; | |
2924 | + FbLockEnableResult result; | |
2925 | + | |
2926 | +#ifdef CONFIG_ANDROID_THINGS_SUPPORT | |
2927 | + if (!strncmp(cmd + len - strlen(FASTBOOT_BOOTLOADER_VBOOT_KEY), | |
2928 | + FASTBOOT_BOOTLOADER_VBOOT_KEY, | |
2929 | + strlen(FASTBOOT_BOOTLOADER_VBOOT_KEY))) { | |
2930 | + strcpy(response, "OKAY"); | |
2931 | + } else if (!strncmp(cmd + len - strlen("unlock_critical"), | |
2932 | + "unlock_critical", strlen("unlock_critical"))) { | |
2933 | +#else | |
2934 | + if (!strncmp(cmd + len - strlen("unlock_critical"), | |
2935 | + "unlock_critical", strlen("unlock_critical"))) { | |
2936 | +#endif | |
2937 | + strcpy(response, "OKAY"); | |
2938 | + } else if (!strncmp(cmd + len - strlen("lock_critical"), | |
2939 | + "lock_critical", strlen("lock_critical"))) { | |
2940 | + strcpy(response, "OKAY"); | |
2941 | + } else if (!strncmp(cmd + len - strlen("unlock"), | |
2942 | + "unlock", strlen("unlock"))) { | |
2943 | + printf("flashing unlock.\n"); | |
2944 | + status = do_fastboot_unlock(false); | |
2945 | + if (status != FASTBOOT_LOCK_ERROR) | |
2946 | + strcpy(response, "OKAY"); | |
2947 | + else | |
2948 | + strcpy(response, "FAIL unlock device failed."); | |
2949 | + } else if (!strncmp(cmd + len - strlen("lock"), "lock", strlen("lock"))) { | |
2950 | + printf("flashing lock.\n"); | |
2951 | + status = do_fastboot_lock(); | |
2952 | + if (status != FASTBOOT_LOCK_ERROR) | |
2953 | + strcpy(response, "OKAY"); | |
2954 | + else | |
2955 | + strcpy(response, "FAIL lock device failed."); | |
2956 | + } else if (!strncmp(cmd + len - strlen("get_unlock_ability"), | |
2957 | + "get_unlock_ability", strlen("get_unlock_ability"))) { | |
2958 | + result = fastboot_lock_enable(); | |
2959 | + if (result == FASTBOOT_UL_ENABLE) { | |
2960 | + fastboot_tx_write_more("INFO1"); | |
2961 | + strcpy(response, "OKAY"); | |
2962 | + } else if (result == FASTBOOT_UL_DISABLE) { | |
2963 | + fastboot_tx_write_more("INFO0"); | |
2964 | + strcpy(response, "OKAY"); | |
2965 | + } else { | |
2966 | + printf("flashing get_unlock_ability fail!\n"); | |
2967 | + strcpy(response, "FAIL get unlock ability failed."); | |
2968 | + } | |
2969 | + } else { | |
2970 | + printf("Unknown flashing command:%s\n", cmd); | |
2971 | + strcpy(response, "FAIL command not defined"); | |
2972 | + } | |
2973 | + fastboot_tx_write_more(response); | |
2974 | +} | |
2975 | + | |
2976 | +static int partition_table_valid(void) | |
2977 | +{ | |
2978 | + int status, mmc_no; | |
2979 | + struct blk_desc *dev_desc; | |
2980 | + disk_partition_t info; | |
2981 | + mmc_no = fastboot_devinfo.dev_id; | |
2982 | + dev_desc = blk_get_dev("mmc", mmc_no); | |
2983 | + if (dev_desc) | |
2984 | + status = part_get_info(dev_desc, 1, &info); | |
2985 | + else | |
2986 | + status = -1; | |
2987 | + return (status == 0); | |
2988 | +} | |
2989 | + | |
2990 | +#endif /* CONFIG_FASTBOOT_LOCK */ | |
2991 | + | |
2992 | +#ifdef CONFIG_FASTBOOT_FLASH | |
2993 | +static void cb_flash(struct usb_ep *ep, struct usb_request *req) | |
2994 | +{ | |
2995 | + char *cmd = req->buf; | |
2996 | + char response[FASTBOOT_RESPONSE_LEN]; | |
2997 | + | |
2998 | + strsep(&cmd, ":"); | |
2999 | + if (!cmd) { | |
3000 | + pr_err("missing partition name"); | |
3001 | + fastboot_tx_write_str("FAILmissing partition name"); | |
3002 | + return; | |
3003 | + } | |
3004 | + | |
3005 | + /* initialize the response buffer */ | |
3006 | + fb_response_str = response; | |
3007 | + | |
3008 | +#ifdef CONFIG_FASTBOOT_LOCK | |
3009 | + int status; | |
3010 | + status = fastboot_get_lock_stat(); | |
3011 | + | |
3012 | + if (status == FASTBOOT_LOCK) { | |
3013 | + pr_err("device is LOCKed!\n"); | |
3014 | + strcpy(response, "FAIL device is locked."); | |
3015 | + fastboot_tx_write_str(response); | |
3016 | + return; | |
3017 | + | |
3018 | + } else if (status == FASTBOOT_LOCK_ERROR) { | |
3019 | + pr_err("write lock status into device!\n"); | |
3020 | + fastboot_set_lock_stat(FASTBOOT_LOCK); | |
3021 | + strcpy(response, "FAIL device is locked."); | |
3022 | + fastboot_tx_write_str(response); | |
3023 | + return; | |
3024 | + } | |
3025 | +#endif | |
3026 | + fastboot_fail("no flash device defined"); | |
3027 | + | |
3028 | +#ifdef CONFIG_FASTBOOT_LOCK | |
3029 | + int gpt_valid_pre = 0; | |
3030 | + int gpt_valid_pst = 0; | |
3031 | + if (strncmp(cmd, "gpt", 3) == 0) | |
3032 | + gpt_valid_pre = partition_table_valid(); | |
3033 | +#endif | |
3034 | + rx_process_flash(cmd); | |
3035 | +#ifdef CONFIG_FASTBOOT_LOCK | |
3036 | + if (strncmp(cmd, "gpt", 3) == 0) { | |
3037 | + gpt_valid_pst = partition_table_valid(); | |
3038 | + /* If gpt is valid, load partitons table into memory. | |
3039 | + So if the next command is "fastboot reboot bootloader", | |
3040 | + it can find the "misc" partition to r/w. */ | |
3041 | + if(gpt_valid_pst) | |
3042 | + _fastboot_load_partitions(); | |
3043 | + /* If gpt invalid -> valid, write unlock status, also wipe data. */ | |
3044 | + if ((gpt_valid_pre == 0) && (gpt_valid_pst == 1)) | |
3045 | + do_fastboot_unlock(true); | |
3046 | + } | |
3047 | + | |
3048 | +#endif | |
3049 | + fastboot_tx_write_str(response); | |
3050 | +} | |
3051 | +#endif | |
3052 | + | |
3053 | +#ifdef CONFIG_FASTBOOT_FLASH | |
3054 | +static void cb_erase(struct usb_ep *ep, struct usb_request *req) | |
3055 | +{ | |
3056 | + char *cmd = req->buf; | |
3057 | + char response[FASTBOOT_RESPONSE_LEN]; | |
3058 | + | |
3059 | + strsep(&cmd, ":"); | |
3060 | + if (!cmd) { | |
3061 | + pr_err("missing partition name"); | |
3062 | + fastboot_tx_write_str("FAILmissing partition name"); | |
3063 | + return; | |
3064 | + } | |
3065 | + | |
3066 | + /* initialize the response buffer */ | |
3067 | + fb_response_str = response; | |
3068 | + | |
3069 | +#ifdef CONFIG_FASTBOOT_LOCK | |
3070 | + FbLockState status; | |
3071 | + status = fastboot_get_lock_stat(); | |
3072 | + if (status == FASTBOOT_LOCK) { | |
3073 | + pr_err("device is LOCKed!\n"); | |
3074 | + strcpy(response, "FAIL device is locked."); | |
3075 | + fastboot_tx_write_str(response); | |
3076 | + return; | |
3077 | + } else if (status == FASTBOOT_LOCK_ERROR) { | |
3078 | + pr_err("write lock status into device!\n"); | |
3079 | + fastboot_set_lock_stat(FASTBOOT_LOCK); | |
3080 | + strcpy(response, "FAIL device is locked."); | |
3081 | + fastboot_tx_write_str(response); | |
3082 | + return; | |
3083 | + } | |
3084 | +#endif | |
3085 | + rx_process_erase(cmd, response); | |
3086 | + fastboot_tx_write_str(response); | |
3087 | +} | |
3088 | +#endif | |
3089 | + | |
3090 | +#ifdef CONFIG_AVB_SUPPORT | |
3091 | +static void cb_set_active_avb(struct usb_ep *ep, struct usb_request *req) | |
3092 | +{ | |
3093 | + AvbIOResult ret; | |
3094 | + int slot = 0; | |
3095 | + char *cmd = req->buf; | |
3096 | + | |
3097 | + strsep(&cmd, ":"); | |
3098 | + if (!cmd) { | |
3099 | + pr_err("missing slot suffix\n"); | |
3100 | + fastboot_tx_write_str("FAILmissing slot suffix"); | |
3101 | + return; | |
3102 | + } | |
3103 | + | |
3104 | + slot = slotidx_from_suffix(cmd); | |
3105 | + | |
3106 | + if (slot < 0) { | |
3107 | + fastboot_tx_write_str("FAILerr slot suffix"); | |
3108 | + return; | |
3109 | + } | |
3110 | + | |
3111 | + ret = avb_ab_mark_slot_active(&fsl_avb_ab_ops, slot); | |
3112 | + if (ret != AVB_IO_RESULT_OK) | |
3113 | + fastboot_tx_write_str("avb IO error"); | |
3114 | + else | |
3115 | + fastboot_tx_write_str("OKAY"); | |
3116 | + | |
3117 | + return; | |
3118 | +} | |
3119 | +#endif /*CONFIG_AVB_SUPPORT*/ | |
3120 | + | |
3121 | +static void cb_reboot_bootloader(struct usb_ep *ep, struct usb_request *req) | |
3122 | +{ | |
3123 | + fastboot_tx_write_str("OKAY"); | |
3124 | + | |
3125 | + udelay(1000000); | |
3126 | + enable_fastboot_command(); | |
3127 | + do_reset(NULL, 0, 0, NULL); | |
3128 | +} | |
3129 | + | |
3130 | +#else /* CONFIG_FSL_FASTBOOT */ | |
3131 | + | |
3132 | +static void cb_getvar(struct usb_ep *ep, struct usb_request *req) | |
3133 | +{ | |
3134 | + char *cmd = req->buf; | |
3135 | + char response[FASTBOOT_RESPONSE_LEN]; | |
405 | 3136 | const char *s; |
406 | 3137 | size_t chars_left; |
407 | 3138 | |
... | ... | @@ -454,6 +3185,87 @@ |
454 | 3185 | fastboot_tx_write_str(response); |
455 | 3186 | } |
456 | 3187 | |
3188 | +#ifdef CONFIG_FASTBOOT_FLASH | |
3189 | +static void cb_flash(struct usb_ep *ep, struct usb_request *req) | |
3190 | +{ | |
3191 | + char *cmd = req->buf; | |
3192 | + char response[FASTBOOT_RESPONSE_LEN]; | |
3193 | + | |
3194 | + strsep(&cmd, ":"); | |
3195 | + if (!cmd) { | |
3196 | + pr_err("missing partition name"); | |
3197 | + fastboot_tx_write_str("FAILmissing partition name"); | |
3198 | + return; | |
3199 | + } | |
3200 | + | |
3201 | + /* initialize the response buffer */ | |
3202 | + fb_response_str = response; | |
3203 | + | |
3204 | + fastboot_fail("no flash device defined"); | |
3205 | +#ifdef CONFIG_FASTBOOT_FLASH_MMC_DEV | |
3206 | + fb_mmc_flash_write(cmd, (void *)CONFIG_FASTBOOT_BUF_ADDR, | |
3207 | + download_bytes); | |
3208 | +#endif | |
3209 | +#ifdef CONFIG_FASTBOOT_FLASH_NAND_DEV | |
3210 | + fb_nand_flash_write(cmd, | |
3211 | + (void *)CONFIG_FASTBOOT_BUF_ADDR, | |
3212 | + download_bytes); | |
3213 | +#endif | |
3214 | + fastboot_tx_write_str(response); | |
3215 | +} | |
3216 | +#endif | |
3217 | + | |
3218 | +static void cb_oem(struct usb_ep *ep, struct usb_request *req) | |
3219 | +{ | |
3220 | + char *cmd = req->buf; | |
3221 | +#ifdef CONFIG_FASTBOOT_FLASH_MMC_DEV | |
3222 | + if (strncmp("format", cmd + 4, 6) == 0) { | |
3223 | + char cmdbuf[32]; | |
3224 | + sprintf(cmdbuf, "gpt write mmc %x $partitions", | |
3225 | + CONFIG_FASTBOOT_FLASH_MMC_DEV); | |
3226 | + if (run_command(cmdbuf, 0)) | |
3227 | + fastboot_tx_write_str("FAIL"); | |
3228 | + else | |
3229 | + fastboot_tx_write_str("OKAY"); | |
3230 | + } else | |
3231 | +#endif | |
3232 | + if (strncmp("unlock", cmd + 4, 8) == 0) { | |
3233 | + fastboot_tx_write_str("FAILnot implemented"); | |
3234 | + } | |
3235 | + else { | |
3236 | + fastboot_tx_write_str("FAILunknown oem command"); | |
3237 | + } | |
3238 | +} | |
3239 | + | |
3240 | +#ifdef CONFIG_FASTBOOT_FLASH | |
3241 | +static void cb_erase(struct usb_ep *ep, struct usb_request *req) | |
3242 | +{ | |
3243 | + char *cmd = req->buf; | |
3244 | + char response[FASTBOOT_RESPONSE_LEN]; | |
3245 | + | |
3246 | + strsep(&cmd, ":"); | |
3247 | + if (!cmd) { | |
3248 | + pr_err("missing partition name"); | |
3249 | + fastboot_tx_write_str("FAILmissing partition name"); | |
3250 | + return; | |
3251 | + } | |
3252 | + | |
3253 | + /* initialize the response buffer */ | |
3254 | + fb_response_str = response; | |
3255 | + | |
3256 | + fastboot_fail("no flash device defined"); | |
3257 | +#ifdef CONFIG_FASTBOOT_FLASH_MMC_DEV | |
3258 | + fb_mmc_erase(cmd); | |
3259 | +#endif | |
3260 | +#ifdef CONFIG_FASTBOOT_FLASH_NAND_DEV | |
3261 | + fb_nand_erase(cmd); | |
3262 | +#endif | |
3263 | + fastboot_tx_write_str(response); | |
3264 | +} | |
3265 | +#endif | |
3266 | + | |
3267 | +#endif /* CONFIG_FSL_FASTBOOT*/ | |
3268 | + | |
457 | 3269 | static unsigned int rx_bytes_expected(struct usb_ep *ep) |
458 | 3270 | { |
459 | 3271 | int rx_remain = download_size - download_bytes; |
... | ... | @@ -530,6 +3342,26 @@ |
530 | 3342 | usb_ep_queue(ep, req, 0); |
531 | 3343 | } |
532 | 3344 | |
3345 | +static void cb_upload(struct usb_ep *ep, struct usb_request *req) | |
3346 | +{ | |
3347 | + char response[FASTBOOT_RESPONSE_LEN]; | |
3348 | + | |
3349 | + if (!download_bytes || download_bytes > (EP_BUFFER_SIZE * 32)) { | |
3350 | + sprintf(response, "FAIL"); | |
3351 | + fastboot_tx_write_str(response); | |
3352 | + return; | |
3353 | + } | |
3354 | + | |
3355 | + printf("Will upload %d bytes.\n", download_bytes); | |
3356 | + snprintf(response, FASTBOOT_RESPONSE_LEN, "DATA%08x", download_bytes); | |
3357 | + fastboot_tx_write_more(response); | |
3358 | + | |
3359 | + fastboot_tx_write((const char *)(interface.transfer_buffer), download_bytes); | |
3360 | + | |
3361 | + snprintf(response,FASTBOOT_RESPONSE_LEN, "OKAY"); | |
3362 | + fastboot_tx_write_more(response); | |
3363 | +} | |
3364 | + | |
533 | 3365 | static void cb_download(struct usb_ep *ep, struct usb_request *req) |
534 | 3366 | { |
535 | 3367 | char *cmd = req->buf; |
536 | 3368 | |
537 | 3369 | |
... | ... | @@ -557,11 +3389,16 @@ |
557 | 3389 | static void do_bootm_on_complete(struct usb_ep *ep, struct usb_request *req) |
558 | 3390 | { |
559 | 3391 | char boot_addr_start[12]; |
3392 | +#ifdef CONFIG_FSL_FASTBOOT | |
3393 | + char *bootm_args[] = { "boota", boot_addr_start, NULL }; | |
3394 | + sprintf(boot_addr_start, "0x%lx", load_addr); | |
3395 | +#else | |
560 | 3396 | char *bootm_args[] = { "bootm", boot_addr_start, NULL }; |
3397 | + sprintf(boot_addr_start, "0x%lx", (long)CONFIG_FASTBOOT_BUF_ADDR); | |
3398 | +#endif | |
561 | 3399 | |
562 | 3400 | puts("Booting kernel..\n"); |
563 | 3401 | |
564 | - sprintf(boot_addr_start, "0x%lx", (long)CONFIG_FASTBOOT_BUF_ADDR); | |
565 | 3402 | do_bootm(NULL, 0, 2, bootm_args); |
566 | 3403 | |
567 | 3404 | /* This only happens if image is somehow faulty so we start over */ |
568 | 3405 | |
569 | 3406 | |
... | ... | @@ -585,92 +3422,39 @@ |
585 | 3422 | fastboot_tx_write_str("OKAY"); |
586 | 3423 | } |
587 | 3424 | |
588 | -#ifdef CONFIG_FASTBOOT_FLASH | |
589 | -static void cb_flash(struct usb_ep *ep, struct usb_request *req) | |
590 | -{ | |
591 | - char *cmd = req->buf; | |
592 | - char response[FASTBOOT_RESPONSE_LEN]; | |
593 | - | |
594 | - strsep(&cmd, ":"); | |
595 | - if (!cmd) { | |
596 | - pr_err("missing partition name"); | |
597 | - fastboot_tx_write_str("FAILmissing partition name"); | |
598 | - return; | |
599 | - } | |
600 | - | |
601 | - /* initialize the response buffer */ | |
602 | - fb_response_str = response; | |
603 | - | |
604 | - fastboot_fail("no flash device defined"); | |
605 | -#ifdef CONFIG_FASTBOOT_FLASH_MMC_DEV | |
606 | - fb_mmc_flash_write(cmd, (void *)CONFIG_FASTBOOT_BUF_ADDR, | |
607 | - download_bytes); | |
608 | -#endif | |
609 | -#ifdef CONFIG_FASTBOOT_FLASH_NAND_DEV | |
610 | - fb_nand_flash_write(cmd, | |
611 | - (void *)CONFIG_FASTBOOT_BUF_ADDR, | |
612 | - download_bytes); | |
613 | -#endif | |
614 | - fastboot_tx_write_str(response); | |
615 | -} | |
616 | -#endif | |
617 | - | |
618 | -static void cb_oem(struct usb_ep *ep, struct usb_request *req) | |
619 | -{ | |
620 | - char *cmd = req->buf; | |
621 | -#ifdef CONFIG_FASTBOOT_FLASH_MMC_DEV | |
622 | - if (strncmp("format", cmd + 4, 6) == 0) { | |
623 | - char cmdbuf[32]; | |
624 | - sprintf(cmdbuf, "gpt write mmc %x $partitions", | |
625 | - CONFIG_FASTBOOT_FLASH_MMC_DEV); | |
626 | - if (run_command(cmdbuf, 0)) | |
627 | - fastboot_tx_write_str("FAIL"); | |
628 | - else | |
629 | - fastboot_tx_write_str("OKAY"); | |
630 | - } else | |
631 | -#endif | |
632 | - if (strncmp("unlock", cmd + 4, 8) == 0) { | |
633 | - fastboot_tx_write_str("FAILnot implemented"); | |
634 | - } | |
635 | - else { | |
636 | - fastboot_tx_write_str("FAILunknown oem command"); | |
637 | - } | |
638 | -} | |
639 | - | |
640 | -#ifdef CONFIG_FASTBOOT_FLASH | |
641 | -static void cb_erase(struct usb_ep *ep, struct usb_request *req) | |
642 | -{ | |
643 | - char *cmd = req->buf; | |
644 | - char response[FASTBOOT_RESPONSE_LEN]; | |
645 | - | |
646 | - strsep(&cmd, ":"); | |
647 | - if (!cmd) { | |
648 | - pr_err("missing partition name"); | |
649 | - fastboot_tx_write_str("FAILmissing partition name"); | |
650 | - return; | |
651 | - } | |
652 | - | |
653 | - /* initialize the response buffer */ | |
654 | - fb_response_str = response; | |
655 | - | |
656 | - fastboot_fail("no flash device defined"); | |
657 | -#ifdef CONFIG_FASTBOOT_FLASH_MMC_DEV | |
658 | - fb_mmc_erase(cmd); | |
659 | -#endif | |
660 | -#ifdef CONFIG_FASTBOOT_FLASH_NAND_DEV | |
661 | - fb_nand_erase(cmd); | |
662 | -#endif | |
663 | - fastboot_tx_write_str(response); | |
664 | -} | |
665 | -#endif | |
666 | - | |
667 | 3425 | struct cmd_dispatch_info { |
668 | 3426 | char *cmd; |
669 | 3427 | void (*cb)(struct usb_ep *ep, struct usb_request *req); |
670 | 3428 | }; |
671 | 3429 | |
672 | 3430 | static const struct cmd_dispatch_info cmd_dispatch_info[] = { |
3431 | +#ifdef CONFIG_FSL_FASTBOOT | |
673 | 3432 | { |
3433 | + .cmd = "reboot-bootloader", | |
3434 | + .cb = cb_reboot_bootloader, | |
3435 | + }, | |
3436 | + { | |
3437 | + .cmd = "upload", | |
3438 | + .cb = cb_upload, | |
3439 | + }, | |
3440 | +#ifdef CONFIG_FASTBOOT_LOCK | |
3441 | + { | |
3442 | + .cmd = "flashing", | |
3443 | + .cb = cb_flashing, | |
3444 | + }, | |
3445 | + { | |
3446 | + .cmd = "oem", | |
3447 | + .cb = cb_flashing, | |
3448 | + }, | |
3449 | +#endif | |
3450 | +#ifdef CONFIG_AVB_SUPPORT | |
3451 | + { | |
3452 | + .cmd = "set_active", | |
3453 | + .cb = cb_set_active_avb, | |
3454 | + }, | |
3455 | +#endif | |
3456 | +#endif | |
3457 | + { | |
674 | 3458 | .cmd = "reboot", |
675 | 3459 | .cb = cb_reboot, |
676 | 3460 | }, { |
677 | 3461 | |
... | ... | @@ -695,10 +3479,12 @@ |
695 | 3479 | .cb = cb_erase, |
696 | 3480 | }, |
697 | 3481 | #endif |
3482 | +#ifndef CONFIG_FSL_FASTBOOT | |
698 | 3483 | { |
699 | 3484 | .cmd = "oem", |
700 | 3485 | .cb = cb_oem, |
701 | 3486 | }, |
3487 | +#endif | |
702 | 3488 | }; |
703 | 3489 | |
704 | 3490 | static void rx_handler_command(struct usb_ep *ep, struct usb_request *req) |
... | ... | @@ -706,6 +3492,10 @@ |
706 | 3492 | char *cmdbuf = req->buf; |
707 | 3493 | void (*func_cb)(struct usb_ep *ep, struct usb_request *req) = NULL; |
708 | 3494 | int i; |
3495 | + | |
3496 | + /* init in request FIFO pointer */ | |
3497 | + fastboot_func->front = NULL; | |
3498 | + fastboot_func->rear = NULL; | |
709 | 3499 | |
710 | 3500 | if (req->status != 0 || req->length == 0) |
711 | 3501 | return; |
drivers/usb/gadget/fastboot_lock_unlock.c
1 | +/* | |
2 | + * Copyright (c) 2016, Freescale Semiconductor, Inc. | |
3 | + * All rights reserved. | |
4 | + * | |
5 | + * Redistribution and use in source and binary forms, with or without modification, | |
6 | + * are permitted provided that the following conditions are met: | |
7 | + * | |
8 | + * o Redistributions of source code must retain the above copyright notice, this list | |
9 | + * of conditions and the following disclaimer. | |
10 | + * | |
11 | + * o Redistributions in binary form must reproduce the above copyright notice, this | |
12 | + * list of conditions and the following disclaimer in the documentation and/or | |
13 | + * other materials provided with the distribution. | |
14 | + * | |
15 | + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its | |
16 | + * contributors may be used to endorse or promote products derived from this | |
17 | + * software without specific prior written permission. | |
18 | + * | |
19 | + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND | |
20 | + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | |
21 | + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | |
22 | + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR | |
23 | + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | |
24 | + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | |
25 | + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON | |
26 | + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |
27 | + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | |
28 | + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
29 | + */ | |
30 | +#include <common.h> | |
31 | +#include <mapmem.h> | |
32 | +#include <linux/types.h> | |
33 | +#include <part.h> | |
34 | +#include <mmc.h> | |
35 | +#include <ext_common.h> | |
36 | +#include <stdio_dev.h> | |
37 | +#include <stdlib.h> | |
38 | +#include "fastboot_lock_unlock.h" | |
39 | +#include <fsl_fastboot.h> | |
40 | + | |
41 | +#ifdef FASTBOOT_ENCRYPT_LOCK | |
42 | + | |
43 | +#include <hash.h> | |
44 | +#include <fsl_caam.h> | |
45 | + | |
46 | +//Encrypted data is 80bytes length. | |
47 | +#define ENDATA_LEN 80 | |
48 | + | |
49 | +#endif | |
50 | + | |
51 | +int fastboot_flash_find_index(const char *name); | |
52 | + | |
53 | +#ifndef FASTBOOT_ENCRYPT_LOCK | |
54 | + | |
55 | +/* | |
56 | + * This will return FASTBOOT_LOCK, FASTBOOT_UNLOCK or FASTBOOT_ERROR | |
57 | + */ | |
58 | +static FbLockState decrypt_lock_store(unsigned char* bdata) { | |
59 | + if (!strncmp((const char *)bdata, "locked", strlen("locked"))) | |
60 | + return FASTBOOT_LOCK; | |
61 | + else if (!strncmp((const char *)bdata, "unlocked", strlen("unlocked"))) | |
62 | + return FASTBOOT_UNLOCK; | |
63 | + else | |
64 | + return FASTBOOT_LOCK_ERROR; | |
65 | +} | |
66 | + | |
67 | +static inline int encrypt_lock_store(FbLockState lock, unsigned char* bdata) { | |
68 | + if (FASTBOOT_LOCK == lock) | |
69 | + strncpy((char *)bdata, "locked", strlen("locked")); | |
70 | + else if (FASTBOOT_UNLOCK == lock) | |
71 | + strncpy((char *)bdata, "unlocked", strlen("unlocked")); | |
72 | + else | |
73 | + return -1; | |
74 | + return 0; | |
75 | +} | |
76 | +#else | |
77 | + | |
78 | +static int sha1sum(unsigned char* data, int len, unsigned char* output) { | |
79 | + struct hash_algo *algo; | |
80 | + void *buf; | |
81 | + if (hash_lookup_algo("sha1", &algo)) { | |
82 | + printf("error in lookup sha1 algo!\n"); | |
83 | + return -1; | |
84 | + } | |
85 | + buf = map_sysmem((ulong)data, len); | |
86 | + algo->hash_func_ws(buf, len, output, algo->chunk_size); | |
87 | + unmap_sysmem(buf); | |
88 | + | |
89 | + return algo->digest_size; | |
90 | + | |
91 | +} | |
92 | + | |
93 | +static int generate_salt(unsigned char* salt) { | |
94 | + unsigned long time = get_timer(0); | |
95 | + return sha1sum((unsigned char *)&time, sizeof(unsigned long), salt); | |
96 | + | |
97 | +} | |
98 | + | |
99 | +static FbLockState decrypt_lock_store(unsigned char *bdata) { | |
100 | + unsigned char plain_data[ENDATA_LEN]; | |
101 | + int p = 0, ret; | |
102 | + | |
103 | + caam_open(); | |
104 | + ret = caam_decap_blob((uint32_t)plain_data, | |
105 | + (uint32_t)bdata + ENDATA_LEN, ENDATA_LEN); | |
106 | + if (ret != 0) { | |
107 | + printf("Error during blob decap operation: 0x%x\n",ret); | |
108 | + return FASTBOOT_LOCK_ERROR; | |
109 | + } | |
110 | +#ifdef FASTBOOT_LOCK_DEBUG | |
111 | + FB_DEBUG("Decrypt data block are:\n \t=======\t\n"); | |
112 | + for (p = 0; p < ENDATA_LEN; p++) { | |
113 | + FB_DEBUG("0x%2x ", *(bdata + p)); | |
114 | + if (p % 16 == 0) | |
115 | + FB_DEBUG("\n"); | |
116 | + } | |
117 | + FB_DEBUG("\n \t========\t\n"); | |
118 | + for (p = ENDATA_LEN; p < (ENDATA_LEN + ENDATA_LEN + 48 ); p++) { | |
119 | + FB_DEBUG("0x%2x ", *(bdata + p)); | |
120 | + if (p % 16 == 0) | |
121 | + FB_DEBUG("\n"); | |
122 | + } | |
123 | + | |
124 | + FB_DEBUG("\n plain text are:\n"); | |
125 | + for (p = 0; p < ENDATA_LEN; p++) { | |
126 | + FB_DEBUG("0x%2x ", plain_data[p]); | |
127 | + if (p % 16 == 0) | |
128 | + FB_DEBUG("\n"); | |
129 | + } | |
130 | + FB_DEBUG("\n"); | |
131 | +#endif | |
132 | + | |
133 | + for (p = 0; p < ENDATA_LEN-1; p++) { | |
134 | + if (*(bdata+p) != plain_data[p]) { | |
135 | + FB_DEBUG("Verify salt in decrypt error on pointer %d\n", p); | |
136 | + return FASTBOOT_LOCK_ERROR; | |
137 | + } | |
138 | + } | |
139 | + | |
140 | + if (plain_data[ENDATA_LEN - 1] >= FASTBOOT_LOCK_NUM) | |
141 | + return FASTBOOT_LOCK_ERROR; | |
142 | + else | |
143 | + return plain_data[ENDATA_LEN-1]; | |
144 | +} | |
145 | + | |
146 | +static int encrypt_lock_store(FbLockState lock, unsigned char* bdata) { | |
147 | + unsigned int p = 0; | |
148 | + int ret; | |
149 | + int salt_len = generate_salt(bdata); | |
150 | + if (salt_len < 0) | |
151 | + return -1; | |
152 | + | |
153 | + //salt_len cannot be longer than endata block size. | |
154 | + if (salt_len >= ENDATA_LEN) | |
155 | + salt_len = ENDATA_LEN - 1; | |
156 | + | |
157 | + p = ENDATA_LEN - 1; | |
158 | + | |
159 | + //Set lock value | |
160 | + *(bdata + p) = lock; | |
161 | + | |
162 | + caam_open(); | |
163 | + ret = caam_gen_blob((uint32_t)bdata, (uint32_t)(bdata + ENDATA_LEN), ENDATA_LEN); | |
164 | + if (ret != 0) { | |
165 | + printf("error in caam_gen_blob:0x%x\n", ret); | |
166 | + return -1; | |
167 | + } | |
168 | + | |
169 | + | |
170 | +#ifdef FASTBOOT_LOCK_DEBUG | |
171 | + int i = 0; | |
172 | + FB_DEBUG("encrypt plain_text:\n"); | |
173 | + for (i = 0; i < ENDATA_LEN; i++) { | |
174 | + FB_DEBUG("0x%2x\t", *(bdata+i)); | |
175 | + if (i % 16 == 0) | |
176 | + printf("\n"); | |
177 | + } | |
178 | + printf("\nto:\n"); | |
179 | + for (i=0; i < ENDATA_LEN + 48; i++) { | |
180 | + FB_DEBUG("0x%2x\t", *(bdata + ENDATA_LEN + i)); | |
181 | + if (i % 16 == 0) | |
182 | + printf("\n"); | |
183 | + } | |
184 | + printf("\n"); | |
185 | + | |
186 | +#endif | |
187 | + //protect value | |
188 | + *(bdata + p) = 0xff; | |
189 | + return 0; | |
190 | +} | |
191 | + | |
192 | +#endif | |
193 | + | |
194 | +static char mmc_dev_part[16]; | |
195 | +static char* get_mmc_part(int part) { | |
196 | + u32 dev_no = mmc_get_env_dev(); | |
197 | + sprintf(mmc_dev_part,"%x:%x",dev_no, part); | |
198 | + return mmc_dev_part; | |
199 | +} | |
200 | + | |
201 | +static inline void set_lock_disable_data(unsigned char* bdata) { | |
202 | + *(bdata + SECTOR_SIZE -1) = 0; | |
203 | +} | |
204 | + | |
205 | +/* | |
206 | + * The enabling value is stored in the last byte of target partition. | |
207 | + */ | |
208 | +static inline unsigned char lock_enable_parse(unsigned char* bdata) { | |
209 | + FB_DEBUG("lock_enable_parse: 0x%x\n", *(bdata + SECTOR_SIZE -1)); | |
210 | + if (*(bdata + SECTOR_SIZE -1) >= FASTBOOT_UL_NUM) | |
211 | + return FASTBOOT_UL_ERROR; | |
212 | + else | |
213 | + return *(bdata + SECTOR_SIZE -1); | |
214 | +} | |
215 | + | |
216 | +static FbLockState g_lockstat = FASTBOOT_UNLOCK; | |
217 | +/* | |
218 | + * Set status of the lock&unlock to FSL_FASTBOOT_FB_PART | |
219 | + * Currently use the very first Byte of FSL_FASTBOOT_FB_PART | |
220 | + * to store the fastboot lock&unlock status | |
221 | + */ | |
222 | +int fastboot_set_lock_stat(FbLockState lock) { | |
223 | + struct blk_desc *fs_dev_desc; | |
224 | + disk_partition_t fs_partition; | |
225 | + unsigned char *bdata; | |
226 | + int mmc_id; | |
227 | + int status, ret; | |
228 | + | |
229 | + bdata = (unsigned char *)memalign(ALIGN_BYTES, SECTOR_SIZE); | |
230 | + if (bdata == NULL) | |
231 | + goto fail2; | |
232 | + memset(bdata, 0, SECTOR_SIZE); | |
233 | + | |
234 | + mmc_id = fastboot_flash_find_index(FASTBOOT_PARTITION_FBMISC); | |
235 | + if (mmc_id < 0) { | |
236 | + printf("%s: error in get mmc part\n", __FUNCTION__); | |
237 | + ret = -1; | |
238 | + goto fail; | |
239 | + } | |
240 | + status = blk_get_device_part_str(FSL_FASTBOOT_FB_DEV, | |
241 | + get_mmc_part(mmc_id), | |
242 | + &fs_dev_desc, &fs_partition, 1); | |
243 | + if (status < 0) { | |
244 | + printf("%s:error in getdevice partition.\n", __FUNCTION__); | |
245 | + ret = -1; | |
246 | + goto fail; | |
247 | + } | |
248 | + | |
249 | + status = encrypt_lock_store(lock, bdata); | |
250 | + if (status < 0) { | |
251 | + ret = -1; | |
252 | + goto fail; | |
253 | + } | |
254 | + status = blk_dwrite(fs_dev_desc, fs_partition.start, 1, bdata); | |
255 | + if (!status) { | |
256 | + printf("%s:error in block write.\n", __FUNCTION__); | |
257 | + ret = -1; | |
258 | + goto fail; | |
259 | + } | |
260 | + ret = 0; | |
261 | +fail: | |
262 | + free(bdata); | |
263 | + return ret; | |
264 | +fail2: | |
265 | + g_lockstat = lock; | |
266 | + return 0; | |
267 | +} | |
268 | + | |
269 | +FbLockState fastboot_get_lock_stat(void) { | |
270 | + struct blk_desc *fs_dev_desc; | |
271 | + disk_partition_t fs_partition; | |
272 | + unsigned char *bdata; | |
273 | + int mmc_id; | |
274 | + FbLockState ret; | |
275 | + | |
276 | + bdata = (unsigned char *)memalign(ALIGN_BYTES, SECTOR_SIZE); | |
277 | + if (bdata == NULL) | |
278 | + return g_lockstat; | |
279 | + | |
280 | + int status; | |
281 | + mmc_id = fastboot_flash_find_index(FASTBOOT_PARTITION_FBMISC); | |
282 | + if (mmc_id < 0) { | |
283 | + printf("%s: error in get mmc part\n", __FUNCTION__); | |
284 | + ret = g_lockstat; | |
285 | + goto fail; | |
286 | + } | |
287 | + status = blk_get_device_part_str(FSL_FASTBOOT_FB_DEV, | |
288 | + get_mmc_part(mmc_id), | |
289 | + &fs_dev_desc, &fs_partition, 1); | |
290 | + | |
291 | + if (status < 0) { | |
292 | + printf("%s:error in getdevice partition.\n", __FUNCTION__); | |
293 | + ret = g_lockstat; | |
294 | + goto fail; | |
295 | + } | |
296 | + | |
297 | + status = blk_dread(fs_dev_desc, fs_partition.start, 1, bdata); | |
298 | + if (!status) { | |
299 | + printf("%s:error in block read.\n", __FUNCTION__); | |
300 | + ret = FASTBOOT_LOCK_ERROR; | |
301 | + goto fail; | |
302 | + } | |
303 | + | |
304 | + ret = decrypt_lock_store(bdata); | |
305 | +fail: | |
306 | + free(bdata); | |
307 | + return ret; | |
308 | +} | |
309 | + | |
310 | + | |
311 | +/* Return the last byte of of FSL_FASTBOOT_PR_DATA | |
312 | + * which is managed by PresistDataService | |
313 | + */ | |
314 | + | |
315 | +#ifdef CONFIG_ENABLE_LOCKSTATUS_SUPPORT | |
316 | +//Brillo has no presist data partition | |
317 | +FbLockEnableResult fastboot_lock_enable(void) { | |
318 | + return FASTBOOT_UL_ENABLE; | |
319 | +} | |
320 | +void set_fastboot_lock_disable(void) { | |
321 | +} | |
322 | +#else | |
323 | +void set_fastboot_lock_disable(void) { | |
324 | + struct blk_desc *fs_dev_desc; | |
325 | + disk_partition_t fs_partition; | |
326 | + unsigned char *bdata; | |
327 | + int mmc_id; | |
328 | + | |
329 | + bdata = (unsigned char *)memalign(ALIGN_BYTES, SECTOR_SIZE); | |
330 | + if (bdata == NULL) | |
331 | + return; | |
332 | + set_lock_disable_data(bdata); | |
333 | + int status; | |
334 | + mmc_id = fastboot_flash_find_index(FASTBOOT_PARTITION_PRDATA); | |
335 | + if (mmc_id < 0) { | |
336 | + printf("%s: error in get mmc part\n", __FUNCTION__); | |
337 | + goto fail; | |
338 | + } | |
339 | + status = blk_get_device_part_str(FSL_FASTBOOT_FB_DEV, | |
340 | + get_mmc_part(mmc_id), | |
341 | + &fs_dev_desc, &fs_partition, 1); | |
342 | + if (status < 0) { | |
343 | + printf("%s:error in getdevice partition.\n", __FUNCTION__); | |
344 | + goto fail; | |
345 | + } | |
346 | + | |
347 | + lbaint_t target_block = fs_partition.start + fs_partition.size - 1; | |
348 | + status = blk_dwrite(fs_dev_desc, target_block, 1, bdata); | |
349 | + if (!status) { | |
350 | + printf("%s: error in block read\n", __FUNCTION__); | |
351 | + goto fail; | |
352 | + } | |
353 | + | |
354 | +fail: | |
355 | + free(bdata); | |
356 | + return; | |
357 | + | |
358 | +} | |
359 | +FbLockEnableResult fastboot_lock_enable() { | |
360 | + struct blk_desc *fs_dev_desc; | |
361 | + disk_partition_t fs_partition; | |
362 | + unsigned char *bdata; | |
363 | + int mmc_id; | |
364 | + FbLockEnableResult ret; | |
365 | + | |
366 | + bdata = (unsigned char *)memalign(ALIGN_BYTES, SECTOR_SIZE); | |
367 | + if (bdata == NULL) | |
368 | + return FASTBOOT_UL_ERROR; | |
369 | + int status; | |
370 | + mmc_id = fastboot_flash_find_index(FASTBOOT_PARTITION_PRDATA); | |
371 | + if (mmc_id < 0) { | |
372 | + printf("%s: error in get mmc part\n", __FUNCTION__); | |
373 | + ret = FASTBOOT_UL_ERROR; | |
374 | + goto fail; | |
375 | + } | |
376 | + status = blk_get_device_part_str(FSL_FASTBOOT_FB_DEV, | |
377 | + get_mmc_part(mmc_id), | |
378 | + &fs_dev_desc, &fs_partition, 1); | |
379 | + if (status < 0) { | |
380 | + printf("%s:error in getdevice partition.\n", __FUNCTION__); | |
381 | + ret = FASTBOOT_UL_ERROR; | |
382 | + goto fail; | |
383 | + } | |
384 | + | |
385 | + //The data is stored in the last blcok of this partition. | |
386 | + lbaint_t target_block = fs_partition.start + fs_partition.size - 1; | |
387 | + status = blk_dread(fs_dev_desc, target_block, 1, bdata); | |
388 | + if (!status) { | |
389 | + printf("%s: error in block read\n", __FUNCTION__); | |
390 | + ret = FASTBOOT_UL_ERROR; | |
391 | + goto fail; | |
392 | + } | |
393 | + int i = 0; | |
394 | + FB_DEBUG("\n PRIST last sector is:\n"); | |
395 | + for (i = 0; i < SECTOR_SIZE; i++) { | |
396 | + FB_DEBUG("0x%x ", *(bdata + i)); | |
397 | + if (i % 32 == 0) | |
398 | + FB_DEBUG("\n"); | |
399 | + } | |
400 | + FB_DEBUG("\n"); | |
401 | + ret = lock_enable_parse(bdata); | |
402 | +fail: | |
403 | + free(bdata); | |
404 | + return ret; | |
405 | + | |
406 | +} | |
407 | +#endif | |
408 | + | |
409 | +int display_lock(FbLockState lock, int verify) { | |
410 | + struct stdio_dev *disp; | |
411 | + disp = stdio_get_by_name("vga"); | |
412 | + if (disp != NULL) { | |
413 | + if (lock == FASTBOOT_UNLOCK) { | |
414 | + disp->puts(disp, "\n============= NOTICE ============\n"); | |
415 | + disp->puts(disp, "| |\n"); | |
416 | + disp->puts(disp, "| Your device is NOT locked. |\n"); | |
417 | + disp->puts(disp, "| |\n"); | |
418 | + disp->puts(disp, "=================================\n"); | |
419 | + } else { | |
420 | + if (verify == -1) { | |
421 | + disp->puts(disp, "\n============= NOTICE ============\n"); | |
422 | + disp->puts(disp, "| |\n"); | |
423 | + disp->puts(disp, "| Your device is NOT protected. |\n"); | |
424 | + disp->puts(disp, "| |\n"); | |
425 | + disp->puts(disp, "=================================\n"); | |
426 | + } else if (verify == 1) { | |
427 | + disp->puts(disp, "\n============= NOTICE ============\n"); | |
428 | + disp->puts(disp, "| |\n"); | |
429 | + disp->puts(disp, "| Boot verify failed! |\n"); | |
430 | + disp->puts(disp, "| |\n"); | |
431 | + disp->puts(disp, "=================================\n"); | |
432 | + } | |
433 | + } | |
434 | + return 0; | |
435 | + } else | |
436 | + printf("not found VGA disp console.\n"); | |
437 | + | |
438 | + return -1; | |
439 | + | |
440 | +} | |
441 | + | |
442 | +int fastboot_wipe_data_partition(void) | |
443 | +{ | |
444 | + struct blk_desc *fs_dev_desc; | |
445 | + disk_partition_t fs_partition; | |
446 | + int status; | |
447 | + int mmc_id; | |
448 | + mmc_id = fastboot_flash_find_index(FASTBOOT_PARTITION_DATA); | |
449 | + if (mmc_id < 0) { | |
450 | + printf("%s: error in get mmc part\n", __FUNCTION__); | |
451 | + return -1; | |
452 | + } | |
453 | + status = blk_get_device_part_str(FSL_FASTBOOT_FB_DEV, | |
454 | + get_mmc_part(mmc_id), &fs_dev_desc, &fs_partition, 1); | |
455 | + if (status < 0) { | |
456 | + printf("error in get device partition for wipe /data\n"); | |
457 | + return -1; | |
458 | + } | |
459 | + status = blk_derase(fs_dev_desc, fs_partition.start , fs_partition.size ); | |
460 | + if (status != fs_partition.size ) { | |
461 | + printf("erase not complete\n"); | |
462 | + return -1; | |
463 | + } | |
464 | + mdelay(2000); | |
465 | + | |
466 | + return 0; | |
467 | +} |
drivers/usb/gadget/fastboot_lock_unlock.h
1 | +/* | |
2 | + * Copyright (c) 2016, Freescale Semiconductor, Inc. | |
3 | + * All rights reserved. | |
4 | + * | |
5 | + * Redistribution and use in source and binary forms, with or without modification, | |
6 | + * are permitted provided that the following conditions are met: | |
7 | + * | |
8 | + * o Redistributions of source code must retain the above copyright notice, this list | |
9 | + * of conditions and the following disclaimer. | |
10 | + * | |
11 | + * o Redistributions in binary form must reproduce the above copyright notice, this | |
12 | + * list of conditions and the following disclaimer in the documentation and/or | |
13 | + * other materials provided with the distribution. | |
14 | + * | |
15 | + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its | |
16 | + * contributors may be used to endorse or promote products derived from this | |
17 | + * software without specific prior written permission. | |
18 | + * | |
19 | + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND | |
20 | + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | |
21 | + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | |
22 | + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR | |
23 | + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | |
24 | + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | |
25 | + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON | |
26 | + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |
27 | + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | |
28 | + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
29 | + */ | |
30 | + | |
31 | +#ifndef FASTBOOT_LOCK_UNLOCK_H | |
32 | +#define FASTBOOT_LOCK_UNLOCK_H | |
33 | + | |
34 | +#define ALIGN_BYTES 64 /*armv7 cache line need 64 bytes aligned */ | |
35 | + | |
36 | +//#define FASTBOOT_LOCK_DEBUG | |
37 | +#ifdef CONFIG_FSL_CAAM_KB | |
38 | +#define FASTBOOT_ENCRYPT_LOCK | |
39 | +#endif | |
40 | + | |
41 | +#ifdef FASTBOOT_LOCK_DEBUG | |
42 | +#define FB_DEBUG(format, ...) printf(format, ##__VA_ARGS__) | |
43 | +#else | |
44 | +#define FB_DEBUG(format, ...) | |
45 | +#endif | |
46 | + | |
47 | +typedef enum { | |
48 | + FASTBOOT_UNLOCK, | |
49 | + FASTBOOT_LOCK, | |
50 | + FASTBOOT_LOCK_ERROR, | |
51 | + FASTBOOT_LOCK_NUM | |
52 | +}FbLockState; | |
53 | + | |
54 | +typedef enum { | |
55 | + FASTBOOT_UL_DISABLE, | |
56 | + FASTBOOT_UL_ENABLE, | |
57 | + FASTBOOT_UL_ERROR, | |
58 | + FASTBOOT_UL_NUM | |
59 | +}FbLockEnableResult; | |
60 | + | |
61 | +FbLockState fastboot_get_lock_stat(void); | |
62 | + | |
63 | +int fastboot_set_lock_stat(FbLockState lock); | |
64 | + | |
65 | +int fastboot_wipe_data_partition(void); | |
66 | + | |
67 | +FbLockEnableResult fastboot_lock_enable(void); | |
68 | +void set_fastboot_lock_disable(void); | |
69 | + | |
70 | +int display_lock(FbLockState lock, int verify); | |
71 | +#endif |
include/android_image.h
... | ... | @@ -20,6 +20,19 @@ |
20 | 20 | #define ANDR_BOOT_ARGS_SIZE 512 |
21 | 21 | #define ANDR_BOOT_EXTRA_ARGS_SIZE 1024 |
22 | 22 | |
23 | +/* Boot metric variables (in millisecond) */ | |
24 | +struct boot_metric | |
25 | +{ | |
26 | + u32 bll_1; /* 1th bootloader load duration */ | |
27 | + u32 ble_1; /* 1th bootloader exec duration */ | |
28 | + u32 kl; /* kernel image load duration */ | |
29 | + u32 kd; /* kernel image decompress duration */ | |
30 | + u32 avb; /* avb verify boot.img duration */ | |
31 | + u32 odt; /* overlay device tree duration */ | |
32 | + u32 sw; /* system wait for UI interaction duration*/ | |
33 | +}; | |
34 | +typedef struct boot_metric boot_metric; | |
35 | + | |
23 | 36 | struct andr_img_hdr { |
24 | 37 | char magic[ANDR_BOOT_MAGIC_SIZE]; |
25 | 38 | |
... | ... | @@ -80,5 +93,17 @@ |
80 | 93 | * 6. if second_size != 0: jump to second_addr |
81 | 94 | * else: jump to kernel_addr |
82 | 95 | */ |
96 | +struct header_image { | |
97 | + uint32_t code0; /* Executable code */ | |
98 | + uint32_t code1; /* Executable code */ | |
99 | + uint64_t text_offset; /* Image load offset, LE */ | |
100 | + uint64_t image_size; /* Effective Image size, LE */ | |
101 | + uint64_t res1; /* reserved */ | |
102 | + uint64_t res2; /* reserved */ | |
103 | + uint64_t res3; /* reserved */ | |
104 | + uint64_t res4; /* reserved */ | |
105 | + uint32_t magic; /* Magic number */ | |
106 | + uint32_t res5; | |
107 | +}; | |
83 | 108 | #endif |
include/common.h
... | ... | @@ -685,6 +685,10 @@ |
685 | 685 | int cpu_release(int nr, int argc, char * const argv[]); |
686 | 686 | #endif |
687 | 687 | |
688 | +#ifdef CONFIG_CMD_READ | |
689 | +int do_raw_read(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]); | |
690 | +#endif | |
691 | + | |
688 | 692 | #else /* __ASSEMBLY__ */ |
689 | 693 | |
690 | 694 | /* Drop a C type modifier (like in 3UL) for constants used in assembly. */ |
include/fsl_fastboot.h
1 | +/* | |
2 | + * Copyright (C) 2010-2016 Freescale Semiconductor, Inc. | |
3 | + * Copyright 2017 NXP | |
4 | + * | |
5 | + * SPDX-License-Identifier: GPL-2.0+ | |
6 | + */ | |
7 | + | |
8 | +#ifndef FSL_FASTBOOT_H | |
9 | +#define FSL_FASTBOOT_H | |
10 | +#include <stdbool.h> | |
11 | +#include <linux/types.h> | |
12 | + | |
13 | +#define FASTBOOT_PTENTRY_FLAGS_REPEAT(n) (n & 0x0f) | |
14 | +#define FASTBOOT_PTENTRY_FLAGS_REPEAT_MASK 0x0000000F | |
15 | + | |
16 | +/* Writes happen a block at a time. | |
17 | + If the write fails, go to next block | |
18 | + NEXT_GOOD_BLOCK and CONTIGOUS_BLOCK can not both be set */ | |
19 | +#define FASTBOOT_PTENTRY_FLAGS_WRITE_NEXT_GOOD_BLOCK 0x00000010 | |
20 | + | |
21 | +/* Find a contiguous block big enough for a the whole file | |
22 | + NEXT_GOOD_BLOCK and CONTIGOUS_BLOCK can not both be set */ | |
23 | +#define FASTBOOT_PTENTRY_FLAGS_WRITE_CONTIGUOUS_BLOCK 0x00000020 | |
24 | + | |
25 | +/* Write the file with write.i */ | |
26 | +#define FASTBOOT_PTENTRY_FLAGS_WRITE_I 0x00000100 | |
27 | + | |
28 | +/* Write the file with write.trimffs */ | |
29 | +#define FASTBOOT_PTENTRY_FLAGS_WRITE_TRIMFFS 0x00000200 | |
30 | + | |
31 | +/* Write the file as a series of variable/value pairs | |
32 | + using the setenv and saveenv commands */ | |
33 | +#define FASTBOOT_PTENTRY_FLAGS_WRITE_ENV 0x00000400 | |
34 | + | |
35 | +/* Uneraseable partition */ | |
36 | +#define FASTBOOT_PTENTRY_FLAGS_UNERASEABLE 0x00000800 | |
37 | + | |
38 | +#define FASTBOOT_MMC_BOOT_PARTITION_ID 1 | |
39 | +#define FASTBOOT_MMC_USER_PARTITION_ID 0 | |
40 | +#define FASTBOOT_MMC_NONE_PARTITION_ID -1 | |
41 | + | |
42 | +#define FASTBOOT_PARTITION_PRDATA "presistdata" | |
43 | + | |
44 | +#ifdef CONFIG_AVB_SUPPORT | |
45 | +#define FASTBOOT_PARTITION_AVBKEY "avbkey" | |
46 | +#endif | |
47 | + | |
48 | +#ifdef CONFIG_FLASH_MCUFIRMWARE_SUPPORT | |
49 | +#define FASTBOOT_MCU_FIRMWARE_PARTITION "m4_os" | |
50 | +#endif | |
51 | + | |
52 | +#ifdef CONFIG_ANDROID_AB_SUPPORT | |
53 | +#define FASTBOOT_PARTITION_BOOT_A "boot_a" | |
54 | +#define FASTBOOT_PARTITION_RECOVERY "recovery" | |
55 | +#define FASTBOOT_PARTITION_SYSTEM_A "system_a" | |
56 | +#define FASTBOOT_PARTITION_BOOTLOADER "bootloader0" | |
57 | +#define FASTBOOT_PARTITION_DATA "userdata" | |
58 | +#define FASTBOOT_PARTITION_BOOT_B "boot_b" | |
59 | +#define FASTBOOT_PARTITION_SYSTEM_B "system_b" | |
60 | +#ifdef CONFIG_AVB_SUPPORT | |
61 | +#define FASTBOOT_PARTITION_VBMETA_A "vbmeta_a" | |
62 | +#define FASTBOOT_PARTITION_VBMETA_B "vbmeta_b" | |
63 | +#endif | |
64 | +#define FASTBOOT_PARTITION_MISC "misc" | |
65 | +#define FASTBOOT_PARTITION_GPT "gpt" | |
66 | +#define FASTBOOT_PARTITION_FBMISC "fbmisc" | |
67 | +#else | |
68 | +#define FASTBOOT_PARTITION_BOOT "boot" | |
69 | +#define FASTBOOT_PARTITION_RECOVERY "recovery" | |
70 | +#define FASTBOOT_PARTITION_SYSTEM "system" | |
71 | +#define FASTBOOT_PARTITION_CACHE "cache" | |
72 | +#define FASTBOOT_PARTITION_DEVICE "device" | |
73 | +#define FASTBOOT_PARTITION_BOOTLOADER "bootloader" | |
74 | +#define FASTBOOT_PARTITION_DATA "userdata" | |
75 | +#define FASTBOOT_PARTITION_GPT "gpt" | |
76 | +#define FASTBOOT_PARTITION_MISC "misc" | |
77 | +#define FASTBOOT_PARTITION_FBMISC "fbmisc" | |
78 | +#endif | |
79 | + | |
80 | +#ifdef CONFIG_ANDROID_THINGS_SUPPORT | |
81 | +#define FASTBOOT_BOOTLOADER_VBOOT_KEY "fuse at-bootloader-vboot-key" | |
82 | +#endif | |
83 | + | |
84 | +enum { | |
85 | + DEV_SATA, | |
86 | + DEV_MMC, | |
87 | + DEV_NAND, | |
88 | +#ifdef CONFIG_FLASH_MCUFIRMWARE_SUPPORT | |
89 | + /* SPI Flash */ | |
90 | + DEV_SF | |
91 | +#endif | |
92 | +}; | |
93 | + | |
94 | +typedef enum { | |
95 | +#ifdef CONFIG_ANDROID_RECOVERY | |
96 | + /* Revoery boot due to combo keys pressed */ | |
97 | + BOOTMODE_RECOVERY_KEY_PRESSED, | |
98 | + /* Recovery boot due to boot-recovery cmd in misc parition */ | |
99 | + BOOTMODE_RECOVERY_BCB_CMD, | |
100 | +#endif | |
101 | + /* Fastboot boot due to bootonce-bootloader cmd in misc parition */ | |
102 | + BOOTMODE_FASTBOOT_BCB_CMD, | |
103 | + /* Normal boot */ | |
104 | + BOOTMODE_NORMAL | |
105 | +}FbBootMode; | |
106 | + | |
107 | + | |
108 | +struct cmd_fastboot_interface { | |
109 | + /* This function is called when a buffer has been | |
110 | + recieved from the client app. | |
111 | + The buffer is a supplied by the board layer and must be unmodified. | |
112 | + The buffer_size is how much data is passed in. | |
113 | + Returns 0 on success | |
114 | + Returns 1 on failure | |
115 | + | |
116 | + Set by cmd_fastboot */ | |
117 | + int (*rx_handler)(const unsigned char *buffer, | |
118 | + unsigned int buffer_size); | |
119 | + | |
120 | + /* This function is called when an exception has | |
121 | + occurred in the device code and the state | |
122 | + off fastboot needs to be reset | |
123 | + | |
124 | + Set by cmd_fastboot */ | |
125 | + void (*reset_handler)(void); | |
126 | + | |
127 | + /* A getvar string for the product name | |
128 | + It can have a maximum of 60 characters | |
129 | + | |
130 | + Set by board */ | |
131 | + char *product_name; | |
132 | + | |
133 | + /* A getvar string for the serial number | |
134 | + It can have a maximum of 60 characters | |
135 | + | |
136 | + Set by board */ | |
137 | + char *serial_no; | |
138 | + | |
139 | + /* Nand block size | |
140 | + Supports the write option WRITE_NEXT_GOOD_BLOCK | |
141 | + | |
142 | + Set by board */ | |
143 | + unsigned int nand_block_size; | |
144 | + | |
145 | + /* Nand oob size | |
146 | + Set by board */ | |
147 | + unsigned int nand_oob_size; | |
148 | + | |
149 | + /* Transfer buffer, for handling flash updates | |
150 | + Should be multiple of the nand_block_size | |
151 | + Care should be take so it does not overrun bootloader memory | |
152 | + Controlled by the configure variable CFG_FASTBOOT_TRANSFER_BUFFER | |
153 | + | |
154 | + Set by board */ | |
155 | + unsigned char *transfer_buffer; | |
156 | + | |
157 | + /* How big is the transfer buffer | |
158 | + Controlled by the configure variable | |
159 | + CFG_FASTBOOT_TRANSFER_BUFFER_SIZE | |
160 | + | |
161 | + Set by board */ | |
162 | + unsigned int transfer_buffer_size; | |
163 | + | |
164 | +}; | |
165 | + | |
166 | +/* flash partitions are defined in terms of blocks | |
167 | +** (flash erase units) | |
168 | +*/ | |
169 | +struct fastboot_ptentry { | |
170 | + /* The logical name for this partition, null terminated */ | |
171 | + char name[16]; | |
172 | + /* The start wrt the nand part, must be multiple of nand block size */ | |
173 | + unsigned int start; | |
174 | + /* The length of the partition, must be multiple of nand block size */ | |
175 | + unsigned int length; | |
176 | + /* Controls the details of how operations are done on the partition | |
177 | + See the FASTBOOT_PTENTRY_FLAGS_*'s defined below */ | |
178 | + unsigned int flags; | |
179 | + /* partition id: 0 - normal partition; 1 - boot partition */ | |
180 | + unsigned int partition_id; | |
181 | + /* partition number in block device */ | |
182 | + unsigned int partition_index; | |
183 | + /* partition file system type in string */ | |
184 | + char fstype[16]; | |
185 | + /* filesystem UUID as string, if exists */ | |
186 | +#ifdef CONFIG_PARTITION_UUIDS | |
187 | + char uuid[37]; | |
188 | +#endif | |
189 | +}; | |
190 | + | |
191 | +struct fastboot_device_info { | |
192 | + unsigned char type; | |
193 | + unsigned char dev_id; | |
194 | +}; | |
195 | + | |
196 | +extern struct fastboot_device_info fastboot_devinfo; | |
197 | + | |
198 | +/* Prepare the fastboot environments, | |
199 | + * should be executed before "fastboot" cmd | |
200 | + */ | |
201 | +void fastboot_setup(void); | |
202 | + | |
203 | + | |
204 | +/* The Android-style flash handling */ | |
205 | + | |
206 | +/* tools to populate and query the partition table */ | |
207 | +void fastboot_flash_add_ptn(struct fastboot_ptentry *ptn); | |
208 | +struct fastboot_ptentry *fastboot_flash_find_ptn(const char *name); | |
209 | +struct fastboot_ptentry *fastboot_flash_get_ptn(unsigned n); | |
210 | +unsigned int fastboot_flash_get_ptn_count(void); | |
211 | +void fastboot_flash_dump_ptn(void); | |
212 | + | |
213 | +/* Make board into special boot mode */ | |
214 | +void fastboot_run_bootmode(void); | |
215 | + | |
216 | +/*Setup board-relative fastboot environment */ | |
217 | +void board_fastboot_setup(void); | |
218 | + | |
219 | +/*return partition index according name*/ | |
220 | +int fastboot_flash_find_index(const char *name); | |
221 | + | |
222 | +/*check whether bootloader is overlay with GPT table*/ | |
223 | +bool bootloader_gpt_overlay(void); | |
224 | +/* Check whether the combo keys pressed | |
225 | + * Return 1 if combo keys pressed for recovery boot | |
226 | + * Return 0 if no combo keys pressed | |
227 | + */ | |
228 | +int is_recovery_key_pressing(void); | |
229 | + | |
230 | +#ifdef CONFIG_FASTBOOT_STORAGE_NAND | |
231 | +/*Save parameters for NAND storage partitions */ | |
232 | +void save_parts_values(struct fastboot_ptentry *ptn, | |
233 | + unsigned int offset, unsigned int size); | |
234 | + | |
235 | +/* Checks parameters for NAND storage partitions | |
236 | + * Return 1 if the parameter is not set | |
237 | + * Return 0 if the parameter has been set | |
238 | + */ | |
239 | +int check_parts_values(struct fastboot_ptentry *ptn); | |
240 | +#endif /*CONFIG_FASTBOOT_STORAGE_NAND*/ | |
241 | + | |
242 | +/* Reads |num_bytes| from offset |offset| from partition with name | |
243 | + * |partition| (NUL-terminated UTF-8 string). If |offset| is | |
244 | + * negative, its absolute value should be interpreted as the number | |
245 | + * of bytes from the end of the partition. | |
246 | + * It's basically copied from fsl_read_from_partition_multi() because | |
247 | + * we may want to read partition when AVB is not enabled. */ | |
248 | +int read_from_partition_multi(const char* partition, | |
249 | + int64_t offset, size_t num_bytes,void* buffer, size_t* out_num_read); | |
250 | +#endif /* FSL_FASTBOOT_H */ |
include/image.h
... | ... | @@ -1277,6 +1277,7 @@ |
1277 | 1277 | ulong android_image_get_end(const struct andr_img_hdr *hdr); |
1278 | 1278 | ulong android_image_get_kload(const struct andr_img_hdr *hdr); |
1279 | 1279 | void android_print_contents(const struct andr_img_hdr *hdr); |
1280 | +bool image_arm64(void *images); | |
1280 | 1281 | |
1281 | 1282 | #endif /* CONFIG_ANDROID_BOOT_IMAGE */ |
1282 | 1283 |
include/mmc.h
... | ... | @@ -814,6 +814,7 @@ |
814 | 814 | int cpu_mmc_init(bd_t *bis); |
815 | 815 | int mmc_get_env_addr(struct mmc *mmc, int copy, u32 *env_addr); |
816 | 816 | int mmc_get_env_dev(void); |
817 | +int mmc_map_to_kernel_blk(int dev_no); | |
817 | 818 | |
818 | 819 | /* Set block count limit because of 16 bit register limit on some hardware*/ |
819 | 820 | #ifndef CONFIG_SYS_MMC_MAX_BLK_COUNT |
include/part.h
... | ... | @@ -375,6 +375,14 @@ |
375 | 375 | int write_mbr_and_gpt_partitions(struct blk_desc *dev_desc, void *buf); |
376 | 376 | |
377 | 377 | /** |
378 | + * write_backup_gpt_partitions - write MBR, backup gpt table. | |
379 | + * @param dev_desc - block device descriptor | |
380 | + * @param buf - buffer which contains the MBR and Primary GPT info | |
381 | + * | |
382 | + * @return - '0' on success, otherwise error | |
383 | + */ | |
384 | +int write_backup_gpt_partitions(struct blk_desc *dev_desc, void *buf); | |
385 | +/** | |
378 | 386 | * gpt_verify_headers() - Function to read and CRC32 check of the GPT's header |
379 | 387 | * and partition table entries (PTE) |
380 | 388 | * |
include/recovery.h
1 | +/* | |
2 | + * Copyright (C) 2010-2016 Freescale Semiconductor, Inc. All Rights Reserved. | |
3 | + * Copyright 2017 NXP | |
4 | + * | |
5 | + * SPDX-License-Identifier: GPL-2.0+ | |
6 | + */ | |
7 | + | |
8 | +#ifndef __RECOVERY_H_ | |
9 | +#define __RECOVERY_H_ | |
10 | + | |
11 | +struct reco_envs { | |
12 | + char *cmd; | |
13 | + char *args; | |
14 | +}; | |
15 | + | |
16 | +void board_recovery_setup(void); | |
17 | + | |
18 | +#endif |
scripts/config_whitelist.txt
... | ... | @@ -31,6 +31,10 @@ |
31 | 31 | CONFIG_AM437X_USB2PHY2_HOST |
32 | 32 | CONFIG_ANDES_PCU |
33 | 33 | CONFIG_ANDES_PCU_BASE |
34 | +CONFIG_ANDROID_AB_SUPPORT | |
35 | +CONFIG_ANDROID_AUTO_SUPPORT | |
36 | +CONFIG_ANDROID_SUPPORT | |
37 | +CONFIG_ANDROID_THINGS_SUPPORT | |
34 | 38 | CONFIG_APER_0_BASE |
35 | 39 | CONFIG_APER_1_BASE |
36 | 40 | CONFIG_APER_SIZE |
... | ... | @@ -106,6 +110,10 @@ |
106 | 110 | CONFIG_ATMEL_SPI0 |
107 | 111 | CONFIG_AT_TRANS |
108 | 112 | CONFIG_AUTO_ZRELADDR |
113 | +CONFIG_AVB_FUSE | |
114 | +CONFIG_AVB_FUSE_BANK_END | |
115 | +CONFIG_AVB_FUSE_BANK_SIZEW | |
116 | +CONFIG_AVB_FUSE_BANK_START | |
109 | 117 | CONFIG_BACKSIDE_L2_CACHE |
110 | 118 | CONFIG_BAT_PAIR |
111 | 119 | CONFIG_BAT_RW |
... | ... | @@ -141,6 +149,8 @@ |
141 | 149 | CONFIG_BOOGER |
142 | 150 | CONFIG_BOOTBLOCK |
143 | 151 | CONFIG_BOOTFILE |
152 | +CONFIG_BOOTLOADER_OFFSET_32K | |
153 | +CONFIG_BOOTLOADER_OFFSET_33K | |
144 | 154 | CONFIG_BOOTMAPSZ |
145 | 155 | CONFIG_BOOTMODE |
146 | 156 | CONFIG_BOOTM_LINUX |
... | ... | @@ -493,6 +503,7 @@ |
493 | 503 | CONFIG_EMMC_BOOT |
494 | 504 | CONFIG_EMU |
495 | 505 | CONFIG_ENABLE_36BIT_PHYS |
506 | +CONFIG_ENABLE_LOCKSTATUS_SUPPORT | |
496 | 507 | CONFIG_ENABLE_MMU |
497 | 508 | CONFIG_ENABLE_MUST_CHECK |
498 | 509 | CONFIG_ENABLE_WARN_DEPRECATED |
... | ... | @@ -603,6 +614,7 @@ |
603 | 614 | CONFIG_FACTORYSET |
604 | 615 | CONFIG_FASTBOOT_FLASH_FILLBUF_SIZE |
605 | 616 | CONFIG_FASTBOOT_FLASH_NAND_TRIMFFS |
617 | +CONFIG_FASTBOOT_LOCK | |
606 | 618 | CONFIG_FAST_FLASH_BIT |
607 | 619 | CONFIG_FB_ADDR |
608 | 620 | CONFIG_FB_BACKLIGHT |
... | ... | @@ -656,6 +668,7 @@ |
656 | 668 | CONFIG_FPGA_DELAY |
657 | 669 | CONFIG_FPGA_STRATIX_V |
658 | 670 | CONFIG_FSLDMAFEC |
671 | +CONFIG_FSL_CAAM_KB | |
659 | 672 | CONFIG_FSL_CADMUS |
660 | 673 | CONFIG_FSL_CORENET |
661 | 674 | CONFIG_FSL_CPLD |
... | ... | @@ -2089,6 +2102,7 @@ |
2089 | 2102 | CONFIG_SYSFLAGS_ADDR |
2090 | 2103 | CONFIG_SYSFS |
2091 | 2104 | CONFIG_SYSMGR_ISWGRP_HANDOFF |
2105 | +CONFIG_SYSTEM_RAMDISK_SUPPORT | |
2092 | 2106 | CONFIG_SYS_33MHZ |
2093 | 2107 | CONFIG_SYS_64BIT |
2094 | 2108 | CONFIG_SYS_64BIT_LBA |