Nandflash关于文件丢失导致启动卡死的解决方案

335x 系列使用 nandflash 作为存储芯片,启动的镜像和数据都保存在 nandflash 上。

nandflash相对于 emmc 来说,成本较低,但是 nandflash 本身也存在丢失数据的概率,这是由于 nandflash 本身的特性导致的。

一般来说,无法启动的原因:频繁的存储数据(log 日志),如果在存储过程突然断电,数据会有概率丢失,一旦文件系统丢失了关键文件,就会影响系统的启动。

解决方法有如下三种:

  1. 硬件上添加断电保护电路
  2. 新建分区,软件上实现系统分区和数据分区的分离
  3. 分区域保护

本篇文章主要从软件层面讲解第二、三种方法:

软件上实现系统分区和数据分区的分离

  1. 新建一个分区(以 335xd-1G 为例):

内核代码修改:arch/arm/mach-omap2/board-am335xevm-xd.c(或 xs.c 或 xs2.c)

涉及函数:am335x_nand_partitions[]

红框为添加修改代码,给文件系统分配 210MiB 的空间,剩下的为用户分区

重新编译内核,替换原来的 uImaga。

  1. 重新生成 200MiB 大小的文件系统

我们默认有八个分区,将文件系统放入最后一个分区,文件系统分区大小为 900 多兆

因此,文件系统制作也制作成 900M,如果这时修改分区或者新添分区,就会导致文件系统的分区变小,文件系统就挂载不上,导致无法正常启动。

制作文件系统用到的文件:Linux\ 源码 \ 系统源码 \rootfs\prebuilt 目录下的

所以需要重新打包文件系统镜像,解决方法如下:

原 ubinize-1G.cfg

修改成

(注意:vol_size 不能大于内核设置的 210MiB)

然后按照 335x 软件手册 4.3.1 节 UBI 文件系统的制作,重新生成文件系统镜像,替换原来的 ubi.img

  1. 挂载分区,按照如下步骤挂载分区:

先查看刚刚新建的 Userfile 分区是否成功

擦除:flash_eraseall /dev/mtd8

添加分区:

ubiattach /dev/ubi_ctrl  -m 8 -O 4096  -d 1(注意:256Mnand 为 2048)

ubimkvol /dev/ubi1 -N ubifs -s 200MiB

创建挂载分区并挂载:

mkdir /rootfs

mount -t ubifs ubi1_0 /rootfs/

Sync

再次启动系统时。重新挂载分区

可以将这两条命令加载到 qt.sh 脚本执行

ubiattach /dev/ubi_ctrl -m 8 -O 4096

root@ok335x:~# mount -t ubifs ubi1_0 /rootfs/

分区域保护

对 NAND 进行合理规划,如 Bootloader、内核、文件系统等不同分区,并对各不同分区设置不同的 mask_flags。对于 Bootloader、内核分区,可以设置 mask_flags 为 MTD_WRITEABLE,禁止该 MTD 分区的可写属性,实现这些分区只读, 防止在系统中意外误操作这些分区。

方法如下:arch/arm/mach-omap2/board-am335xevm-xd.c(xs.c 或者 xs2.c 对应板子)

nand 分区配置如下

设置了 mask_flags 的分区,在进入系统后,将无法用 flash_erase 命令擦除该分区, 也无法改写该分区的数据, 从而保护该分区的数据。例如:

对于文件系统分区,则不能通过 mask_flags 来设置只读实现分区保护。不过可以通过修改 /etc/fatab 文件来挂载只读的文件系统:

将 defaults 默认修改成 ro只读:

加了 ro 启动的系统都是只读的,对文件系统进行任何改写都会提示 “Read-only filesystem”,例如:

对这样的只读系统,如果要进行系统修改,可用 mount 命令经系统重新以可写方式挂载:

如果一个系统全部都是只读属性,在实际应用中会很不友好,如果用户需要存储数据,建议单独分出一个 MTD 分区为好,并将这个 MTD 分区单独挂载到文件系统的某个目录。

posted @ 2022-07-12 17:13  不明白就去明白  阅读(1201)  评论(0编辑  收藏  举报