Skip to content

openwrt - flash

Flash 分区

Linux系统对闪存类存储器是采用MTD设备驱动实现的。

[    0.290000] spi-mt7621 10000b00.spi: sys_freq: 193333333
[    0.300000] m25p80 spi32766.0: w25q256 (32768 Kbytes)
[    0.300000] m25p80 spi32766.0: using chunked io
[    0.310000] 4 ofpart partitions found on MTD device spi32766.0
[    0.310000] Creating 4 MTD partitions on "spi32766.0":
[    0.320000] 0x000000000000-0x000000030000 : "u-boot"
[    0.320000] 0x000000030000-0x000000040000 : "u-boot-env"
[    0.330000] 0x000000040000-0x000000050000 : "factory"
[    0.340000] 0x000000050000-0x000002000000 : "firmware"
[    0.410000] 2 uimage-fw partitions found on MTD device firmware
[    0.410000] 0x000000050000-0x000000168da1 : "kernel"
[    0.420000] 0x000000168da1-0x000002000000 : "rootfs"
[    0.420000] mtd: device 5 (rootfs) set to be root filesystem
[    0.430000] 1 squashfs-split partitions found on MTD device rootfs
[    0.440000] 0x000000620000-0x000002000000 : "rootfs_data"

系统在SPI设备上创建了4个MTD分区

分区名 分区作用
u-boot 引导程序
u-boot-env 引导程序的配置数据
factory 路由器芯片的初始化参数,存放mac地址等
firmware 固件分区
kernel 固件分区
Linux 内核
rootfs 固件分区
文件系统子集
rootfs_rom 固件分区
文件系统子集
只读分区子集
rootfs_data 固件分区
文件系统子集
可写分区子集

分区存在子分区,kernel和rootfs就是firmware的子分区,rootfs_rom和rootfs_data就是rootfs的子分区。

查看系统 MTD 分配

root@Thingoo:~# cat /proc/mtd
dev:    size   erasesize  name
mtd0: 00030000 00010000 "u-boot"
mtd1: 00010000 00010000 "u-boot-env"
mtd2: 00010000 00010000 "factory"
mtd3: 01fb0000 00010000 "firmware"
mtd4: 00118da1 00010000 "kernel"
mtd5: 01e9725f 00010000 "rootfs"
mtd6: 019e0000 00010000 "rootfs_data"

查看系统 MTD 分配

root@Thingoo:~# cat /proc/partitions
major   minor  #blocks    name
31       0        192   mtdblock0
31       1         64   mtdblock1
31       2         64   mtdblock2
31       3      32448   mtdblock3
31       4       1123   mtdblock4
31       5      31324   mtdblock5
31       6      26496   mtdblock6

读取/备份 factory 分区

factory 分区(位于 /dev/mtd2)保存了重要的配置参数(如MAC地址,天线匹配参数等)。

查看分区内容

root@Thingoo:~# hexdump /dev/mtd2
0000000 7628 0001 ef0c d2af b8a9 0000 0000 0000
0000010 ffff ffff ffff ffff ffff ffff ffff ffff
0000020 0000 0000 0020 0000 ef0c d2af b8a9 ef0c
0000030 d2af b9a9 3422 2000 ffff 0100 0000 0000
0000040 0000 0022 0000 0000 0030 0000 0000 0000
0000050 0081 9400 b040 c640 c31a c2c3 c5c0 0027
0000060 ffff ffff ffff ffff ffff ffff ffff ffff
*
00000a0 c6c6 c4c4 c0c4 c4c0 c4c4 c0c4 c0c0 0000
00000b0 ffff ffff ffff ffff ffff ffff ffff ffff
*
00000f0 0000 0000 00d1 8800 0000 0000 0000 0000
0000100 ffff ffff ffff ffff ffff ffff ffff ffff
*
0000120 0000 0000 0000 0000 0000 0000 0000 0077
0000130 1d11 1d11 7f15 7f15 7f17 7f17 3b10 3b10
0000140 ffff ffff ffff ffff ffff ffff ffff ffff
*
0010000
# 查看mac地址,这里mac地址的信息在mtdblock2,第四字节到第六字节
dd bs=1 skip=4 count=6 if=/dev/mtd2 2>/dev/null | /usr/sbin/maccalc bin2mac

备份分区

使用 dd 命令将分区读到一个文件中,然后使用浏览器下载到本地。

# 备份factory分区
root@Thingoo:~# dd if=/dev/mtd2 of=/www/art.bin
128+0 records in
128+0 records out
root@Thingoo:~# ls -l /www/art.bin
-rw-r--r--    1 root     root         65536 Apr 27 18:26 /www/art.bin
# 备份所有分区的数据, 注意不要把子分区备份进去, 当有某个网关成砖后,可以备份其他正常的网关的所有数据,再用编程器手段将备份好的文件写入进去
root@Thingoo:~# (dd if=/dev/mtd0; dd if=/dev/mtd1; dd if=/dev/mtd2; dd if=/dev/mtd3;) > /tmp/thingoo.bin

文件系统

root@Thingoo:/# df
Filesystem           1K-blocks      Used Available Use% Mounted on
rootfs                   26496       752     25744   3% /
/dev/root                 4864      4864         0 100% /rom
tmpfs                    63232        84     63148   0% /tmp
/dev/mtdblock6           26496       752     25744   3% /overlay
overlayfs:/overlay       26496       752     25744   3% /
tmpfs                      512         0       512   0% /dev
  1. 引导程序启动内核完成后,由内核加载 rootfs_rom 只读分区来完成系统的初步启动。rootfs_rom 只读分区采用的是 Linux 内核支持的 squashFS 文件系统,加载完毕后将其挂载到 /rom 目录,同时也挂载为 / 目录。
  2. 系统将使用 JFFS2 文件系统格式化的 rootfs_data 可写文件分区并将这部分挂载到 /overlay 目录。
  3. 系统再将 /overlay 透明挂载为 / 根目录。
  4. 最后将一部分内存挂载为/tmp 目录。

透明挂载根目录

OpenWrt 设计的一个特点是:系统先将 rootfs_rom 挂载为 / 根目录,这样就具备了一个完整的系统,然后再将 rootfs_data 以透明方式挂载在 / 根目录上。

  • 最终呈现的根文件系统是由 rootfs_romrootfs_data 两个分区组合在一起的效果。
  • 对任何文件的修改(增、删、改)都会记录在 rootfs_data 分区中。
  • 读取文件内容时,首先检测 rootfs_data 里的状态,再检测 roots_rom 里的内容,最后输出结果。

如果修改了一个名为 abc 的文件,那么在 /rom 里还会保留修改之前的那个 abc 文件,同时在 /overlay 里有修改后的 abc 文件,因此所占的空间将会倍增。这样带来的一个好处是,在任何时候,只要删除 /overlay 里所有的文件,就能达到恢复出厂的效果。

常用文件夹

文件夹路径 作用
/etc/ 存放系统所有的配置文件
/etc/init.d/ 存放启动的服务脚本
/etc/config/ 存放 OpenWrt 的配置文件,包括网络
/tmp/ 存放临时文件和动态的配置文件
/tmp/TZ 系统启动后所使用的时区参数