Previously, read only root partitions were not detected if they did not use a squashfs filesystem.
Signed-off-by: Jonas Lochmann <[email protected]> --- target/linux/generic/config-6.12 | 1 + .../files/drivers/mtd/mtdsplit/Kconfig | 9 ++ .../files/drivers/mtd/mtdsplit/Makefile | 1 + .../files/drivers/mtd/mtdsplit/mtdsplit.c | 13 ++ .../files/drivers/mtd/mtdsplit/mtdsplit.h | 2 + .../drivers/mtd/mtdsplit/mtdsplit_erofs.c | 138 ++++++++++++++++++ 6 files changed, 164 insertions(+) create mode 100644 target/linux/generic/files/drivers/mtd/mtdsplit/mtdsplit_erofs.c diff --git a/target/linux/generic/config-6.12 b/target/linux/generic/config-6.12 index fda78b422e..5e7d9af098 100644 --- a/target/linux/generic/config-6.12 +++ b/target/linux/generic/config-6.12 @@ -3913,6 +3913,7 @@ CONFIG_MTD_SPLIT=y # CONFIG_MTD_SPLIT_BCM_WFI_FW is not set # CONFIG_MTD_SPLIT_BRNIMAGE_FW is not set # CONFIG_MTD_SPLIT_ELF_FW is not set +CONFIG_MTD_SPLIT_EROFS_ROOT=y # CONFIG_MTD_SPLIT_EVA_FW is not set # CONFIG_MTD_SPLIT_FIRMWARE is not set CONFIG_MTD_SPLIT_FIRMWARE_NAME="firmware" diff --git a/target/linux/generic/files/drivers/mtd/mtdsplit/Kconfig b/target/linux/generic/files/drivers/mtd/mtdsplit/Kconfig index 396becf160..3d64428470 100644 --- a/target/linux/generic/files/drivers/mtd/mtdsplit/Kconfig +++ b/target/linux/generic/files/drivers/mtd/mtdsplit/Kconfig @@ -17,6 +17,15 @@ config MTD_SPLIT_SQUASHFS_ROOT offset and size of the unused portion of a rootfs partition containing a squashfs. +config MTD_SPLIT_EROFS_ROOT + bool "EROFS based root partition parser" + depends on MTD_SPLIT_SUPPORT + select MTD_SPLIT + help + This provides a parsing function which allows to detect the + offset and size of the unused portion of a rootfs partition + containing a erofs. + comment "Firmware partition parsers" config MTD_SPLIT_BCM63XX_FW diff --git a/target/linux/generic/files/drivers/mtd/mtdsplit/Makefile b/target/linux/generic/files/drivers/mtd/mtdsplit/Makefile index b85ce5d21f..e6f3d2c3e4 100644 --- a/target/linux/generic/files/drivers/mtd/mtdsplit/Makefile +++ b/target/linux/generic/files/drivers/mtd/mtdsplit/Makefile @@ -5,6 +5,7 @@ obj-$(CONFIG_MTD_SPLIT_CFE_BOOTFS) += mtdsplit_cfe_bootfs.o obj-$(CONFIG_MTD_SPLIT_SEAMA_FW) += mtdsplit_seama.o obj-$(CONFIG_MTD_SPLIT_SEIL_FW) += mtdsplit_seil.o obj-$(CONFIG_MTD_SPLIT_SQUASHFS_ROOT) += mtdsplit_squashfs.o +obj-$(CONFIG_MTD_SPLIT_EROFS_ROOT) += mtdsplit_erofs.o obj-$(CONFIG_MTD_SPLIT_UIMAGE_FW) += mtdsplit_uimage.o obj-$(CONFIG_MTD_SPLIT_FIT_FW) += mtdsplit_fit.o obj-$(CONFIG_MTD_SPLIT_LZMA_FW) += mtdsplit_lzma.o diff --git a/target/linux/generic/files/drivers/mtd/mtdsplit/mtdsplit.c b/target/linux/generic/files/drivers/mtd/mtdsplit/mtdsplit.c index 42edb97c3a..ce72e8939b 100644 --- a/target/linux/generic/files/drivers/mtd/mtdsplit/mtdsplit.c +++ b/target/linux/generic/files/drivers/mtd/mtdsplit/mtdsplit.c @@ -3,6 +3,7 @@ * Copyright (C) 2009-2013 Gabor Juhos <[email protected]> * Copyright (C) 2012 Jonas Gorski <[email protected]> * Copyright (C) 2013 Hauke Mehrtens <[email protected]> + * Copyright (C) 2025 Jonas Lochmann <[email protected]> * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 as published @@ -101,6 +102,18 @@ int mtd_check_rootfs_magic(struct mtd_info *mtd, size_t offset, return 0; } + ret = mtd_read(mtd, offset + 1024, sizeof(magic), &retlen, + (unsigned char *) &magic); + + if (ret) + return ret; + + if (magic == EROFS_SUPER_MAGIC_V1) { + if (type) + *type = MTDSPLIT_PART_TYPE_EROFS; + return 0; + } + return -EINVAL; } EXPORT_SYMBOL_GPL(mtd_check_rootfs_magic); diff --git a/target/linux/generic/files/drivers/mtd/mtdsplit/mtdsplit.h b/target/linux/generic/files/drivers/mtd/mtdsplit/mtdsplit.h index 1d3f031733..8d9c084f28 100644 --- a/target/linux/generic/files/drivers/mtd/mtdsplit/mtdsplit.h +++ b/target/linux/generic/files/drivers/mtd/mtdsplit/mtdsplit.h @@ -3,6 +3,7 @@ * Copyright (C) 2009-2013 Gabor Juhos <[email protected]> * Copyright (C) 2012 Jonas Gorski <[email protected]> * Copyright (C) 2013 Hauke Mehrtens <[email protected]> + * Copyright (C) 2025 Jonas Lochmann <[email protected]> * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 as published @@ -24,6 +25,7 @@ enum mtdsplit_part_type { MTDSPLIT_PART_TYPE_SQUASHFS, MTDSPLIT_PART_TYPE_JFFS2, MTDSPLIT_PART_TYPE_UBI, + MTDSPLIT_PART_TYPE_EROFS, }; #ifdef CONFIG_MTD_SPLIT diff --git a/target/linux/generic/files/drivers/mtd/mtdsplit/mtdsplit_erofs.c b/target/linux/generic/files/drivers/mtd/mtdsplit/mtdsplit_erofs.c new file mode 100644 index 0000000000..bf1287cf59 --- /dev/null +++ b/target/linux/generic/files/drivers/mtd/mtdsplit/mtdsplit_erofs.c @@ -0,0 +1,138 @@ +/* + * Copyright (C) 2009-2013 Gabor Juhos <[email protected]> + * Copyright (C) 2012 Jonas Gorski <[email protected]> + * Copyright (C) 2013 Hauke Mehrtens <[email protected]> + * Copyright (C) 2013 Felix Fietkau <[email protected]> + * Copyright (C) 2025 Jonas Lochmann <[email protected]> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published + * by the Free Software Foundation. + * + */ + +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + +#include <linux/module.h> +#include <linux/init.h> +#include <linux/kernel.h> +#include <linux/slab.h> +#include <linux/magic.h> +#include <linux/mtd/mtd.h> +#include <linux/mtd/partitions.h> +#include <linux/byteorder/generic.h> + +#include "mtdsplit.h" + +struct erofs_super_block { + __le32 magic; + __le32 pad1[2]; + __u8 blkszbits; + __u8 pad2; + __le16 pad3; + __le32 pad4[5]; + __le32 blocks; +}; + +static int mtd_get_erofs_len(struct mtd_info *master, + size_t offset, + size_t *erofs_len) +{ + struct erofs_super_block sb; + size_t retlen, blksz; + int err; + + err = mtd_read(master, offset + 1024, sizeof(sb), &retlen, (void *)&sb); + if (err || (retlen != sizeof(sb))) { + pr_alert("error occured while reading from \"%s\"\n", + master->name); + return -EIO; + } + + if (le32_to_cpu(sb.magic) != EROFS_SUPER_MAGIC_V1) { + pr_alert("no erofs found in \"%s\"\n", master->name); + return -EINVAL; + } + + blksz = 1 << sb.blkszbits; + + // this catches overflows too as the number goes negative + // or reaches zero in case of an overflow + if (blksz < 512) { + pr_alert("erofs has invalid blkszbits in \"%s\"\n", master->name); + return -EINVAL; + } + + int blocks = le32_to_cpu(sb.blocks); + + retlen = blksz * blocks; + + if (retlen / blksz != blocks) { + pr_alert("erofs size overflow in \"%s\"\n", master->name); + return -ENOENT; + } + + if (retlen <= 0) { + pr_alert("erofs is empty in \"%s\"\n", master->name); + return -ENOENT; + } + + if (offset + retlen > master->size) { + pr_alert("erofs has invalid size in \"%s\"\n", + master->name); + return -EINVAL; + } + + *erofs_len = retlen; + return 0; +} + +static int +mtdsplit_parse_erofs(struct mtd_info *master, + const struct mtd_partition **pparts, + struct mtd_part_parser_data *data) +{ + struct mtd_partition *part; + struct mtd_info *parent_mtd; + size_t part_offset; + size_t erofs_len; + int err; + + err = mtd_get_erofs_len(master, 0, &erofs_len); + if (err) + return err; + + parent_mtd = mtd_get_master(master); + part_offset = mtdpart_get_offset(master); + + part = kzalloc(sizeof(*part), GFP_KERNEL); + if (!part) { + pr_alert("unable to allocate memory for \"%s\" partition\n", + ROOTFS_SPLIT_NAME); + return -ENOMEM; + } + + part->name = ROOTFS_SPLIT_NAME; + part->offset = mtd_roundup_to_eb(part_offset + erofs_len, + parent_mtd) - part_offset; + part->size = mtd_rounddown_to_eb(master->size - part->offset, master); + + *pparts = part; + return 1; +} + +static struct mtd_part_parser mtdsplit_erofs_parser = { + .owner = THIS_MODULE, + .name = "erofs-split", + .parse_fn = mtdsplit_parse_erofs, + .type = MTD_PARSER_TYPE_ROOTFS, +}; + +static int __init mtdsplit_erofs_init(void) +{ + register_mtd_parser(&mtdsplit_erofs_parser); + + return 0; +} + +subsys_initcall(mtdsplit_erofs_init); -- 2.47.3 _______________________________________________ openwrt-devel mailing list [email protected] https://lists.openwrt.org/mailman/listinfo/openwrt-devel
