[UBI]为AM335x uboot 移植UBI UBIFS功能

本文详细介绍了如何修改U-Boot配置文件以解决UBI相关问题,包括增加配置项、调整内存分配大小以及修复生成spl/u-boot-spl.lds文件时的错误。同时,通过修改配置解决了在进行ubiwrite操作时出现的错误。

1.修改配置文件include/configs/devkit8600.h,添加

/* lc add for ubi */

#define CONFIG_CMD_UBI
#define CONFIG_CMD_UBIFS
#define CONFIG_CMD_MTDPARTS
#define CONFIG_MTD_DEVICE
#define CONFIG_MTD_PARTITIONS
#define CONFIG_RBTREE
#define CONFIG_LZO
    
#define MTDIDS_DEFAULT "nand0=nand0"
#define MTDPARTS_DEFAULT "mtdparts=nand0:0x80000(spl),0x200000(u-boot),0x500000(kernel),0x19000000(rootfs),-(reserved)"
#define MTD_ACTIVE_PART "nand0,3"
    

/* lc add for ubi end */


2.出现错误

build.c:50:2: error: #error Malloc area too small for UBI, increase CONFIG_SYS_MALLOC_LEN to >= 512k

修改include/configs/devkit8600.h

//#define CONFIG_SYS_MALLOC_LEN        (CONFIG_ENV_SIZE + (32 * 1024))
#define CONFIG_SYS_MALLOC_LEN        (CONFIG_ENV_SIZE + (512 * 1024))


3.出现错误

arm-none-linux-gnueabi-ld:/contec/liuchang/am335x/uboot_ok1/spl/u-boot-spl.lds:1: ignoring invalid character `#' in expression
arm-none-linux-gnueabi-ld:/contec/liuchang/am335x/uboot_ok1/spl/u-boot-spl.lds:1: syntax error

修改include/configs/devkit8600.h
//#define CONFIG_SYS_MALLOC_LEN        (CONFIG_ENV_SIZE + (32 * 1024)) 删除,

否则生成的spl/u-boot-spl.lds 包含这一行


4.在ubi write 时 出现错误

Cannot start volume update

因為CONFIG_SYS_MALLOC_LEN 设置的太小,修改

#define CONFIG_SYS_MALLOC_LEN        (CONFIG_ENV_SIZE + (512 * 1024))


#define CONFIG_SYS_MALLOC_LEN        (CONFIG_ENV_SIZE + (1024 * 1024))



<think>我们被要求检查用户提供的bootargs环境变量配置是否存在问题。配置如下: "init=/linuxrc ubi.mtd=2 root=ubi0:rootfs rootfstype=ubifs ro ubi.mtd=3 sys=ubi1:system rootfstype=ubifs ro mtdparts=sfc0_nand:1M(uboot),3M(kernel),20M(root),-(appfs)" 根据引用[1]和[2]以及之前的知识,我们来分析这个bootargs配置。 首先,我们分解这个bootargs字符串: 1. `init=/linuxrc`:指定init程序,没有问题。 2. `ubi.mtd=2`:指示将mtd2分区附加到UBI上(作为UBI设备)。注意,这里指定的是mtd分区编号。 3. `root=ubi0:rootfs`:指定根文件系统在ubi0设备上的名为rootfs的卷上。这里ubi0是由前面的`ubi.mtd=2`创建的,所以mtd2被附加为ubi0。 4. `rootfstype=ubifs`:根文件系统类型为UBIFS,正确。 5. `ro`:以只读方式挂载根文件系统。 6. `ubi.mtd=3`:这里再次出现ubi.mtd,它指示将mtd3分区附加到UBI上。由于之前已经有一个ubi.mtd=2,这里应该是创建另一个UBI设备。根据UBI的规则,每个mtd分区附加到一个UBI设备,所以这里mtd3会被附加到ubi1(因为ubi0已经被占用)。 7. `sys=ubi1:system`:这里定义了一个参数sys,其值为ubi1:system。这个参数可能是给内核传递的,内核本身不会处理,需要用户空间程序来解析。它可能表示系统分区在ubi1上的system卷。 8. `rootfstype=ubifs ro`:这里再次指定了rootfstype和ro,但注意,这个ro是针对前面的sys分区的吗?从语法上看,它紧跟在sys参数后面,但实际上,bootargs是一个空格分隔的键值对列表。这里重复的`rootfstype=ubifs`和`ro`可能会引起混淆,因为根文件系统已经指定过一次了。 9. `mtdparts=sfc0_nand:1M(uboot),3M(kernel),20M(root),-(appfs)`:定义MTD分区表。总共有四个分区:uboot(1MB)、kernel(3MB)、root(20MB)和appfs(剩余空间)。 现在,我们分析可能的问题: 1. **MTD分区定义与UBI附加的对应关系**: - 根据mtdparts定义,我们有: - mtd0: uboot (1MB) - mtd1: kernel (3MB) - mtd2: root (20MB) - mtd3: appfs (剩余空间) - 在bootargs中,我们指定了`ubi.mtd=2`,即附加mtd2(root分区)到UBI,成为ubi0,并从中挂载根文件系统(rootfs卷)。 - 然后指定`ubi.mtd=3`,即附加mtd3(appfs分区)到UBI,成为ubi1,并定义了一个参数`sys=ubi1:system`,表示这个UBI设备上有一个名为system的卷,但这里并没有挂载它,只是传递了参数。 2. **重复的rootfstype和ro**: - 在`root=ubi0:rootfs rootfstype=ubifs ro`之后,又出现了`ubi.mtd=3 sys=ubi1:system rootfstype=ubifs ro`。 - 这里第二个`rootfstype=ubifs ro`没有对应的挂载点定义。可能意图是为sys分区指定文件系统类型和只读,但内核不会自动挂载sys分区。所以这两个参数可能是多余的,或者会被用户空间程序使用。 3. **分区大小和布局**: - 我们需要确保分区大小总和不超过闪存总容量。假设闪存总容量为X,则: - uboot: 1MB - kernel: 3MB - root: 20MB - appfs: 剩余空间(X-24MB) - 所以,只要闪存容量大于24MB,就没有问题。 4. **UBI卷的存在**: - 在mtd2(root分区)上必须存在一个名为rootfs的UBI卷,因为根文件系统将从这里挂载。 - 在mtd3(appfs分区)上,如果用户空间程序使用sys参数,那么需要存在一个名为system的UBI卷。 5. **UBI设备编号**: - 第一个`ubi.mtd=2`会创建ubi0,第二个`ubi.mtd=3`会创建ubi1。这是正确的,因为每个mtd分区对应一个UBI设备。 6. **可能的冲突**: - 注意,在同一个bootargs中,我们为根文件系统指定了两次`ro`(一次在root参数后,一次在最后)。这不会引起冲突,因为它们是重复的,但也不会影响。 7. **分区命名**: - mtdparts中的分区名(uboot, kernel, root, appfs)与UBI卷名(rootfs, system)是不同的概念。分区名用于标识MTD分区,而卷名是UBI层上的逻辑卷。 8. **关键问题**:在bootargs中,我们指定了`ubi.mtd=2`和`ubi.mtd=3`,这意味着内核在启动时会自动将这两个MTD分区附加到UBI。但是,我们需要注意,这两个分区必须是已经格式化为UBI的(即包含UBI元数据)。如果这些分区没有预先格式化,那么附加操作会失败,导致挂载失败。 9. **另一个问题**:在mtdparts定义中,root分区(mtd2)被指定为20MB,而appfs分区(mtd3)使用剩余空间。但是,在bootargs中,根文件系统是从ubi0(即mtd2)上的rootfs卷挂载的,而mtd3(appfs)被附加为ubi1,并有一个system卷。这里要注意,mtd3分区被命名为appfs,但在UBI中,我们创建的是system卷,这并不冲突,因为UBI卷名是独立的。 10. **语法问题**:在bootargs中,我们有两个`ubi.mtd`参数,这是允许的,因为每个`ubi.mtd`对应一个不同的MTD分区。但是,注意在同一个bootargs中,不能对同一个MTD分区多次附加。 11. **重复的ro**:两个ro分别属于不同的文件系统?第一个ro是针对根文件系统的,第二个ro是针对sys分区的?但是,sys分区并没有在bootargs中挂载,所以第二个ro可能是无效的。实际上,bootargs中的ro是全局的,但通常只影响根文件系统。所以第二个ro可能是多余的,或者会被忽略。 12. **总结可能的问题**: - 多余的`rootfstype=ubifs`和`ro`:第二个`rootfstype=ubifs`和`ro`没有对应的挂载点,可能是无用的,或者会导致解析问题。 - 分区大小:确保闪存容量足够。 - UBI卷的存在:确保在mtd2上存在rootfs卷,在mtd3上存在system卷(如果应用程序需要)。 - 分区对齐:确保每个分区的起始地址和大小是擦除块大小的整数倍。 为了更清楚地看到问题,我们重新组织bootargs: 原始bootargs字符串: "init=/linuxrc ubi.mtd=2 root=ubi0:rootfs rootfstype=ubifs ro ubi.mtd=3 sys=ubi1:system rootfstype=ubifs ro mtdparts=sfc0_nand:1M(uboot),3M(kernel),20M(root),-(appfs)" 我们可以将其分解为键值对(或独立参数): 1. init=/linuxrc 2. ubi.mtd=2 3. root=ubi0:rootfs 4. rootfstype=ubifs 5. ro 6. ubi.mtd=3 7. sys=ubi1:system 8. rootfstype=ubifs # 重复 9. ro # 重复 10. mtdparts=sfc0_nand:1M(uboot),3M(kernel),20M(root),-(appfs) 问题在于第8和第9个参数:重复的rootfstype和ro。由于根文件系统已经指定了rootfstype和ro,这里再次出现可能是笔误。而且,第二个rootfstype和ro没有对应的挂载点,所以它们可能被忽略,也可能导致内核解析错误(如果内核严格按照顺序解析,可能会认为这是根文件系统的再次设置,但这是不正确的)。 建议的修改: 删除重复的`rootfstype=ubifs`和`ro`,因为sys分区并没有被挂载为文件系统(至少不是在启动时由内核挂载)。所以,bootargs应该改为: "init=/linuxrc ubi.mtd=2 root=ubi0:rootfs rootfstype=ubifs ro ubi.mtd=3 sys=ubi1:system mtdparts=sfc0_nand:1M(uboot),3M(kernel),20M(root),-(appfs)" 另外,注意`sys=ubi1:system`这个参数,它只是传递了一个字符串,内核不会自动挂载。用户空间程序需要解析这个参数,然后自己挂载ubi1:system到某个目录(比如/system)。 另外,我们还需要注意,在mtdparts定义中,分区名"root"对应的是mtd2,而我们在bootargs中通过`ubi.mtd=2`来引用它。同样,分区名"appfs"对应mtd3,通过`ubi.mtd=3`引用。分区名在启动后可以通过`/proc/mtd`看到,但在内核启动参数中,我们使用MTD分区编号(mtdX)来指定。 最后,检查分区大小是否合理。假设闪存总容量为128MB,则: - uboot: 1MB - kernel: 3MB - root: 20MB - appfs: 128-24=104MB 如果闪存容量小于24MB,则appfs分区大小为负,这是错误的。 因此,总结问题: 1. 存在重复且可能无效的`rootfstype=ubifs`和`ro`,建议删除。 2. 需要确保闪存总容量大于等于24MB,且分区对齐(擦除块大小的整数倍)。 3. 确保mtd2和mtd3分区已经格式化为UBI,并且mtd2上有rootfs卷,mtd3上有system卷(如果应用程序需要)。 修改后的bootargs建议: "init=/linuxrc ubi.mtd=2 root=ubi0:rootfs rootfstype=ubifs ro ubi.mtd=3 sys=ubi1:system mtdparts=sfc0_nand:1M(uboot),3M(kernel),20M(root),-(appfs)"</think>### 检查bootargs配置的问题分析 您提供的bootargs配置为: `init=/linuxrc ubi.mtd=2 root=ubi0:rootfs rootfstype=ubifs ro ubi.mtd=3 sys=ubi1:system rootfstype=ubifs ro mtdparts=sfc0_nand:1M(uboot),3M(kernel),20M(root),-(appfs)` #### 🔍 发现的主要问题 1. **UBI设备引用冲突** `ubi.mtd=2` 和 `ubi.mtd=3` 同时存在会导致设备映射冲突: - 第一个 `ubi.mtd=2` 将MTD2附加到UBI设备**ubi0** - 第二个 `ubi.mtd=3` 尝试将MTD3附加到UBI设备**ubi1** 但根据引用[1]的说明,UBI设备名应按顺序自动分配为`ubi0, ubi1,...`。 **错误表现**:`sys=ubi1:system` 中的`ubi1`与`ubi.mtd=3`的显式声明冲突[^1]。 2. **重复参数定义** `rootfstype=ubifs ro` 在配置中重复出现两次: ```diff - root=ubi0:rootfs rootfstype=ubifs ro - sys=ubi1:system rootfstype=ubifs ro ``` 第二个`rootfstype`和`ro`是冗余的,可能干扰内核解析[^1]。 3. **MTD分区与UBI映射不匹配** MTD分区定义: ``` mtd0: uboot (1M) mtd1: kernel (3M) mtd2: root (20M) → 对应 ubi.mtd=2 mtd3: appfs (剩余空间) → 对应 ubi.mtd=3 ``` 但`root=ubi0:rootfs`要求MTD2分区必须有名为`rootfs`的UBI卷,而`sys=ubi1:system`要求MTD3分区必须有名为`system`的UBI卷。若实际分区未创建这些卷,将导致挂载失败。 4. **动态分区位置问题** `-(appfs)`定义的动态分区位于最后,但`ubi.mtd=3`引用了它,需确保: $$ \text{总容量} \geq (1+3+20)\text{MB} + \text{appfs最小需求} $$ #### ✅ 修正建议方案 ```bash # 修正后的bootargs配置 init=/linuxrc ubi.mtd=2 # 附加MTD2到UBI系统 → 自动分配为ubi0 root=ubi0:rootfs # 从ubi0的rootfs卷挂载根文件系统 rootfstype=ubifs ro # 文件系统类型和挂载属性 ubi.mtd=3 # 附加MTD3到UBI系统 → 自动分配为ubi1 sys=ubi0:system # 修改为ubi0:system(若需挂载到ubi0) mtdparts=sfc0_nand:1M(uboot),3M(kernel),20M(rootfs),-(system) # 分区名与卷名对齐 ``` #### ⚠️ 关键验证步骤 1. **检查MTD分区映射** ```bash cat /proc/mtd ``` 预期输出: ``` mtd0: 00100000 00020000 "uboot" mtd1: 00300000 00020000 "kernel" mtd2: 01400000 00020000 "rootfs" # 20MB分区 mtd3: ... "system" # 动态分配的分区 ``` 2. **确认UBI卷存在性** ```bash ubinfo /dev/ubi0 # 检查rootfs卷 ubinfo /dev/ubi1 # 检查system卷 ``` 3. **擦除块对齐验证** 确保每个分区起始地址是擦除块大小的整数倍: $$ \text{起始地址} \mod \text{erasesize} = 0 $$ 通过`cat /proc/mtd`查看擦除块大小(通常为128KiB/256KiB)。 #### 📚 相关问题 1. 当UBI卷名与MTD分区名不一致时如何正确挂载文件系统?[^1] 2. 如何验证内核是否正确解析了`mtdparts`参数中的动态分区大小?[^2] 3. 在UBIFS文件系统中,`ro`(只读)和`rw`(读写)挂载选项对NAND寿命有何影响? 4. 如果`appfs`分区的实际容量小于应用需求,系统会出现什么故障现象? [^1]: UBI设备名应自动分配,显式指定`ubi1`会导致映射冲突。 [^2]: 动态分区`-`必须位于分区列表末尾,其大小由闪存总容量减去固定分区容量得出。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值