mediatek: add mtd multi layout support for ubi images
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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 \
|
||||
|
||||
83
uboot-mtk-20220606/board/mediatek/common/mtd_layout.c
Normal file
83
uboot-mtk-20220606/board/mediatek/common/mtd_layout.c
Normal 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);
|
||||
}
|
||||
@@ -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);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user