Commit ff92794f05268eac978e9ab3e7d97a651819fe36

Authored by zhang sanshan
Committed by Chen Guoyin
1 parent 1c79796a52

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

Showing 5 changed files with 300 additions and 33 deletions Side-by-side Diff

board/technexion/pico-imx6ul/pico-imx6ul.c
... ... @@ -190,6 +190,16 @@
190 190 {USDHC1_BASE_ADDR},
191 191 };
192 192  
  193 +int board_mmc_get_env_dev(int devno)
  194 +{
  195 + return devno;
  196 +}
  197 +
  198 +int mmc_map_to_kernel_blk(int dev_no)
  199 +{
  200 + return dev_no;
  201 +}
  202 +
193 203 int board_mmc_getcd(struct mmc *mmc)
194 204 {
195 205 return 1;
common/image-android.c
... ... @@ -126,6 +126,19 @@
126 126 strcat(commandline, bootargs_sec);
127 127 }
128 128 #endif
  129 +#ifdef CONFIG_SYSTEM_RAMDISK_SUPPORT
  130 + /* Normal boot:
  131 + * cmdline to bypass ramdisk in boot.img, but use the system.img
  132 + * Recovery boot:
  133 + * Use the ramdisk in boot.img
  134 + */
  135 + char *bootargs_3rd = getenv("bootargs_3rd");
  136 + if (bootargs_3rd) {
  137 + strcat(commandline, " ");
  138 + strcat(commandline, bootargs_3rd);
  139 + }
  140 +#endif
  141 + printf("Kernel command line: %s\n", commandline);
129 142 setenv("bootargs", commandline);
130 143  
131 144 if (os_data) {
drivers/usb/gadget/bootctrl.c
... ... @@ -285,7 +285,6 @@
285 285 struct boot_ctl t_bootctl;
286 286 memset(&t_bootctl, 0, sizeof(t_bootctl));
287 287  
288   - /* these two var no need to read_bootctl */
289 288 if (!strcmp_l1("has-slot:", cmd)) {
290 289 char *ptnname = NULL;
291 290 ptnname = strchr(cmd, ':') + 1;
drivers/usb/gadget/f_fastboot.c
... ... @@ -100,6 +100,10 @@
100 100 static struct f_fastboot *fastboot_func;
101 101 static unsigned int download_size;
102 102 static unsigned int download_bytes;
  103 +#ifdef CONFIG_SYSTEM_RAMDISK_SUPPORT
  104 +static bool is_recovery_mode;
  105 +#endif
  106 +
103 107 static int strcmp_l1(const char *s1, const char *s2);
104 108  
105 109 static struct usb_endpoint_descriptor fs_ep_in = {
... ... @@ -1051,6 +1055,12 @@
1051 1055 printf("Writing '%s' DONE!\n", ptn->name);
1052 1056 fastboot_okay("");
1053 1057 }
  1058 + if (strncmp(ptn->name, "gpt", 3) == 0) {
  1059 + /* will force scan the device,
  1060 + so dev_desc can be re-inited
  1061 + with the latest data */
  1062 + run_command(mmc_dev, 0);
  1063 + }
1054 1064 }
1055 1065 }
1056 1066 } else {
1057 1067  
1058 1068  
1059 1069  
1060 1070  
... ... @@ -1060,14 +1070,87 @@
1060 1070  
1061 1071 #endif
1062 1072  
  1073 +#if defined(CONFIG_FASTBOOT_STORAGE_MMC)
  1074 +static void process_erase_mmc(const char *cmdbuf, char *response)
  1075 +{
  1076 + int mmc_no = 0;
  1077 + lbaint_t blks, blks_start, blks_size, grp_size;
  1078 + struct mmc *mmc;
  1079 + struct blk_desc *dev_desc;
  1080 + struct fastboot_ptentry *ptn;
  1081 + disk_partition_t info;
1063 1082  
1064   -static int rx_process_erase(const char *cmdbuf)
  1083 + ptn = fastboot_flash_find_ptn(cmdbuf);
  1084 + if ((ptn == NULL) || (ptn->flags & FASTBOOT_PTENTRY_FLAGS_UNERASEABLE)) {
  1085 + sprintf(response, "FAILpartition does not exist or uneraseable");
  1086 + return;
  1087 + }
  1088 +
  1089 + mmc_no = fastboot_devinfo.dev_id;
  1090 + printf("erase target is MMC:%d\n", mmc_no);
  1091 +
  1092 + mmc = find_mmc_device(mmc_no);
  1093 + if ((mmc == NULL) || mmc_init(mmc)) {
  1094 + printf("MMC card init failed!\n");
  1095 + return;
  1096 + }
  1097 +
  1098 + dev_desc = blk_get_dev("mmc", mmc_no);
  1099 + if (NULL == dev_desc) {
  1100 + printf("Block device MMC %d not supported\n",
  1101 + mmc_no);
  1102 + sprintf(response, "FAILnot valid MMC card");
  1103 + return;
  1104 + }
  1105 +
  1106 + if (part_get_info(dev_desc,
  1107 + ptn->partition_index, &info)) {
  1108 + printf("Bad partition index:%d for partition:%s\n",
  1109 + ptn->partition_index, ptn->name);
  1110 + sprintf(response, "FAILerasing of MMC card");
  1111 + return;
  1112 + }
  1113 +
  1114 + /* Align blocks to erase group size to avoid erasing other partitions */
  1115 + grp_size = mmc->erase_grp_size;
  1116 + blks_start = (info.start + grp_size - 1) & ~(grp_size - 1);
  1117 + if (info.size >= grp_size)
  1118 + blks_size = (info.size - (blks_start - info.start)) &
  1119 + (~(grp_size - 1));
  1120 + else
  1121 + blks_size = 0;
  1122 +
  1123 + printf("Erasing blocks " LBAFU " to " LBAFU " due to alignment\n",
  1124 + blks_start, blks_start + blks_size);
  1125 +
  1126 + blks = dev_desc->block_erase(dev_desc, blks_start, blks_size);
  1127 + if (blks != blks_size) {
  1128 + printf("failed erasing from device %d", dev_desc->devnum);
  1129 + sprintf(response, "FAILerasing of MMC card");
  1130 + return;
  1131 + }
  1132 +
  1133 + printf("........ erased " LBAFU " bytes from '%s'\n",
  1134 + blks_size * info.blksz, cmdbuf);
  1135 + sprintf(response, "OKAY");
  1136 +
  1137 + return;
  1138 +}
  1139 +#endif
  1140 +
  1141 +#if defined(CONFIG_FASTBOOT_STORAGE_SATA)
  1142 +static void process_erase_sata(const char *cmdbuf, char *response)
1065 1143 {
  1144 + return;
  1145 +}
  1146 +#endif
1066 1147 #if defined(CONFIG_FASTBOOT_STORAGE_NAND)
  1148 +static int process_erase_nand(const char *cmdbuf, char *response)
  1149 +{
1067 1150 struct fastboot_ptentry *ptn;
1068 1151  
1069 1152 ptn = fastboot_flash_find_ptn(cmdbuf);
1070   - if (ptn == 0) {
  1153 + if (ptn == NULL || (ptn->flags & FASTBOOT_PTENTRY_FLAGS_UNERASEABLE)) {
1071 1154 fastboot_fail("partition does not exist");
1072 1155 } else {
1073 1156 int status, repeat, repeat_max;
1074 1157  
... ... @@ -1117,12 +1200,35 @@
1117 1200 fastboot_okay("");
1118 1201 }
1119 1202 }
1120   - return 0;
1121   -#else
1122   - printf("Not support erase command for EMMC\n");
1123   - return -1;
  1203 + return;
  1204 +}
1124 1205 #endif
1125 1206  
  1207 +static void rx_process_erase(const char *cmdbuf, char *response)
  1208 +{
  1209 + switch (fastboot_devinfo.type) {
  1210 +#if defined(CONFIG_FASTBOOT_STORAGE_SATA)
  1211 + case DEV_SATA:
  1212 + process_erase_sata(cmdbuf, response);
  1213 + break;
  1214 +#endif
  1215 +#if defined(CONFIG_FASTBOOT_STORAGE_MMC)
  1216 + case DEV_MMC:
  1217 + process_erase_mmc(cmdbuf, response);
  1218 + break;
  1219 +#endif
  1220 +#if defined(CONFIG_FASTBOOT_STORAGE_NAND)
  1221 + case DEV_NAND:
  1222 + process_erase_nand(cmdbuf, response);
  1223 + break;
  1224 +#endif
  1225 + default:
  1226 + printf("Not support flash command for current device %d\n",
  1227 + fastboot_devinfo.type);
  1228 + sprintf(response,
  1229 + "FAILfailed to flash device");
  1230 + break;
  1231 + }
1126 1232 }
1127 1233  
1128 1234 static void rx_process_flash(const char *cmdbuf)
... ... @@ -1206,6 +1312,7 @@
1206 1312 int mmc_dos_partition_index,
1207 1313 int mmc_partition_index,
1208 1314 const char *name,
  1315 + const char *fstype,
1209 1316 struct blk_desc *dev_desc,
1210 1317 struct fastboot_ptentry *ptable)
1211 1318 {
1212 1319  
... ... @@ -1221,11 +1328,8 @@
1221 1328 ptable[ptable_index].length = info.size;
1222 1329 ptable[ptable_index].partition_id = mmc_partition_index;
1223 1330 ptable[ptable_index].partition_index = mmc_dos_partition_index;
1224   -#ifdef CONFIG_EFI_PARTITION
1225 1331 strcpy(ptable[ptable_index].name, (const char *)info.name);
1226   -#else
1227   - strcpy(ptable[ptable_index].name, name);
1228   -#endif
  1332 + strcpy(ptable[ptable_index].fstype, (const char *)info.type);
1229 1333  
1230 1334 #ifdef CONFIG_PARTITION_UUIDS
1231 1335 strcpy(ptable[ptable_index].uuid, (const char *)info.uuid);
... ... @@ -1300,6 +1404,7 @@
1300 1404 ptable[PTN_GPT_INDEX].start = ANDROID_GPT_OFFSET / dev_desc->blksz;
1301 1405 ptable[PTN_GPT_INDEX].length = ANDROID_GPT_SIZE / dev_desc->blksz;
1302 1406 ptable[PTN_GPT_INDEX].partition_id = user_partition;
  1407 + ptable[PTN_GPT_INDEX].flags = FASTBOOT_PTENTRY_FLAGS_UNERASEABLE;
1303 1408 /* Bootloader */
1304 1409 strcpy(ptable[PTN_BOOTLOADER_INDEX].name, FASTBOOT_PARTITION_BOOTLOADER);
1305 1410 ptable[PTN_BOOTLOADER_INDEX].start =
... ... @@ -1307,6 +1412,7 @@
1307 1412 ptable[PTN_BOOTLOADER_INDEX].length =
1308 1413 ANDROID_BOOTLOADER_SIZE / dev_desc->blksz;
1309 1414 ptable[PTN_BOOTLOADER_INDEX].partition_id = boot_partition;
  1415 + ptable[PTN_BOOTLOADER_INDEX].flags = FASTBOOT_PTENTRY_FLAGS_UNERASEABLE;
1310 1416  
1311 1417 int tbl_idx;
1312 1418 int part_idx = 1;
... ... @@ -1316,6 +1422,7 @@
1316 1422 part_idx++,
1317 1423 user_partition,
1318 1424 NULL,
  1425 + NULL,
1319 1426 dev_desc, ptable);
1320 1427 if (ret)
1321 1428 break;
... ... @@ -1674,7 +1781,7 @@
1674 1781 char serial[17];
1675 1782  
1676 1783 get_board_serial(&serialnr);
1677   - sprintf(serial, "%u%u", serialnr.high, serialnr.low);
  1784 + sprintf(serial, "%08x%08x", serialnr.high, serialnr.low);
1678 1785 g_dnl_set_serialnumber(serial);
1679 1786  
1680 1787 /*execute board relevant initilizations for preparing fastboot */
... ... @@ -1733,6 +1840,33 @@
1733 1840 return boot_mode;
1734 1841 }
1735 1842  
  1843 +#ifdef CONFIG_SYSTEM_RAMDISK_SUPPORT
  1844 +/* Setup booargs for taking the system parition as ramdisk */
  1845 +static void fastboot_setup_system_boot_args(const char *slot)
  1846 +{
  1847 + const char *system_part_name = NULL;
  1848 + if(slot == NULL)
  1849 + return;
  1850 + if(!strncmp(slot, "_a", strlen("_a")) || !strncmp(slot, "boot_a", strlen("boot_a"))) {
  1851 + system_part_name = FASTBOOT_PARTITION_SYSTEM_A;
  1852 + }
  1853 + else if(!strncmp(slot, "_b", strlen("_b")) || !strncmp(slot, "boot_b", strlen("boot_b"))) {
  1854 + system_part_name = FASTBOOT_PARTITION_SYSTEM_B;
  1855 + }
  1856 + struct fastboot_ptentry *ptentry = fastboot_flash_find_ptn(system_part_name);
  1857 + if(ptentry != NULL) {
  1858 + char bootargs_3rd[ANDR_BOOT_ARGS_SIZE];
  1859 +#if defined(CONFIG_FASTBOOT_STORAGE_MMC)
  1860 + u32 dev_no = mmc_map_to_kernel_blk(mmc_get_env_dev());
  1861 + sprintf(bootargs_3rd, "skip_initramfs root=/dev/mmcblk%dp%d",
  1862 + dev_no,
  1863 + ptentry->partition_index);
  1864 + setenv("bootargs_3rd", bootargs_3rd);
  1865 +#endif
  1866 + //TBD to support NAND ubifs system parition boot directly
  1867 + }
  1868 +}
  1869 +#endif
1736 1870 /* export to lib_arm/board.c */
1737 1871 void fastboot_run_bootmode(void)
1738 1872 {
... ... @@ -2012,6 +2146,11 @@
2012 2146 printf("no valid slot found, enter to recovery\n");
2013 2147 ptn = "recovery";
2014 2148 }
  2149 +#ifdef CONFIG_SYSTEM_RAMDISK_SUPPORT
  2150 + else {
  2151 + fastboot_setup_system_boot_args(ptn);
  2152 + }
  2153 +#endif
2015 2154 use_given_ptn:
2016 2155 printf("use slot %s\n", ptn);
2017 2156 }
... ... @@ -2587,6 +2726,40 @@
2587 2726 return false;
2588 2727 }
2589 2728  
  2729 +static char *get_serial(void)
  2730 +{
  2731 +#ifdef CONFIG_SERIAL_TAG
  2732 + struct tag_serialnr serialnr;
  2733 + static char serial[32];
  2734 + get_board_serial(&serialnr);
  2735 + sprintf(serial, "%08x%08x", serialnr.high, serialnr.low);
  2736 + return serial;
  2737 +#else
  2738 + return NULL;
  2739 +#endif
  2740 +}
  2741 +
  2742 +#if !defined(PRODUCT_NAME)
  2743 +#define PRODUCT_NAME "NXP i.MX"
  2744 +#endif
  2745 +
  2746 +#if !defined(VARIANT_NAME)
  2747 +#define VARIANT_NAME "NXP i.MX"
  2748 +#endif
  2749 +
  2750 +static int get_block_size(void) {
  2751 + int mmc_no = 0;
  2752 + struct blk_desc *dev_desc;
  2753 + mmc_no = fastboot_devinfo.dev_id;
  2754 + dev_desc = blk_get_dev("mmc", mmc_no);
  2755 + if (NULL == dev_desc) {
  2756 + printf("** Block device MMC %d not supported\n",
  2757 + mmc_no);
  2758 + return 0;
  2759 + }
  2760 + return dev_desc->blksz;
  2761 +}
  2762 +
2590 2763 static void cb_getvar(struct usb_ep *ep, struct usb_request *req)
2591 2764 {
2592 2765 char *cmd = req->buf;
2593 2766  
... ... @@ -2616,10 +2789,47 @@
2616 2789 strncat(response, FASTBOOT_VAR_NO, chars_left);
2617 2790 #endif
2618 2791 }
2619   - if (!strcmp_l1("version", cmd)) {
2620   - strncat(response, FASTBOOT_VERSION, chars_left);
2621   - } else if (!strcmp_l1("bootloader-version", cmd)) {
  2792 +
  2793 + char *str = cmd;
  2794 + if ((str = strstr(cmd, "partition-size:"))) {
  2795 + str +=strlen("partition-size:");
  2796 + struct fastboot_ptentry* fb_part;
  2797 + fb_part = fastboot_flash_find_ptn(str);
  2798 + if (!fb_part) {
  2799 + strncat(response, "Wrong partition name.", chars_left);
  2800 + goto fail;
  2801 + } else {
  2802 + char str_num[20];
  2803 + sprintf(str_num, "0x%016x", fb_part->length * get_block_size());
  2804 + strncat(response, str_num, chars_left);
  2805 + }
  2806 + } else if ((str = strstr(cmd, "partition-type:"))) {
  2807 + str +=strlen("partition-type:");
  2808 + struct fastboot_ptentry* fb_part;
  2809 + fb_part = fastboot_flash_find_ptn(str);
  2810 + if (!fb_part) {
  2811 + strncat(response, "Wrong partition name.", chars_left);
  2812 + goto fail;
  2813 + } else {
  2814 + strncat(response, fb_part->fstype, chars_left);
  2815 + }
  2816 + } else if (!strcmp_l1("all", cmd)) {
  2817 + /* FIXME need to return all vars here */
  2818 + } else if (!strcmp_l1("version-baseband", cmd)) {
  2819 + strncat(response, "N/A", chars_left);
  2820 + } else if (!strcmp_l1("version-bootloader", cmd) ||
  2821 + !strcmp_l1("bootloader-version", cmd)) {
2622 2822 strncat(response, U_BOOT_VERSION, chars_left);
  2823 + } else if (!strcmp_l1("version", cmd)) {
  2824 + strncat(response, FASTBOOT_VERSION, chars_left);
  2825 + } else if (!strcmp_l1("battery-voltage", cmd)) {
  2826 + strncat(response, "0mV", chars_left);
  2827 + } else if (!strcmp_l1("battery-soc-ok", cmd)) {
  2828 + strncat(response, "yes", chars_left);
  2829 + } else if (!strcmp_l1("variant", cmd)) {
  2830 + strncat(response, VARIANT_NAME, chars_left);
  2831 + } else if (!strcmp_l1("off-mode-charge", cmd)) {
  2832 + strncat(response, "1", chars_left);
2623 2833 } else if (!strcmp_l1("downloadsize", cmd) ||
2624 2834 !strcmp_l1("max-download-size", cmd)) {
2625 2835 char str_num[12];
2626 2836  
2627 2837  
... ... @@ -2627,13 +2837,15 @@
2627 2837 sprintf(str_num, "0x%08x", CONFIG_FASTBOOT_BUF_SIZE);
2628 2838 strncat(response, str_num, chars_left);
2629 2839 } else if (!strcmp_l1("serialno", cmd)) {
2630   - s = getenv("serial#");
  2840 + s = get_serial();
2631 2841 if (s)
2632 2842 strncat(response, s, chars_left);
2633   - else
2634   - strcpy(response, "FAILValue not set");
  2843 + else {
  2844 + strncat(response, "FAILValue not set", chars_left);
  2845 + goto fail;
  2846 + }
2635 2847 } else if (!strcmp_l1("product", cmd)) {
2636   - strncat(response, "Freescale i.MX", chars_left);
  2848 + strncat(response, PRODUCT_NAME, chars_left);
2637 2849 }
2638 2850 #ifdef CONFIG_FASTBOOT_LOCK
2639 2851 else if (!strcmp_l1("secure", cmd)) {
... ... @@ -2948,6 +3160,17 @@
2948 3160  
2949 3161 #endif
2950 3162  
  3163 +static int partition_table_valid(void)
  3164 +{
  3165 + int status, mmc_no;
  3166 + struct blk_desc *dev_desc;
  3167 + disk_partition_t info;
  3168 + mmc_no = fastboot_devinfo.dev_id;
  3169 + dev_desc = blk_get_dev("mmc", mmc_no);
  3170 + status = part_get_info(dev_desc, 1, &info);
  3171 + return (status == 0);
  3172 +}
  3173 +
2951 3174 #ifdef CONFIG_FASTBOOT_FLASH
2952 3175 static void cb_flash(struct usb_ep *ep, struct usb_request *req)
2953 3176 {
2954 3177  
... ... @@ -2985,11 +3208,26 @@
2985 3208 fastboot_fail("no flash device defined");
2986 3209  
2987 3210 #ifdef CONFIG_FSL_FASTBOOT
  3211 +#ifdef CONFIG_FASTBOOT_LOCK
  3212 + int gpt_valid_pre = 0;
  3213 + int gpt_valid_pst = 0;
  3214 + if (strncmp(cmd, "gpt", 3) == 0)
  3215 + gpt_valid_pre = partition_table_valid();
  3216 +#endif
2988 3217 rx_process_flash(cmd);
2989   -#else
2990   -#ifdef CONFIG_FASTBOOT_FLASH_MMC_DEV
2991   - fb_mmc_flash_write(cmd, (void *)CONFIG_FASTBOOT_BUF_ADDR,
2992   - download_bytes);
  3218 +#ifdef CONFIG_FASTBOOT_LOCK
  3219 + if (strncmp(cmd, "gpt", 3) == 0) {
  3220 + gpt_valid_pst = partition_table_valid();
  3221 + /* If gpt is valid, load partitons table into memory.
  3222 + So if the next command is "fastboot reboot bootloader",
  3223 + it can find the "misc" partition to r/w. */
  3224 + if(gpt_valid_pst)
  3225 + _fastboot_load_partitions();
  3226 + /* If gpt invalid -> valid, write unlock status, also wipe data. */
  3227 + if ((gpt_valid_pre == 0) && (gpt_valid_pst == 1))
  3228 + do_fastboot_unlock(true);
  3229 + }
  3230 +
2993 3231 #endif
2994 3232 #ifdef CONFIG_FASTBOOT_FLASH_NAND_DEV
2995 3233 fb_nand_flash_write(cmd,
2996 3234  
... ... @@ -3017,17 +3255,23 @@
3017 3255 /* initialize the response buffer */
3018 3256 fb_response_str = response;
3019 3257  
3020   - fastboot_fail("no flash device defined");
3021   -#ifdef CONFIG_FSL_FASTBOOT
3022   - rx_process_erase(cmd);
3023   -#else
3024   -#ifdef CONFIG_FASTBOOT_FLASH_MMC_DEV
3025   - fb_mmc_erase(cmd);
  3258 +#ifdef CONFIG_FASTBOOT_LOCK
  3259 + FbLockState status;
  3260 + status = fastboot_get_lock_stat();
  3261 + if (status == FASTBOOT_LOCK) {
  3262 + error("device is LOCKed!\n");
  3263 + strcpy(response, "FAIL device is locked.");
  3264 + fastboot_tx_write_str(response);
  3265 + return;
  3266 + } else if (status == FASTBOOT_LOCK_ERROR) {
  3267 + error("write lock status into device!\n");
  3268 + fastboot_set_lock_stat(FASTBOOT_LOCK);
  3269 + strcpy(response, "FAIL device is locked.");
  3270 + fastboot_tx_write_str(response);
  3271 + return;
  3272 + }
3026 3273 #endif
3027   -#ifdef CONFIG_FASTBOOT_FLASH_NAND_DEV
3028   - fb_nand_erase(cmd);
3029   -#endif
3030   -#endif
  3274 + rx_process_erase(cmd, response);
3031 3275 fastboot_tx_write_str(response);
3032 3276 }
3033 3277 #endif
... ... @@ -584,6 +584,7 @@
584 584 int cpu_mmc_init(bd_t *bis);
585 585 int mmc_get_env_addr(struct mmc *mmc, int copy, u32 *env_addr);
586 586 int mmc_get_env_dev(void);
  587 +int mmc_map_to_kernel_blk(int dev_no);
587 588  
588 589 struct pci_device_id;
589 590