summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorcharles.park <charles.park@hardkernel.com>2017-08-03 06:36:39 +0300
committercharles.park <charles.park@hardkernel.com>2017-08-03 06:36:39 +0300
commit1ee342a005ba216d10d3da35b74c0d9798b024b3 (patch)
tree63c07a2baba7a973ea386b3c2e314c8da82210cc
parentff2835dac9b2fde047d9db59458d496a98b4a635 (diff)
downloadu-boot-1ee342a005ba216d10d3da35b74c0d9798b024b3.tar.xz
ODROID-XU4 : fastboot function add for android.
Change-Id: I49707609740f971e93d2c049aa6f91f386428f99
-rwxr-xr-xboard/samsung/common/odroid_misc.c173
-rwxr-xr-x[-rw-r--r--]cmd/Makefile5
-rwxr-xr-xcmd/mmc.c78
-rwxr-xr-xcmd/odroid_fastboot.c514
-rwxr-xr-xfs/fat/fat.c5
-rwxr-xr-xinclude/configs/odroid_xu4.h76
-rwxr-xr-xinclude/fastboot.h159
-rwxr-xr-xinclude/samsung/odroid_misc.h23
8 files changed, 877 insertions, 156 deletions
diff --git a/board/samsung/common/odroid_misc.c b/board/samsung/common/odroid_misc.c
index e648328a53..171f59f8db 100755
--- a/board/samsung/common/odroid_misc.c
+++ b/board/samsung/common/odroid_misc.c
@@ -54,6 +54,142 @@ DECLARE_GLOBAL_DATA_PTR;
#define ODROID_MISC_DEBUG
*/
+/*
+ Default Partition Info for Android system
+*/
+static struct partition_info gPartInfo[PART_MAX] = {
+ [PART_FWBL1] = {
+ .name = "fwbl1",
+ .blk_start = PART_BL1_ST_BLK,
+ .size = PART_SIZE_BL1,
+ .raw_en = 1,
+ },
+ [PART_BL2] = {
+ .name = "bl2",
+ .blk_start = PART_BL2_ST_BLK,
+ .size = PART_SIZE_BL2,
+ .raw_en = 1,
+ },
+ [PART_BOOTLOADER] = {
+ .name = "bootloader",
+ .blk_start = PART_UBOOT_ST_BLK,
+ .size = PART_SIZE_UBOOT,
+ .raw_en = 1,
+ },
+ [PART_TZSW] = {
+ .name = "tzsw",
+ .blk_start = PART_TZSW_ST_BLK,
+ .size = PART_SIZE_TZSW,
+ .raw_en = 1,
+ },
+ [PART_ENV] = {
+ .name = "env",
+ .blk_start = PART_ENV_ST_BLK,
+ .size = PART_SIZE_ENV,
+ .raw_en = 0,
+ },
+ [PART_KERENEL] = {
+ .name = "kernel",
+ .blk_start = PART_KERNEL_ST_BLK,
+ .size = PART_SIZE_KERNEL,
+ .raw_en = 0,
+ },
+ [PART_SYSTEM] = {
+ .name = "system",
+ .blk_start = 0,
+ .size = 0,
+ .raw_en = 0,
+ },
+ [PART_USERDATA] = {
+ .name = "userdata",
+ .blk_start = 0,
+ .size = 0,
+ .raw_en = 0,
+ },
+ [PART_CACHE] = {
+ .name = "cache",
+ .blk_start = 0,
+ .size = 0,
+ .raw_en = 0,
+ },
+};
+
+/*---------------------------------------------------------------------------*/
+/* from cmd/mmc.c */
+extern int get_mmc_part_info(char *device_name, int part_num, uint *block_start,
+ uint *block_count, uchar *part_Id);
+
+/*---------------------------------------------------------------------------*/
+static void odroid_print_part_info(char *dev_no)
+{
+ int i;
+
+ printf("\n*** Partition Information for Andorid ***");
+ printf("\nControl Device ID : %s", dev_no);
+ printf("\npNo\tStart Block\tpSize(bytes)\tpName");
+ for (i = 0; i < PART_MAX; i++) {
+ printf("\n %d \t0x%08x\t0x%08x\t%s",
+ i,
+ gPartInfo[i].blk_start,
+ gPartInfo[i].size,
+ gPartInfo[i].name);
+ }
+ printf("\n\n");
+}
+
+/*---------------------------------------------------------------------------*/
+int odroid_get_partition_info(const char *ptn, struct partition_info *pinfo)
+{
+ int i;
+
+ for (i = 0; i < PART_MAX; i++) {
+ if (!strncmp(gPartInfo[i].name, ptn, strlen(ptn)))
+ break;
+ }
+ if (PART_MAX == i)
+ return -1;
+
+ memcpy((void *)pinfo, (void *)&gPartInfo[i],
+ sizeof(struct partition_info));
+ return 0;
+}
+
+/*---------------------------------------------------------------------------*/
+/*
+ Partition information setup for Android fastboot.
+
+ Partition 1 = fat partition
+ Partition 2 - system partition
+ Partition 3 - userdata partition
+ Partition 4 - cache partition
+*/
+/*---------------------------------------------------------------------------*/
+int odroid_partition_setup(char *dev_no)
+{
+ unsigned int blk_st, blk_cnt;
+ unsigned char pid, i;
+
+ for (i = 0; i < 3; i++) {
+ if (get_mmc_part_info (dev_no, i + 2, &blk_st, &blk_cnt, &pid))
+ goto err;
+ if (pid != 0x83)
+ goto err;
+ gPartInfo[PART_SYSTEM+i].blk_start = blk_st;
+ gPartInfo[PART_SYSTEM+i].size = (blk_cnt * MOVI_BLK_SIZE);
+ }
+
+ odroid_print_part_info(dev_no);
+ return 0;
+err:
+ printf( "\n****************************\n" \
+ "\n*** Warning!!! ***\n" \
+ "\n****************************\n" \
+ "\This is not an Android Partition device!" \
+ "\nIf you want Android partitioning," \
+ "use fdisk command befor fastboot command.\n\n");
+ return -1;
+}
+
/*---------------------------------------------------------------------------*/
void odroid_led_ctrl(int gpio, int status)
{
@@ -177,6 +313,40 @@ err:
}
/*---------------------------------------------------------------------------*/
+/* firmware update check */
+static void odroid_fw_update(unsigned int option)
+{
+}
+
+/*---------------------------------------------------------------------------*/
+static void odroid_magic_cmd_check(void)
+{
+ struct exynos5_power *pmu =
+ (struct exynos5_power *)samsung_get_base_power();
+
+ unsigned int cmd, option;
+
+ cmd = (pmu->sysip_dat0 & 0xFFFF);
+ option = (pmu->inform0 & 0xFFFF);
+
+#if defined(ODROID_MISC_DEBUG)
+ printf("pmu->sysip = 0x%08x, pmu->inform0 = 0x%08x\n",
+ cmd, option);
+#endif
+ pmu->sysip_dat0 = 0; pmu->inform0 = 0;
+
+ switch(cmd) {
+ case FASTBOOT_MAGIC_REBOOT_CMD:
+ run_command("fastboot", 0);
+ break;
+ case FASTBOOT_MAGIC_UPDATE_CMD:
+ odroid_fw_update(option);
+ run_command("reset", 0);
+ break;
+ }
+}
+
+/*---------------------------------------------------------------------------*/
/*
ODROID XU3/XU3-Lite/XU4 Hardware Init.
call from board/samsung/common/board.c
@@ -188,6 +358,9 @@ void odroid_misc_init(void)
odroid_pmic_init();
odroid_gpio_init();
odroid_led_init();
+
+ /* check Android Image update or fastboot Magic command */
+ odroid_magic_cmd_check();
}
/*---------------------------------------------------------------------------*/
diff --git a/cmd/Makefile b/cmd/Makefile
index 7dfd523063..120a604246 100644..100755
--- a/cmd/Makefile
+++ b/cmd/Makefile
@@ -134,7 +134,12 @@ obj-$(CONFIG_CMD_LZMADEC) += lzmadec.o
endif
obj-$(CONFIG_CMD_USB) += usb.o disk.o
+ifdef CONFIG_TARGET_ODROID_XU4
+obj-$(CONFIG_CMD_FASTBOOT) += odroid_fastboot.o
+else
obj-$(CONFIG_CMD_FASTBOOT) += fastboot.o
+endif
+
obj-$(CONFIG_CMD_FS_UUID) += fs_uuid.o
obj-$(CONFIG_CMD_USB_MASS_STORAGE) += usb_mass_storage.o
diff --git a/cmd/mmc.c b/cmd/mmc.c
index 03e5d51398..ac6bb702ad 100755
--- a/cmd/mmc.c
+++ b/cmd/mmc.c
@@ -1237,7 +1237,7 @@ static int put_mmc_mbr(uchar *mbr, char *device_name)
return -1;
}
-static int get_mmc_part_info(char *device_name, int part_num,
+int get_mmc_part_info(char *device_name, int part_num,
uint *block_start, uint *block_count, uchar *part_Id)
{
int rv;
@@ -1403,4 +1403,80 @@ U_BOOT_CMD(
"MMC size writes to env variable mmc_size_gb [1, 2, 4, 8, 16, 32, 64, 128]\n"
);
+#include <samsung/odroid_misc.h>
+
+static int get_partition_info(const char *ptn, struct partition_info *pinfo)
+{
+ switch(ptn[0]) {
+ case 'f':
+ return odroid_get_partition_info("fwbl1", pinfo);
+ case 'b':
+ return odroid_get_partition_info("bl2", pinfo);
+ case 'u':
+ return odroid_get_partition_info("bootloader", pinfo);
+ case 't':
+ return odroid_get_partition_info("tzsw", pinfo);
+ case 'k':
+ return odroid_get_partition_info("kernel", pinfo);
+ default:
+ break;
+ }
+ return -1;
+}
+
+static int do_movi(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
+{
+ unsigned int dev_num, ret = -1, addr, offset = 0;
+ char cmd[64] = {0, };
+ struct partition_info pinfo;
+
+ switch(argc) {
+ case 3:
+ if ('i' == argv[1][0]) {
+ dev_num = simple_strtoul(argv[2], NULL, 10);
+ if (dev_num)
+ ret = run_command("mmc dev 1", 0);
+ if (!ret)
+ run_command("mmc info", 0);
+ if (dev_num && !ret)
+ run_command("mmc dev 0", 0);
+
+ return ret ? CMD_RET_FAILURE:CMD_RET_SUCCESS;
+ }
+ break;
+ case 5:
+ dev_num = simple_strtoul(argv[3], NULL, 10);
+ addr = simple_strtoul(argv[4], NULL, 10);
+ ret = get_partition_info(argv[2], &pinfo);
+ break;
+ case 6:
+ dev_num = simple_strtoul(argv[4], NULL, 10);
+ addr = simple_strtoul(argv[5], NULL, 10);
+ ret = get_partition_info(argv[3], &pinfo);
+ if ((argv[2][0] == 'z') && pinfo.raw_en)
+ offset = 1;
+ break;
+ default :
+ break;
+ }
+ if (!ret) {
+ sprintf(cmd, "mmc %s %d %x %x",
+ (argv[1][0] == 'w') ? "write" : "read",
+ addr,
+ pinfo.blk_start - offset,
+ pinfo.size / MOVI_BLK_SIZE);
+ run_command(cmd, 0);
+ return CMD_RET_SUCCESS;
+ }
+usage:
+ return CMD_RET_USAGE;
+}
+
+U_BOOT_CMD(
+ movi, 7, 0, do_movi,
+ "movi emmc/sd r/w command",
+ "{read|write} [zero] {fwbl1|bl2|u-boot|tzsw|kernel} {dev no} {addr}\n"
+ "[zero] - flag for emmc raw partition"
+);
+
#endif
diff --git a/cmd/odroid_fastboot.c b/cmd/odroid_fastboot.c
new file mode 100755
index 0000000000..5b5255d3c0
--- /dev/null
+++ b/cmd/odroid_fastboot.c
@@ -0,0 +1,514 @@
+/*
+ * Copyright 2008 - 2009 Windriver, <www.windriver.com>
+ * Author: Tom Rix <Tom.Rix@windriver.com>
+ *
+ * (C) Copyright 2014 Linaro, Ltd.
+ * Rob Herring <robh@kernel.org>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+#include <common.h>
+#include <command.h>
+#include <console.h>
+#include <malloc.h>
+
+#include <mach/power.h>
+#include <fastboot.h>
+#include <samsung/odroid_misc.h>
+#include <mmc.h>
+
+static unsigned int download_size;
+static unsigned int download_bytes;
+static unsigned int download_error;
+static int rx_handler (const unsigned char *buffer, unsigned int buffer_size);
+static struct cmd_fastboot_interface interface =
+{
+ .rx_handler = rx_handler,
+ .reset_handler = NULL,
+ .product_name = NULL,
+ .serial_no = NULL,
+ .nand_block_size = 0,
+ .transfer_buffer = (unsigned char *)0xffffffff,
+ .transfer_buffer_size = 0,
+};
+
+static int flashing_raw_data(struct partition_info *pinfo,
+ unsigned int addr, unsigned int size, unsigned int dev_no)
+{
+ struct mmc *mmc;
+ char cmd[64] = { 0, };
+ unsigned int blk_start = pinfo->blk_start;
+ unsigned int blk_cnt = size / MOVI_BLK_SIZE;
+
+ mmc = find_mmc_device(dev_no);
+
+ if (!IS_SD(mmc) && pinfo->raw_en) {
+ memset(cmd, 0x00, sizeof(cmd));
+ sprintf(cmd, "emmc open %d", dev_no);
+ run_command(cmd, 0);
+ blk_start = pinfo->blk_start -1;
+ }
+ memset(cmd, 0x00, sizeof(cmd));
+ sprintf(cmd, "mmc write %x %x %x",
+ (unsigned int)addr, blk_start, blk_cnt);
+ run_command(cmd, 0);
+ printf("%s : %s\n", __func__, cmd);
+
+ if (!IS_SD(mmc) && pinfo->raw_en) {
+ memset(cmd, 0x00, sizeof(cmd));
+ sprintf(cmd, "emmc close %d", dev_no);
+ run_command(cmd, 0);
+ }
+ return 0;
+}
+
+static void erase_partition(struct partition_info *pinfo, unsigned int dev_no)
+{
+ #define BLOCK_ERASE_SIZE (512 * 1024)
+
+ unsigned int blk_start = pinfo->blk_start;
+ unsigned int blk_cnt = pinfo->size / MOVI_BLK_SIZE;
+ struct mmc *mmc;
+ unsigned char *clrbuf =
+ (unsigned char *)calloc(sizeof(char), BLOCK_ERASE_SIZE);
+
+ printf("Erasing partition(%s)... blk_st = 0x%08x, blk_cnt = 0x%08x\n",
+ pinfo->name, blk_start, blk_cnt);
+
+ mmc = find_mmc_device(dev_no);
+
+ if (blk_start & 0x3FF) {
+ mmc->block_dev.block_write(&mmc->block_dev,
+ blk_start,
+ 1024 - (blk_start & 0x3ff),
+ clrbuf);
+ printf("*** erase start block 0x%x ***\n", blk_start);
+ }
+ if (blk_cnt & 0x3FF) {
+ mmc->block_dev.block_write(&mmc->block_dev,
+ blk_start + blk_cnt - (blk_cnt & 0x3FF),
+ (blk_cnt & 0x3FF),
+ clrbuf);
+ printf("*** erase block length 0x%x ***\n", blk_cnt);
+ }
+ if (blk_cnt >> 10) {
+ mmc->block_dev.block_erase(&mmc->block_dev, blk_start, blk_cnt);
+ printf("*** erase block start 0x%x, cnt 0x%x ***\n", blk_start, blk_cnt);
+ }
+
+ free(clrbuf);
+}
+
+static int check_compress_ext4(char *img_base, unsigned long long parti_size) {
+ ext4_file_header *file_header;
+
+ file_header = (ext4_file_header*)img_base;
+
+ if (file_header->magic != EXT4_FILE_HEADER_MAGIC) {
+ return -1;
+ }
+
+ if (file_header->major != EXT4_FILE_HEADER_MAJOR) {
+ printf("Invalid Version Info! 0x%2x\n", file_header->major);
+ return -1;
+ }
+
+ if (file_header->file_header_size != EXT4_FILE_HEADER_SIZE) {
+ printf("Invalid File Header Size! 0x%8x\n",
+ file_header->file_header_size);
+ return -1;
+ }
+
+ if (file_header->chunk_header_size != EXT4_CHUNK_HEADER_SIZE) {
+ printf("Invalid Chunk Header Size! 0x%8x\n",
+ file_header->chunk_header_size);
+ return -1;
+ }
+
+ if (file_header->block_size != EXT4_FILE_BLOCK_SIZE) {
+ printf("Invalid Block Size! 0x%8x\n", file_header->block_size);
+ return -1;
+ }
+
+ if ((parti_size/file_header->block_size) < file_header->total_blocks) {
+ printf("Invalid Volume Size! Image is bigger than partition size!\n");
+ printf("partion size %lld , image size %d \n",
+ (parti_size/file_header->block_size), file_header->total_blocks);
+ while(1);
+ }
+
+ /* image is compressed ext4 */
+ return 0;
+}
+
+static int write_compressed_ext4(char* img_base, unsigned int sector_base,
+ unsigned int dev_no)
+{
+ #define SECTOR_BITS 9 /* 512B */
+
+ unsigned int sector_size;
+ int total_chunks;
+ ext4_chunk_header *chunk_header;
+ ext4_file_header *file_header;
+ struct mmc *mmc;
+
+ mmc = find_mmc_device(dev_no);
+
+ file_header = (ext4_file_header*)img_base;
+ total_chunks = file_header->total_chunks;
+
+ printf("%s : total chunk = %d \n", __func__, total_chunks);
+
+ img_base += EXT4_FILE_HEADER_SIZE;
+
+ odroid_led_ctrl (GPIO_LED_G, 1);
+ while(total_chunks) {
+ chunk_header = (ext4_chunk_header*)img_base;
+ sector_size =
+ (chunk_header->chunk_size *
+ file_header->block_size) >> SECTOR_BITS;
+
+ switch(chunk_header->type)
+ {
+ case EXT4_CHUNK_TYPE_RAW:
+ mmc->block_dev.block_write(&mmc->block_dev,
+ sector_base,
+ sector_size,
+ (const void *)(img_base + EXT4_CHUNK_HEADER_SIZE));
+ sector_base += sector_size;
+ break;
+
+ case EXT4_CHUNK_TYPE_FILL:
+ printf("*** fill_chunk ***\n");
+ sector_base += sector_size;
+ break;
+
+ case EXT4_CHUNK_TYPE_NONE:
+ printf("none chunk \n");
+ sector_base += sector_size;
+ break;
+
+ default:
+ printf("*** unknown chunk type ***\n");
+ sector_base += sector_size;
+ break;
+ }
+ total_chunks--;
+ printf("mmc write blk = 0x%08x, size = 0x%08x, remain chunks = %d\n",
+ sector_base,
+ sector_size,
+ total_chunks);
+
+ img_base += chunk_header->total_size;
+ };
+
+ odroid_led_ctrl (GPIO_LED_G, 0);
+ printf("write done \n");
+ return 0;
+}
+
+static int flashing_data(struct partition_info *pinfo,
+ unsigned int addr, unsigned int size, unsigned int dev_no)
+{
+ if (check_compress_ext4((char *)addr, pinfo->size))
+ flashing_raw_data(pinfo, addr, size, dev_no);
+ else {
+ erase_partition(pinfo, dev_no);
+ write_compressed_ext4((char*)addr, pinfo->blk_start, dev_no);
+ }
+
+ run_command("mmc dev 0", 0);
+ return 0;
+}
+
+static int rx_handler (const unsigned char *buffer, unsigned int buffer_size)
+{
+ int ret = 1;
+
+ /* Use 65 instead of 64
+ null gets dropped
+ strcpy's need the extra byte */
+ char response[65];
+
+ if (download_size) {
+ /* Something to download */
+
+ if (buffer_size) {
+ /* Handle possible overflow */
+ unsigned int transfer_size = download_size - download_bytes;
+
+ if (buffer_size < transfer_size)
+ transfer_size = buffer_size;
+
+ /* Save the data to the transfer buffer */
+ memcpy (interface.transfer_buffer + download_bytes,
+ buffer, transfer_size);
+
+ download_bytes += transfer_size;
+
+ /* Check if transfer is done */
+ if (download_bytes >= download_size) {
+ /* Reset global transfer variable,
+ Keep download_bytes because it will be
+ used in the next possible flashing command */
+ download_size = 0;
+
+ if (download_error) {
+ /* There was an earlier error */
+ sprintf(response, "ERROR");
+ } else {
+ /* Everything has transferred,
+ send the OK response */
+ sprintf(response, "OKAY");
+ }
+ fastboot_tx_status(response, strlen(response), FASTBOOT_TX_ASYNC);
+
+ printf("\ndownloading of %d bytes finished\n", download_bytes);
+ }
+
+ /* Provide some feedback */
+ if (download_bytes && download_size &&
+ 0 == (download_bytes & (0x100000 - 1))) {
+ /* Some feeback that the download is happening */
+ if (download_error)
+ printf("X");
+ else
+ printf(".");
+ if (0 == (download_bytes %
+ (80 * 0x100000)))
+ printf("\n");
+ }
+ } else {
+ /* Ignore empty buffers */
+ printf("Warning empty download buffer\n");
+ printf("Ignoring\n");
+ }
+ ret = 0;
+ } else {
+ /* A command */
+
+ /* Cast to make compiler happy with string functions */
+ const char *cmdbuf = (char *) buffer;
+
+ /* Generic failed response */
+ sprintf(response, "FAIL");
+
+ /* reboot
+ Reboot the board. */
+ if (memcmp(cmdbuf, "reboot", 6) == 0) {
+ if (!strcmp(cmdbuf + 6, "-bootloader")) {
+ struct exynos5_power *pmu =
+ (struct exynos5_power *)samsung_get_base_power();
+ pmu->sysip_dat0 = FASTBOOT_MAGIC_REBOOT_CMD;
+ printf("reboot-bootloader (reboot fastboot)\n");
+ } else {
+ memset(interface.transfer_buffer, 0x0, FASTBOOT_REBOOT_MAGIC_SIZE);
+ }
+
+ sprintf(response,"OKAY");
+ fastboot_tx_status(response, strlen(response), FASTBOOT_TX_SYNC);
+
+ do_reset (NULL, 0, 0, NULL);
+
+ /* This code is unreachable,
+ leave it to make the compiler happy */
+ return 0;
+ }
+
+ /* getvar
+ Get common fastboot variables
+ Board has a chance to handle other variables */
+ if (memcmp(cmdbuf, "getvar:", 7) == 0)
+ {
+ strcpy(response,"OKAY");
+
+ if (!strcmp(cmdbuf + 7, "version")) {
+ strcpy(response + 4, FASTBOOT_VERSION);
+ } else if (!strcmp(cmdbuf + 7, "product")) {
+ if (interface.product_name)
+ strcpy(response + 4, interface.product_name);
+ } else if (!strcmp(cmdbuf + 7, "serialno")) {
+ if (interface.serial_no)
+ strcpy(response + 4, interface.serial_no);
+ } else if (!strcmp(cmdbuf + 7, "downloadsize")) {
+ if (interface.transfer_buffer_size)
+ sprintf(response + 4, "%08x", interface.transfer_buffer_size);
+ } else {
+ fastboot_getvar(cmdbuf + 7, response + 4);
+ }
+ ret = 0;
+ goto send_tx_status;
+ }
+
+ /* erase
+ Erase a register flash partition
+ Board has to set up flash partitions */
+ if (memcmp(cmdbuf, "erase:", 6) == 0)
+ {
+ struct partition_info pinfo;
+ printf("partition '%s' erased\n", cmdbuf + 6);
+
+ if (!strncmp(cmdbuf + 6, "fat", sizeof("fat"))) {
+ run_command("fatformat mmc 0:1", 0);
+ sprintf(response, "OKAY");
+ ret = 0;
+ goto send_tx_status;
+ }
+ if (odroid_get_partition_info(&cmdbuf[6], &pinfo))
+ sprintf(response, "FAILUnsupport partitiond");
+ else {
+ if (!pinfo.raw_en) {
+ erase_partition(&pinfo, 0);
+ sprintf(response, "OKAY");
+ }
+ else
+ sprintf(response, "FAILUnsupport partitiond");
+ }
+ ret = 0;
+ goto send_tx_status;
+ }
+
+ /* download
+ download something ..
+ What happens to it depends on the next command after data */
+ if (memcmp(cmdbuf, "download:", 9) == 0)
+ {
+ /* save the size */
+ download_size = simple_strtoul(cmdbuf + 9, NULL, 16);
+ /* Reset the bytes count, now it is safe */
+ download_bytes = 0;
+ /* Reset error */
+ download_error = 0;
+
+ printf("Starting download of %d bytes\n", download_size);
+
+ if (0 == download_size) {
+ /* bad user input */
+ sprintf(response, "FAILdata invalid size");
+ } else if (download_size > interface.transfer_buffer_size) {
+ /* set download_size to 0 because this is an error */
+ download_size = 0;
+ sprintf(response, "FAILdata too large");
+ } else {
+ /* The default case, the transfer fits
+ completely in the interface buffer */
+ sprintf(response, "DATA%08x", download_size);
+ }
+ ret = 0;
+ goto send_tx_status;
+ }
+
+ /* flash
+ Flash what was downloaded */
+ if (memcmp(cmdbuf, "flash:", 6) == 0) {
+ struct partition_info pinfo;
+
+ ret = 0;
+ if (download_bytes == 0) {
+ sprintf(response, "FAILno image downloaded");
+ goto send_tx_status;
+ }
+ if (odroid_get_partition_info(&cmdbuf[6], &pinfo)) {
+ sprintf(response, "FAILunknown(%s) partition!",
+ cmdbuf + 6);
+ goto send_tx_status;
+ }
+ if (pinfo.size < download_bytes) {
+ sprintf(response, "FAILimage too large for partition(%s)!",
+ cmdbuf + 6);
+ goto send_tx_status;
+ }
+ if (flashing_data(&pinfo,
+ (unsigned int)interface.transfer_buffer,
+ download_bytes, 0)) {
+ sprintf(response, "FAILfailed to flash %s partition!",
+ cmdbuf + 6);
+ goto send_tx_status;
+ }
+ sprintf(response, "OKAY");
+ goto send_tx_status;
+ }
+ /* verify */
+ /* continue */
+ /* powerdown */
+send_tx_status:
+ fastboot_tx_status(response, strlen(response), FASTBOOT_TX_ASYNC);
+ } /* End of command */
+
+ return ret;
+}
+
+static int do_fastboot(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
+{
+ int continue_from_disconnect = 0, poll_status;
+ int led_status = 0, led_blink_cnt = 0;
+ int ret = 1;
+
+ if (argv[4] != NULL)
+ ret = odroid_partition_setup(argv[4]);
+ else
+ ret = odroid_partition_setup("0");
+ if (ret)
+ return ret;
+
+ do
+ {
+ continue_from_disconnect = 0;
+
+ /* Initialize the board specific support */
+ if (0 == fastboot_init(&interface))
+ {
+ /* If we got this far, we are a success */
+ ret = 0;
+
+ while (1)
+ {
+ /* Green LED Blink */
+ if (led_blink_cnt++ > 0x8000) {
+ if (led_status) {
+ odroid_led_ctrl (GPIO_LED_G, led_status);
+ led_status = 0;
+ } else {
+ odroid_led_ctrl (GPIO_LED_G, led_status);
+ led_status = 1;
+ }
+ led_blink_cnt = 0;
+ }
+
+ poll_status = fastboot_poll();
+
+ /* Check if the user wanted to terminate with ^C */
+ if ((FASTBOOT_OK != poll_status) && ctrlc()) {
+ printf("Fastboot ended by user\n");
+ continue_from_disconnect = 0;
+ break;
+ }
+
+ if (FASTBOOT_ERROR == poll_status) {
+ /* Error */
+ printf("Fastboot error \n");
+ break;
+ }
+ else if (FASTBOOT_DISCONNECT == poll_status) {
+ /* break, cleanup and re-init */
+ printf("Fastboot disconnect detected\n");
+ continue_from_disconnect = 1;
+ break;
+ }
+ } /* while (1) */
+ }
+ /* Reset the board specific support */
+ fastboot_shutdown();
+ /* restart the loop if a disconnect was detected */
+ } while (continue_from_disconnect);
+
+ odroid_led_ctrl (GPIO_LED_G, 0);
+ return ret;
+}
+
+U_BOOT_CMD(
+ fastboot, 5, 1, do_fastboot,
+ "use USB Fastboot protocol",
+ "<USB_controller>\n"
+ " - run as a fastboot usb device"
+);
diff --git a/fs/fat/fat.c b/fs/fat/fat.c
index c7a1b3e90f..a1c576e435 100755
--- a/fs/fat/fat.c
+++ b/fs/fat/fat.c
@@ -1573,8 +1573,11 @@ write_fat(struct blk_desc *dev_desc, disk_partition_t *info, int fat_size)
RESERVED_CNT + i, 16, (ulong *)dummy) != 16) {
printf ("Can't erase FAT region~~!!!\n");
}
- if((i % 160) == 0)
+ if((i % 160) == 0) {
+ if ((i % 12800) == 0)
+ printf("\n");
printf(".");
+ }
}
printf("\n");
diff --git a/include/configs/odroid_xu4.h b/include/configs/odroid_xu4.h
index 18b2dc9bea..319dc3e635 100755
--- a/include/configs/odroid_xu4.h
+++ b/include/configs/odroid_xu4.h
@@ -15,6 +15,7 @@
#undef CONFIG_ENV_IS_IN_SPI_FLASH
#define CONFIG_BOARD_COMMON
+#define CONFIG_BOARD_LATE_INIT
#define CONFIG_SYS_SDRAM_BASE 0x40000000
#define CONFIG_SYS_TEXT_BASE 0x43E00000
@@ -24,13 +25,13 @@
#define TZPC_BASE_OFFSET 0x10000
-#define CONFIG_NR_DRAM_BANKS 8
-#define SDRAM_BANK_SIZE (256UL << 20UL) /* 256 MB */
+#define CONFIG_NR_DRAM_BANKS 8
+#define SDRAM_BANK_SIZE (256UL << 20UL) /* 256 MB */
/* Reserve the last 22 MiB for the secure firmware */
#define CONFIG_SYS_MEM_TOP_HIDE (22UL << 20UL)
#define CONFIG_TZSW_RESERVED_DRAM_SIZE CONFIG_SYS_MEM_TOP_HIDE
-#define CONFIG_SYS_MMC_MAX_DEVICE 2
+#define CONFIG_SYS_MMC_MAX_DEVICE 2
#if defined(CONFIG_FASTBOOT)
/* Fastboot SDMMC Partition Table for ODROID(Exynos5422) */
@@ -62,6 +63,8 @@
(PART_SIZE_UBOOT / MOVI_BLK_SIZE))
#define PART_ENV_ST_BLK (PART_TZSW_ST_BLK + \
(PART_SIZE_TZSW / MOVI_BLK_SIZE))
+#define PART_KERNEL_ST_BLK (PART_ENV_ST_BLK + \
+ (PART_SIZE_ENV / MOVI_BLK_SIZE))
/* Android Partition size for ODROID */
#define PART_SIZE_SYSTEM SZ_1G
@@ -69,13 +72,6 @@
#define PART_SIZE_CACHE SZ_256M
#define ANDROID_PART_START SZ_64M
-#define CFG_FASTBOOT_TRANSFER_BUFFER (CONFIG_SYS_SDRAM_BASE + 0x8000000)
-#define CFG_FASTBOOT_TRANSFER_BUFFER_SIZE (0x30000000) /* 768MB */
-#define CFG_FASTBOOT_ADDR_KERNEL (CONFIG_SYS_SDRAM_BASE + 0x8000)
-#define CFG_FASTBOOT_ADDR_RAMDISK (CONFIG_SYS_SDRAM_BASE + 0x1000000)
-#define CFG_FASTBOOT_PAGESIZE (2048) // Page size of booting device
-#define CFG_FASTBOOT_SDMMC_BLOCKSIZE (512) // Block size of sdmmc
-
#endif /* #if defined(CONFIG_FASTBOOT) */
#define CONFIG_ENV_IS_IN_MMC
@@ -114,7 +110,7 @@
"mmc dev 1; mmc write ${loadaddr} 0x0001 0x07de;mmc dev 0;" \
"mmc dev 1; mmc write ${loadaddr} 0x07df 0x0020;mmc dev 0\0"
-#define CONFIG_SYS_INIT_SP_ADDR (CONFIG_SYS_LOAD_ADDR - 0x1000000)
+#define CONFIG_SYS_INIT_SP_ADDR (CONFIG_SYS_LOAD_ADDR - 0x1000000)
#define CONFIG_DEFAULT_CONSOLE "console=ttySAC2,115200n8\0"
@@ -122,27 +118,10 @@
#define CONFIG_USB_EHCI
#define CONFIG_USB_EHCI_EXYNOS
-/*
-#define CONFIG_EXYNOS_USBD3
-*/
-#define EXYNOS_SYSREG_BASE EXYNOS5_SYSREG_BASE
-#define EXYNOS_POWER_BASE EXYNOS5_POWER_BASE
-
-/*
- * USBD 3.0 SFR
- */
-#define USBDEVICE3_LINK_CH0_BASE 0x12000000
-#define USBDEVICE3_PHYCTRL_CH0_BASE 0x12100000
-#define USBDEVICE3_LINK_CH1_BASE 0x12400000
-#define USBDEVICE3_PHYCTRL_CH1_BASE 0x12500000
-
-#define EXYNOS_USB_PHY_BASE EXYNOS5_USBPHY_BASE
-#define EXYNOS_USB_LINK_BASE EXYNOS5_USBOTG_BASE
-
-/* DFU */
+/* DFU : need enable */
#define CONFIG_SYS_DFU_DATA_BUF_SIZE SZ_32M
#define DFU_DEFAULT_POLL_TIMEOUT 300
-#define DFU_MANIFEST_POLL_TIMEOUT 25000
+#define DFU_MANIFEST_POLL_TIMEOUT 25000
/* THOR */
#define CONFIG_G_DNL_THOR_VENDOR_NUM CONFIG_G_DNL_VENDOR_NUM
@@ -155,6 +134,43 @@
#define CONFIG_G_DNL_UMS_PRODUCT_NUM 0xA4A5
#define CONFIG_USB_FUNCTION_MASS_STORAGE
+/* #if defined(CONFIG_USB_DEVICE) */
+/*
+#define CONFIG_USB_DEVICE
+- need function : void udc_disconnect(void), void udc_connedt(void)
+*/
+#if !defined(CONFIG_USB_DEVICE)
+ /*
+ #define CONFIG_EXYNOS_USBD3
+ */
+ #define EXYNOS_SYSREG_BASE EXYNOS5_SYSREG_BASE
+ #define EXYNOS_POWER_BASE EXYNOS5_POWER_BASE
+ /*
+ * USBD 3.0 SFR
+ */
+ #define USBDEVICE3_LINK_CH0_BASE 0x12000000
+ #define USBDEVICE3_PHYCTRL_CH0_BASE 0x12100000
+ #define USBDEVICE3_LINK_CH1_BASE 0x12400000
+ #define USBDEVICE3_PHYCTRL_CH1_BASE 0x12500000
+
+ #define EXYNOS_USB_PHY_BASE EXYNOS5_USBPHY_BASE
+ #define EXYNOS_USB_LINK_BASE EXYNOS5_USBOTG_BASE
+
+ #if defined(CONFIG_FASTBOOT)
+ #define CFG_FASTBOOT_TRANSFER_BUFFER (CONFIG_SYS_SDRAM_BASE + 0x8000000)
+ #define CFG_FASTBOOT_TRANSFER_BUFFER_SIZE (0x30000000) /* 768MB */
+ #define CFG_FASTBOOT_ADDR_KERNEL (CONFIG_SYS_SDRAM_BASE + 0x8000)
+ #define CFG_FASTBOOT_ADDR_RAMDISK (CONFIG_SYS_SDRAM_BASE + 0x1000000)
+ #define CFG_FASTBOOT_PAGESIZE (2048) // Page size of booting device
+ #define CFG_FASTBOOT_SDMMC_BLOCKSIZE (512) // Block size of sdmmc
+ #endif
+
+ /* cmd from kernel reboot */
+ #define FASTBOOT_MAGIC_REBOOT_CMD 0xFAB0
+ #define FASTBOOT_MAGIC_UPDATE_CMD 0xFADA
+
+#endif /*#if defined(CONFIG_USB_DEVICE) */
+
/* FIXME: MUST BE REMOVED AFTER TMU IS TURNED ON */
#undef CONFIG_EXYNOS_TMU
#undef CONFIG_TMU_CMD_DTT
diff --git a/include/fastboot.h b/include/fastboot.h
index b47196979c..f70b0403d6 100755
--- a/include/fastboot.h
+++ b/include/fastboot.h
@@ -20,12 +20,37 @@ void fastboot_fail(const char *reason);
void fastboot_okay(const char *reason);
#if defined(CONFIG_TARGET_ODROID_XU4) || defined(CONFIG_TARGET_ODROID_XU3)
-#include <common.h>
-#include <command.h>
-#include <asm/byteorder.h>
-#include <asm/arch/cpu.h>
-#include <asm/io.h>
+typedef struct _ext4_file_header {
+ unsigned int magic;
+ unsigned short major;
+ unsigned short minor;
+ unsigned short file_header_size;
+ unsigned short chunk_header_size;
+ unsigned int block_size;
+ unsigned int total_blocks;
+ unsigned int total_chunks;
+ unsigned int crc32;
+} ext4_file_header;
+
+typedef struct _ext4_chunk_header {
+ unsigned short type;
+ unsigned short reserved;
+ unsigned int chunk_size;
+ unsigned int total_size;
+} ext4_chunk_header;
+
+#define EXT4_FILE_HEADER_MAGIC 0xED26FF3A
+#define EXT4_FILE_HEADER_MAJOR 0x0001
+#define EXT4_FILE_HEADER_MINOR 0x0000
+#define EXT4_FILE_BLOCK_SIZE 0x1000
+
+#define EXT4_FILE_HEADER_SIZE (sizeof(ext4_file_header))
+#define EXT4_CHUNK_HEADER_SIZE (sizeof(ext4_chunk_header))
+
+#define EXT4_CHUNK_TYPE_RAW 0xCAC1
+#define EXT4_CHUNK_TYPE_FILL 0xCAC2
+#define EXT4_CHUNK_TYPE_NONE 0xCAC3
/* This is the interface file between the common cmd_fastboot.c and
the board specific support.
@@ -107,68 +132,8 @@ struct cmd_fastboot_interface
Set by board */
unsigned int transfer_buffer_size;
-
-};
-
-/* Android-style flash naming */
-typedef struct fastboot_ptentry fastboot_ptentry;
-
-/* 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 long long start;
- /* The length of the partition, must be multiple of nand block size */
- unsigned long long length;
- /* Controls the details of how operations are done on the partition
- See the FASTBOOT_PTENTRY_FLAGS_*'s defined below */
- unsigned int flags;
};
-/* Lower byte shows if the read/write/erase operation in
- repeated. The base address is incremented.
- Either 0 or 1 is ok for a default */
-
-#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
-
-/* Sets the ECC to hardware before writing
- HW and SW ECC should not both be set. */
-#define FASTBOOT_PTENTRY_FLAGS_WRITE_HW_ECC 0x00000040
-
-/* Sets the ECC to software before writing
- HW and SW ECC should not both be set. */
-#define FASTBOOT_PTENTRY_FLAGS_WRITE_SW_ECC 0x00000080
-
-/* Write the file with write.i */
-#define FASTBOOT_PTENTRY_FLAGS_WRITE_I 0x00000100
-
-/* Write the file with write.yaffs */
-#define FASTBOOT_PTENTRY_FLAGS_WRITE_YAFFS 0x00000200
-
-/* Write the file as a series of variable/value pairs
- using the setenv and saveenv commands */
-#define FASTBOOT_PTENTRY_FLAGS_WRITE_ENV 0x00000400
-
-/* Use mmc command to read/write this partition */
-#define FASTBOOT_PTENTRY_FLAGS_USE_MMC_CMD 0x00010000
-
-/* Use movi command to read/write this partition */
-#define FASTBOOT_PTENTRY_FLAGS_USE_MOVI_CMD 0x00020000
-
/* Status values */
#define FASTBOOT_OK 0
#define FASTBOOT_ERROR -1
@@ -176,42 +141,19 @@ struct fastboot_ptentry
#define FASTBOOT_INACTIVE 2
/* Magic string to enable fastboot during preboot */
-#define FASTBOOT_REBOOT_MAGIC "REBOOT-FASTBOOT"
-#define FASTBOOT_REBOOT_MAGIC_SIZE 15
+#define FASTBOOT_REBOOT_MAGIC "REBOOT-FASTBOOT"
+#define FASTBOOT_REBOOT_MAGIC_SIZE 15
/* Android bootimage file format */
#define FASTBOOT_BOOT_MAGIC "ANDROID!"
-#define FASTBOOT_BOOT_MAGIC_SIZE 8
-#define FASTBOOT_BOOT_NAME_SIZE 16
-#define FASTBOOT_BOOT_ARGS_SIZE 512
+#define FASTBOOT_BOOT_MAGIC_SIZE 8
+#define FASTBOOT_BOOT_NAME_SIZE 16
+#define FASTBOOT_BOOT_ARGS_SIZE 512
/* Input of fastboot_tx_status */
#define FASTBOOT_TX_ASYNC 0
#define FASTBOOT_TX_SYNC 1
-struct fastboot_boot_img_hdr {
- unsigned char magic[FASTBOOT_BOOT_MAGIC_SIZE];
-
- unsigned kernel_size; /* size in bytes */
- unsigned kernel_addr; /* physical load addr */
-
- unsigned ramdisk_size; /* size in bytes */
- unsigned ramdisk_addr; /* physical load addr */
-
- unsigned second_size; /* size in bytes */
- unsigned second_addr; /* physical load addr */
-
- unsigned tags_addr; /* physical addr for kernel tags */
- unsigned page_size; /* flash page size we assume */
- unsigned unused[2]; /* future expansion: should be 0 */
-
- unsigned char name[FASTBOOT_BOOT_NAME_SIZE]; /* asciiz product name */
-
- unsigned char cmdline[FASTBOOT_BOOT_ARGS_SIZE];
-
- unsigned id[8]; /* timestamp / checksum / sha1 / etc */
-};
-
#if defined(CONFIG_FASTBOOT)
/* A board specific test if u-boot should go into the fastboot command
ahead of the bootcmd
@@ -260,26 +202,6 @@ extern int fastboot_tx_status(const char *buffer, unsigned int buffer_size, cons
Returns 1 on failure */
extern int fastboot_getvar(const char *rx_buffer, char *tx_buffer);
-/* The Android-style flash handling */
-
-/* tools to populate and query the partition table */
-extern void fastboot_flash_add_ptn(fastboot_ptentry *ptn);
-extern fastboot_ptentry *fastboot_flash_find_ptn(const char *name);
-extern fastboot_ptentry *fastboot_flash_get_ptn(unsigned n);
-extern unsigned int fastboot_flash_get_ptn_count(void);
-extern void fastboot_flash_dump_ptn(void);
-
-extern int fastboot_flash_init(void);
-extern int fastboot_flash_erase(fastboot_ptentry *ptn);
-extern int fastboot_flash_read_ext(fastboot_ptentry *ptn,
- unsigned extra_per_page, unsigned offset,
- void *data, unsigned bytes);
-#define fastboot_flash_read(ptn, offset, data, bytes) \
- flash_read_ext(ptn, 0, offset, data, bytes)
-extern int fastboot_flash_write(fastboot_ptentry *ptn, unsigned extra_per_page,
- const void *data, unsigned bytes);
-
-
#else
/* Stubs for when CONFIG_FASTBOOT is not defined */
@@ -292,17 +214,6 @@ extern int fastboot_flash_write(fastboot_ptentry *ptn, unsigned extra_per_page,
#define fastboot_tx_status(a, b, c) 1
#define fastboot_getvar(a,b) 1
-#define fastboot_flash_add_ptn(a)
-#define fastboot_flash_find_ptn(a) NULL
-#define fastboot_flash_get_ptn(a) NULL
-#define fastboot_flash_get_ptn_count() 0
-#define fastboot_flash_dump_ptn()
-#define fastboot_flash_init()
-#define fastboot_flash_erase(a) 1
-#define fastboot_flash_read_ext(a, b, c, d, e) 0
-#define fastboot_flash_read(a, b, c, d, e) 0
-#define fastboot_flash_write(a, b, c, d) 0
-
#endif /* CONFIG_FASTBOOT */
#endif /* #if defined(CONFIG_TARGET_ODROID_XU4) || defined(CONFIG_TARGET_ODROID_XU3) */
diff --git a/include/samsung/odroid_misc.h b/include/samsung/odroid_misc.h
index e181e94229..1131dba91a 100755
--- a/include/samsung/odroid_misc.h
+++ b/include/samsung/odroid_misc.h
@@ -11,6 +11,29 @@
#define GPIO_FAN_CTL EXYNOS5420_GPIO_B20
#define GPIO_LCD_PWM EXYNOS5420_GPIO_B23
+enum {
+ PART_FWBL1 = 0,
+ PART_BL2,
+ PART_BOOTLOADER,
+ PART_TZSW,
+ PART_ENV,
+ PART_KERENEL,
+ PART_SYSTEM,
+ PART_USERDATA,
+ PART_CACHE,
+ PART_MAX
+};
+
+struct partition_info {
+ const char name[16]; /* partition name */
+ unsigned int blk_start; /* start blk number */
+ unsigned int size; /* size in bytes */
+ unsigned int raw_en; /* raw access enable for emmc */
+};
+
+extern int odroid_get_partition_info (const char *ptn, struct partition_info *pinfo);
+extern int odroid_partition_setup (char *dev_no);
+
extern void odroid_led_ctrl (int gpio, int status);
extern void odroid_misc_init (void);