ubnt NAND flash保护策略

本人使用的设备及版本为:EdgeRouter X v1.10.11。

我的设备是er-x。考虑到网上说,erx的flash大概只能用3年,个人感觉是nand flash的频繁擦写问题,导致flash坏掉,设备无法再正常使用。讨论附图如下:

 (原始链接

决定研究一下,如何保护"路由器NAND闪存里频繁读写"问题

计划的nand flash保护方案如下:

  1. 静默跑几天(假设2天),然后登陆设备,通过这条命令获取这2天系统修改的文件
    find /root.dev -mtime -2
  2. 将这些文件的所在目录进行tmpfs格式mount,方法如下:
    1. 在tmp目录下新建一个文件夹,因为tmp目录是tmpfs格式的,不会占用磁盘空间;
    2. 拷贝这些文件所在目录(注意保持文件所有者和权限)到这个tmpfs文件夹;
    3. 将这个tmpfs目录直接mount到文件所在目录;
  3. 再静默跑几天(假设2天),然后登陆设备,再查找这2天系统修改的文件
  4. 如此反复,直至所有相关文件都转义到tmpfs下
  5. 编写脚本或程序,并实现开机自启;关机时自动将修改写入flash进行保存,确保下次开机不丢失。

方案原理:

        将易变的数据,使用tmpfs方式挂载掉,这样设备在运行过程中的频繁磁盘写动作,变成了内存条里的数据的改写,从而保护了nand flash不会被频繁刷写。

        最后,设备关机时,还是需要将数据写入flash进行保存的。因为在内存中的数据,断电就会强制被丢失。写回磁盘后,才能确保数据不被丢失。

        优化之后,就没有了设备在运行过程中的频繁flash擦写动作,有效保护了nand flash。

实施方法:

  1. 部分脚本的sed需要调整为自研的sed2程序,因为sed用的mv,mount后是不能用mv命令进行覆写文件的。(sed2是一个脚本,源码参看附件中的sed2文件)
  2. 编写mount工具。(源码参看附件中的tmp-mount_src,对应二进制程序在附件中的tmp-mount_bin目录下)
  3. 经实践积累,需要mount掉的文件清单(即mount工具的配置文件)
    # 将频繁变动的文件转为tmpfs来mount
    /etc/ubnt/last_time
    /etc/hosts
    /var/lib/logrotate/status
    /home/nat/.ssh/authorized_keys
    /config/dhcpd.leases
    /var/lib/ntp
    # 2022-9-7新添加
    /etc/dnsmasq.conf
    /etc/cron.hourly/dnsmasq-cron
    /config/dnsmasq-dhcp.leases
    /var/cache/ddclient
    /etc/ppp
    # 2022-11-18新添加
    /etc/resolv.conf
    /etc/resolv.conf.tmp
    /etc/resolv.conf.pppd-backup
    # 2022-12-11新添加
    /home/ubnt/.lesshst
    /root/.lesshst
  4. 系统开机自动mount掉上述文件,关机时再自动写回上述文件到磁盘。工具已含umount功能(但仅写回单个文件,写回文件夹太复杂就暂不实现了)。
  5. 安装配置工具,让其开机自动执行mount,关机也能自动执行umount。(源码参看附件中的install.sh)

可能的缺陷:

  1. 强制断电的话没有umount,就没有拷贝文件的内容回去了。经过实际测试,断电并没有对系统有什么影响,还是能正常使用。

目前的机器现状(作记录,仅供参考)

查看dmesg信息如下(2022-09-11):

root@ubnt:/var/log# dmesg

UBI: attaching mtd7 to ubi0

UBI: scanning is finished

UBI: attached mtd7 (name "RootFS", size 247 MiB) to ubi0

UBI: PEB size: 131072 bytes (128 KiB), LEB size: 126976 bytes

UBI: min./max. I/O unit sizes: 2048/2048, sub-page size 2048

UBI: VID header offset: 2048 (aligned 2048), data offset: 4096

UBI: good PEBs: 1982, bad PEBs: 0, corrupted PEBs: 0

UBI: user volume: 1, internal volumes: 1, max. volumes count: 128

UBI: max/mean erase counter: 16/7, WL threshold: 4096, image sequence number: 1473513539

UBI: available PEBs: 0, total reserved PEBs: 1982, PEBs reserved for bad PEB handling: 40

UBI: background thread "ubi_bgt0d" started, PID 54

UBIFS: background thread "ubifs_bgt0_0" started, PID 55

UBIFS: mounted UBI device 0, volume 0, name "troot"

UBIFS: LEB size: 126976 bytes (124 KiB), min./max. I/O unit sizes: 2048 bytes/2048 bytes

UBIFS: FS size: 244428800 bytes (233 MiB, 1925 LEBs), journal size 12189696 bytes (11 MiB, 96 LEBs)

UBIFS: reserved for root: 4952683 bytes (4836 KiB)

UBIFS: media format: w4/r0 (latest is w4/r0), UUID D4683CBE-27A0-4D67-BB9C-0BD4293353B8, small LPT model

VFS: Mounted root (aufs filesystem) on device 0:12.

devtmpfs: mounted

max/mean erase counter: 16/7的含义:最大单个块的擦除次数为16次,平均每个块的擦除次数为7次。

下面分析其中几条其他的主要信息(分析的数据是从其他博文拷贝的,不是依据上面的打印数据来的):

# 在 mtddata 原始分区初始化 ubi 卷

Info: init ubi volumes on mtddata raw partition

# 将mtd20附加到ubi0...

UBI: attaching mtd20 to ubi0

# 将mtd20附加到ubi0 完成

UBI: attached mtd20 (name "mtddata", size 30 MiB) to ubi0

# PEB 128KB, LEB 124KB

UBI: PEB size: 131072 bytes (128 KiB), LEB size: 126976 bytes

# 最小最大I/O读写单元:2048/2048, subpage 2048, 就是2KB

UBI: min./max. I/O unit sizes: 2048/2048, sub-page size 2048

# VID header偏移量2KB,用于对齐,数据偏移量4KB

UBI: VID header offset: 2048 (aligned 2048), data offset: 4096

# 240 pebs正常,无坏块

UBI: good PEBs: 240, bad PEBs: 0, corrupted PEBs: 0

# 剩余可用3 PEBs, 总保留 237 PEBs(已用或保留),用于坏块处理的保留PEBs 20(本文讨论重点)

UBI: available PEBs: 3, total reserved PEBs: 237, PEBs reserved for bad PEB handling: 20

# UBI 设备号0,共240 LEBs(29.1MB),剩余可用3 LEBs,每个LEB大小为124KB

UBI device number 0, total 240 LEBs (30474240 bytes, 29.1 MiB), available 3 LEBs (380928 bytes, 372.0 KiB), LEB size 126976 bytes 

    (124.0 KiB)

# 成功在mtddata附加ubi设备

Info: attach ubi device on mtddata success!

从log中可以知晓很多关键信息,UBI挂载的分区名称为mtddata,对应mtd20; PEB 128KB, LEB 124KB; ubi0共240 LEBs/PEBs, 剩余可以3 LEBs/PEBs, 无坏块; 用于坏块处理的保留部分为20 PEBs。

执行sudo ubinfo -a信息如下(2022-09-11):

ubnt@ubnt:/var/log$ sudo ubinfo -a

UBI version:                    1

Count of UBI devices:           1

UBI control device major/minor: 10:60

Present UBI devices:            ubi0

ubi0

Volumes count:                           1

Logical eraseblock size:                 126976 bytes, 124.0 KiB

Total amount of logical eraseblocks:     1982 (251666432 bytes, 240.0 MiB)

Amount of available logical eraseblocks: 0 (0 bytes)

Maximum count of volumes                 128

Count of bad physical eraseblocks:       0

Count of reserved physical eraseblocks:  40

Current maximum erase counter value:     16

Minimum input/output unit size:          2048 bytes

Character device major/minor:            254:0

Present volumes:                         0

Volume ID:   0 (on ubi0)

Type:        dynamic

Alignment:   1

Size:        1938 LEBs (246079488 bytes, 234.7 MiB)

State:       OK

Name:        troot

Character device major/minor: 254:1

ubi的工具集,保存在/usr/sbin/目录下:

工具作用
ubinfo提供ubi设备和卷的信息
ubiattach链接MTD设备到UBI并且创建相应的UBI设备
ubidetachubiattach相反的操作,将MTD设备从UBI设备上去链接
ubimkvol从UBI设备上创建UBI卷
ubirmvol从UBI设备上删除UBI卷
ubiblock管理UBI卷上的block
ubiupdatevol更新卷,例如OTA直接更新某个分区镜像
ubicrc32使用与ubi相同的基数计算文件的crc32
ubinize制作UBI镜像
ubiformat格式化空的Flash设备,擦除Flash,保存擦除计数,写入UBI镜像到Flash
mtdinfo报告从系统中找到的UBI设备的信息

NAND的物理性质决定了其每个块都有擦除寿命的限制,SLC约10W次,MLC约5000次,TLC约1000次

未能分析出ubnt的颗粒,感觉非常可能就是TLC,甚至以下,毕竟是比较老型号的设备了。

源码附件:

https://download.csdn.net/download/whgjjim/87399944

参考链接:

MTD中的nand驱动初步分析_shexujia的博客-CSDN博客; Linux MTD下获取Nand flash各个参数的过程的详细解析 - 程序员大本营 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

whgjjim

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值