summaryrefslogtreecommitdiff
path: root/common
diff options
context:
space:
mode:
Diffstat (limited to 'common')
-rw-r--r--common/Makefile3
-rw-r--r--common/cmd_bootm.c23
-rw-r--r--common/cmd_fastboot.c36
-rw-r--r--common/cmd_usb_mass_storage.c91
-rw-r--r--common/image-android.c84
-rw-r--r--common/image.c20
6 files changed, 239 insertions, 18 deletions
diff --git a/common/Makefile b/common/Makefile
index 7c853ae..219cb51 100644
--- a/common/Makefile
+++ b/common/Makefile
@@ -168,6 +168,8 @@ obj-y += cmd_usb.o
obj-y += usb.o usb_hub.o
obj-$(CONFIG_USB_STORAGE) += usb_storage.o
endif
+obj-$(CONFIG_CMD_FASTBOOT) += cmd_fastboot.o
+
obj-$(CONFIG_CMD_USB_MASS_STORAGE) += cmd_usb_mass_storage.o
obj-$(CONFIG_CMD_THOR_DOWNLOAD) += cmd_thordown.o
obj-$(CONFIG_CMD_XIMG) += cmd_ximg.o
@@ -237,6 +239,7 @@ obj-y += console.o
obj-$(CONFIG_CROS_EC) += cros_ec.o
obj-y += dlmalloc.o
obj-y += image.o
+obj-$(CONFIG_ANDROID_BOOT_IMAGE) += image-android.o
obj-$(CONFIG_OF_LIBFDT) += image-fdt.o
obj-$(CONFIG_FIT) += image-fit.o
obj-$(CONFIG_FIT_SIGNATURE) += image-sig.o
diff --git a/common/cmd_bootm.c b/common/cmd_bootm.c
index e683af3..34b4b58 100644
--- a/common/cmd_bootm.c
+++ b/common/cmd_bootm.c
@@ -222,6 +222,7 @@ static int bootm_find_os(cmd_tbl_t *cmdtp, int flag, int argc,
char * const argv[])
{
const void *os_hdr;
+ bool ep_found = false;
/* get kernel image header, start address and length */
os_hdr = boot_get_kernel(cmdtp, flag, argc, argv,
@@ -274,6 +275,18 @@ static int bootm_find_os(cmd_tbl_t *cmdtp, int flag, int argc,
}
break;
#endif
+#ifdef CONFIG_ANDROID_BOOT_IMAGE
+ case IMAGE_FORMAT_ANDROID:
+ images.os.type = IH_TYPE_KERNEL;
+ images.os.comp = IH_COMP_NONE;
+ images.os.os = IH_OS_LINUX;
+ images.ep = images.os.load;
+ ep_found = true;
+
+ images.os.end = android_image_get_end(os_hdr);
+ images.os.load = android_image_get_kload(os_hdr);
+ break;
+#endif
default:
puts("ERROR: unknown image format type!\n");
return 1;
@@ -293,7 +306,7 @@ static int bootm_find_os(cmd_tbl_t *cmdtp, int flag, int argc,
return 1;
}
#endif
- } else {
+ } else if (!ep_found) {
puts("Could not find kernel entry point!\n");
return 1;
}
@@ -1002,6 +1015,14 @@ static const void *boot_get_kernel(cmd_tbl_t *cmdtp, int flag, int argc,
images->fit_noffset_os = os_noffset;
break;
#endif
+#ifdef CONFIG_ANDROID_BOOT_IMAGE
+ case IMAGE_FORMAT_ANDROID:
+ printf("## Booting Android Image at 0x%08lx ...\n", img_addr);
+ if (android_image_get_kernel((void *)img_addr, images->verify,
+ os_data, os_len))
+ return NULL;
+ break;
+#endif
default:
printf("Wrong Image Format for %s command\n", cmdtp->name);
bootstage_error(BOOTSTAGE_ID_FIT_KERNEL_INFO);
diff --git a/common/cmd_fastboot.c b/common/cmd_fastboot.c
new file mode 100644
index 0000000..83fa7bd
--- /dev/null
+++ b/common/cmd_fastboot.c
@@ -0,0 +1,36 @@
+/*
+ * 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 <g_dnl.h>
+
+static int do_fastboot(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
+{
+ int ret;
+
+ ret = g_dnl_register("usb_dnl_fastboot");
+ if (ret)
+ return ret;
+
+ while (1) {
+ if (ctrlc())
+ break;
+ usb_gadget_handle_interrupts();
+ }
+
+ g_dnl_unregister();
+ return CMD_RET_SUCCESS;
+}
+
+U_BOOT_CMD(
+ fastboot, 1, 1, do_fastboot,
+ "fastboot - enter USB Fastboot protocol",
+ ""
+);
diff --git a/common/cmd_usb_mass_storage.c b/common/cmd_usb_mass_storage.c
index d8d9efd..2c879ea 100644
--- a/common/cmd_usb_mass_storage.c
+++ b/common/cmd_usb_mass_storage.c
@@ -9,41 +9,107 @@
#include <common.h>
#include <command.h>
#include <g_dnl.h>
+#include <part.h>
#include <usb.h>
#include <usb_mass_storage.h>
+static int ums_read_sector(struct ums *ums_dev,
+ ulong start, lbaint_t blkcnt, void *buf)
+{
+ block_dev_desc_t *block_dev = ums_dev->block_dev;
+ lbaint_t blkstart = start + ums_dev->start_sector;
+ int dev_num = block_dev->dev;
+
+ return block_dev->block_read(dev_num, blkstart, blkcnt, buf);
+}
+
+static int ums_write_sector(struct ums *ums_dev,
+ ulong start, lbaint_t blkcnt, const void *buf)
+{
+ block_dev_desc_t *block_dev = ums_dev->block_dev;
+ lbaint_t blkstart = start + ums_dev->start_sector;
+ int dev_num = block_dev->dev;
+
+ return block_dev->block_write(dev_num, blkstart, blkcnt, buf);
+}
+
+static struct ums ums_dev = {
+ .read_sector = ums_read_sector,
+ .write_sector = ums_write_sector,
+ .name = "UMS disk",
+};
+
+struct ums *ums_init(const char *devtype, const char *devnum)
+{
+ block_dev_desc_t *block_dev;
+ int ret;
+
+ ret = get_device(devtype, devnum, &block_dev);
+ if (ret < 0)
+ return NULL;
+
+ /* f_mass_storage.c assumes SECTOR_SIZE sectors */
+ if (block_dev->blksz != SECTOR_SIZE)
+ return NULL;
+
+ ums_dev.block_dev = block_dev;
+ ums_dev.start_sector = 0;
+ ums_dev.num_sectors = block_dev->lba;
+
+ printf("UMS: disk start sector: %#x, count: %#x\n",
+ ums_dev.start_sector, ums_dev.num_sectors);
+
+ return &ums_dev;
+}
+
int do_usb_mass_storage(cmd_tbl_t *cmdtp, int flag,
int argc, char * const argv[])
{
+ const char *usb_controller;
+ const char *devtype;
+ const char *devnum;
+ struct ums *ums;
+ unsigned int controller_index;
+ int rc;
+ int cable_ready_timeout __maybe_unused;
+
if (argc < 3)
return CMD_RET_USAGE;
- const char *usb_controller = argv[1];
- const char *mmc_devstring = argv[2];
-
- unsigned int dev_num = simple_strtoul(mmc_devstring, NULL, 0);
+ usb_controller = argv[1];
+ if (argc >= 4) {
+ devtype = argv[2];
+ devnum = argv[3];
+ } else {
+ devtype = "mmc";
+ devnum = argv[2];
+ }
- struct ums *ums = ums_init(dev_num);
+ ums = ums_init(devtype, devnum);
if (!ums)
return CMD_RET_FAILURE;
- unsigned int controller_index = (unsigned int)(simple_strtoul(
- usb_controller, NULL, 0));
+ controller_index = (unsigned int)(simple_strtoul(
+ usb_controller, NULL, 0));
if (board_usb_init(controller_index, USB_INIT_DEVICE)) {
error("Couldn't init USB controller.");
return CMD_RET_FAILURE;
}
- int rc = fsg_init(ums);
+ rc = fsg_init(ums);
if (rc) {
error("fsg_init failed");
return CMD_RET_FAILURE;
}
- g_dnl_register("usb_dnl_ums");
+ rc = g_dnl_register("usb_dnl_ums");
+ if (rc) {
+ error("g_dnl_register failed");
+ return CMD_RET_FAILURE;
+ }
/* Timeout unit: seconds */
- int cable_ready_timeout = UMS_CABLE_READY_TIMEOUT;
+ cable_ready_timeout = UMS_CABLE_READY_TIMEOUT;
if (!g_dnl_board_usb_cable_connected()) {
/*
@@ -91,7 +157,8 @@ exit:
return CMD_RET_SUCCESS;
}
-U_BOOT_CMD(ums, CONFIG_SYS_MAXARGS, 1, do_usb_mass_storage,
+U_BOOT_CMD(ums, 4, 1, do_usb_mass_storage,
"Use the UMS [User Mass Storage]",
- "ums <USB_controller> <mmc_dev> e.g. ums 0 0"
+ "ums <USB_controller> [<devtype>] <devnum> e.g. ums 0 mmc 0\n"
+ " devtype defaults to mmc"
);
diff --git a/common/image-android.c b/common/image-android.c
new file mode 100644
index 0000000..6ded7e2
--- /dev/null
+++ b/common/image-android.c
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 2011 Sebastian Andrzej Siewior <bigeasy@linutronix.de>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <image.h>
+#include <android_image.h>
+
+static char andr_tmp_str[ANDR_BOOT_ARGS_SIZE + 1];
+
+int android_image_get_kernel(const struct andr_img_hdr *hdr, int verify,
+ ulong *os_data, ulong *os_len)
+{
+ /*
+ * Not all Android tools use the id field for signing the image with
+ * sha1 (or anything) so we don't check it. It is not obvious that the
+ * string is null terminated so we take care of this.
+ */
+ strncpy(andr_tmp_str, hdr->name, ANDR_BOOT_NAME_SIZE);
+ andr_tmp_str[ANDR_BOOT_NAME_SIZE] = '\0';
+ if (strlen(andr_tmp_str))
+ printf("Android's image name: %s\n", andr_tmp_str);
+
+ printf("Kernel load addr 0x%08x size %u KiB\n",
+ hdr->kernel_addr, DIV_ROUND_UP(hdr->kernel_size, 1024));
+ strncpy(andr_tmp_str, hdr->cmdline, ANDR_BOOT_ARGS_SIZE);
+ andr_tmp_str[ANDR_BOOT_ARGS_SIZE] = '\0';
+ if (strlen(andr_tmp_str)) {
+ printf("Kernel command line: %s\n", andr_tmp_str);
+ setenv("bootargs", andr_tmp_str);
+ }
+ if (hdr->ramdisk_size)
+ printf("RAM disk load addr 0x%08x size %u KiB\n",
+ hdr->ramdisk_addr,
+ DIV_ROUND_UP(hdr->ramdisk_size, 1024));
+
+ if (os_data) {
+ *os_data = (ulong)hdr;
+ *os_data += hdr->page_size;
+ }
+ if (os_len)
+ *os_len = hdr->kernel_size;
+ return 0;
+}
+
+int android_image_check_header(const struct andr_img_hdr *hdr)
+{
+ return memcmp(ANDR_BOOT_MAGIC, hdr->magic, ANDR_BOOT_MAGIC_SIZE);
+}
+
+ulong android_image_get_end(const struct andr_img_hdr *hdr)
+{
+ u32 size = 0;
+ /*
+ * The header takes a full page, the remaining components are aligned
+ * on page boundary
+ */
+ size += hdr->page_size;
+ size += ALIGN(hdr->kernel_size, hdr->page_size);
+ size += ALIGN(hdr->ramdisk_size, hdr->page_size);
+ size += ALIGN(hdr->second_size, hdr->page_size);
+
+ return size;
+}
+
+ulong android_image_get_kload(const struct andr_img_hdr *hdr)
+{
+ return hdr->kernel_addr;
+}
+
+int android_image_get_ramdisk(const struct andr_img_hdr *hdr,
+ ulong *rd_data, ulong *rd_len)
+{
+ if (!hdr->ramdisk_size)
+ return -1;
+ *rd_data = (unsigned long)hdr;
+ *rd_data += hdr->page_size;
+ *rd_data += ALIGN(hdr->kernel_size, hdr->page_size);
+
+ *rd_len = hdr->ramdisk_size;
+ return 0;
+}
diff --git a/common/image.c b/common/image.c
index fcc5a9c..fa4864d 100644
--- a/common/image.c
+++ b/common/image.c
@@ -660,10 +660,12 @@ int genimg_get_format(const void *img_addr)
if (image_check_magic(hdr))
format = IMAGE_FORMAT_LEGACY;
#if defined(CONFIG_FIT) || defined(CONFIG_OF_LIBFDT)
- else {
- if (fdt_check_header(img_addr) == 0)
- format = IMAGE_FORMAT_FIT;
- }
+ else if (fdt_check_header(img_addr) == 0)
+ format = IMAGE_FORMAT_FIT;
+#endif
+#ifdef CONFIG_ANDROID_BOOT_IMAGE
+ else if (android_image_check_header(img_addr) == 0)
+ format = IMAGE_FORMAT_ANDROID;
#endif
return format;
@@ -933,7 +935,15 @@ int boot_get_ramdisk(int argc, char * const argv[], bootm_headers_t *images,
(ulong)images->legacy_hdr_os);
image_multi_getimg(images->legacy_hdr_os, 1, &rd_data, &rd_len);
- } else {
+ }
+#ifdef CONFIG_ANDROID_BOOT_IMAGE
+ else if ((genimg_get_format(images) == IMAGE_FORMAT_ANDROID) &&
+ (!android_image_get_ramdisk((void *)images->os.start,
+ &rd_data, &rd_len))) {
+ /* empty */
+ }
+#endif
+ else {
/*
* no initrd image
*/