rockchip: add basic uimage code
Signed-off-by: Joseph Chen <chenjh@rock-chips.com> Change-Id: Idaf6d9e1888fde4e750435a0484636945442cbe2
This commit is contained in:
parent
059c50ac0b
commit
191c6877bc
|
|
@ -0,0 +1,18 @@
|
||||||
|
/*
|
||||||
|
* (C) Copyright 2019 Rockchip Electronics Co., Ltd
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: GPL-2.0+
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __ROCKCHIP_UIMAGE_H_
|
||||||
|
#define __ROCKCHIP_UIMAGE_H_
|
||||||
|
|
||||||
|
#define UIMG_I(fmt, args...) printf("uImage: "fmt, ##args)
|
||||||
|
|
||||||
|
void *uimage_load_bootables(void);
|
||||||
|
int uimage_sysmem_free_each(image_header_t *img);
|
||||||
|
int uimage_sysmem_reserve_each(image_header_t *hdr);
|
||||||
|
int rockchip_read_uimage_dtb(void *fdt_addr, char **hash, int *hash_size);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
@ -592,6 +592,14 @@ config ROCKCHIP_FIT_IMAGE
|
||||||
help
|
help
|
||||||
This enables loading dtb from fit image.
|
This enables loading dtb from fit image.
|
||||||
|
|
||||||
|
config ROCKCHIP_UIMAGE
|
||||||
|
bool "Enable support for legacy uImage"
|
||||||
|
depends on !FIT_SIGNATURE && USING_KERNEL_DTB
|
||||||
|
select CMD_BOOT_UIMAGE
|
||||||
|
default n
|
||||||
|
help
|
||||||
|
This enables loading dtb from uImage image.
|
||||||
|
|
||||||
config ROCKCHIP_EARLY_DISTRO_DTB
|
config ROCKCHIP_EARLY_DISTRO_DTB
|
||||||
bool "Enable support for distro dtb early"
|
bool "Enable support for distro dtb early"
|
||||||
depends on DISTRO_DEFAULTS && USING_KERNEL_DTB && CMD_FS_GENERIC
|
depends on DISTRO_DEFAULTS && USING_KERNEL_DTB && CMD_FS_GENERIC
|
||||||
|
|
|
||||||
|
|
@ -30,6 +30,7 @@ obj-y += hotkey.o
|
||||||
|
|
||||||
obj-$(CONFIG_USING_KERNEL_DTB) += kernel_dtb.o
|
obj-$(CONFIG_USING_KERNEL_DTB) += kernel_dtb.o
|
||||||
obj-$(CONFIG_ROCKCHIP_FIT_IMAGE) += fit.o
|
obj-$(CONFIG_ROCKCHIP_FIT_IMAGE) += fit.o
|
||||||
|
obj-$(CONFIG_ROCKCHIP_UIMAGE) += uimage.o
|
||||||
obj-$(CONFIG_ROCKCHIP_SMCCC) += rockchip_smccc.o
|
obj-$(CONFIG_ROCKCHIP_SMCCC) += rockchip_smccc.o
|
||||||
obj-$(CONFIG_ROCKCHIP_VENDOR_PARTITION) += vendor.o
|
obj-$(CONFIG_ROCKCHIP_VENDOR_PARTITION) += vendor.o
|
||||||
obj-$(CONFIG_ROCKCHIP_RESOURCE_IMAGE) += resource_img.o
|
obj-$(CONFIG_ROCKCHIP_RESOURCE_IMAGE) += resource_img.o
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,257 @@
|
||||||
|
/*
|
||||||
|
* (C) Copyright 2019 Rockchip Electronics Co., Ltd
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: GPL-2.0+
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <common.h>
|
||||||
|
#include <boot_rkimg.h>
|
||||||
|
#include <image.h>
|
||||||
|
#include <malloc.h>
|
||||||
|
#include <sysmem.h>
|
||||||
|
#include <asm/arch/resource_img.h>
|
||||||
|
#include <asm/arch/uimage.h>
|
||||||
|
|
||||||
|
static int uimage_load_one(struct blk_desc *dev_desc, disk_partition_t *part,
|
||||||
|
int pos_off, int size, void *dst)
|
||||||
|
{
|
||||||
|
u32 blknum, blkoff;
|
||||||
|
u32 unused;
|
||||||
|
ulong blksz;
|
||||||
|
void *buf;
|
||||||
|
|
||||||
|
blksz = dev_desc->blksz;
|
||||||
|
blkoff = pos_off / blksz;
|
||||||
|
unused = pos_off - blkoff * blksz;
|
||||||
|
blknum = DIV_ROUND_UP(size, blksz) + !!unused;
|
||||||
|
|
||||||
|
if (!size)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
if (!IS_ALIGNED(unused, ARCH_DMA_MINALIGN)) {
|
||||||
|
buf = memalign(ARCH_DMA_MINALIGN, blknum * blksz);
|
||||||
|
if (!buf)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
|
if (blk_dread(dev_desc, part->start + blkoff,
|
||||||
|
blknum, buf) != blknum) {
|
||||||
|
free(buf);
|
||||||
|
return -EIO;
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy(dst, buf + unused, size);
|
||||||
|
free(buf);
|
||||||
|
} else {
|
||||||
|
if (blk_dread(dev_desc, part->start + blkoff,
|
||||||
|
blknum, (void *)((ulong)dst - unused)) != blknum)
|
||||||
|
return -EIO;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static image_header_t *uimage_get_hdr(struct blk_desc *dev_desc,
|
||||||
|
disk_partition_t *part)
|
||||||
|
{
|
||||||
|
image_header_t *hdr;
|
||||||
|
|
||||||
|
hdr = memalign(ARCH_DMA_MINALIGN, RK_BLK_SIZE);
|
||||||
|
if (!hdr)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
if (blk_dread(dev_desc, part->start, 1, hdr) != 1)
|
||||||
|
goto err;
|
||||||
|
|
||||||
|
if (!image_check_magic(hdr) || (image_get_type(hdr) != IH_TYPE_MULTI))
|
||||||
|
goto err;
|
||||||
|
|
||||||
|
return hdr;
|
||||||
|
err:
|
||||||
|
free(hdr);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void *uimage_load_bootables(void)
|
||||||
|
{
|
||||||
|
struct blk_desc *dev_desc;
|
||||||
|
disk_partition_t part;
|
||||||
|
image_header_t *hdr;
|
||||||
|
char *part_name;
|
||||||
|
ulong raddr;
|
||||||
|
ulong kaddr;
|
||||||
|
ulong faddr;
|
||||||
|
int blknum;
|
||||||
|
|
||||||
|
raddr = env_get_ulong("ramdisk_addr_r", 16, 0);
|
||||||
|
kaddr = env_get_ulong("kernel_addr_r", 16, 0);
|
||||||
|
faddr = env_get_ulong("fdt_addr_r", 16, 0);
|
||||||
|
|
||||||
|
if (!faddr || !kaddr || !raddr)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
dev_desc = rockchip_get_bootdev();
|
||||||
|
if (!dev_desc) {
|
||||||
|
UIMG_I("No dev_desc\n");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rockchip_get_boot_mode() == BOOT_MODE_RECOVERY)
|
||||||
|
part_name = PART_RECOVERY;
|
||||||
|
else
|
||||||
|
part_name = PART_BOOT;
|
||||||
|
|
||||||
|
if (part_get_info_by_name(dev_desc, part_name, &part) < 0) {
|
||||||
|
UIMG_I("No %s partition\n", part_name);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
hdr = uimage_get_hdr(dev_desc, &part);
|
||||||
|
if (!hdr)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
/* load */
|
||||||
|
blknum = DIV_ROUND_UP(image_get_image_size(hdr), dev_desc->blksz);
|
||||||
|
hdr = sysmem_alloc(MEM_UIMAGE, blknum * dev_desc->blksz);
|
||||||
|
if (!hdr)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
if (blk_dread(dev_desc, part.start, blknum, (void *)hdr) != blknum) {
|
||||||
|
UIMG_I("Failed to read %s data\n", part.name);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return hdr;
|
||||||
|
}
|
||||||
|
|
||||||
|
int uimage_sysmem_reserve_each(image_header_t *hdr)
|
||||||
|
{
|
||||||
|
ulong raddr, kaddr, faddr;
|
||||||
|
ulong data, size;
|
||||||
|
int blknum;
|
||||||
|
int blksz = RK_BLK_SIZE;
|
||||||
|
|
||||||
|
raddr = env_get_ulong("ramdisk_addr_r", 16, 0);
|
||||||
|
kaddr = env_get_ulong("kernel_addr_r", 16, 0);
|
||||||
|
faddr = env_get_ulong("fdt_addr_r", 16, 0);
|
||||||
|
|
||||||
|
if (!faddr || !kaddr || !raddr)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
/* kernel */
|
||||||
|
image_multi_getimg(hdr, 0, &data, &size);
|
||||||
|
blknum = DIV_ROUND_UP(size, blksz);
|
||||||
|
if (!sysmem_alloc_base(MEM_KERNEL, (phys_addr_t)kaddr,
|
||||||
|
blknum * blksz))
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
|
/* ramdisk */
|
||||||
|
image_multi_getimg(hdr, 1, &data, &size);
|
||||||
|
blknum = DIV_ROUND_UP(size, blksz);
|
||||||
|
if (!sysmem_alloc_base(MEM_RAMDISK, (phys_addr_t)raddr,
|
||||||
|
blknum * blksz))
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
|
/* fdt */
|
||||||
|
image_multi_getimg(hdr, 2, &data, &size);
|
||||||
|
blknum = DIV_ROUND_UP(size, blksz);
|
||||||
|
if (!sysmem_alloc_base(MEM_FDT, (phys_addr_t)faddr,
|
||||||
|
blknum * blksz))
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
|
env_set_hex("fdt_high", faddr);
|
||||||
|
env_set_hex("initrd_high", raddr);
|
||||||
|
env_set("bootm-reloc-at", "y");
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int uimage_sysmem_free_each(image_header_t *img)
|
||||||
|
{
|
||||||
|
ulong raddr, kaddr, faddr;
|
||||||
|
|
||||||
|
raddr = env_get_ulong("ramdisk_addr_r", 16, 0);
|
||||||
|
kaddr = env_get_ulong("kernel_addr_r", 16, 0);
|
||||||
|
faddr = env_get_ulong("fdt_addr_r", 16, 0);
|
||||||
|
|
||||||
|
sysmem_free((phys_addr_t)img);
|
||||||
|
sysmem_free((phys_addr_t)raddr);
|
||||||
|
sysmem_free((phys_addr_t)kaddr);
|
||||||
|
sysmem_free((phys_addr_t)faddr);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int rockchip_read_uimage_dtb(void *fdt_addr, char **hash, int *hash_size)
|
||||||
|
{
|
||||||
|
struct blk_desc *dev_desc;
|
||||||
|
disk_partition_t part;
|
||||||
|
image_header_t *hdr;
|
||||||
|
char *part_name;
|
||||||
|
ulong data, offset;
|
||||||
|
ulong size;
|
||||||
|
#ifdef CONFIG_ROCKCHIP_RESOURCE_IMAGE
|
||||||
|
ulong dst;
|
||||||
|
int idx = 3;
|
||||||
|
#else
|
||||||
|
int idx = 2;
|
||||||
|
#endif
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
dev_desc = rockchip_get_bootdev();
|
||||||
|
if (!dev_desc) {
|
||||||
|
printf("No dev_desc!\n");
|
||||||
|
return ENODEV;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rockchip_get_boot_mode() == BOOT_MODE_RECOVERY)
|
||||||
|
part_name = PART_RECOVERY;
|
||||||
|
else
|
||||||
|
part_name = PART_BOOT;
|
||||||
|
|
||||||
|
if (part_get_info_by_name(dev_desc, part_name, &part) < 0) {
|
||||||
|
UIMG_I("No %s partition\n", part_name);
|
||||||
|
return -ENODEV;
|
||||||
|
}
|
||||||
|
|
||||||
|
hdr = uimage_get_hdr(dev_desc, &part);
|
||||||
|
if (!hdr)
|
||||||
|
return -ENODEV;
|
||||||
|
|
||||||
|
image_multi_getimg(hdr, idx, &data, &size);
|
||||||
|
offset = data - (ulong)hdr;
|
||||||
|
free(hdr);
|
||||||
|
|
||||||
|
#ifdef CONFIG_ROCKCHIP_RESOURCE_IMAGE
|
||||||
|
/* reserve enough space before fdt */
|
||||||
|
dst = (ulong)fdt_addr -
|
||||||
|
ALIGN(size, dev_desc->blksz) - CONFIG_SYS_FDT_PAD;
|
||||||
|
|
||||||
|
ret = uimage_load_one(dev_desc, &part, offset, size, (void *)dst);
|
||||||
|
if (ret) {
|
||||||
|
UIMG_I("Failed to load resource file, ret=%d\n", ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!sysmem_alloc_base(MEM_RESOURCE, (phys_addr_t)dst,
|
||||||
|
ALIGN(size, RK_BLK_SIZE)))
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
|
ret = resource_create_ram_list(dev_desc, (void *)dst);
|
||||||
|
if (ret) {
|
||||||
|
UIMG_I("Failed to create resource list, ret=%d\n", ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("Found DTB in uImage.%d\n", idx);
|
||||||
|
ret = rockchip_read_resource_dtb(fdt_addr, hash, hash_size);
|
||||||
|
#else
|
||||||
|
printf("DTB(uimage.%d): rk-kernel.dtb\n", idx);
|
||||||
|
ret = uimage_load_one(dev_desc, &part, offset, size, fdt_addr);
|
||||||
|
#endif
|
||||||
|
if (ret) {
|
||||||
|
UIMG_I("Failed to load fdt, ret=%d\n", ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue