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>zero-sugar
parent
4ec81a0b07
commit
2c840c82b3
|
@ -19,3 +19,4 @@ struct pass_over_info_t {
|
|||
int print_bootinfo(void);
|
||||
int init_otg_power(void);
|
||||
void power_off_pd_devices(const char* permanent_on_devices[], int size);
|
||||
enum boot_device get_boot_device(void);
|
||||
|
|
|
@ -35,6 +35,7 @@ static inline void iomuxc_set_rgmii_io_voltage(int io_vol)
|
|||
}
|
||||
|
||||
void set_wdog_reset(struct wdog_regs *wdog);
|
||||
enum boot_device get_boot_device(void);
|
||||
|
||||
#ifdef CONFIG_LDO_BYPASS_CHECK
|
||||
int check_ldo_bypass(void);
|
||||
|
|
|
@ -100,3 +100,9 @@ config NXP_BOARD_REVISION
|
|||
NXP boards based on i.MX6/7 contain the board revision information
|
||||
stored in the fuses. Select this option if you want to be able to
|
||||
retrieve the board revision information.
|
||||
|
||||
config FLASH_MCUFIRMWARE_SUPPORT
|
||||
bool "Enable mcu firmware flash support"
|
||||
depends on ARCH_MX7ULP || ARCH_IMX8M
|
||||
help
|
||||
This enables the mcu firmware flash support for some SOCs.
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
#include <fdtdec.h>
|
||||
#include <asm/arch/cpu.h>
|
||||
#include <generated/version_autogenerated.h>
|
||||
#include <asm/setup.h>
|
||||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
|
@ -1392,4 +1393,4 @@ void disconnect_from_pc(void)
|
|||
printf("conn_usb0 finding failed!\n");
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
#include <fsl_wdog.h>
|
||||
#include <imx_sip.h>
|
||||
#include <generated/version_autogenerated.h>
|
||||
#include <asm/setup.h>
|
||||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
|
@ -196,6 +197,18 @@ bool is_usb_boot(void)
|
|||
{
|
||||
return get_boot_device() == USB_BOOT;
|
||||
}
|
||||
#ifdef CONFIG_SERIAL_TAG
|
||||
void get_board_serial(struct tag_serialnr *serialnr)
|
||||
{
|
||||
struct ocotp_regs *ocotp = (struct ocotp_regs *)OCOTP_BASE_ADDR;
|
||||
struct fuse_bank *bank = &ocotp->bank[0];
|
||||
struct fuse_bank0_regs *fuse =
|
||||
(struct fuse_bank0_regs *)bank->fuse_regs;
|
||||
|
||||
serialnr->low = fuse->uid_low;
|
||||
serialnr->high = fuse->uid_high;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_OF_SYSTEM_SETUP
|
||||
static int ft_add_optee_node(void *fdt, bd_t *bd)
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
#include <dm.h>
|
||||
#include <imx_thermal.h>
|
||||
#include <mmc.h>
|
||||
#include <asm/setup.h>
|
||||
|
||||
enum ldo_reg {
|
||||
LDO_ARM,
|
||||
|
@ -805,6 +806,10 @@ void s_init(void)
|
|||
u32 mask528;
|
||||
u32 reg, periph1, periph2;
|
||||
|
||||
#if defined(CONFIG_ANDROID_SUPPORT)
|
||||
/* Enable RTC */
|
||||
writel(0x21, 0x020cc038);
|
||||
#endif
|
||||
if (is_mx6sx() || is_mx6ul() || is_mx6ull() || is_mx6sll())
|
||||
return;
|
||||
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
#include <imx_thermal.h>
|
||||
#include <fsl_sec.h>
|
||||
#include <fsl_wdog.h>
|
||||
#include <asm/setup.h>
|
||||
|
||||
#if defined(CONFIG_IMX_THERMAL)
|
||||
static const struct imx_thermal_plat imx7_thermal_plat = {
|
||||
|
@ -293,6 +294,10 @@ void s_init(void)
|
|||
/* clock configuration. */
|
||||
clock_init();
|
||||
|
||||
#if defined(CONFIG_ANDROID_SUPPORT)
|
||||
/* Enable RTC */
|
||||
writel(0x21, 0x30370038);
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
#include <asm/mach-imx/hab.h>
|
||||
#include <asm/mach-imx/boot_mode.h>
|
||||
#include <fdt_support.h>
|
||||
#include <asm/setup.h>
|
||||
|
||||
static char *get_reset_cause(char *);
|
||||
|
||||
|
@ -155,6 +156,11 @@ void s_init(void)
|
|||
if (soc_rev() < CHIP_REV_2_0) {
|
||||
/* enable dumb pmic */
|
||||
writel((readl(SNVS_LP_LPCR) | SNVS_LPCR_DPEN), SNVS_LP_LPCR);
|
||||
|
||||
#if defined(CONFIG_ANDROID_SUPPORT)
|
||||
/* Enable RTC */
|
||||
writel((readl(SNVS_LP_LPCR) | SNVS_LPCR_SRTC_ENV), SNVS_LP_LPCR);
|
||||
#endif
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
@ -370,3 +376,18 @@ enum boot_device get_boot_device(void)
|
|||
|
||||
return boot_dev;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_FSL_FASTBOOT
|
||||
#ifdef CONFIG_SERIAL_TAG
|
||||
void get_board_serial(struct tag_serialnr *serialnr)
|
||||
{
|
||||
|
||||
struct ocotp_regs *ocotp = (struct ocotp_regs *)OCOTP_BASE_ADDR;
|
||||
struct fuse_bank *bank = &ocotp->bank[1];
|
||||
struct fuse_bank1_regs *fuse =
|
||||
(struct fuse_bank1_regs *)bank->fuse_regs;
|
||||
serialnr->low = (fuse->cfg0 & 0xFFFF) + ((fuse->cfg1 & 0xFFFF) << 16);
|
||||
serialnr->high = (fuse->cfg2 & 0xFFFF) + ((fuse->cfg3 & 0xFFFF) << 16);
|
||||
}
|
||||
#endif /*CONFIG_SERIAL_TAG*/
|
||||
#endif /*CONFIG_FSL_FASTBOOT*/
|
||||
|
|
|
@ -65,6 +65,9 @@ obj-$(CONFIG_$(SPL_)DM_PMIC_PFUZE100) += pfuze.o
|
|||
obj-$(CONFIG_POWER_MC34VR500) += mc34vr500.o
|
||||
obj-$(CONFIG_MXC_EPDC) += epdc_setup.o
|
||||
obj-y += mmc.o
|
||||
ifdef CONFIG_FSL_FASTBOOT
|
||||
obj-${CONFIG_ANDROID_RECOVERY} += recovery_keypad.o
|
||||
endif
|
||||
|
||||
obj-$(CONFIG_LS102XA_STREAM_ID) += ls102xa_stream_id.o
|
||||
|
||||
|
|
|
@ -0,0 +1,60 @@
|
|||
/*
|
||||
* Copyright (C) 2010-2016 Freescale Semiconductor, Inc. All Rights Reserved.
|
||||
* Copyright 2017 NXP
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
#include <common.h>
|
||||
#include <malloc.h>
|
||||
#include <recovery.h>
|
||||
#ifdef CONFIG_MXC_KPD
|
||||
#include <mxc_keyb.h>
|
||||
#endif
|
||||
#include <asm/mach-imx/boot_mode.h>
|
||||
|
||||
#ifdef CONFIG_MXC_KPD
|
||||
#define PRESSED_VOL_DOWN 0x01
|
||||
#define PRESSED_POWER 0x02
|
||||
#define RECOVERY_KEY_MASK (PRESSED_VOL_DOWN | PRESSED_POWER)
|
||||
|
||||
inline int test_key(int value, struct kpp_key_info *ki)
|
||||
{
|
||||
return (ki->val == value) && (ki->evt == KDepress);
|
||||
}
|
||||
|
||||
int is_recovery_keypad_pressing(void)
|
||||
{
|
||||
struct kpp_key_info *key_info = NULL;
|
||||
int state = 0, keys, i;
|
||||
|
||||
int ret = 0;
|
||||
|
||||
mxc_kpp_init();
|
||||
/* due to glitch suppression circuit,
|
||||
wait sometime to let all keys scanned. */
|
||||
udelay(1000);
|
||||
keys = mxc_kpp_getc(&key_info);
|
||||
|
||||
printf("Detecting VOL_DOWN+POWER key for recovery(%d:%d) ...\n",
|
||||
keys, keys ? key_info->val : 0);
|
||||
if (keys > 1) {
|
||||
for (i = 0; i < keys; i++) {
|
||||
if (test_key(CONFIG_POWER_KEY, &key_info[i]))
|
||||
state |= PRESSED_POWER;
|
||||
else if (test_key(CONFIG_VOL_DOWN_KEY, &key_info[i]))
|
||||
state |= PRESSED_VOL_DOWN;
|
||||
}
|
||||
}
|
||||
if ((state & RECOVERY_KEY_MASK) == RECOVERY_KEY_MASK)
|
||||
ret = 1;
|
||||
if (key_info)
|
||||
free(key_info);
|
||||
return ret;
|
||||
}
|
||||
#else
|
||||
/* If not using mxc keypad, currently we will detect power key on board */
|
||||
int is_recovery_keypad_pressing(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
#endif
|
|
@ -0,0 +1,13 @@
|
|||
/*
|
||||
* Copyright (C) 2016 Freescale Semiconductor, Inc. All Rights Reserved.
|
||||
* Copyright 2017 NXP
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
|
||||
#ifndef __RECOVERY_KEYPAD_H_
|
||||
#define __RECOVERY_KEYPAD_H_
|
||||
|
||||
int is_recovery_keypad_pressing(void);
|
||||
|
||||
#endif
|
|
@ -23,7 +23,11 @@ static int do_fastboot(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
|
|||
return CMD_RET_USAGE;
|
||||
|
||||
usb_controller = argv[1];
|
||||
#ifdef CONFIG_FASTBOOT_USB_DEV
|
||||
controller_index = CONFIG_FASTBOOT_USB_DEV;
|
||||
#else
|
||||
controller_index = simple_strtoul(usb_controller, NULL, 0);
|
||||
#endif
|
||||
|
||||
ret = board_usb_init(controller_index, USB_INIT_DEVICE);
|
||||
if (ret) {
|
||||
|
|
|
@ -26,6 +26,48 @@ config CMD_FASTBOOT
|
|||
|
||||
See doc/README.android-fastboot for more information.
|
||||
|
||||
config FSL_FASTBOOT
|
||||
bool "Enable FSL fastboot support"
|
||||
select BCB_SUPPORT
|
||||
help
|
||||
This enables FSL implementation for Android fastboot.
|
||||
|
||||
if FSL_FASTBOOT
|
||||
|
||||
config ANDROID_RECOVERY
|
||||
bool "Enable the recovery boot function"
|
||||
help
|
||||
This enables the Android Recovery boot function.
|
||||
|
||||
config CMD_BOOTA
|
||||
bool "Enable the boota command"
|
||||
help
|
||||
This enables the boota command for booting android images.
|
||||
|
||||
config BCB_SUPPORT
|
||||
bool
|
||||
|
||||
choice
|
||||
prompt "Android Image Storage select"
|
||||
default FASTBOOT_STORAGE_MMC
|
||||
|
||||
config FASTBOOT_STORAGE_MMC
|
||||
bool "Using eMMC/SD for Android fastboot storage media"
|
||||
|
||||
config FASTBOOT_STORAGE_NAND
|
||||
bool "Using NAND flash for Android fastboot storage media"
|
||||
|
||||
config FASTBOOT_STORAGE_SATA
|
||||
bool "Using SATA disk for Android fastboot storage media"
|
||||
|
||||
endchoice
|
||||
|
||||
config FASTBOOT_SATA_NO
|
||||
int "Sata device index"
|
||||
depends on FASTBOOT_STORAGE_SATA
|
||||
|
||||
endif #FSL_FASTBOOT
|
||||
|
||||
if USB_FUNCTION_FASTBOOT
|
||||
|
||||
config FASTBOOT_BUF_ADDR
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
#include <command.h>
|
||||
#include <part.h>
|
||||
|
||||
int do_read(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
|
||||
int do_raw_read(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
|
||||
{
|
||||
char *ep;
|
||||
struct blk_desc *dev_desc = NULL;
|
||||
|
@ -75,7 +75,7 @@ int do_read(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
|
|||
}
|
||||
|
||||
U_BOOT_CMD(
|
||||
read, 6, 0, do_read,
|
||||
read, 6, 0, do_raw_read,
|
||||
"Load binary data from a partition",
|
||||
"<interface> <dev[:part]> addr blk# cnt"
|
||||
);
|
||||
|
|
|
@ -311,7 +311,7 @@ const char *bootdelay_process(void)
|
|||
s = env_get("bootdelay");
|
||||
bootdelay = s ? (int)simple_strtol(s, NULL, 10) : CONFIG_BOOTDELAY;
|
||||
|
||||
#ifdef is_boot_from_usb
|
||||
#if !defined(CONFIG_FSL_FASTBOOT) && defined(is_boot_from_usb)
|
||||
if (is_boot_from_usb()) {
|
||||
disconnect_from_pc();
|
||||
printf("Boot from USB for mfgtools\n");
|
||||
|
@ -349,7 +349,7 @@ const char *bootdelay_process(void)
|
|||
#endif /* CONFIG_BOOTCOUNT_LIMIT */
|
||||
s = env_get("bootcmd");
|
||||
|
||||
#ifdef is_boot_from_usb
|
||||
#if !defined(CONFIG_FSL_FASTBOOT) && defined(is_boot_from_usb)
|
||||
if (is_boot_from_usb()) {
|
||||
s = env_get("bootcmd_mfg");
|
||||
printf("Run bootcmd_mfg: %s\n", s);
|
||||
|
|
|
@ -54,6 +54,9 @@
|
|||
#include <linux/compiler.h>
|
||||
#include <linux/err.h>
|
||||
#include <efi_loader.h>
|
||||
#ifdef CONFIG_FSL_FASTBOOT
|
||||
#include <fsl_fastboot.h>
|
||||
#endif
|
||||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
|
@ -659,6 +662,20 @@ static int initr_avbkey(void)
|
|||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_FSL_FASTBOOT
|
||||
static int initr_fastboot_setup(void)
|
||||
{
|
||||
fastboot_setup();
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int initr_check_fastboot(void)
|
||||
{
|
||||
fastboot_run_bootmode();
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int run_main_loop(void)
|
||||
{
|
||||
#ifdef CONFIG_SANDBOX
|
||||
|
@ -831,6 +848,9 @@ static init_fnc_t init_sequence_r[] = {
|
|||
#ifdef CONFIG_BOARD_LATE_INIT
|
||||
board_late_init,
|
||||
#endif
|
||||
#ifdef CONFIG_FSL_FASTBOOT
|
||||
initr_fastboot_setup,
|
||||
#endif
|
||||
#if defined(CONFIG_SCSI) && !defined(CONFIG_DM_SCSI)
|
||||
INIT_FUNC_WATCHDOG_RESET
|
||||
initr_scsi,
|
||||
|
@ -872,6 +892,9 @@ static init_fnc_t init_sequence_r[] = {
|
|||
#endif
|
||||
#ifdef AVB_RPMB
|
||||
initr_avbkey,
|
||||
#endif
|
||||
#ifdef CONFIG_FSL_FASTBOOT
|
||||
initr_check_fastboot,
|
||||
#endif
|
||||
run_main_loop,
|
||||
};
|
||||
|
|
|
@ -1,6 +1,9 @@
|
|||
/*
|
||||
* Copyright (c) 2011 Sebastian Andrzej Siewior <bigeasy@linutronix.de>
|
||||
*
|
||||
* Copyright (C) 2015-2016 Freescale Semiconductor, Inc.
|
||||
* Copyright 2017 NXP
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
|
||||
|
@ -9,6 +12,11 @@
|
|||
#include <android_image.h>
|
||||
#include <malloc.h>
|
||||
#include <errno.h>
|
||||
#include <asm/bootm.h>
|
||||
#include <asm/mach-imx/boot_mode.h>
|
||||
#include <asm/arch/sys_proto.h>
|
||||
#include <fsl_fastboot.h>
|
||||
#include <asm/setup.h>
|
||||
|
||||
#define ANDROID_IMAGE_DEFAULT_KERNEL_ADDR 0x10008000
|
||||
|
||||
|
@ -51,6 +59,7 @@ static ulong android_image_get_kernel_addr(const struct andr_img_hdr *hdr)
|
|||
int android_image_get_kernel(const struct andr_img_hdr *hdr, int verify,
|
||||
ulong *os_data, ulong *os_len)
|
||||
{
|
||||
extern boot_metric metrics;
|
||||
u32 kernel_addr = android_image_get_kernel_addr(hdr);
|
||||
|
||||
/*
|
||||
|
@ -66,31 +75,110 @@ int android_image_get_kernel(const struct andr_img_hdr *hdr, int verify,
|
|||
printf("Kernel load addr 0x%08x size %u KiB\n",
|
||||
kernel_addr, DIV_ROUND_UP(hdr->kernel_size, 1024));
|
||||
|
||||
int len = 0;
|
||||
if (*hdr->cmdline) {
|
||||
printf("Kernel command line: %s\n", hdr->cmdline);
|
||||
len += strlen(hdr->cmdline);
|
||||
}
|
||||
|
||||
char newbootargs[512] = {0};
|
||||
char commandline[2048] = {0};
|
||||
char *bootargs = env_get("bootargs");
|
||||
if (bootargs)
|
||||
len += strlen(bootargs);
|
||||
|
||||
char *newbootargs = malloc(len + 2);
|
||||
if (!newbootargs) {
|
||||
puts("Error: malloc in android_image_get_kernel failed!\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
*newbootargs = '\0';
|
||||
|
||||
if (bootargs) {
|
||||
strcpy(newbootargs, bootargs);
|
||||
strcat(newbootargs, " ");
|
||||
if (strlen(bootargs) + 1 > sizeof(commandline)) {
|
||||
printf("bootargs is too long!\n");
|
||||
return -1;
|
||||
}
|
||||
else
|
||||
strncpy(commandline, bootargs, sizeof(commandline) - 1);
|
||||
} else if (*hdr->cmdline) {
|
||||
if (strlen(hdr->cmdline) + 1 > sizeof(commandline)) {
|
||||
printf("cmdline in bootimg is too long!\n");
|
||||
return -1;
|
||||
}
|
||||
else
|
||||
strncpy(commandline, hdr->cmdline, strlen(commandline) - 1);
|
||||
}
|
||||
if (*hdr->cmdline)
|
||||
strcat(newbootargs, hdr->cmdline);
|
||||
|
||||
env_set("bootargs", newbootargs);
|
||||
#ifdef CONFIG_SERIAL_TAG
|
||||
struct tag_serialnr serialnr;
|
||||
get_board_serial(&serialnr);
|
||||
|
||||
sprintf(newbootargs,
|
||||
" androidboot.serialno=%08x%08x",
|
||||
serialnr.high,
|
||||
serialnr.low);
|
||||
strncat(commandline, newbootargs, sizeof(commandline) - strlen(commandline));
|
||||
#endif
|
||||
|
||||
/* append soc type into bootargs */
|
||||
char *soc_type = env_get("soc_type");
|
||||
if (soc_type) {
|
||||
sprintf(newbootargs,
|
||||
" androidboot.soc_type=%s",
|
||||
soc_type);
|
||||
strncat(commandline, newbootargs, sizeof(commandline) - strlen(commandline));
|
||||
}
|
||||
|
||||
int bootdev = get_boot_device();
|
||||
if (bootdev == SD1_BOOT || bootdev == SD2_BOOT ||
|
||||
bootdev == SD3_BOOT || bootdev == SD4_BOOT) {
|
||||
sprintf(newbootargs,
|
||||
" androidboot.storage_type=sd");
|
||||
} else if (bootdev == MMC1_BOOT || bootdev == MMC2_BOOT ||
|
||||
bootdev == MMC3_BOOT || bootdev == MMC4_BOOT) {
|
||||
sprintf(newbootargs,
|
||||
" androidboot.storage_type=emmc");
|
||||
} else if (bootdev == NAND_BOOT) {
|
||||
sprintf(newbootargs,
|
||||
" androidboot.storage_type=nand");
|
||||
} else
|
||||
printf("boot device type is incorrect.\n");
|
||||
strncat(commandline, newbootargs, sizeof(commandline) - strlen(commandline));
|
||||
if (bootloader_gpt_overlay()) {
|
||||
sprintf(newbootargs, " gpt");
|
||||
strncat(commandline, newbootargs, sizeof(commandline) - strlen(commandline));
|
||||
}
|
||||
|
||||
/* boot metric variables */
|
||||
metrics.ble_1 = get_timer(0);
|
||||
sprintf(newbootargs,
|
||||
" androidboot.boottime=1BLL:%d,1BLE:%d,KL:%d,KD:%d,AVB:%d,ODT:%d,SW:%d",
|
||||
metrics.bll_1, metrics.ble_1, metrics.kl, metrics.kd, metrics.avb,
|
||||
metrics.odt, metrics.sw);
|
||||
strncat(commandline, newbootargs, sizeof(commandline) - strlen(commandline));
|
||||
|
||||
#ifdef CONFIG_AVB_SUPPORT
|
||||
/* secondary cmdline added by avb */
|
||||
char *bootargs_sec = env_get("bootargs_sec");
|
||||
if (bootargs_sec) {
|
||||
strncat(commandline, " ", sizeof(commandline) - strlen(commandline));
|
||||
strncat(commandline, bootargs_sec, sizeof(commandline) - strlen(commandline));
|
||||
}
|
||||
#endif
|
||||
#ifdef CONFIG_SYSTEM_RAMDISK_SUPPORT
|
||||
/* Normal boot:
|
||||
* cmdline to bypass ramdisk in boot.img, but use the system.img
|
||||
* Recovery boot:
|
||||
* Use the ramdisk in boot.img
|
||||
*/
|
||||
char *bootargs_3rd = env_get("bootargs_3rd");
|
||||
if (bootargs_3rd) {
|
||||
strncat(commandline, " ", sizeof(commandline) - strlen(commandline));
|
||||
strncat(commandline, bootargs_3rd, sizeof(commandline) - strlen(commandline));
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Add 'append_bootargs' to hold some paramemters which need to be appended
|
||||
* to bootargs */
|
||||
char *append_bootargs = env_get("append_bootargs");
|
||||
if (append_bootargs) {
|
||||
if (strlen(append_bootargs) + 2 >
|
||||
(sizeof(commandline) - strlen(commandline))) {
|
||||
printf("The 'append_bootargs' is too long to be appended to bootargs\n");
|
||||
} else {
|
||||
strncat(commandline, " ", sizeof(commandline) - strlen(commandline));
|
||||
strncat(commandline, append_bootargs, sizeof(commandline) - strlen(commandline));
|
||||
}
|
||||
}
|
||||
|
||||
printf("Kernel command line: %s\n", commandline);
|
||||
env_set("bootargs", commandline);
|
||||
|
||||
if (os_data) {
|
||||
*os_data = (ulong)hdr;
|
||||
|
@ -202,3 +290,15 @@ void android_print_contents(const struct andr_img_hdr *hdr)
|
|||
printf("%scmdline: %s\n", p, hdr->cmdline);
|
||||
}
|
||||
#endif
|
||||
|
||||
#define ARM64_IMAGE_MAGIC 0x644d5241
|
||||
bool image_arm64(void *images)
|
||||
{
|
||||
struct header_image *ih;
|
||||
|
||||
ih = (struct header_image *)images;
|
||||
debug("image magic: %x\n", ih->magic);
|
||||
if (ih->magic == le32_to_cpu(ARM64_IMAGE_MAGIC))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -6,6 +6,8 @@
|
|||
* (C) Copyright 2000-2006
|
||||
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
|
||||
*
|
||||
* Copyright (C) 2015-2016 Freescale Semiconductor, Inc.
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
|
||||
|
@ -413,7 +415,34 @@ int boot_get_fdt(int flag, int argc, char * const argv[], uint8_t arch,
|
|||
debug("## No Flattened Device Tree\n");
|
||||
goto no_fdt;
|
||||
}
|
||||
} else {
|
||||
}
|
||||
#ifdef CONFIG_ANDROID_BOOT_IMAGE
|
||||
else if (genimg_get_format((void *)images->os.start) ==
|
||||
IMAGE_FORMAT_ANDROID) {
|
||||
ulong fdt_data, fdt_len;
|
||||
android_image_get_second((void *)images->os.start,
|
||||
&fdt_data, &fdt_len);
|
||||
|
||||
if (fdt_len) {
|
||||
fdt_blob = (char *)fdt_data;
|
||||
printf(" Booting using the fdt at 0x%p\n", fdt_blob);
|
||||
|
||||
if (fdt_check_header(fdt_blob) != 0) {
|
||||
fdt_error("image is not a fdt");
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (fdt_totalsize(fdt_blob) != fdt_len) {
|
||||
fdt_error("fdt size != image size");
|
||||
goto error;
|
||||
}
|
||||
} else {
|
||||
debug("## No Flattened Device Tree\n");
|
||||
goto no_fdt;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
else {
|
||||
debug("## No Flattened Device Tree\n");
|
||||
goto no_fdt;
|
||||
}
|
||||
|
|
|
@ -135,6 +135,25 @@ static int validate_gpt_header(gpt_header *gpt_h, lbaint_t lba,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void prepare_last_lba_gpt_header(struct blk_desc *dev_desc, gpt_header *gpt_h)
|
||||
{
|
||||
uint32_t calc_crc32;
|
||||
uint64_t val;
|
||||
|
||||
/* recalculate the values for the Backup GPT Header */
|
||||
val = le64_to_cpu(gpt_h->my_lba);
|
||||
gpt_h->my_lba = cpu_to_le64(dev_desc->lba - 1);;
|
||||
gpt_h->alternate_lba = cpu_to_le64(val);
|
||||
gpt_h->last_usable_lba = cpu_to_le64(dev_desc->lba - 34);
|
||||
gpt_h->partition_entry_lba =
|
||||
cpu_to_le64(le64_to_cpu(gpt_h->last_usable_lba) + 1);
|
||||
gpt_h->header_crc32 = 0;
|
||||
|
||||
calc_crc32 = efi_crc32((const unsigned char *)gpt_h,
|
||||
le32_to_cpu(gpt_h->header_size));
|
||||
gpt_h->header_crc32 = cpu_to_le32(calc_crc32);
|
||||
}
|
||||
|
||||
static int validate_gpt_entries(gpt_header *gpt_h, gpt_entry *gpt_e)
|
||||
{
|
||||
uint32_t calc_crc32;
|
||||
|
@ -145,7 +164,7 @@ static int validate_gpt_entries(gpt_header *gpt_h, gpt_entry *gpt_e)
|
|||
le32_to_cpu(gpt_h->sizeof_partition_entry));
|
||||
|
||||
if (calc_crc32 != le32_to_cpu(gpt_h->partition_entry_array_crc32)) {
|
||||
printf("%s: 0x%x != 0x%x\n",
|
||||
debug("%s: 0x%x != 0x%x\n",
|
||||
"GUID Partition Table Entry Array CRC is wrong",
|
||||
le32_to_cpu(gpt_h->partition_entry_array_crc32),
|
||||
calc_crc32);
|
||||
|
@ -281,14 +300,14 @@ int part_get_info_efi(struct blk_desc *dev_desc, int part,
|
|||
/* This function validates AND fills in the GPT header and PTE */
|
||||
if (is_gpt_valid(dev_desc, GPT_PRIMARY_PARTITION_TABLE_LBA,
|
||||
gpt_head, &gpt_pte) != 1) {
|
||||
printf("%s: *** ERROR: Invalid GPT ***\n", __func__);
|
||||
debug("%s: *** ERROR: Invalid GPT ***\n", __func__);
|
||||
if (is_gpt_valid(dev_desc, (dev_desc->lba - 1),
|
||||
gpt_head, &gpt_pte) != 1) {
|
||||
printf("%s: *** ERROR: Invalid Backup GPT ***\n",
|
||||
__func__);
|
||||
return -1;
|
||||
} else {
|
||||
printf("%s: *** Using Backup GPT ***\n",
|
||||
debug("%s: *** Using Backup GPT ***\n",
|
||||
__func__);
|
||||
}
|
||||
}
|
||||
|
@ -869,6 +888,58 @@ int write_mbr_and_gpt_partitions(struct blk_desc *dev_desc, void *buf)
|
|||
|
||||
return 0;
|
||||
}
|
||||
int write_backup_gpt_partitions(struct blk_desc *dev_desc, void *buf)
|
||||
{
|
||||
gpt_header *gpt_h;
|
||||
gpt_entry *gpt_e;
|
||||
int gpt_e_blk_cnt;
|
||||
lbaint_t lba;
|
||||
int cnt;
|
||||
|
||||
if (is_valid_gpt_buf(dev_desc, buf))
|
||||
return -1;
|
||||
|
||||
/* determine start of GPT Header in the buffer */
|
||||
gpt_h = buf + (GPT_PRIMARY_PARTITION_TABLE_LBA *
|
||||
dev_desc->blksz);
|
||||
|
||||
/* determine start of GPT Entries in the buffer */
|
||||
gpt_e = buf + (le64_to_cpu(gpt_h->partition_entry_lba) *
|
||||
dev_desc->blksz);
|
||||
gpt_e_blk_cnt = BLOCK_CNT((le32_to_cpu(gpt_h->num_partition_entries) *
|
||||
le32_to_cpu(gpt_h->sizeof_partition_entry)),
|
||||
dev_desc);
|
||||
|
||||
/* write MBR */
|
||||
lba = 0; /* MBR is always at 0 */
|
||||
cnt = 1; /* MBR (1 block) */
|
||||
if (blk_dwrite(dev_desc, lba, cnt, buf) != cnt) {
|
||||
printf("%s: failed writing '%s' (%d blks at 0x" LBAF ")\n",
|
||||
__func__, "MBR", cnt, lba);
|
||||
return 1;
|
||||
}
|
||||
|
||||
prepare_last_lba_gpt_header(dev_desc, gpt_h);
|
||||
|
||||
/* write Backup GPT */
|
||||
lba = le64_to_cpu(gpt_h->partition_entry_lba);
|
||||
cnt = gpt_e_blk_cnt;
|
||||
if (blk_dwrite(dev_desc, lba, cnt, gpt_e) != cnt) {
|
||||
printf("%s: failed writing '%s' (%d blks at 0x" LBAF ")\n",
|
||||
__func__, "Backup GPT Entries", cnt, lba);
|
||||
return 1;
|
||||
}
|
||||
|
||||
lba = le64_to_cpu(gpt_h->my_lba);
|
||||
cnt = 1; /* GPT Header (1 block) */
|
||||
if (blk_dwrite(dev_desc, lba, cnt, gpt_h) != cnt) {
|
||||
printf("%s: failed writing '%s' (%d blks at 0x" LBAF ")\n",
|
||||
__func__, "Backup GPT Header", cnt, lba);
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
|
|
|
@ -29,6 +29,8 @@ obj-$(CONFIG_USB_FUNCTION_THOR) += f_thor.o
|
|||
obj-$(CONFIG_DFU_OVER_USB) += f_dfu.o
|
||||
obj-$(CONFIG_USB_FUNCTION_MASS_STORAGE) += f_mass_storage.o
|
||||
obj-$(CONFIG_USB_FUNCTION_FASTBOOT) += f_fastboot.o
|
||||
obj-$(CONFIG_FASTBOOT_LOCK) += fastboot_lock_unlock.o
|
||||
obj-$(CONFIG_BCB_SUPPORT) += command.o bcb.o
|
||||
obj-$(CONFIG_USB_FUNCTION_SDP) += f_sdp.o
|
||||
obj-$(CONFIG_USB_FUNCTION_ROCKUSB) += f_rockusb.o
|
||||
endif
|
||||
|
|
|
@ -0,0 +1,169 @@
|
|||
/*
|
||||
* Copyright (C) 2015-2016 Freescale Semiconductor, Inc.
|
||||
* Copyright 2017 NXP
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
|
||||
#include <fsl_fastboot.h>
|
||||
#include <linux/stat.h>
|
||||
#include <linux/types.h>
|
||||
#include <common.h>
|
||||
#include <g_dnl.h>
|
||||
#include <mmc.h>
|
||||
#include "bcb.h"
|
||||
#define ALIGN_BYTES 64 /*armv7 cache line need 64 bytes aligned */
|
||||
|
||||
static ulong get_block_size(char *ifname, int dev)
|
||||
{
|
||||
struct blk_desc *dev_desc = NULL;
|
||||
|
||||
dev_desc = blk_get_dev(ifname, dev);
|
||||
if (dev_desc == NULL) {
|
||||
printf("Block device %s %d not supported\n", ifname, dev);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return dev_desc->blksz;
|
||||
}
|
||||
|
||||
static int do_write(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
|
||||
{
|
||||
char *ep;
|
||||
struct blk_desc *dev_desc = NULL;
|
||||
int dev;
|
||||
int part = 0;
|
||||
disk_partition_t part_info;
|
||||
ulong offset = 0u;
|
||||
ulong limit = 0u;
|
||||
void *addr;
|
||||
uint blk;
|
||||
uint cnt;
|
||||
|
||||
if (argc != 6) {
|
||||
cmd_usage(cmdtp);
|
||||
return 1;
|
||||
}
|
||||
|
||||
dev = (int)simple_strtoul(argv[2], &ep, 16);
|
||||
if (*ep) {
|
||||
if (*ep != ':') {
|
||||
printf("Invalid block device %s\n", argv[2]);
|
||||
return 1;
|
||||
}
|
||||
part = (int)simple_strtoul(++ep, NULL, 16);
|
||||
}
|
||||
|
||||
dev_desc = blk_get_dev(argv[1], dev);
|
||||
if (dev_desc == NULL) {
|
||||
printf("Block device %s %d not supported\n", argv[1], dev);
|
||||
return 1;
|
||||
}
|
||||
|
||||
addr = (void *)simple_strtoul(argv[3], NULL, 16);
|
||||
blk = simple_strtoul(argv[4], NULL, 16);
|
||||
cnt = simple_strtoul(argv[5], NULL, 16);
|
||||
|
||||
if (part != 0) {
|
||||
if (part_get_info(dev_desc, part, &part_info)) {
|
||||
printf("Cannot find partition %d\n", part);
|
||||
return 1;
|
||||
}
|
||||
offset = part_info.start;
|
||||
limit = part_info.size;
|
||||
} else {
|
||||
/* Largest address not available in block_dev_desc_t. */
|
||||
limit = ~0;
|
||||
}
|
||||
|
||||
if (cnt + blk > limit) {
|
||||
printf("Write out of range\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (blk_dwrite(dev_desc, offset + blk, cnt, addr) != cnt) {
|
||||
printf("Error writing blocks\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
U_BOOT_CMD(
|
||||
write, 6, 0, do_write,
|
||||
"write binary data to a partition",
|
||||
"<interface> <dev[:part]> addr blk# cnt"
|
||||
);
|
||||
|
||||
int bcb_rw_block(bool bread, char **ppblock,
|
||||
uint *pblksize, char *pblock_write, uint offset, uint size)
|
||||
{
|
||||
int ret;
|
||||
char *argv[6];
|
||||
char addr_str[20];
|
||||
char cnt_str[8];
|
||||
char devpart_str[8];
|
||||
char block_begin_str[8];
|
||||
ulong blk_size = 0;
|
||||
uint blk_begin = 0;
|
||||
uint blk_end = 0;
|
||||
uint block_cnt = 0;
|
||||
char *p_block = NULL;
|
||||
unsigned int mmc_id;
|
||||
|
||||
if (bread && ((ppblock == NULL) || (pblksize == NULL)))
|
||||
return -1;
|
||||
|
||||
if (!bread && (pblock_write == NULL))
|
||||
return -1;
|
||||
|
||||
mmc_id = mmc_get_env_dev();
|
||||
blk_size = get_block_size("mmc", mmc_id);
|
||||
if (blk_size == 0) {
|
||||
printf("bcb_rw_block, get_block_size return 0\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
blk_begin = offset/blk_size;
|
||||
blk_end = (offset + size)/blk_size;
|
||||
block_cnt = 1 + (blk_end - blk_begin);
|
||||
|
||||
sprintf(devpart_str, "0x%x:0x%x", mmc_id,
|
||||
fastboot_flash_find_index(FASTBOOT_PARTITION_MISC));
|
||||
sprintf(block_begin_str, "0x%x", blk_begin);
|
||||
sprintf(cnt_str, "0x%x", block_cnt);
|
||||
|
||||
argv[0] = "rw"; /* not care */
|
||||
argv[1] = "mmc";
|
||||
argv[2] = devpart_str;
|
||||
argv[3] = addr_str;
|
||||
argv[4] = block_begin_str;
|
||||
argv[5] = cnt_str;
|
||||
|
||||
if (bread) {
|
||||
p_block = (char *)memalign(ALIGN_BYTES, blk_size * block_cnt);
|
||||
if (NULL == p_block) {
|
||||
printf("bcb_rw_block, memalign %d bytes failed\n",
|
||||
(int)(blk_size * block_cnt));
|
||||
return -1;
|
||||
}
|
||||
sprintf(addr_str, "0x%x", (unsigned int)(uintptr_t)p_block);
|
||||
ret = do_raw_read(NULL, 0, 6, argv);
|
||||
if (ret) {
|
||||
free(p_block);
|
||||
printf("do_raw_read failed, ret %d\n", ret);
|
||||
return -1;
|
||||
}
|
||||
|
||||
*ppblock = p_block;
|
||||
*pblksize = (uint)blk_size;
|
||||
} else {
|
||||
sprintf(addr_str, "0x%x", (unsigned int)(uintptr_t)pblock_write);
|
||||
ret = do_write(NULL, 0, 6, argv);
|
||||
if (ret) {
|
||||
printf("do_write failed, ret %d\n", ret);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,58 @@
|
|||
/*
|
||||
* Copyright (C) 2015-2016 Freescale Semiconductor, Inc.
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
|
||||
#ifndef BCB_H
|
||||
#define BCB_H
|
||||
#include <linux/types.h>
|
||||
#include <linux/stat.h>
|
||||
|
||||
#define FASTBOOT_BCB_CMD "bootonce-bootloader"
|
||||
#ifdef CONFIG_ANDROID_RECOVERY
|
||||
#define RECOVERY_BCB_CMD "boot-recovery"
|
||||
#endif
|
||||
/* keep same as bootable/recovery/bootloader.h */
|
||||
struct bootloader_message {
|
||||
char command[32];
|
||||
char status[32];
|
||||
char recovery[768];
|
||||
|
||||
/* The 'recovery' field used to be 1024 bytes. It has only ever
|
||||
been used to store the recovery command line, so 768 bytes
|
||||
should be plenty. We carve off the last 256 bytes to store the
|
||||
stage string (for multistage packages) and possible future
|
||||
expansion. */
|
||||
char stage[32];
|
||||
|
||||
/* The 'reserved' field used to be 224 bytes when it was initially
|
||||
carved off from the 1024-byte recovery field. Bump it up to
|
||||
1184-byte so that the entire bootloader_message struct rounds up
|
||||
to 2048-byte.
|
||||
*/
|
||||
char reserved[1184];
|
||||
};
|
||||
|
||||
struct bootloader_message_ab {
|
||||
struct bootloader_message message;
|
||||
char slot_suffix[32];
|
||||
|
||||
/* Round up the entire struct to 4096-byte. */
|
||||
char reserved[2016];
|
||||
};
|
||||
|
||||
/* start from bootloader_message_ab.slot_suffix[BOOTCTRL_IDX] */
|
||||
#define BOOTCTRL_IDX 0
|
||||
#define MISC_COMMAND_IDX 0
|
||||
#define BOOTCTRL_OFFSET \
|
||||
(u32)(&(((struct bootloader_message_ab *)0)->slot_suffix[BOOTCTRL_IDX]))
|
||||
#define MISC_COMMAND \
|
||||
(u32)(uintptr_t)(&(((struct bootloader_message *)0)->command[MISC_COMMAND_IDX]))
|
||||
int bcb_rw_block(bool bread, char **ppblock,
|
||||
uint *pblksize, char *pblock_write, uint offset, uint size);
|
||||
|
||||
int bcb_write_command(char *bcb_command);
|
||||
int bcb_read_command(char *command);
|
||||
|
||||
#endif
|
|
@ -0,0 +1,62 @@
|
|||
/*
|
||||
* Copyright (C) 2015-2016 Freescale Semiconductor, Inc.
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <g_dnl.h>
|
||||
#include "bcb.h"
|
||||
|
||||
int bcb_read_command(char *command)
|
||||
{
|
||||
int ret = 0;
|
||||
char *p_block = NULL;
|
||||
uint offset_in_block = 0;
|
||||
uint blk_size = 0;
|
||||
|
||||
if (command == NULL)
|
||||
return -1;
|
||||
|
||||
ret = bcb_rw_block(true, &p_block, &blk_size, NULL, MISC_COMMAND, 32);
|
||||
if (ret) {
|
||||
printf("read_bootctl, bcb_rw_block read failed\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
offset_in_block = MISC_COMMAND%blk_size;
|
||||
memcpy(command, p_block + offset_in_block, 32);
|
||||
free(p_block);
|
||||
|
||||
return 0;
|
||||
}
|
||||
int bcb_write_command(char *bcb_command)
|
||||
{
|
||||
int ret = 0;
|
||||
char *p_block = NULL;
|
||||
uint offset_in_block = 0;
|
||||
uint blk_size = 0;
|
||||
|
||||
if (bcb_command == NULL)
|
||||
return -1;
|
||||
|
||||
|
||||
ret = bcb_rw_block(true, &p_block, &blk_size, NULL, MISC_COMMAND, 32);
|
||||
if (ret) {
|
||||
printf("write_bootctl, bcb_rw_block read failed\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
offset_in_block = MISC_COMMAND%blk_size;
|
||||
memcpy(p_block + offset_in_block, bcb_command, 32);
|
||||
|
||||
ret = bcb_rw_block(false, NULL, NULL, p_block, MISC_COMMAND, 32);
|
||||
if (ret) {
|
||||
free(p_block);
|
||||
printf("write_bootctl, bcb_rw_block write failed\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
free(p_block);
|
||||
return 0;
|
||||
}
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,467 @@
|
|||
/*
|
||||
* Copyright (c) 2016, Freescale Semiconductor, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* o Redistributions of source code must retain the above copyright notice, this list
|
||||
* of conditions and the following disclaimer.
|
||||
*
|
||||
* o Redistributions in binary form must reproduce the above copyright notice, this
|
||||
* list of conditions and the following disclaimer in the documentation and/or
|
||||
* other materials provided with the distribution.
|
||||
*
|
||||
* o Neither the name of Freescale Semiconductor, Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#include <common.h>
|
||||
#include <mapmem.h>
|
||||
#include <linux/types.h>
|
||||
#include <part.h>
|
||||
#include <mmc.h>
|
||||
#include <ext_common.h>
|
||||
#include <stdio_dev.h>
|
||||
#include <stdlib.h>
|
||||
#include "fastboot_lock_unlock.h"
|
||||
#include <fsl_fastboot.h>
|
||||
|
||||
#ifdef FASTBOOT_ENCRYPT_LOCK
|
||||
|
||||
#include <hash.h>
|
||||
#include <fsl_caam.h>
|
||||
|
||||
//Encrypted data is 80bytes length.
|
||||
#define ENDATA_LEN 80
|
||||
|
||||
#endif
|
||||
|
||||
int fastboot_flash_find_index(const char *name);
|
||||
|
||||
#ifndef FASTBOOT_ENCRYPT_LOCK
|
||||
|
||||
/*
|
||||
* This will return FASTBOOT_LOCK, FASTBOOT_UNLOCK or FASTBOOT_ERROR
|
||||
*/
|
||||
static FbLockState decrypt_lock_store(unsigned char* bdata) {
|
||||
if (!strncmp((const char *)bdata, "locked", strlen("locked")))
|
||||
return FASTBOOT_LOCK;
|
||||
else if (!strncmp((const char *)bdata, "unlocked", strlen("unlocked")))
|
||||
return FASTBOOT_UNLOCK;
|
||||
else
|
||||
return FASTBOOT_LOCK_ERROR;
|
||||
}
|
||||
|
||||
static inline int encrypt_lock_store(FbLockState lock, unsigned char* bdata) {
|
||||
if (FASTBOOT_LOCK == lock)
|
||||
strncpy((char *)bdata, "locked", strlen("locked"));
|
||||
else if (FASTBOOT_UNLOCK == lock)
|
||||
strncpy((char *)bdata, "unlocked", strlen("unlocked"));
|
||||
else
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
|
||||
static int sha1sum(unsigned char* data, int len, unsigned char* output) {
|
||||
struct hash_algo *algo;
|
||||
void *buf;
|
||||
if (hash_lookup_algo("sha1", &algo)) {
|
||||
printf("error in lookup sha1 algo!\n");
|
||||
return -1;
|
||||
}
|
||||
buf = map_sysmem((ulong)data, len);
|
||||
algo->hash_func_ws(buf, len, output, algo->chunk_size);
|
||||
unmap_sysmem(buf);
|
||||
|
||||
return algo->digest_size;
|
||||
|
||||
}
|
||||
|
||||
static int generate_salt(unsigned char* salt) {
|
||||
unsigned long time = get_timer(0);
|
||||
return sha1sum((unsigned char *)&time, sizeof(unsigned long), salt);
|
||||
|
||||
}
|
||||
|
||||
static FbLockState decrypt_lock_store(unsigned char *bdata) {
|
||||
unsigned char plain_data[ENDATA_LEN];
|
||||
int p = 0, ret;
|
||||
|
||||
caam_open();
|
||||
ret = caam_decap_blob((uint32_t)plain_data,
|
||||
(uint32_t)bdata + ENDATA_LEN, ENDATA_LEN);
|
||||
if (ret != 0) {
|
||||
printf("Error during blob decap operation: 0x%x\n",ret);
|
||||
return FASTBOOT_LOCK_ERROR;
|
||||
}
|
||||
#ifdef FASTBOOT_LOCK_DEBUG
|
||||
FB_DEBUG("Decrypt data block are:\n \t=======\t\n");
|
||||
for (p = 0; p < ENDATA_LEN; p++) {
|
||||
FB_DEBUG("0x%2x ", *(bdata + p));
|
||||
if (p % 16 == 0)
|
||||
FB_DEBUG("\n");
|
||||
}
|
||||
FB_DEBUG("\n \t========\t\n");
|
||||
for (p = ENDATA_LEN; p < (ENDATA_LEN + ENDATA_LEN + 48 ); p++) {
|
||||
FB_DEBUG("0x%2x ", *(bdata + p));
|
||||
if (p % 16 == 0)
|
||||
FB_DEBUG("\n");
|
||||
}
|
||||
|
||||
FB_DEBUG("\n plain text are:\n");
|
||||
for (p = 0; p < ENDATA_LEN; p++) {
|
||||
FB_DEBUG("0x%2x ", plain_data[p]);
|
||||
if (p % 16 == 0)
|
||||
FB_DEBUG("\n");
|
||||
}
|
||||
FB_DEBUG("\n");
|
||||
#endif
|
||||
|
||||
for (p = 0; p < ENDATA_LEN-1; p++) {
|
||||
if (*(bdata+p) != plain_data[p]) {
|
||||
FB_DEBUG("Verify salt in decrypt error on pointer %d\n", p);
|
||||
return FASTBOOT_LOCK_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
if (plain_data[ENDATA_LEN - 1] >= FASTBOOT_LOCK_NUM)
|
||||
return FASTBOOT_LOCK_ERROR;
|
||||
else
|
||||
return plain_data[ENDATA_LEN-1];
|
||||
}
|
||||
|
||||
static int encrypt_lock_store(FbLockState lock, unsigned char* bdata) {
|
||||
unsigned int p = 0;
|
||||
int ret;
|
||||
int salt_len = generate_salt(bdata);
|
||||
if (salt_len < 0)
|
||||
return -1;
|
||||
|
||||
//salt_len cannot be longer than endata block size.
|
||||
if (salt_len >= ENDATA_LEN)
|
||||
salt_len = ENDATA_LEN - 1;
|
||||
|
||||
p = ENDATA_LEN - 1;
|
||||
|
||||
//Set lock value
|
||||
*(bdata + p) = lock;
|
||||
|
||||
caam_open();
|
||||
ret = caam_gen_blob((uint32_t)bdata, (uint32_t)(bdata + ENDATA_LEN), ENDATA_LEN);
|
||||
if (ret != 0) {
|
||||
printf("error in caam_gen_blob:0x%x\n", ret);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
#ifdef FASTBOOT_LOCK_DEBUG
|
||||
int i = 0;
|
||||
FB_DEBUG("encrypt plain_text:\n");
|
||||
for (i = 0; i < ENDATA_LEN; i++) {
|
||||
FB_DEBUG("0x%2x\t", *(bdata+i));
|
||||
if (i % 16 == 0)
|
||||
printf("\n");
|
||||
}
|
||||
printf("\nto:\n");
|
||||
for (i=0; i < ENDATA_LEN + 48; i++) {
|
||||
FB_DEBUG("0x%2x\t", *(bdata + ENDATA_LEN + i));
|
||||
if (i % 16 == 0)
|
||||
printf("\n");
|
||||
}
|
||||
printf("\n");
|
||||
|
||||
#endif
|
||||
//protect value
|
||||
*(bdata + p) = 0xff;
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
static char mmc_dev_part[16];
|
||||
static char* get_mmc_part(int part) {
|
||||
u32 dev_no = mmc_get_env_dev();
|
||||
sprintf(mmc_dev_part,"%x:%x",dev_no, part);
|
||||
return mmc_dev_part;
|
||||
}
|
||||
|
||||
static inline void set_lock_disable_data(unsigned char* bdata) {
|
||||
*(bdata + SECTOR_SIZE -1) = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* The enabling value is stored in the last byte of target partition.
|
||||
*/
|
||||
static inline unsigned char lock_enable_parse(unsigned char* bdata) {
|
||||
FB_DEBUG("lock_enable_parse: 0x%x\n", *(bdata + SECTOR_SIZE -1));
|
||||
if (*(bdata + SECTOR_SIZE -1) >= FASTBOOT_UL_NUM)
|
||||
return FASTBOOT_UL_ERROR;
|
||||
else
|
||||
return *(bdata + SECTOR_SIZE -1);
|
||||
}
|
||||
|
||||
static FbLockState g_lockstat = FASTBOOT_UNLOCK;
|
||||
/*
|
||||
* Set status of the lock&unlock to FSL_FASTBOOT_FB_PART
|
||||
* Currently use the very first Byte of FSL_FASTBOOT_FB_PART
|
||||
* to store the fastboot lock&unlock status
|
||||
*/
|
||||
int fastboot_set_lock_stat(FbLockState lock) {
|
||||
struct blk_desc *fs_dev_desc;
|
||||
disk_partition_t fs_partition;
|
||||
unsigned char *bdata;
|
||||
int mmc_id;
|
||||
int status, ret;
|
||||
|
||||
bdata = (unsigned char *)memalign(ALIGN_BYTES, SECTOR_SIZE);
|
||||
if (bdata == NULL)
|
||||
goto fail2;
|
||||
memset(bdata, 0, SECTOR_SIZE);
|
||||
|
||||
mmc_id = fastboot_flash_find_index(FASTBOOT_PARTITION_FBMISC);
|
||||
if (mmc_id < 0) {
|
||||
printf("%s: error in get mmc part\n", __FUNCTION__);
|
||||
ret = -1;
|
||||
goto fail;
|
||||
}
|
||||
status = blk_get_device_part_str(FSL_FASTBOOT_FB_DEV,
|
||||
get_mmc_part(mmc_id),
|
||||
&fs_dev_desc, &fs_partition, 1);
|
||||
if (status < 0) {
|
||||
printf("%s:error in getdevice partition.\n", __FUNCTION__);
|
||||
ret = -1;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
status = encrypt_lock_store(lock, bdata);
|
||||
if (status < 0) {
|
||||
ret = -1;
|
||||
goto fail;
|
||||
}
|
||||
status = blk_dwrite(fs_dev_desc, fs_partition.start, 1, bdata);
|
||||
if (!status) {
|
||||
printf("%s:error in block write.\n", __FUNCTION__);
|
||||
ret = -1;
|
||||
goto fail;
|
||||
}
|
||||
ret = 0;
|
||||
fail:
|
||||
free(bdata);
|
||||
return ret;
|
||||
fail2:
|
||||
g_lockstat = lock;
|
||||
return 0;
|
||||
}
|
||||
|
||||
FbLockState fastboot_get_lock_stat(void) {
|
||||
struct blk_desc *fs_dev_desc;
|
||||
disk_partition_t fs_partition;
|
||||
unsigned char *bdata;
|
||||
int mmc_id;
|
||||
FbLockState ret;
|
||||
|
||||
bdata = (unsigned char *)memalign(ALIGN_BYTES, SECTOR_SIZE);
|
||||
if (bdata == NULL)
|
||||
return g_lockstat;
|
||||
|
||||
int status;
|
||||
mmc_id = fastboot_flash_find_index(FASTBOOT_PARTITION_FBMISC);
|
||||
if (mmc_id < 0) {
|
||||
printf("%s: error in get mmc part\n", __FUNCTION__);
|
||||
ret = g_lockstat;
|
||||
goto fail;
|
||||
}
|
||||
status = blk_get_device_part_str(FSL_FASTBOOT_FB_DEV,
|
||||
get_mmc_part(mmc_id),
|
||||
&fs_dev_desc, &fs_partition, 1);
|
||||
|
||||
if (status < 0) {
|
||||
printf("%s:error in getdevice partition.\n", __FUNCTION__);
|
||||
ret = g_lockstat;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
status = blk_dread(fs_dev_desc, fs_partition.start, 1, bdata);
|
||||
if (!status) {
|
||||
printf("%s:error in block read.\n", __FUNCTION__);
|
||||
ret = FASTBOOT_LOCK_ERROR;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
ret = decrypt_lock_store(bdata);
|
||||
fail:
|
||||
free(bdata);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/* Return the last byte of of FSL_FASTBOOT_PR_DATA
|
||||
* which is managed by PresistDataService
|
||||
*/
|
||||
|
||||
#ifdef CONFIG_ENABLE_LOCKSTATUS_SUPPORT
|
||||
//Brillo has no presist data partition
|
||||
FbLockEnableResult fastboot_lock_enable(void) {
|
||||
return FASTBOOT_UL_ENABLE;
|
||||
}
|
||||
void set_fastboot_lock_disable(void) {
|
||||
}
|
||||
#else
|
||||
void set_fastboot_lock_disable(void) {
|
||||
struct blk_desc *fs_dev_desc;
|
||||
disk_partition_t fs_partition;
|
||||
unsigned char *bdata;
|
||||
int mmc_id;
|
||||
|
||||
bdata = (unsigned char *)memalign(ALIGN_BYTES, SECTOR_SIZE);
|
||||
if (bdata == NULL)
|
||||
return;
|
||||
set_lock_disable_data(bdata);
|
||||
int status;
|
||||
mmc_id = fastboot_flash_find_index(FASTBOOT_PARTITION_PRDATA);
|
||||
if (mmc_id < 0) {
|
||||
printf("%s: error in get mmc part\n", __FUNCTION__);
|
||||
goto fail;
|
||||
}
|
||||
status = blk_get_device_part_str(FSL_FASTBOOT_FB_DEV,
|
||||
get_mmc_part(mmc_id),
|
||||
&fs_dev_desc, &fs_partition, 1);
|
||||
if (status < 0) {
|
||||
printf("%s:error in getdevice partition.\n", __FUNCTION__);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
lbaint_t target_block = fs_partition.start + fs_partition.size - 1;
|
||||
status = blk_dwrite(fs_dev_desc, target_block, 1, bdata);
|
||||
if (!status) {
|
||||
printf("%s: error in block read\n", __FUNCTION__);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
fail:
|
||||
free(bdata);
|
||||
return;
|
||||
|
||||
}
|
||||
FbLockEnableResult fastboot_lock_enable() {
|
||||
struct blk_desc *fs_dev_desc;
|
||||
disk_partition_t fs_partition;
|
||||
unsigned char *bdata;
|
||||
int mmc_id;
|
||||
FbLockEnableResult ret;
|
||||
|
||||
bdata = (unsigned char *)memalign(ALIGN_BYTES, SECTOR_SIZE);
|
||||
if (bdata == NULL)
|
||||
return FASTBOOT_UL_ERROR;
|
||||
int status;
|
||||
mmc_id = fastboot_flash_find_index(FASTBOOT_PARTITION_PRDATA);
|
||||
if (mmc_id < 0) {
|
||||
printf("%s: error in get mmc part\n", __FUNCTION__);
|
||||
ret = FASTBOOT_UL_ERROR;
|
||||
goto fail;
|
||||
}
|
||||
status = blk_get_device_part_str(FSL_FASTBOOT_FB_DEV,
|
||||
get_mmc_part(mmc_id),
|
||||
&fs_dev_desc, &fs_partition, 1);
|
||||
if (status < 0) {
|
||||
printf("%s:error in getdevice partition.\n", __FUNCTION__);
|
||||
ret = FASTBOOT_UL_ERROR;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
//The data is stored in the last blcok of this partition.
|
||||
lbaint_t target_block = fs_partition.start + fs_partition.size - 1;
|
||||
status = blk_dread(fs_dev_desc, target_block, 1, bdata);
|
||||
if (!status) {
|
||||
printf("%s: error in block read\n", __FUNCTION__);
|
||||
ret = FASTBOOT_UL_ERROR;
|
||||
goto fail;
|
||||
}
|
||||
int i = 0;
|
||||
FB_DEBUG("\n PRIST last sector is:\n");
|
||||
for (i = 0; i < SECTOR_SIZE; i++) {
|
||||
FB_DEBUG("0x%x ", *(bdata + i));
|
||||
if (i % 32 == 0)
|
||||
FB_DEBUG("\n");
|
||||
}
|
||||
FB_DEBUG("\n");
|
||||
ret = lock_enable_parse(bdata);
|
||||
fail:
|
||||
free(bdata);
|
||||
return ret;
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
int display_lock(FbLockState lock, int verify) {
|
||||
struct stdio_dev *disp;
|
||||
disp = stdio_get_by_name("vga");
|
||||
if (disp != NULL) {
|
||||
if (lock == FASTBOOT_UNLOCK) {
|
||||
disp->puts(disp, "\n============= NOTICE ============\n");
|
||||
disp->puts(disp, "| |\n");
|
||||
disp->puts(disp, "| Your device is NOT locked. |\n");
|
||||
disp->puts(disp, "| |\n");
|
||||
disp->puts(disp, "=================================\n");
|
||||
} else {
|
||||
if (verify == -1) {
|
||||
disp->puts(disp, "\n============= NOTICE ============\n");
|
||||
disp->puts(disp, "| |\n");
|
||||
disp->puts(disp, "| Your device is NOT protected. |\n");
|
||||
disp->puts(disp, "| |\n");
|
||||
disp->puts(disp, "=================================\n");
|
||||
} else if (verify == 1) {
|
||||
disp->puts(disp, "\n============= NOTICE ============\n");
|
||||
disp->puts(disp, "| |\n");
|
||||
disp->puts(disp, "| Boot verify failed! |\n");
|
||||
disp->puts(disp, "| |\n");
|
||||
disp->puts(disp, "=================================\n");
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
} else
|
||||
printf("not found VGA disp console.\n");
|
||||
|
||||
return -1;
|
||||
|
||||
}
|
||||
|
||||
int fastboot_wipe_data_partition(void)
|
||||
{
|
||||
struct blk_desc *fs_dev_desc;
|
||||
disk_partition_t fs_partition;
|
||||
int status;
|
||||
int mmc_id;
|
||||
mmc_id = fastboot_flash_find_index(FASTBOOT_PARTITION_DATA);
|
||||
if (mmc_id < 0) {
|
||||
printf("%s: error in get mmc part\n", __FUNCTION__);
|
||||
return -1;
|
||||
}
|
||||
status = blk_get_device_part_str(FSL_FASTBOOT_FB_DEV,
|
||||
get_mmc_part(mmc_id), &fs_dev_desc, &fs_partition, 1);
|
||||
if (status < 0) {
|
||||
printf("error in get device partition for wipe /data\n");
|
||||
return -1;
|
||||
}
|
||||
status = blk_derase(fs_dev_desc, fs_partition.start , fs_partition.size );
|
||||
if (status != fs_partition.size ) {
|
||||
printf("erase not complete\n");
|
||||
return -1;
|
||||
}
|
||||
mdelay(2000);
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,71 @@
|
|||
/*
|
||||
* Copyright (c) 2016, Freescale Semiconductor, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* o Redistributions of source code must retain the above copyright notice, this list
|
||||
* of conditions and the following disclaimer.
|
||||
*
|
||||
* o Redistributions in binary form must reproduce the above copyright notice, this
|
||||
* list of conditions and the following disclaimer in the documentation and/or
|
||||
* other materials provided with the distribution.
|
||||
*
|
||||
* o Neither the name of Freescale Semiconductor, Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef FASTBOOT_LOCK_UNLOCK_H
|
||||
#define FASTBOOT_LOCK_UNLOCK_H
|
||||
|
||||
#define ALIGN_BYTES 64 /*armv7 cache line need 64 bytes aligned */
|
||||
|
||||
//#define FASTBOOT_LOCK_DEBUG
|
||||
#ifdef CONFIG_FSL_CAAM_KB
|
||||
#define FASTBOOT_ENCRYPT_LOCK
|
||||
#endif
|
||||
|
||||
#ifdef FASTBOOT_LOCK_DEBUG
|
||||
#define FB_DEBUG(format, ...) printf(format, ##__VA_ARGS__)
|
||||
#else
|
||||
#define FB_DEBUG(format, ...)
|
||||
#endif
|
||||
|
||||
typedef enum {
|
||||
FASTBOOT_UNLOCK,
|
||||
FASTBOOT_LOCK,
|
||||
FASTBOOT_LOCK_ERROR,
|
||||
FASTBOOT_LOCK_NUM
|
||||
}FbLockState;
|
||||
|
||||
typedef enum {
|
||||
FASTBOOT_UL_DISABLE,
|
||||
FASTBOOT_UL_ENABLE,
|
||||
FASTBOOT_UL_ERROR,
|
||||
FASTBOOT_UL_NUM
|
||||
}FbLockEnableResult;
|
||||
|
||||
FbLockState fastboot_get_lock_stat(void);
|
||||
|
||||
int fastboot_set_lock_stat(FbLockState lock);
|
||||
|
||||
int fastboot_wipe_data_partition(void);
|
||||
|
||||
FbLockEnableResult fastboot_lock_enable(void);
|
||||
void set_fastboot_lock_disable(void);
|
||||
|
||||
int display_lock(FbLockState lock, int verify);
|
||||
#endif
|
|
@ -20,6 +20,19 @@ typedef struct andr_img_hdr andr_img_hdr;
|
|||
#define ANDR_BOOT_ARGS_SIZE 512
|
||||
#define ANDR_BOOT_EXTRA_ARGS_SIZE 1024
|
||||
|
||||
/* Boot metric variables (in millisecond) */
|
||||
struct boot_metric
|
||||
{
|
||||
u32 bll_1; /* 1th bootloader load duration */
|
||||
u32 ble_1; /* 1th bootloader exec duration */
|
||||
u32 kl; /* kernel image load duration */
|
||||
u32 kd; /* kernel image decompress duration */
|
||||
u32 avb; /* avb verify boot.img duration */
|
||||
u32 odt; /* overlay device tree duration */
|
||||
u32 sw; /* system wait for UI interaction duration*/
|
||||
};
|
||||
typedef struct boot_metric boot_metric;
|
||||
|
||||
struct andr_img_hdr {
|
||||
char magic[ANDR_BOOT_MAGIC_SIZE];
|
||||
|
||||
|
@ -80,4 +93,16 @@ struct andr_img_hdr {
|
|||
* 6. if second_size != 0: jump to second_addr
|
||||
* else: jump to kernel_addr
|
||||
*/
|
||||
struct header_image {
|
||||
uint32_t code0; /* Executable code */
|
||||
uint32_t code1; /* Executable code */
|
||||
uint64_t text_offset; /* Image load offset, LE */
|
||||
uint64_t image_size; /* Effective Image size, LE */
|
||||
uint64_t res1; /* reserved */
|
||||
uint64_t res2; /* reserved */
|
||||
uint64_t res3; /* reserved */
|
||||
uint64_t res4; /* reserved */
|
||||
uint32_t magic; /* Magic number */
|
||||
uint32_t res5;
|
||||
};
|
||||
#endif
|
||||
|
|
|
@ -685,6 +685,10 @@ int cpu_disable(int nr);
|
|||
int cpu_release(int nr, int argc, char * const argv[]);
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_CMD_READ
|
||||
int do_raw_read(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]);
|
||||
#endif
|
||||
|
||||
#else /* __ASSEMBLY__ */
|
||||
|
||||
/* Drop a C type modifier (like in 3UL) for constants used in assembly. */
|
||||
|
|
|
@ -0,0 +1,250 @@
|
|||
/*
|
||||
* Copyright (C) 2010-2016 Freescale Semiconductor, Inc.
|
||||
* Copyright 2017 NXP
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
|
||||
#ifndef FSL_FASTBOOT_H
|
||||
#define FSL_FASTBOOT_H
|
||||
#include <stdbool.h>
|
||||
#include <linux/types.h>
|
||||
|
||||
#define FASTBOOT_PTENTRY_FLAGS_REPEAT(n) (n & 0x0f)
|
||||
#define FASTBOOT_PTENTRY_FLAGS_REPEAT_MASK 0x0000000F
|
||||
|
||||
/* Writes happen a block at a time.
|
||||
If the write fails, go to next block
|
||||
NEXT_GOOD_BLOCK and CONTIGOUS_BLOCK can not both be set */
|
||||
#define FASTBOOT_PTENTRY_FLAGS_WRITE_NEXT_GOOD_BLOCK 0x00000010
|
||||
|
||||
/* Find a contiguous block big enough for a the whole file
|
||||
NEXT_GOOD_BLOCK and CONTIGOUS_BLOCK can not both be set */
|
||||
#define FASTBOOT_PTENTRY_FLAGS_WRITE_CONTIGUOUS_BLOCK 0x00000020
|
||||
|
||||
/* Write the file with write.i */
|
||||
#define FASTBOOT_PTENTRY_FLAGS_WRITE_I 0x00000100
|
||||
|
||||
/* Write the file with write.trimffs */
|
||||
#define FASTBOOT_PTENTRY_FLAGS_WRITE_TRIMFFS 0x00000200
|
||||
|
||||
/* Write the file as a series of variable/value pairs
|
||||
using the setenv and saveenv commands */
|
||||
#define FASTBOOT_PTENTRY_FLAGS_WRITE_ENV 0x00000400
|
||||
|
||||
/* Uneraseable partition */
|
||||
#define FASTBOOT_PTENTRY_FLAGS_UNERASEABLE 0x00000800
|
||||
|
||||
#define FASTBOOT_MMC_BOOT_PARTITION_ID 1
|
||||
#define FASTBOOT_MMC_USER_PARTITION_ID 0
|
||||
#define FASTBOOT_MMC_NONE_PARTITION_ID -1
|
||||
|
||||
#define FASTBOOT_PARTITION_PRDATA "presistdata"
|
||||
|
||||
#ifdef CONFIG_AVB_SUPPORT
|
||||
#define FASTBOOT_PARTITION_AVBKEY "avbkey"
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_FLASH_MCUFIRMWARE_SUPPORT
|
||||
#define FASTBOOT_MCU_FIRMWARE_PARTITION "m4_os"
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_ANDROID_AB_SUPPORT
|
||||
#define FASTBOOT_PARTITION_BOOT_A "boot_a"
|
||||
#define FASTBOOT_PARTITION_RECOVERY "recovery"
|
||||
#define FASTBOOT_PARTITION_SYSTEM_A "system_a"
|
||||
#define FASTBOOT_PARTITION_BOOTLOADER "bootloader0"
|
||||
#define FASTBOOT_PARTITION_DATA "userdata"
|
||||
#define FASTBOOT_PARTITION_BOOT_B "boot_b"
|
||||
#define FASTBOOT_PARTITION_SYSTEM_B "system_b"
|
||||
#ifdef CONFIG_AVB_SUPPORT
|
||||
#define FASTBOOT_PARTITION_VBMETA_A "vbmeta_a"
|
||||
#define FASTBOOT_PARTITION_VBMETA_B "vbmeta_b"
|
||||
#endif
|
||||
#define FASTBOOT_PARTITION_MISC "misc"
|
||||
#define FASTBOOT_PARTITION_GPT "gpt"
|
||||
#define FASTBOOT_PARTITION_FBMISC "fbmisc"
|
||||
#else
|
||||
#define FASTBOOT_PARTITION_BOOT "boot"
|
||||
#define FASTBOOT_PARTITION_RECOVERY "recovery"
|
||||
#define FASTBOOT_PARTITION_SYSTEM "system"
|
||||
#define FASTBOOT_PARTITION_CACHE "cache"
|
||||
#define FASTBOOT_PARTITION_DEVICE "device"
|
||||
#define FASTBOOT_PARTITION_BOOTLOADER "bootloader"
|
||||
#define FASTBOOT_PARTITION_DATA "userdata"
|
||||
#define FASTBOOT_PARTITION_GPT "gpt"
|
||||
#define FASTBOOT_PARTITION_MISC "misc"
|
||||
#define FASTBOOT_PARTITION_FBMISC "fbmisc"
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_ANDROID_THINGS_SUPPORT
|
||||
#define FASTBOOT_BOOTLOADER_VBOOT_KEY "fuse at-bootloader-vboot-key"
|
||||
#endif
|
||||
|
||||
enum {
|
||||
DEV_SATA,
|
||||
DEV_MMC,
|
||||
DEV_NAND,
|
||||
#ifdef CONFIG_FLASH_MCUFIRMWARE_SUPPORT
|
||||
/* SPI Flash */
|
||||
DEV_SF
|
||||
#endif
|
||||
};
|
||||
|
||||
typedef enum {
|
||||
#ifdef CONFIG_ANDROID_RECOVERY
|
||||
/* Revoery boot due to combo keys pressed */
|
||||
BOOTMODE_RECOVERY_KEY_PRESSED,
|
||||
/* Recovery boot due to boot-recovery cmd in misc parition */
|
||||
BOOTMODE_RECOVERY_BCB_CMD,
|
||||
#endif
|
||||
/* Fastboot boot due to bootonce-bootloader cmd in misc parition */
|
||||
BOOTMODE_FASTBOOT_BCB_CMD,
|
||||
/* Normal boot */
|
||||
BOOTMODE_NORMAL
|
||||
}FbBootMode;
|
||||
|
||||
|
||||
struct cmd_fastboot_interface {
|
||||
/* This function is called when a buffer has been
|
||||
recieved from the client app.
|
||||
The buffer is a supplied by the board layer and must be unmodified.
|
||||
The buffer_size is how much data is passed in.
|
||||
Returns 0 on success
|
||||
Returns 1 on failure
|
||||
|
||||
Set by cmd_fastboot */
|
||||
int (*rx_handler)(const unsigned char *buffer,
|
||||
unsigned int buffer_size);
|
||||
|
||||
/* This function is called when an exception has
|
||||
occurred in the device code and the state
|
||||
off fastboot needs to be reset
|
||||
|
||||
Set by cmd_fastboot */
|
||||
void (*reset_handler)(void);
|
||||
|
||||
/* A getvar string for the product name
|
||||
It can have a maximum of 60 characters
|
||||
|
||||
Set by board */
|
||||
char *product_name;
|
||||
|
||||
/* A getvar string for the serial number
|
||||
It can have a maximum of 60 characters
|
||||
|
||||
Set by board */
|
||||
char *serial_no;
|
||||
|
||||
/* Nand block size
|
||||
Supports the write option WRITE_NEXT_GOOD_BLOCK
|
||||
|
||||
Set by board */
|
||||
unsigned int nand_block_size;
|
||||
|
||||
/* Nand oob size
|
||||
Set by board */
|
||||
unsigned int nand_oob_size;
|
||||
|
||||
/* Transfer buffer, for handling flash updates
|
||||
Should be multiple of the nand_block_size
|
||||
Care should be take so it does not overrun bootloader memory
|
||||
Controlled by the configure variable CFG_FASTBOOT_TRANSFER_BUFFER
|
||||
|
||||
Set by board */
|
||||
unsigned char *transfer_buffer;
|
||||
|
||||
/* How big is the transfer buffer
|
||||
Controlled by the configure variable
|
||||
CFG_FASTBOOT_TRANSFER_BUFFER_SIZE
|
||||
|
||||
Set by board */
|
||||
unsigned int transfer_buffer_size;
|
||||
|
||||
};
|
||||
|
||||
/* flash partitions are defined in terms of blocks
|
||||
** (flash erase units)
|
||||
*/
|
||||
struct fastboot_ptentry {
|
||||
/* The logical name for this partition, null terminated */
|
||||
char name[16];
|
||||
/* The start wrt the nand part, must be multiple of nand block size */
|
||||
unsigned int start;
|
||||
/* The length of the partition, must be multiple of nand block size */
|
||||
unsigned int length;
|
||||
/* Controls the details of how operations are done on the partition
|
||||
See the FASTBOOT_PTENTRY_FLAGS_*'s defined below */
|
||||
unsigned int flags;
|
||||
/* partition id: 0 - normal partition; 1 - boot partition */
|
||||
unsigned int partition_id;
|
||||
/* partition number in block device */
|
||||
unsigned int partition_index;
|
||||
/* partition file system type in string */
|
||||
char fstype[16];
|
||||
/* filesystem UUID as string, if exists */
|
||||
#ifdef CONFIG_PARTITION_UUIDS
|
||||
char uuid[37];
|
||||
#endif
|
||||
};
|
||||
|
||||
struct fastboot_device_info {
|
||||
unsigned char type;
|
||||
unsigned char dev_id;
|
||||
};
|
||||
|
||||
extern struct fastboot_device_info fastboot_devinfo;
|
||||
|
||||
/* Prepare the fastboot environments,
|
||||
* should be executed before "fastboot" cmd
|
||||
*/
|
||||
void fastboot_setup(void);
|
||||
|
||||
|
||||
/* The Android-style flash handling */
|
||||
|
||||
/* tools to populate and query the partition table */
|
||||
void fastboot_flash_add_ptn(struct fastboot_ptentry *ptn);
|
||||
struct fastboot_ptentry *fastboot_flash_find_ptn(const char *name);
|
||||
struct fastboot_ptentry *fastboot_flash_get_ptn(unsigned n);
|
||||
unsigned int fastboot_flash_get_ptn_count(void);
|
||||
void fastboot_flash_dump_ptn(void);
|
||||
|
||||
/* Make board into special boot mode */
|
||||
void fastboot_run_bootmode(void);
|
||||
|
||||
/*Setup board-relative fastboot environment */
|
||||
void board_fastboot_setup(void);
|
||||
|
||||
/*return partition index according name*/
|
||||
int fastboot_flash_find_index(const char *name);
|
||||
|
||||
/*check whether bootloader is overlay with GPT table*/
|
||||
bool bootloader_gpt_overlay(void);
|
||||
/* Check whether the combo keys pressed
|
||||
* Return 1 if combo keys pressed for recovery boot
|
||||
* Return 0 if no combo keys pressed
|
||||
*/
|
||||
int is_recovery_key_pressing(void);
|
||||
|
||||
#ifdef CONFIG_FASTBOOT_STORAGE_NAND
|
||||
/*Save parameters for NAND storage partitions */
|
||||
void save_parts_values(struct fastboot_ptentry *ptn,
|
||||
unsigned int offset, unsigned int size);
|
||||
|
||||
/* Checks parameters for NAND storage partitions
|
||||
* Return 1 if the parameter is not set
|
||||
* Return 0 if the parameter has been set
|
||||
*/
|
||||
int check_parts_values(struct fastboot_ptentry *ptn);
|
||||
#endif /*CONFIG_FASTBOOT_STORAGE_NAND*/
|
||||
|
||||
/* Reads |num_bytes| from offset |offset| from partition with name
|
||||
* |partition| (NUL-terminated UTF-8 string). If |offset| is
|
||||
* negative, its absolute value should be interpreted as the number
|
||||
* of bytes from the end of the partition.
|
||||
* It's basically copied from fsl_read_from_partition_multi() because
|
||||
* we may want to read partition when AVB is not enabled. */
|
||||
int read_from_partition_multi(const char* partition,
|
||||
int64_t offset, size_t num_bytes,void* buffer, size_t* out_num_read);
|
||||
#endif /* FSL_FASTBOOT_H */
|
|
@ -1277,6 +1277,7 @@ int android_image_get_second(const struct andr_img_hdr *hdr,
|
|||
ulong android_image_get_end(const struct andr_img_hdr *hdr);
|
||||
ulong android_image_get_kload(const struct andr_img_hdr *hdr);
|
||||
void android_print_contents(const struct andr_img_hdr *hdr);
|
||||
bool image_arm64(void *images);
|
||||
|
||||
#endif /* CONFIG_ANDROID_BOOT_IMAGE */
|
||||
|
||||
|
|
|
@ -814,6 +814,7 @@ int board_mmc_init(bd_t *bis);
|
|||
int cpu_mmc_init(bd_t *bis);
|
||||
int mmc_get_env_addr(struct mmc *mmc, int copy, u32 *env_addr);
|
||||
int mmc_get_env_dev(void);
|
||||
int mmc_map_to_kernel_blk(int dev_no);
|
||||
|
||||
/* Set block count limit because of 16 bit register limit on some hardware*/
|
||||
#ifndef CONFIG_SYS_MMC_MAX_BLK_COUNT
|
||||
|
|
|
@ -374,6 +374,14 @@ int is_valid_gpt_buf(struct blk_desc *dev_desc, void *buf);
|
|||
*/
|
||||
int write_mbr_and_gpt_partitions(struct blk_desc *dev_desc, void *buf);
|
||||
|
||||
/**
|
||||
* write_backup_gpt_partitions - write MBR, backup gpt table.
|
||||
* @param dev_desc - block device descriptor
|
||||
* @param buf - buffer which contains the MBR and Primary GPT info
|
||||
*
|
||||
* @return - '0' on success, otherwise error
|
||||
*/
|
||||
int write_backup_gpt_partitions(struct blk_desc *dev_desc, void *buf);
|
||||
/**
|
||||
* gpt_verify_headers() - Function to read and CRC32 check of the GPT's header
|
||||
* and partition table entries (PTE)
|
||||
|
|
|
@ -0,0 +1,18 @@
|
|||
/*
|
||||
* Copyright (C) 2010-2016 Freescale Semiconductor, Inc. All Rights Reserved.
|
||||
* Copyright 2017 NXP
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
|
||||
#ifndef __RECOVERY_H_
|
||||
#define __RECOVERY_H_
|
||||
|
||||
struct reco_envs {
|
||||
char *cmd;
|
||||
char *args;
|
||||
};
|
||||
|
||||
void board_recovery_setup(void);
|
||||
|
||||
#endif
|
|
@ -31,6 +31,10 @@ CONFIG_AM335X_USB1_MODE
|
|||
CONFIG_AM437X_USB2PHY2_HOST
|
||||
CONFIG_ANDES_PCU
|
||||
CONFIG_ANDES_PCU_BASE
|
||||
CONFIG_ANDROID_AB_SUPPORT
|
||||
CONFIG_ANDROID_AUTO_SUPPORT
|
||||
CONFIG_ANDROID_SUPPORT
|
||||
CONFIG_ANDROID_THINGS_SUPPORT
|
||||
CONFIG_APER_0_BASE
|
||||
CONFIG_APER_1_BASE
|
||||
CONFIG_APER_SIZE
|
||||
|
@ -106,6 +110,10 @@ CONFIG_ATMEL_NAND_HW_PMECC
|
|||
CONFIG_ATMEL_SPI0
|
||||
CONFIG_AT_TRANS
|
||||
CONFIG_AUTO_ZRELADDR
|
||||
CONFIG_AVB_FUSE
|
||||
CONFIG_AVB_FUSE_BANK_END
|
||||
CONFIG_AVB_FUSE_BANK_SIZEW
|
||||
CONFIG_AVB_FUSE_BANK_START
|
||||
CONFIG_BACKSIDE_L2_CACHE
|
||||
CONFIG_BAT_PAIR
|
||||
CONFIG_BAT_RW
|
||||
|
@ -141,6 +149,8 @@ CONFIG_BOARD_TYPES
|
|||
CONFIG_BOOGER
|
||||
CONFIG_BOOTBLOCK
|
||||
CONFIG_BOOTFILE
|
||||
CONFIG_BOOTLOADER_OFFSET_32K
|
||||
CONFIG_BOOTLOADER_OFFSET_33K
|
||||
CONFIG_BOOTMAPSZ
|
||||
CONFIG_BOOTMODE
|
||||
CONFIG_BOOTM_LINUX
|
||||
|
@ -493,6 +503,7 @@ CONFIG_ELBC_NAND_SPL_STATIC_PGSIZE
|
|||
CONFIG_EMMC_BOOT
|
||||
CONFIG_EMU
|
||||
CONFIG_ENABLE_36BIT_PHYS
|
||||
CONFIG_ENABLE_LOCKSTATUS_SUPPORT
|
||||
CONFIG_ENABLE_MMU
|
||||
CONFIG_ENABLE_MUST_CHECK
|
||||
CONFIG_ENABLE_WARN_DEPRECATED
|
||||
|
@ -603,6 +614,7 @@ CONFIG_EXYNOS_TMU
|
|||
CONFIG_FACTORYSET
|
||||
CONFIG_FASTBOOT_FLASH_FILLBUF_SIZE
|
||||
CONFIG_FASTBOOT_FLASH_NAND_TRIMFFS
|
||||
CONFIG_FASTBOOT_LOCK
|
||||
CONFIG_FAST_FLASH_BIT
|
||||
CONFIG_FB_ADDR
|
||||
CONFIG_FB_BACKLIGHT
|
||||
|
@ -656,6 +668,7 @@ CONFIG_FPGA_COUNT
|
|||
CONFIG_FPGA_DELAY
|
||||
CONFIG_FPGA_STRATIX_V
|
||||
CONFIG_FSLDMAFEC
|
||||
CONFIG_FSL_CAAM_KB
|
||||
CONFIG_FSL_CADMUS
|
||||
CONFIG_FSL_CORENET
|
||||
CONFIG_FSL_CPLD
|
||||
|
@ -2089,6 +2102,7 @@ CONFIG_SXNI855T
|
|||
CONFIG_SYSFLAGS_ADDR
|
||||
CONFIG_SYSFS
|
||||
CONFIG_SYSMGR_ISWGRP_HANDOFF
|
||||
CONFIG_SYSTEM_RAMDISK_SUPPORT
|
||||
CONFIG_SYS_33MHZ
|
||||
CONFIG_SYS_64BIT
|
||||
CONFIG_SYS_64BIT_LBA
|
||||
|
|
Loading…
Reference in New Issue