android: support boot images packed with rockchip android hdr
For some legacy reasons, rockchip use mkbootimg tool to pack android images with special pack parameters(SDK version lower than 8.1) to assign kernel/ramdisk/seconds address and page size. Android hdr on RK3399 SDK-7.1: kernel size: 1299808 kernel address: 60408000 ramdisk size: 1e6b80 ramdisk addrress: 62000000 second size: 41c00 second address: 60f00000 tags address: 60088000 page size: 4000 header_version: 0 os_version: e041114 (ver: 1.7.2, level: 2017.4) name: cmdline: buildvariant=userdebug The kernel/ramdisk/seconds address base is not from 0x10000000 and page size is not 0x800! This patch makes bootflow to compatible with above legacy packing. Change-Id: I663a0d1386694658c97586706ff21ed887d6a2e7 Signed-off-by: Joseph Chen <chenjh@rock-chips.com>
This commit is contained in:
parent
ab70714e5a
commit
ee465021fe
|
|
@ -48,7 +48,7 @@ static int do_boot_android(cmd_tbl_t *cmdtp, int flag, int argc,
|
|||
*/
|
||||
load_address &= ~0x7ffff;
|
||||
#endif
|
||||
load_address -= 0x800; /* default page size for boot header */
|
||||
|
||||
dev_desc = blk_get_dev(argv[1], simple_strtoul(argv[2], NULL, 16));
|
||||
if (!dev_desc) {
|
||||
printf("Could not get %s %s\n", argv[1], argv[2]);
|
||||
|
|
|
|||
|
|
@ -424,7 +424,7 @@ static void slot_set_unbootable(AvbABSlotData* slot)
|
|||
}
|
||||
|
||||
static AvbSlotVerifyResult android_slot_verify(char *boot_partname,
|
||||
unsigned long load_address,
|
||||
unsigned long *android_load_address,
|
||||
char *slot_suffix)
|
||||
{
|
||||
const char *requested_partitions[1] = {NULL};
|
||||
|
|
@ -437,6 +437,8 @@ static AvbSlotVerifyResult android_slot_verify(char *boot_partname,
|
|||
size_t slot_index_to_boot = 0;
|
||||
char verify_state[38] = {0};
|
||||
char can_boot = 1;
|
||||
unsigned long load_address = *android_load_address;
|
||||
struct andr_img_hdr *hdr;
|
||||
|
||||
requested_partitions[0] = boot_partname;
|
||||
ops = avb_ops_user_new();
|
||||
|
|
@ -539,6 +541,11 @@ static AvbSlotVerifyResult android_slot_verify(char *boot_partname,
|
|||
strcat(newbootargs, slot_data[0]->cmdline);
|
||||
env_set("bootargs", newbootargs);
|
||||
|
||||
/* Reserve page_size */
|
||||
hdr = (void *)slot_data[0]->loaded_partitions->data;
|
||||
load_address -= hdr->page_size;
|
||||
*android_load_address = load_address;
|
||||
|
||||
memcpy((uint8_t *)load_address,
|
||||
slot_data[0]->loaded_partitions->data,
|
||||
slot_data[0]->loaded_partitions->data_size);
|
||||
|
|
@ -878,7 +885,7 @@ int android_bootloader_boot_flow(struct blk_desc *dev_desc,
|
|||
}
|
||||
|
||||
#ifdef CONFIG_ANDROID_AVB
|
||||
if (android_slot_verify(boot_partname, load_address, slot_suffix))
|
||||
if (android_slot_verify(boot_partname, &load_address, slot_suffix))
|
||||
return -1;
|
||||
#else
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -38,7 +38,25 @@ static ulong android_image_get_kernel_addr(const struct andr_img_hdr *hdr)
|
|||
if (hdr->kernel_addr == ANDROID_IMAGE_DEFAULT_KERNEL_ADDR)
|
||||
return (ulong)hdr + hdr->page_size;
|
||||
|
||||
#ifdef CONFIG_ARCH_ROCKCHIP
|
||||
/*
|
||||
* If kernel is compressed, kernel_addr is set as decompressed address
|
||||
* after compressed being loaded to ram, so let's use it.
|
||||
*/
|
||||
if (android_kernel_comp_type != IH_COMP_NONE &&
|
||||
android_kernel_comp_type != IH_COMP_ZIMAGE)
|
||||
return hdr->kernel_addr;
|
||||
|
||||
/*
|
||||
* Compatble with rockchip legacy packing with kernel/ramdisk/second
|
||||
* address base from 0x60000000(SDK versiont < 8.1), these are invalid
|
||||
* address, so we calc it by real size.
|
||||
*/
|
||||
return (ulong)hdr + hdr->page_size;
|
||||
#else
|
||||
return hdr->kernel_addr;
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
void android_image_set_comp(struct andr_img_hdr *hdr, u32 comp)
|
||||
|
|
@ -172,14 +190,14 @@ int android_image_get_ramdisk(const struct andr_img_hdr *hdr,
|
|||
return -1;
|
||||
}
|
||||
|
||||
printf("RAM disk load addr 0x%08x size %u KiB\n",
|
||||
hdr->ramdisk_addr, DIV_ROUND_UP(hdr->ramdisk_size, 1024));
|
||||
|
||||
*rd_data = (unsigned long)hdr;
|
||||
*rd_data += hdr->page_size;
|
||||
*rd_data += ALIGN(hdr->kernel_size, hdr->page_size);
|
||||
|
||||
*rd_len = hdr->ramdisk_size;
|
||||
|
||||
printf("RAM disk load addr 0x%08lx size %u KiB\n",
|
||||
*rd_data, DIV_ROUND_UP(hdr->ramdisk_size, 1024));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -253,37 +271,48 @@ long android_image_load(struct blk_desc *dev_desc,
|
|||
long blk_read = 0;
|
||||
u32 comp;
|
||||
u32 kload_addr;
|
||||
u32 blkcnt;
|
||||
struct andr_img_hdr *hdr;
|
||||
|
||||
if (max_size < part_info->blksz)
|
||||
return -1;
|
||||
|
||||
/*
|
||||
* Read the Android boot.img header and a few parts of
|
||||
* the head of kernel image.
|
||||
*/
|
||||
blkcnt = DIV_ROUND_UP(sizeof(*hdr), 512);
|
||||
hdr = memalign(ARCH_DMA_MINALIGN, blkcnt * 512);
|
||||
if (!hdr) {
|
||||
printf("%s: no memory\n", __func__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (blk_dread(dev_desc, part_info->start, blkcnt, hdr) != blkcnt)
|
||||
blk_read = -1;
|
||||
|
||||
if (!blk_read && android_image_check_header(hdr) != 0) {
|
||||
printf("** Invalid Android Image header **\n");
|
||||
blk_read = -1;
|
||||
}
|
||||
|
||||
/* page_size for image header */
|
||||
load_address -= hdr->page_size;
|
||||
|
||||
/* We don't know the size of the Android image before reading the header
|
||||
* so we don't limit the size of the mapped memory.
|
||||
*/
|
||||
buf = map_sysmem(load_address, 0 /* size */);
|
||||
|
||||
/* Read the Android boot.img header and a few parts of
|
||||
* the head of kernel image.
|
||||
*/
|
||||
if (blk_dread(dev_desc, part_info->start, 8, buf) != 8)
|
||||
blk_read = -1;
|
||||
|
||||
if (!blk_read && android_image_check_header(buf) != 0) {
|
||||
printf("** Invalid Android Image header **\n");
|
||||
blk_read = -1;
|
||||
}
|
||||
|
||||
|
||||
if (!blk_read) {
|
||||
blk_cnt = (android_image_get_end(buf) - (ulong)buf +
|
||||
blk_cnt = (android_image_get_end(hdr) - (ulong)hdr +
|
||||
part_info->blksz - 1) / part_info->blksz;
|
||||
comp = android_image_parse_kernel_comp(buf);
|
||||
comp = android_image_parse_kernel_comp(hdr);
|
||||
/*
|
||||
* We should load a compressed kernel Image
|
||||
* to high memory
|
||||
*/
|
||||
if (comp != IH_COMP_NONE) {
|
||||
load_address += android_image_get_ksize(buf) * 3;
|
||||
load_address += android_image_get_ksize(hdr) * 3;
|
||||
load_address = env_get_ulong("kernel_addr_c", 16, load_address);
|
||||
unmap_sysmem(buf);
|
||||
buf = map_sysmem(load_address, 0 /* size */);
|
||||
|
|
@ -291,7 +320,7 @@ long android_image_load(struct blk_desc *dev_desc,
|
|||
|
||||
if (blk_cnt * part_info->blksz > max_size) {
|
||||
debug("Android Image too big (%lu bytes, max %lu)\n",
|
||||
android_image_get_end(buf) - (ulong)buf,
|
||||
android_image_get_end(hdr) - (ulong)hdr,
|
||||
max_size);
|
||||
blk_read = -1;
|
||||
} else {
|
||||
|
|
@ -315,6 +344,7 @@ long android_image_load(struct blk_desc *dev_desc,
|
|||
|
||||
}
|
||||
|
||||
free(hdr);
|
||||
unmap_sysmem(buf);
|
||||
|
||||
debug("%lu blocks read: %s\n",
|
||||
|
|
|
|||
Loading…
Reference in New Issue