MA-9409-2 fix some issue for android and android things
authorzhang sanshan <sanshan.zhang@nxp.com>
Mon, 22 May 2017 06:08:14 +0000 (14:08 +0800)
committerJason Liu <jason.hui.liu@nxp.com>
Thu, 2 Nov 2017 18:36:57 +0000 (02:36 +0800)
* 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

board/technexion/pico-imx6ul/pico-imx6ul.c
common/image-android.c
drivers/usb/gadget/bootctrl.c
drivers/usb/gadget/f_fastboot.c
include/mmc.h

index 9bffd93..ec0d9c0 100644 (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;
index 2101504..05fea0b 100644 (file)
@@ -136,6 +136,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) {
index 8e0b999..f736074 100644 (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;
index 10b4fb4..82cd4ae 100644 (file)
@@ -101,6 +101,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 = {
@@ -1052,6 +1056,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 {
@@ -1061,14 +1071,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;
@@ -1118,12 +1201,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)
@@ -1207,6 +1313,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)
 {
@@ -1222,11 +1329,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);
@@ -1301,6 +1405,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 =
@@ -1308,6 +1413,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;
@@ -1317,6 +1423,7 @@ static int _fastboot_parts_load_from_ptable(void)
                                part_idx++,
                                user_partition,
                                NULL,
+                               NULL,
                                dev_desc, ptable);
                if (ret)
                        break;
@@ -1708,7 +1815,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 */
@@ -1767,6 +1874,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)
 {
@@ -2046,6 +2180,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);
        }
@@ -2621,6 +2760,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;
@@ -2650,10 +2823,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];
@@ -2661,13 +2871,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)) {
@@ -2982,6 +3194,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)
 {
@@ -3019,11 +3242,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,
@@ -3051,17 +3289,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
index fad12d6..f5ed9da 100644 (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;