mirror of
https://github.com/openwrt/openwrt.git
synced 2025-02-18 16:40:29 +00:00
kernel: add parser finding rootfs after CFE bootfs
It's required for BCM4908. It cannot use "bcm-wfi-fw" parser because that one requires *two* JFFS2 partitions which is untested / unsupported on the BCM4908 architecture. With a single JFFS2 partition "bcm-wfi-fw" parser will: 1. Fail to find "vmlinux.lz" as it doesn't follow "1-openwrt" file 2. Create partitions that don't precisely match bootfs layout The new parser is described in details in the MTD_SPLIT_CFE_BOOTFS symbol help message. Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
This commit is contained in:
parent
6ba3a0e889
commit
20b4f77bb6
@ -138,7 +138,8 @@ CONFIG_MTD_NAND_BRCMNAND=y
|
||||
CONFIG_MTD_NAND_CORE=y
|
||||
CONFIG_MTD_NAND_ECC_SW_HAMMING=y
|
||||
CONFIG_MTD_RAW_NAND=y
|
||||
CONFIG_MTD_SPLIT_BCM_WFI_FW=y
|
||||
CONFIG_MTD_SPLIT_CFE_BOOTFS=y
|
||||
# CONFIG_MTD_SPLIT_SQUASHFS_ROOT is not set
|
||||
CONFIG_MTD_UBI=y
|
||||
CONFIG_MTD_UBI_BEB_LIMIT=20
|
||||
CONFIG_MTD_UBI_BLOCK=y
|
||||
|
@ -25,6 +25,18 @@ config MTD_SPLIT_BCM_WFI_FW
|
||||
depends on MTD_SPLIT_SUPPORT
|
||||
select MTD_SPLIT
|
||||
|
||||
config MTD_SPLIT_CFE_BOOTFS
|
||||
bool "Parser finding rootfs appended to the CFE bootfs"
|
||||
depends on MTD_SPLIT_SUPPORT && ARCH_BCM4908
|
||||
select MTD_SPLIT
|
||||
help
|
||||
cferom on BCM4908 (and bcm63xx) uses JFFS2 bootfs partition
|
||||
for storing kernel, cferam and some device specific files.
|
||||
There isn't any straight way of storing rootfs so it gets
|
||||
appended to the JFFS2 bootfs partition. Kernel needs to find
|
||||
it and run init from it. This parser is responsible for
|
||||
finding appended rootfs.
|
||||
|
||||
config MTD_SPLIT_SEAMA_FW
|
||||
bool "Seama firmware parser"
|
||||
depends on MTD_SPLIT_SUPPORT
|
||||
|
@ -1,5 +1,6 @@
|
||||
obj-$(CONFIG_MTD_SPLIT) += mtdsplit.o
|
||||
obj-$(CONFIG_MTD_SPLIT_BCM_WFI_FW) += mtdsplit_bcm_wfi.o
|
||||
obj-$(CONFIG_MTD_SPLIT_CFE_BOOTFS) += mtdsplit_cfe_bootfs.o
|
||||
obj-$(CONFIG_MTD_SPLIT_SEAMA_FW) += mtdsplit_seama.o
|
||||
obj-$(CONFIG_MTD_SPLIT_SQUASHFS_ROOT) += mtdsplit_squashfs.o
|
||||
obj-$(CONFIG_MTD_SPLIT_UIMAGE_FW) += mtdsplit_uimage.o
|
||||
|
@ -0,0 +1,86 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (C) 2021 Rafał Miłecki <rafal@milecki.pl>
|
||||
*/
|
||||
|
||||
#include <linux/init.h>
|
||||
#include <linux/jffs2.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/mtd/mtd.h>
|
||||
#include <linux/mtd/partitions.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/slab.h>
|
||||
|
||||
#include "mtdsplit.h"
|
||||
|
||||
#define je16_to_cpu(x) ((x).v16)
|
||||
#define je32_to_cpu(x) ((x).v32)
|
||||
|
||||
#define NR_PARTS 1
|
||||
|
||||
static int mtdsplit_cfe_bootfs_parse(struct mtd_info *mtd,
|
||||
const struct mtd_partition **pparts,
|
||||
struct mtd_part_parser_data *data)
|
||||
{
|
||||
struct jffs2_raw_dirent node;
|
||||
enum mtdsplit_part_type type;
|
||||
struct mtd_partition *parts;
|
||||
size_t rootfs_offset;
|
||||
size_t retlen;
|
||||
size_t offset;
|
||||
int err;
|
||||
|
||||
/* Don't parse backup partitions */
|
||||
if (strcmp(mtd->name, "firmware"))
|
||||
return -EINVAL;
|
||||
|
||||
/* Find the end of JFFS2 bootfs partition */
|
||||
offset = 0;
|
||||
do {
|
||||
err = mtd_read(mtd, offset, sizeof(node), &retlen, (void *)&node);
|
||||
if (err || retlen != sizeof(node))
|
||||
break;
|
||||
|
||||
if (je16_to_cpu(node.magic) != JFFS2_MAGIC_BITMASK)
|
||||
break;
|
||||
|
||||
offset += je32_to_cpu(node.totlen);
|
||||
offset = (offset + 0x3) & ~0x3;
|
||||
} while (offset < mtd->size);
|
||||
|
||||
/* Find rootfs partition that follows the bootfs */
|
||||
err = mtd_find_rootfs_from(mtd, mtd->erasesize, mtd->size, &rootfs_offset, &type);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
parts = kzalloc(NR_PARTS * sizeof(*parts), GFP_KERNEL);
|
||||
if (!parts)
|
||||
return -ENOMEM;
|
||||
|
||||
if (type == MTDSPLIT_PART_TYPE_UBI)
|
||||
parts[0].name = UBI_PART_NAME;
|
||||
else
|
||||
parts[0].name = ROOTFS_PART_NAME;
|
||||
parts[0].offset = rootfs_offset;
|
||||
parts[0].size = mtd->size - rootfs_offset;
|
||||
|
||||
*pparts = parts;
|
||||
|
||||
return NR_PARTS;
|
||||
}
|
||||
|
||||
static const struct of_device_id mtdsplit_cfe_bootfs_of_match_table[] = {
|
||||
{ .compatible = "brcm,bcm4908-firmware" },
|
||||
{},
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, mtdsplit_cfe_bootfs_of_match_table);
|
||||
|
||||
static struct mtd_part_parser mtdsplit_cfe_bootfs_parser = {
|
||||
.owner = THIS_MODULE,
|
||||
.name = "cfe-bootfs",
|
||||
.of_match_table = mtdsplit_cfe_bootfs_of_match_table,
|
||||
.parse_fn = mtdsplit_cfe_bootfs_parse,
|
||||
};
|
||||
|
||||
module_mtd_part_parser(mtdsplit_cfe_bootfs_parser);
|
Loading…
x
Reference in New Issue
Block a user