1
0
Fork 0

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
Ye Li 2018-06-05 01:34:41 -07:00
parent 4ec81a0b07
commit 2c840c82b3
34 changed files with 4499 additions and 161 deletions

View File

@ -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);

View File

@ -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);

View File

@ -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.

View File

@ -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;
}
}
}

View File

@ -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)

View File

@ -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;

View File

@ -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;
}

View File

@ -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*/

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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) {

View File

@ -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

View File

@ -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"
);

View File

@ -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);

View File

@ -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,
};

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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
/*

View File

@ -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

View File

@ -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;
}

View File

@ -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

View File

@ -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

View File

@ -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;
}

View File

@ -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

View File

@ -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

View File

@ -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. */

View File

@ -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 */

View File

@ -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 */

View File

@ -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

View File

@ -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)

18
include/recovery.h 100644
View File

@ -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

View File

@ -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