uboot: support mainline FIT image

Signed-off-by: Tianling Shen <cnsztl@immortalwrt.org>
This commit is contained in:
Tianling Shen
2024-09-08 17:16:52 +08:00
committed by hanwckf
parent 1dbebb4242
commit 68913c964f
10 changed files with 199 additions and 9 deletions

View File

@@ -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:

View File

@@ -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);

View File

@@ -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 */
}

View File

@@ -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();

View File

@@ -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 */
}

View File

@@ -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();

View File

@@ -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);
}

View File

@@ -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;

View File

@@ -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);

View File

@@ -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);