uboot: support mainline FIT image
Signed-off-by: Tianling Shen <cnsztl@immortalwrt.org>
This commit is contained in:
@@ -25,8 +25,12 @@
|
||||
int boot_from_mem(ulong data_load_addr)
|
||||
{
|
||||
char cmd[64];
|
||||
const char *bootconf = env_get("bootconf");
|
||||
|
||||
snprintf(cmd, sizeof(cmd), "bootm 0x%lx", data_load_addr);
|
||||
if (bootconf && strlen(bootconf) > 0)
|
||||
snprintf(cmd, sizeof(cmd), "bootm 0x%lx#%s", data_load_addr, bootconf);
|
||||
else
|
||||
snprintf(cmd, sizeof(cmd), "bootm 0x%lx", data_load_addr);
|
||||
|
||||
return run_command(cmd, 0);
|
||||
}
|
||||
@@ -57,7 +61,16 @@ static int _boot_from_mmc(u32 dev, struct mmc *mmc, u64 offset)
|
||||
#endif
|
||||
#if defined(CONFIG_FIT)
|
||||
case IMAGE_FORMAT_FIT:
|
||||
size = fit_get_size((const void *)data_load_addr);
|
||||
size = fit_get_totalsize((const void *)data_load_addr);
|
||||
if (size <= 0x2000) {
|
||||
/* Load FDT header into memory */
|
||||
ret = _mmc_read(mmc, offset, (void *)data_load_addr, size);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* Read whole FIT image */
|
||||
size = fit_get_totalsize((const void *)data_load_addr);
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
|
||||
@@ -511,6 +511,50 @@ out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int write_ubi_fit_image(const void *data, size_t size,
|
||||
struct mtd_info *mtd)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = mount_ubi(mtd);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (!find_ubi_volume("fit")) {
|
||||
/* ubi is dirty, erase ubi and recreate volumes */
|
||||
umount_ubi();
|
||||
ret = mtd_erase_generic(mtd, 0, mtd->size);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = mount_ubi(mtd);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = create_ubi_volume("ubootenv", 0x100000, -1, false);
|
||||
if (ret)
|
||||
goto out;
|
||||
|
||||
ret = create_ubi_volume("ubootenv2", 0x100000, -1, false);
|
||||
if (ret)
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* Remove this volume first in case of no enough PEBs */
|
||||
remove_ubi_volume("rootfs_data");
|
||||
|
||||
ret = update_ubi_volume("fit", -1, data, size);
|
||||
if (ret)
|
||||
goto out;
|
||||
|
||||
ret = create_ubi_volume("rootfs_data", 0, -1, true);
|
||||
|
||||
out:
|
||||
umount_ubi();
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int boot_from_ubi(struct mtd_info *mtd)
|
||||
{
|
||||
ulong data_load_addr;
|
||||
@@ -528,6 +572,8 @@ static int boot_from_ubi(struct mtd_info *mtd)
|
||||
return ret;
|
||||
|
||||
ret = read_ubi_volume("kernel", (void *)data_load_addr, 0);
|
||||
if (ret == -ENODEV)
|
||||
ret = read_ubi_volume("fit", (void *)data_load_addr, 0);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
@@ -577,6 +623,9 @@ int ubi_upgrade_image(const void *data, size_t size)
|
||||
} else {
|
||||
ret = parse_image_ram(data, size, mtd->erasesize, &ii);
|
||||
|
||||
if (ii.header_type == HEADER_FIT)
|
||||
return write_ubi_fit_image(data, size, mtd);
|
||||
|
||||
if (!ret && ii.type == IMAGE_UBI2)
|
||||
return mtd_update_generic(mtd, data, size);
|
||||
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
#include <asm/global_data.h>
|
||||
#include <command.h>
|
||||
#include <fdtdec.h>
|
||||
#include <image.h>
|
||||
#include <linux/sizes.h>
|
||||
#include <errno.h>
|
||||
#include <dm/ofnode.h>
|
||||
@@ -37,6 +38,7 @@ DECLARE_GLOBAL_DATA_PTR;
|
||||
#define GPT_MAX_SIZE (34 * 512)
|
||||
|
||||
#define PART_FIP_NAME "fip"
|
||||
#define PART_PRODUCTION_NAME "production"
|
||||
#define PART_KERNEL_NAME "kernel"
|
||||
#define PART_ROOTFS_NAME "rootfs"
|
||||
|
||||
@@ -145,6 +147,20 @@ int write_firmware(void *priv, const struct data_part_entry *dpe,
|
||||
u32 slot;
|
||||
#endif /* CONFIG_MTK_DUAL_BOOT */
|
||||
|
||||
/* FIT image logic */
|
||||
if (genimg_get_format(data) == IMAGE_FORMAT_FIT) {
|
||||
ret = write_part(PART_PRODUCTION_NAME, data, size, true);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* Mark rootfs_data unavailable */
|
||||
rootfs_data_offs = (size + ROOTDEV_OVERLAY_ALIGN - 1) &
|
||||
(~(ROOTDEV_OVERLAY_ALIGN - 1));
|
||||
erase_part(PART_PRODUCTION_NAME, rootfs_data_offs, SZ_512K);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = parse_tar_image(data, size, &kernel_data, &kernel_size,
|
||||
&rootfs_data, &rootfs_size);
|
||||
if (ret)
|
||||
@@ -273,7 +289,13 @@ int board_boot_default(void)
|
||||
|
||||
return dual_boot_mmc(&mbd);
|
||||
#else
|
||||
return boot_from_mmc_partition(EMMC_DEV_INDEX, 0, PART_KERNEL_NAME);
|
||||
int ret;
|
||||
|
||||
ret = boot_from_mmc_partition(EMMC_DEV_INDEX, 0, PART_KERNEL_NAME);
|
||||
if (ret == -ENODEV)
|
||||
return boot_from_mmc_partition(EMMC_DEV_INDEX, 0, PART_PRODUCTION_NAME);
|
||||
|
||||
return ret;
|
||||
#endif /* CONFIG_MTK_DUAL_BOOT */
|
||||
}
|
||||
|
||||
|
||||
@@ -91,7 +91,7 @@ static int write_flash_image(void *priv, const struct data_part_entry *dpe,
|
||||
static int erase_env(void *priv, const struct data_part_entry *dpe,
|
||||
const void *data, size_t size)
|
||||
{
|
||||
#if !defined(CONFIG_MTK_SECURE_BOOT) && !defined(CONFIG_ENV_IS_NOWHERE)
|
||||
#if !defined(CONFIG_MTK_SECURE_BOOT) && defined(CONFIG_ENV_IS_IN_MTD)
|
||||
struct mtd_info *mtd;
|
||||
|
||||
ubi_probe_mtd_devices();
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
#include <asm/global_data.h>
|
||||
#include <command.h>
|
||||
#include <fdtdec.h>
|
||||
#include <image.h>
|
||||
#include <linux/sizes.h>
|
||||
#include <errno.h>
|
||||
#include <dm/ofnode.h>
|
||||
@@ -37,6 +38,7 @@ DECLARE_GLOBAL_DATA_PTR;
|
||||
#define GPT_MAX_SIZE (34 * 512)
|
||||
|
||||
#define PART_FIP_NAME "fip"
|
||||
#define PART_PRODUCTION_NAME "production"
|
||||
#define PART_KERNEL_NAME "kernel"
|
||||
#define PART_ROOTFS_NAME "rootfs"
|
||||
|
||||
@@ -145,6 +147,20 @@ int write_firmware(void *priv, const struct data_part_entry *dpe,
|
||||
u32 slot;
|
||||
#endif /* CONFIG_MTK_DUAL_BOOT */
|
||||
|
||||
/* FIT image logic */
|
||||
if (genimg_get_format(data) == IMAGE_FORMAT_FIT) {
|
||||
ret = write_part(PART_PRODUCTION_NAME, data, size, true);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* Mark rootfs_data unavailable */
|
||||
rootfs_data_offs = (size + ROOTDEV_OVERLAY_ALIGN - 1) &
|
||||
(~(ROOTDEV_OVERLAY_ALIGN - 1));
|
||||
erase_part(PART_PRODUCTION_NAME, rootfs_data_offs, SZ_512K);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = parse_tar_image(data, size, &kernel_data, &kernel_size,
|
||||
&rootfs_data, &rootfs_size);
|
||||
if (ret)
|
||||
@@ -273,7 +289,13 @@ int board_boot_default(void)
|
||||
|
||||
return dual_boot_mmc(&mbd);
|
||||
#else
|
||||
return boot_from_mmc_partition(EMMC_DEV_INDEX, 0, PART_KERNEL_NAME);
|
||||
int ret;
|
||||
|
||||
ret = boot_from_mmc_partition(EMMC_DEV_INDEX, 0, PART_KERNEL_NAME);
|
||||
if (ret == -ENODEV)
|
||||
return boot_from_mmc_partition(EMMC_DEV_INDEX, 0, PART_PRODUCTION_NAME);
|
||||
|
||||
return ret;
|
||||
#endif /* CONFIG_MTK_DUAL_BOOT */
|
||||
}
|
||||
|
||||
|
||||
@@ -91,7 +91,7 @@ static int write_flash_image(void *priv, const struct data_part_entry *dpe,
|
||||
static int erase_env(void *priv, const struct data_part_entry *dpe,
|
||||
const void *data, size_t size)
|
||||
{
|
||||
#if !defined(CONFIG_MTK_SECURE_BOOT) && !defined(CONFIG_ENV_IS_NOWHERE)
|
||||
#if !defined(CONFIG_MTK_SECURE_BOOT) && defined(CONFIG_ENV_IS_IN_MTD)
|
||||
struct mtd_info *mtd;
|
||||
|
||||
ubi_probe_mtd_devices();
|
||||
|
||||
@@ -22,8 +22,12 @@
|
||||
int boot_from_mem(ulong data_load_addr)
|
||||
{
|
||||
char cmd[64];
|
||||
const char *bootconf = env_get("bootconf");
|
||||
|
||||
snprintf(cmd, sizeof(cmd), "bootm 0x%lx", data_load_addr);
|
||||
if (bootconf && strlen(bootconf) > 0)
|
||||
snprintf(cmd, sizeof(cmd), "bootm 0x%lx#%s", data_load_addr, bootconf);
|
||||
else
|
||||
snprintf(cmd, sizeof(cmd), "bootm 0x%lx", data_load_addr);
|
||||
|
||||
return run_command(cmd, 0);
|
||||
}
|
||||
|
||||
@@ -331,6 +331,7 @@ static int erase_env(void *priv, const struct data_part_entry *dpe,
|
||||
return -EIO;
|
||||
|
||||
ubi_remove_vol(CONFIG_ENV_UBI_VOLUME);
|
||||
create_ubi_volume(CONFIG_ENV_UBI_VOLUME, CONFIG_ENV_SIZE, UBI_VID_OFFSET, false);
|
||||
ubi_exit();
|
||||
#else
|
||||
struct mtd_info *mtd;
|
||||
|
||||
@@ -36,6 +36,7 @@
|
||||
*/
|
||||
#define ROOTDEV_OVERLAY_ALIGN (64ULL * 1024ULL)
|
||||
|
||||
#define PART_PRODUCTION_NAME "production"
|
||||
#define PART_KERNEL_NAME "kernel"
|
||||
#define PART_ROOTFS_NAME "rootfs"
|
||||
|
||||
@@ -691,7 +692,16 @@ static int _boot_from_mmc(struct mmc *mmc, u64 offset)
|
||||
#endif
|
||||
#if defined(CONFIG_FIT)
|
||||
case IMAGE_FORMAT_FIT:
|
||||
size = fit_get_size((const void *)data_load_addr);
|
||||
size = fit_get_totalsize((const void *)data_load_addr);
|
||||
if (size <= 0x2000) {
|
||||
/* Load FDT header into memory */
|
||||
ret = _mmc_read(mmc, offset, (void *)data_load_addr, size);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* Read whole FIT image */
|
||||
size = fit_get_totalsize((const void *)data_load_addr);
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
@@ -965,10 +975,17 @@ static int mmc_dual_boot(u32 dev)
|
||||
|
||||
int mmc_boot_image(u32 dev)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (IS_ENABLED(CONFIG_MTK_DUAL_BOOT))
|
||||
return mmc_dual_boot(dev);
|
||||
|
||||
return boot_from_mmc_partition(dev, 0, PART_KERNEL_NAME);
|
||||
ret = boot_from_mmc_partition(dev, 0, PART_KERNEL_NAME);
|
||||
if (ret == -ENOENT) {
|
||||
return boot_from_mmc_partition(dev, 0, PART_PRODUCTION_NAME);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int mmc_upgrade_image(u32 dev, const void *data, size_t size)
|
||||
@@ -980,6 +997,20 @@ int mmc_upgrade_image(u32 dev, const void *data, size_t size)
|
||||
u32 slot;
|
||||
int ret;
|
||||
|
||||
/* FIT image logic */
|
||||
if (genimg_get_format(data) == IMAGE_FORMAT_FIT) {
|
||||
ret = mmc_write_part(dev, 0, PART_PRODUCTION_NAME, data, size, true);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* Mark rootfs_data unavailable */
|
||||
rootfs_data_offs = (size + ROOTDEV_OVERLAY_ALIGN - 1) &
|
||||
(~(ROOTDEV_OVERLAY_ALIGN - 1));
|
||||
mmc_erase_part(dev, 0, PART_PRODUCTION_NAME, rootfs_data_offs, SZ_512K);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (IS_ENABLED(CONFIG_MTK_DUAL_BOOT)) {
|
||||
slot = dual_boot_get_next_slot();
|
||||
printf("Upgrading image slot %u ...\n", slot);
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
|
||||
#define PART_UBI_NAME "ubi"
|
||||
#define PART_FIRMWARE_NAME "firmware"
|
||||
#define PART_FIT_NAME "fit"
|
||||
#define PART_KERNEL_NAME "kernel"
|
||||
#define PART_ROOTFS_NAME "rootfs"
|
||||
#define PART_ROOTFS_DATA_NAME "rootfs_data"
|
||||
@@ -634,6 +635,48 @@ static int read_ubi_volume(const char *volume, void *buff, size_t size)
|
||||
return ubi_volume_read((char *)volume, buff, size);
|
||||
}
|
||||
|
||||
static int write_ubi_fit_image(const void *data, size_t size,
|
||||
struct mtd_info *mtd)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = mount_ubi(mtd, true);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (!ubi_find_volume(PART_FIT_NAME)) {
|
||||
/* ubi is dirty, erase ubi and recreate volumes */
|
||||
ubi_exit();
|
||||
ret = mtd_erase_skip_bad(mtd, 0, size, mtd->size, NULL, NULL, true);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = mount_ubi(mtd, true);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = create_ubi_volume("ubootenv", 0x100000, -1, false);
|
||||
if (ret)
|
||||
goto out;
|
||||
|
||||
ret = create_ubi_volume("ubootenv2", 0x100000, -1, false);
|
||||
if (ret)
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* Remove this volume first in case of no enough PEBs */
|
||||
remove_ubi_volume(PART_ROOTFS_DATA_NAME);
|
||||
|
||||
ret = update_ubi_volume(PART_FIT_NAME, -1, data, size);
|
||||
if (ret)
|
||||
goto out;
|
||||
|
||||
ret = create_ubi_volume(PART_ROOTFS_DATA_NAME, 0, -1, true);
|
||||
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_MEDIATEK_MULTI_MTD_LAYOUT
|
||||
static int write_ubi2_tar_image_separate(const void *data, size_t size,
|
||||
struct mtd_info *mtd_kernel, struct mtd_info *mtd_rootfs)
|
||||
@@ -988,6 +1031,8 @@ static int boot_from_ubi(struct mtd_info *mtd)
|
||||
return ret;
|
||||
|
||||
ret = read_ubi_volume(PART_KERNEL_NAME, (void *)data_load_addr, 0);
|
||||
if (ret == ENODEV)
|
||||
ret = read_ubi_volume(PART_FIT_NAME, (void *)data_load_addr, 0);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
@@ -1067,6 +1112,9 @@ int mtd_upgrade_image(const void *data, size_t size)
|
||||
} else {
|
||||
ret = parse_image_ram(data, size, mtd->erasesize, &ii);
|
||||
|
||||
if (ii.header_type == HEADER_FIT)
|
||||
return write_ubi_fit_image(data, size, mtd);
|
||||
|
||||
if (!ret && ii.type == IMAGE_UBI2 &&
|
||||
!IS_ENABLED(CONFIG_MTK_DUAL_BOOT))
|
||||
return mtd_update_generic(mtd, data, size, true);
|
||||
|
||||
Reference in New Issue
Block a user