Browse Source

MA-9409-2 fix some issue for android and android things

* Add CONFIG_SYSTEM_RAMDISK_SUPPORT to support system's ramdisk
* Normal boot: cmdline to bypass ramdisk in boot.img,
  but use Recovery boot: Use the ramdisk in boot.img
* commandline is larger than 512, system can't bootup sometime for commandline issue.
* support fastboot getvar.
* Support "fastboot erase" command for emmc device.
  TODO: uboot community have api to operate flash, we can unify this part
* support "fastboot flash" even on damaged gpt

Change-Id: I080c25d6569d6cab56ff025601cd3b8df21cf3dd
imx_v2017.03_4.9.11_1.0.0_ga
zhang sanshan 4 years ago
committed by Chen Guoyin
parent
commit
ff92794f05
5 changed files with 300 additions and 33 deletions
  1. +10
    -0
      board/technexion/pico-imx6ul/pico-imx6ul.c
  2. +13
    -0
      common/image-android.c
  3. +0
    -1
      drivers/usb/gadget/bootctrl.c
  4. +276
    -32
      drivers/usb/gadget/f_fastboot.c
  5. +1
    -0
      include/mmc.h

+ 10
- 0
board/technexion/pico-imx6ul/pico-imx6ul.c View File

@ -190,6 +190,16 @@ static struct fsl_esdhc_cfg usdhc_cfg[1] = {
{USDHC1_BASE_ADDR},
};
int board_mmc_get_env_dev(int devno)
{
return devno;
}
int mmc_map_to_kernel_blk(int dev_no)
{
return dev_no;
}
int board_mmc_getcd(struct mmc *mmc)
{
return 1;


+ 13
- 0
common/image-android.c View File

@ -126,6 +126,19 @@ int android_image_get_kernel(const struct andr_img_hdr *hdr, int verify,
strcat(commandline, bootargs_sec);
}
#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 = getenv("bootargs_3rd");
if (bootargs_3rd) {
strcat(commandline, " ");
strcat(commandline, bootargs_3rd);
}
#endif
printf("Kernel command line: %s\n", commandline);
setenv("bootargs", commandline);
if (os_data) {


+ 0
- 1
drivers/usb/gadget/bootctrl.c View File

@ -285,7 +285,6 @@ int get_slotvar(char *cmd, char *response, size_t chars_left)
struct boot_ctl t_bootctl;
memset(&t_bootctl, 0, sizeof(t_bootctl));
/* these two var no need to read_bootctl */
if (!strcmp_l1("has-slot:", cmd)) {
char *ptnname = NULL;
ptnname = strchr(cmd, ':') + 1;


+ 276
- 32
drivers/usb/gadget/f_fastboot.c View File

@ -100,6 +100,10 @@ static inline struct f_fastboot *func_to_fastboot(struct usb_function *f)
static struct f_fastboot *fastboot_func;
static unsigned int download_size;
static unsigned int download_bytes;
#ifdef CONFIG_SYSTEM_RAMDISK_SUPPORT
static bool is_recovery_mode;
#endif
static int strcmp_l1(const char *s1, const char *s2);
static struct usb_endpoint_descriptor fs_ep_in = {
@ -1051,6 +1055,12 @@ static void process_flash_mmc(const char *cmdbuf)
printf("Writing '%s' DONE!\n", ptn->name);
fastboot_okay("");
}
if (strncmp(ptn->name, "gpt", 3) == 0) {
/* will force scan the device,
so dev_desc can be re-inited
with the latest data */
run_command(mmc_dev, 0);
}
}
}
} else {
@ -1060,14 +1070,87 @@ static void process_flash_mmc(const char *cmdbuf)
#endif
#if defined(CONFIG_FASTBOOT_STORAGE_MMC)
static void process_erase_mmc(const char *cmdbuf, char *response)
{
int mmc_no = 0;
lbaint_t blks, blks_start, blks_size, grp_size;
struct mmc *mmc;
struct blk_desc *dev_desc;
struct fastboot_ptentry *ptn;
disk_partition_t info;
ptn = fastboot_flash_find_ptn(cmdbuf);
if ((ptn == NULL) || (ptn->flags & FASTBOOT_PTENTRY_FLAGS_UNERASEABLE)) {
sprintf(response, "FAILpartition does not exist or uneraseable");
return;
}
mmc_no = fastboot_devinfo.dev_id;
printf("erase target is MMC:%d\n", mmc_no);
mmc = find_mmc_device(mmc_no);
if ((mmc == NULL) || mmc_init(mmc)) {
printf("MMC card init failed!\n");
return;
}
dev_desc = blk_get_dev("mmc", mmc_no);
if (NULL == dev_desc) {
printf("Block device MMC %d not supported\n",
mmc_no);
sprintf(response, "FAILnot valid MMC card");
return;
}
if (part_get_info(dev_desc,
ptn->partition_index, &info)) {
printf("Bad partition index:%d for partition:%s\n",
ptn->partition_index, ptn->name);
sprintf(response, "FAILerasing of MMC card");
return;
}
/* Align blocks to erase group size to avoid erasing other partitions */
grp_size = mmc->erase_grp_size;
blks_start = (info.start + grp_size - 1) & ~(grp_size - 1);
if (info.size >= grp_size)
blks_size = (info.size - (blks_start - info.start)) &
(~(grp_size - 1));
else
blks_size = 0;
printf("Erasing blocks " LBAFU " to " LBAFU " due to alignment\n",
blks_start, blks_start + blks_size);
blks = dev_desc->block_erase(dev_desc, blks_start, blks_size);
if (blks != blks_size) {
printf("failed erasing from device %d", dev_desc->devnum);
sprintf(response, "FAILerasing of MMC card");
return;
}
printf("........ erased " LBAFU " bytes from '%s'\n",
blks_size * info.blksz, cmdbuf);
sprintf(response, "OKAY");
return;
}
#endif
static int rx_process_erase(const char *cmdbuf)
#if defined(CONFIG_FASTBOOT_STORAGE_SATA)
static void process_erase_sata(const char *cmdbuf, char *response)
{
return;
}
#endif
#if defined(CONFIG_FASTBOOT_STORAGE_NAND)
static int process_erase_nand(const char *cmdbuf, char *response)
{
struct fastboot_ptentry *ptn;
ptn = fastboot_flash_find_ptn(cmdbuf);
if (ptn == 0) {
if (ptn == NULL || (ptn->flags & FASTBOOT_PTENTRY_FLAGS_UNERASEABLE)) {
fastboot_fail("partition does not exist");
} else {
int status, repeat, repeat_max;
@ -1117,12 +1200,35 @@ static int rx_process_erase(const char *cmdbuf)
fastboot_okay("");
}
}
return 0;
#else
printf("Not support erase command for EMMC\n");
return -1;
return;
}
#endif
static void rx_process_erase(const char *cmdbuf, char *response)
{
switch (fastboot_devinfo.type) {
#if defined(CONFIG_FASTBOOT_STORAGE_SATA)
case DEV_SATA:
process_erase_sata(cmdbuf, response);
break;
#endif
#if defined(CONFIG_FASTBOOT_STORAGE_MMC)
case DEV_MMC:
process_erase_mmc(cmdbuf, response);
break;
#endif
#if defined(CONFIG_FASTBOOT_STORAGE_NAND)
case DEV_NAND:
process_erase_nand(cmdbuf, response);
break;
#endif
default:
printf("Not support flash command for current device %d\n",
fastboot_devinfo.type);
sprintf(response,
"FAILfailed to flash device");
break;
}
}
static void rx_process_flash(const char *cmdbuf)
@ -1206,6 +1312,7 @@ static int _fastboot_parts_add_ptable_entry(int ptable_index,
int mmc_dos_partition_index,
int mmc_partition_index,
const char *name,
const char *fstype,
struct blk_desc *dev_desc,
struct fastboot_ptentry *ptable)
{
@ -1221,11 +1328,8 @@ static int _fastboot_parts_add_ptable_entry(int ptable_index,
ptable[ptable_index].length = info.size;
ptable[ptable_index].partition_id = mmc_partition_index;
ptable[ptable_index].partition_index = mmc_dos_partition_index;
#ifdef CONFIG_EFI_PARTITION
strcpy(ptable[ptable_index].name, (const char *)info.name);
#else
strcpy(ptable[ptable_index].name, name);
#endif
strcpy(ptable[ptable_index].fstype, (const char *)info.type);
#ifdef CONFIG_PARTITION_UUIDS
strcpy(ptable[ptable_index].uuid, (const char *)info.uuid);
@ -1300,6 +1404,7 @@ static int _fastboot_parts_load_from_ptable(void)
ptable[PTN_GPT_INDEX].start = ANDROID_GPT_OFFSET / dev_desc->blksz;
ptable[PTN_GPT_INDEX].length = ANDROID_GPT_SIZE / dev_desc->blksz;
ptable[PTN_GPT_INDEX].partition_id = user_partition;
ptable[PTN_GPT_INDEX].flags = FASTBOOT_PTENTRY_FLAGS_UNERASEABLE;
/* Bootloader */
strcpy(ptable[PTN_BOOTLOADER_INDEX].name, FASTBOOT_PARTITION_BOOTLOADER);
ptable[PTN_BOOTLOADER_INDEX].start =
@ -1307,6 +1412,7 @@ static int _fastboot_parts_load_from_ptable(void)
ptable[PTN_BOOTLOADER_INDEX].length =
ANDROID_BOOTLOADER_SIZE / dev_desc->blksz;
ptable[PTN_BOOTLOADER_INDEX].partition_id = boot_partition;
ptable[PTN_BOOTLOADER_INDEX].flags = FASTBOOT_PTENTRY_FLAGS_UNERASEABLE;
int tbl_idx;
int part_idx = 1;
@ -1316,6 +1422,7 @@ static int _fastboot_parts_load_from_ptable(void)
part_idx++,
user_partition,
NULL,
NULL,
dev_desc, ptable);
if (ret)
break;
@ -1674,7 +1781,7 @@ void fastboot_setup(void)
char serial[17];
get_board_serial(&serialnr);
sprintf(serial, "%u%u", serialnr.high, serialnr.low);
sprintf(serial, "%08x%08x", serialnr.high, serialnr.low);
g_dnl_set_serialnumber(serial);
/*execute board relevant initilizations for preparing fastboot */
@ -1733,6 +1840,33 @@ static FbBootMode fastboot_get_bootmode(void)
return boot_mode;
}
#ifdef CONFIG_SYSTEM_RAMDISK_SUPPORT
/* Setup booargs for taking the system parition as ramdisk */
static void fastboot_setup_system_boot_args(const char *slot)
{
const char *system_part_name = NULL;
if(slot == NULL)
return;
if(!strncmp(slot, "_a", strlen("_a")) || !strncmp(slot, "boot_a", strlen("boot_a"))) {
system_part_name = FASTBOOT_PARTITION_SYSTEM_A;
}
else if(!strncmp(slot, "_b", strlen("_b")) || !strncmp(slot, "boot_b", strlen("boot_b"))) {
system_part_name = FASTBOOT_PARTITION_SYSTEM_B;
}
struct fastboot_ptentry *ptentry = fastboot_flash_find_ptn(system_part_name);
if(ptentry != NULL) {
char bootargs_3rd[ANDR_BOOT_ARGS_SIZE];
#if defined(CONFIG_FASTBOOT_STORAGE_MMC)
u32 dev_no = mmc_map_to_kernel_blk(mmc_get_env_dev());
sprintf(bootargs_3rd, "skip_initramfs root=/dev/mmcblk%dp%d",
dev_no,
ptentry->partition_index);
setenv("bootargs_3rd", bootargs_3rd);
#endif
//TBD to support NAND ubifs system parition boot directly
}
}
#endif
/* export to lib_arm/board.c */
void fastboot_run_bootmode(void)
{
@ -2012,6 +2146,11 @@ slot_select:
printf("no valid slot found, enter to recovery\n");
ptn = "recovery";
}
#ifdef CONFIG_SYSTEM_RAMDISK_SUPPORT
else {
fastboot_setup_system_boot_args(ptn);
}
#endif
use_given_ptn:
printf("use slot %s\n", ptn);
}
@ -2587,6 +2726,40 @@ bool is_slotvar(char *cmd)
return false;
}
static char *get_serial(void)
{
#ifdef CONFIG_SERIAL_TAG
struct tag_serialnr serialnr;
static char serial[32];
get_board_serial(&serialnr);
sprintf(serial, "%08x%08x", serialnr.high, serialnr.low);
return serial;
#else
return NULL;
#endif
}
#if !defined(PRODUCT_NAME)
#define PRODUCT_NAME "NXP i.MX"
#endif
#if !defined(VARIANT_NAME)
#define VARIANT_NAME "NXP i.MX"
#endif
static int get_block_size(void) {
int mmc_no = 0;
struct blk_desc *dev_desc;
mmc_no = fastboot_devinfo.dev_id;
dev_desc = blk_get_dev("mmc", mmc_no);
if (NULL == dev_desc) {
printf("** Block device MMC %d not supported\n",
mmc_no);
return 0;
}
return dev_desc->blksz;
}
static void cb_getvar(struct usb_ep *ep, struct usb_request *req)
{
char *cmd = req->buf;
@ -2616,10 +2789,47 @@ static void cb_getvar(struct usb_ep *ep, struct usb_request *req)
strncat(response, FASTBOOT_VAR_NO, chars_left);
#endif
}
if (!strcmp_l1("version", cmd)) {
strncat(response, FASTBOOT_VERSION, chars_left);
} else if (!strcmp_l1("bootloader-version", cmd)) {
char *str = cmd;
if ((str = strstr(cmd, "partition-size:"))) {
str +=strlen("partition-size:");
struct fastboot_ptentry* fb_part;
fb_part = fastboot_flash_find_ptn(str);
if (!fb_part) {
strncat(response, "Wrong partition name.", chars_left);
goto fail;
} else {
char str_num[20];
sprintf(str_num, "0x%016x", fb_part->length * get_block_size());
strncat(response, str_num, chars_left);
}
} else if ((str = strstr(cmd, "partition-type:"))) {
str +=strlen("partition-type:");
struct fastboot_ptentry* fb_part;
fb_part = fastboot_flash_find_ptn(str);
if (!fb_part) {
strncat(response, "Wrong partition name.", chars_left);
goto fail;
} else {
strncat(response, fb_part->fstype, chars_left);
}
} else if (!strcmp_l1("all", cmd)) {
/* FIXME need to return all vars here */
} else if (!strcmp_l1("version-baseband", cmd)) {
strncat(response, "N/A", chars_left);
} else if (!strcmp_l1("version-bootloader", cmd) ||
!strcmp_l1("bootloader-version", cmd)) {
strncat(response, U_BOOT_VERSION, chars_left);
} else if (!strcmp_l1("version", cmd)) {
strncat(response, FASTBOOT_VERSION, chars_left);
} else if (!strcmp_l1("battery-voltage", cmd)) {
strncat(response, "0mV", chars_left);
} else if (!strcmp_l1("battery-soc-ok", cmd)) {
strncat(response, "yes", chars_left);
} else if (!strcmp_l1("variant", cmd)) {
strncat(response, VARIANT_NAME, chars_left);
} else if (!strcmp_l1("off-mode-charge", cmd)) {
strncat(response, "1", chars_left);
} else if (!strcmp_l1("downloadsize", cmd) ||
!strcmp_l1("max-download-size", cmd)) {
char str_num[12];
@ -2627,13 +2837,15 @@ static void cb_getvar(struct usb_ep *ep, struct usb_request *req)
sprintf(str_num, "0x%08x", CONFIG_FASTBOOT_BUF_SIZE);
strncat(response, str_num, chars_left);
} else if (!strcmp_l1("serialno", cmd)) {
s = getenv("serial#");
s = get_serial();
if (s)
strncat(response, s, chars_left);
else
strcpy(response, "FAILValue not set");
else {
strncat(response, "FAILValue not set", chars_left);
goto fail;
}
} else if (!strcmp_l1("product", cmd)) {
strncat(response, "Freescale i.MX", chars_left);
strncat(response, PRODUCT_NAME, chars_left);
}
#ifdef CONFIG_FASTBOOT_LOCK
else if (!strcmp_l1("secure", cmd)) {
@ -2948,6 +3160,17 @@ static void cb_flashing(struct usb_ep *ep, struct usb_request *req)
#endif
static int partition_table_valid(void)
{
int status, mmc_no;
struct blk_desc *dev_desc;
disk_partition_t info;
mmc_no = fastboot_devinfo.dev_id;
dev_desc = blk_get_dev("mmc", mmc_no);
status = part_get_info(dev_desc, 1, &info);
return (status == 0);
}
#ifdef CONFIG_FASTBOOT_FLASH
static void cb_flash(struct usb_ep *ep, struct usb_request *req)
{
@ -2985,11 +3208,26 @@ static void cb_flash(struct usb_ep *ep, struct usb_request *req)
fastboot_fail("no flash device defined");
#ifdef CONFIG_FSL_FASTBOOT
#ifdef CONFIG_FASTBOOT_LOCK
int gpt_valid_pre = 0;
int gpt_valid_pst = 0;
if (strncmp(cmd, "gpt", 3) == 0)
gpt_valid_pre = partition_table_valid();
#endif
rx_process_flash(cmd);
#else
#ifdef CONFIG_FASTBOOT_FLASH_MMC_DEV
fb_mmc_flash_write(cmd, (void *)CONFIG_FASTBOOT_BUF_ADDR,
download_bytes);
#ifdef CONFIG_FASTBOOT_LOCK
if (strncmp(cmd, "gpt", 3) == 0) {
gpt_valid_pst = partition_table_valid();
/* If gpt is valid, load partitons table into memory.
So if the next command is "fastboot reboot bootloader",
it can find the "misc" partition to r/w. */
if(gpt_valid_pst)
_fastboot_load_partitions();
/* If gpt invalid -> valid, write unlock status, also wipe data. */
if ((gpt_valid_pre == 0) && (gpt_valid_pst == 1))
do_fastboot_unlock(true);
}
#endif
#ifdef CONFIG_FASTBOOT_FLASH_NAND_DEV
fb_nand_flash_write(cmd,
@ -3017,17 +3255,23 @@ static void cb_erase(struct usb_ep *ep, struct usb_request *req)
/* initialize the response buffer */
fb_response_str = response;
fastboot_fail("no flash device defined");
#ifdef CONFIG_FSL_FASTBOOT
rx_process_erase(cmd);
#else
#ifdef CONFIG_FASTBOOT_FLASH_MMC_DEV
fb_mmc_erase(cmd);
#endif
#ifdef CONFIG_FASTBOOT_FLASH_NAND_DEV
fb_nand_erase(cmd);
#endif
#ifdef CONFIG_FASTBOOT_LOCK
FbLockState status;
status = fastboot_get_lock_stat();
if (status == FASTBOOT_LOCK) {
error("device is LOCKed!\n");
strcpy(response, "FAIL device is locked.");
fastboot_tx_write_str(response);
return;
} else if (status == FASTBOOT_LOCK_ERROR) {
error("write lock status into device!\n");
fastboot_set_lock_stat(FASTBOOT_LOCK);
strcpy(response, "FAIL device is locked.");
fastboot_tx_write_str(response);
return;
}
#endif
rx_process_erase(cmd, response);
fastboot_tx_write_str(response);
}
#endif


+ 1
- 0
include/mmc.h View File

@ -584,6 +584,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);
struct pci_device_id;


Loading…
Cancel
Save