mediatek: add mtd multi layout support for ubi images

This commit is contained in:
hanwckf
2023-07-20 00:35:33 +08:00
parent 2c6abac4c9
commit 9d992f1b9e
4 changed files with 170 additions and 3 deletions

View File

@@ -121,3 +121,8 @@ config MTK_DUAL_BOOT_ROOTFS_DATA_NAME
string "Name for rootfs_data of both image slots"
depends on MTK_DUAL_BOOT_SHARED_ROOTFS_DATA
default "rootfs_data"
config MEDIATEK_MULTI_MTD_LAYOUT
bool "Enable multi mtd layout support"
select SYS_MTDPARTS_RUNTIME
default n

View File

@@ -9,6 +9,7 @@ obj-$(CONFIG_MEDIATEK_BOOTMENU) += load_data.o upgrade_helper.o boot_helper.o \
dm_parser.o
ifdef CONFIG_MTD
obj-$(CONFIG_MEDIATEK_BOOTMENU) += ubi_helper.o
obj-$(CONFIG_MEDIATEK_MULTI_MTD_LAYOUT) += mtd_layout.o
endif
obj-$(CONFIG_MEDIATEK_BOOTMENU) += cmd_mtkupgrade.o cmd_mtkload.o \

View File

@@ -0,0 +1,83 @@
// SPDX-License-Identifier: GPL-2.0+
#include <common.h>
#include <command.h>
#include <env.h>
#include <mtd_node.h>
#include <linux/mtd/mtd.h>
#include <linux/string.h>
#include <dm/ofnode.h>
static ofnode ofnode_get_mtd_layout(const char *layout_label)
{
ofnode node, layout;
const char *label;
node = ofnode_path("/mtd-layout");
if (!ofnode_valid(node)) {
return ofnode_null();
}
if (!ofnode_get_child_count(node)) {
return ofnode_null();
}
ofnode_for_each_subnode(layout, node) {
label = ofnode_read_string(layout, "label");
if (!strcmp(layout_label, label)) {
return layout;
}
}
return ofnode_null();
}
#define MTD_LABEL_MAXLEN 32
void board_mtdparts_default(const char **mtdids, const char **mtdparts)
{
const char *ids = NULL;
const char *parts = NULL;
const char *layout_label = NULL;
const char *boot_part = NULL;
const char *factory_part = NULL;
const char *sysupgrade_kernel_ubipart = NULL;
const char *sysupgrade_rootfs_ubipart = NULL;
const char *cmdline = NULL;
static char tmp_label[MTD_LABEL_MAXLEN];
ofnode layout_node;
// try to get mtd layout from fdt
if (gd->flags & GD_FLG_ENV_READY)
layout_label = env_get("mtd_layout_label");
else if (env_get_f("mtd_layout_label", tmp_label, sizeof(tmp_label)) != -1)
layout_label = tmp_label;
if (!layout_label)
layout_label = "default";
layout_node = ofnode_get_mtd_layout(layout_label);
if (ofnode_valid(layout_node)) {
ids = ofnode_read_string(layout_node, "mtdids");
parts = ofnode_read_string(layout_node, "mtdparts");
boot_part = ofnode_read_string(layout_node, "boot_part");
factory_part = ofnode_read_string(layout_node, "factory_part");
sysupgrade_kernel_ubipart = ofnode_read_string(layout_node, "sysupgrade_kernel_ubipart");
sysupgrade_rootfs_ubipart = ofnode_read_string(layout_node, "sysupgrade_rootfs_ubipart");
cmdline = ofnode_read_string(layout_node, "cmdline");
}
if (ids && parts) {
*mtdids = ids;
*mtdparts = parts;
//printf("%s: mtdids=%s & mtdparts=%s\n", __func__, ids, parts);
}
env_set("bootargs", cmdline);
env_set("ubi_boot_part", boot_part);
env_set("factory_part", factory_part);
env_set("sysupgrade_kernel_ubipart", sysupgrade_kernel_ubipart);
env_set("sysupgrade_rootfs_ubipart", sysupgrade_rootfs_ubipart);
}

View File

@@ -429,6 +429,49 @@ 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)
{
const void *kernel_data, *rootfs_data;
size_t kernel_size, rootfs_size;
int ret;
ret = parse_tar_image(data, size, &kernel_data, &kernel_size,
&rootfs_data, &rootfs_size);
if (ret)
return ret;
ret = mount_ubi(mtd_kernel);
if (ret)
return ret;
ret = update_ubi_volume("kernel", -1, kernel_data, kernel_size);
if (ret)
goto out;
umount_ubi();
ret = mount_ubi(mtd_rootfs);
if (ret)
return ret;
/* Remove this volume first in case of no enough PEBs */
remove_ubi_volume("rootfs_data");
ret = update_ubi_volume("rootfs", -1, rootfs_data, rootfs_size);
if (ret)
goto out;
ret = create_ubi_volume("rootfs_data", 0, -1, true);
out:
umount_ubi();
return ret;
}
#endif
static int write_ubi2_tar_image(const void *data, size_t size,
struct mtd_info *mtd)
{
@@ -492,6 +535,12 @@ int ubi_upgrade_image(const void *data, size_t size)
struct owrt_image_info ii;
struct mtd_info *mtd, *mtd_kernel;
int ret;
const char *ubi_flash_part = "ubi";
#ifdef CONFIG_MEDIATEK_MULTI_MTD_LAYOUT
struct mtd_info *mtd_ubikernel, *mtd_ubirootfs;
const char *ubi_kernel_part;
const char *ubi_rootfs_part;
#endif
ubi_probe_mtd_devices();
@@ -501,7 +550,13 @@ int ubi_upgrade_image(const void *data, size_t size)
else
mtd_kernel = NULL;
mtd = get_mtd_device_nm("ubi");
#ifdef CONFIG_MEDIATEK_MULTI_MTD_LAYOUT
ubi_flash_part = env_get("factory_part");
if (!ubi_flash_part)
ubi_flash_part = "ubi";
#endif
mtd = get_mtd_device_nm(ubi_flash_part);
if (!IS_ERR_OR_NULL(mtd)) {
put_mtd_device(mtd);
@@ -521,8 +576,24 @@ int ubi_upgrade_image(const void *data, size_t size)
if (!ret && ii.type == IMAGE_UBI2)
return mtd_update_generic(mtd, data, size);
if (!ret && ii.type == IMAGE_TAR)
if (!ret && ii.type == IMAGE_TAR) {
#ifdef CONFIG_MEDIATEK_MULTI_MTD_LAYOUT
ubi_kernel_part = env_get("sysupgrade_kernel_ubipart");
ubi_rootfs_part = env_get("sysupgrade_rootfs_ubipart");
if (ubi_kernel_part && ubi_rootfs_part) {
mtd_ubikernel = get_mtd_device_nm(ubi_kernel_part);
mtd_ubirootfs = get_mtd_device_nm(ubi_rootfs_part);
if (!IS_ERR_OR_NULL(mtd_ubikernel) && !IS_ERR_OR_NULL(mtd_ubirootfs)) {
put_mtd_device(mtd_ubikernel);
put_mtd_device(mtd_ubirootfs);
return write_ubi2_tar_image_separate(data, size, mtd_ubikernel, mtd_ubirootfs);
} else {
return -ENOTSUPP;
}
}
#endif
return write_ubi2_tar_image(data, size, mtd);
}
}
}
@@ -541,6 +612,7 @@ int ubi_upgrade_image(const void *data, size_t size)
int ubi_boot_image(void)
{
struct mtd_info *mtd, *mtd_kernel;
const char *ubi_boot_part = "ubi";
ubi_probe_mtd_devices();
@@ -550,7 +622,13 @@ int ubi_boot_image(void)
else
mtd_kernel = NULL;
mtd = get_mtd_device_nm("ubi");
#ifdef CONFIG_MEDIATEK_MULTI_MTD_LAYOUT
ubi_boot_part = env_get("ubi_boot_part");
if (!ubi_boot_part)
ubi_boot_part = "ubi";
#endif
mtd = get_mtd_device_nm(ubi_boot_part);
if (!IS_ERR_OR_NULL(mtd)) {
put_mtd_device(mtd);