diff options
author | Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com> | 2012-04-11 07:42:34 +0200 |
---|---|---|
committer | Sascha Hauer <s.hauer@pengutronix.de> | 2012-04-13 12:08:42 +0200 |
commit | 5efbed3b272b2b8b6bfa1e8317801f1637eeec88 (patch) | |
tree | 9b7e002816b02d711efd99cc78242b500bfa6876 /arch | |
parent | 2c3db7776b81afd2b36a07d484a49216cb72199b (diff) | |
download | barebox-5efbed3b272b2b8b6bfa1e8317801f1637eeec88.tar.gz barebox-5efbed3b272b2b8b6bfa1e8317801f1637eeec88.tar.xz |
arm: add Android boot image support
The Android Image contains 3 components and params
- kernel
- initrd
- second stage (optional)
- tags addr
- bootargs
In fast boot the initrd is mandatory, in barebox we are less restrictive
use the initrd only if present
add to env params:
aimage_noverwrite_bootargs
Disable overwrite of the bootargs with the one present in aimage
aimage_noverwrite_tags
Disable overwrite of the tags addr with the one present in aimage
Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
Cc: Magnus Damm <magnus.damm@gmail.com>
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
Diffstat (limited to 'arch')
-rw-r--r-- | arch/arm/lib/bootm.c | 147 |
1 files changed, 147 insertions, 0 deletions
diff --git a/arch/arm/lib/bootm.c b/arch/arm/lib/bootm.c index defc89b7fd..ac83ec7a30 100644 --- a/arch/arm/lib/bootm.c +++ b/arch/arm/lib/bootm.c @@ -13,6 +13,7 @@ #include <errno.h> #include <sizes.h> #include <libbb.h> +#include <magicvar.h> #include <asm/byteorder.h> #include <asm/setup.h> @@ -231,12 +232,158 @@ static struct image_handler barebox_handler = { .filetype = filetype_arm_barebox, }; +#include <aimage.h> + +static int aimage_load_resource(int fd, struct resource *r, void* buf, int ps) +{ + int ret; + void *image = (void *)r->start; + unsigned to_read = ps - r->size % ps; + + ret = read_full(fd, image, r->size); + if (ret < 0) + return ret; + + ret = read_full(fd, buf, to_read); + if (ret < 0) + printf("could not read dummy %d\n", to_read); + + return ret; +} + +static int do_bootm_aimage(struct image_data *data) +{ + struct resource *snd_stage_res; + int fd, ret; + struct android_header __header, *header; + void *buf; + int to_read; + struct android_header_comp *cmp; + + fd = open(data->os_file, O_RDONLY); + if (fd < 0) { + perror("open"); + return 1; + } + + header = &__header; + ret = read(fd, header, sizeof(*header)); + if (ret < sizeof(*header)) { + printf("could not read %s\n", data->os_file); + goto err_out; + } + + printf("Android Image for '%s'\n", header->name); + + /* + * As on tftp we do not support lseek and we will just have to seek + * for the size of a page - 1 max just buffer instead to read to dummy + * data + */ + buf = xmalloc(header->page_size); + + to_read = header->page_size - sizeof(*header); + ret = read_full(fd, buf, to_read); + if (ret < 0) { + printf("could not read dummy %d from %s\n", to_read, data->os_file); + goto err_out; + } + + cmp = &header->kernel; + data->os_res = request_sdram_region("akernel", cmp->load_addr, cmp->size); + if (!data->os_res) { + ret = -ENOMEM; + goto err_out; + } + + ret = aimage_load_resource(fd, data->os_res, buf, header->page_size); + if (ret < 0) { + perror("could not read kernel"); + goto err_out; + } + + /* + * fastboot always expect a ramdisk + * in barebox we can be less restrictive + */ + cmp = &header->ramdisk; + if (cmp->size) { + data->initrd_res = request_sdram_region("ainitrd", cmp->load_addr, cmp->size); + if (!data->initrd_res) { + ret = -ENOMEM; + goto err_out; + } + + ret = aimage_load_resource(fd, data->initrd_res, buf, header->page_size); + if (ret < 0) { + perror("could not read initrd"); + goto err_out; + } + } + + if (!getenv("aimage_noverwrite_bootargs")) + setenv("bootargs", header->cmdline); + + if (!getenv("aimage_noverwrite_tags")) + armlinux_set_bootparams((void*)header->tags_addr); + + if (data->oftree) { + ret = of_fix_tree(data->oftree); + if (ret) + goto err_out; + } + + cmp = &header->second_stage; + if (cmp->size) { + void (*second)(void); + + snd_stage_res = request_sdram_region("asecond", cmp->load_addr, cmp->size); + if (!snd_stage_res) { + ret = -ENOMEM; + goto err_out; + } + + ret = aimage_load_resource(fd, snd_stage_res, buf, header->page_size); + if (ret < 0) { + perror("could not read initrd"); + goto err_out; + } + + second = (void*)snd_stage_res->start; + shutdown_barebox(); + + second(); + + reset_cpu(0); + } + + return __do_bootm_linux(data, 0); + +err_out: + close(fd); + + return ret; +} + +static struct image_handler aimage_handler = { + .name = "ARM Android Image", + .bootm = do_bootm_aimage, + .filetype = filetype_aimage, +}; + +#ifdef CONFIG_CMD_BOOTM_AIMAGE +BAREBOX_MAGICVAR(aimage_noverwrite_bootargs, "Disable overwrite of the bootargs with the one present in aimage"); +BAREBOX_MAGICVAR(aimage_noverwrite_tags, "Disable overwrite of the tags addr with the one present in aimage"); +#endif + static int armlinux_register_image_handler(void) { register_image_handler(&barebox_handler); register_image_handler(&uimage_handler); register_image_handler(&rawimage_handler); register_image_handler(&zimage_handler); + if (IS_BUILTIN(CONFIG_CMD_BOOTM_AIMAGE)) + register_image_handler(&aimage_handler); return 0; } |