转载请注明博主
参考书籍Openwrt智能路由系统开发 跟hoowa学智能路由 王伟 孙冰 刘龙著
1、了解分区
在路由器的flash上时有分区的。
openwrt首次刷机完成后,再过一段时间会有以下提示
jffs2: notice: (246) jffs2_build_xattr_subsystem: complete building xattr subsystem, 1 of xdatum (0 unchecked, 0 orphan) and 9 of xref (0 dead, 2 orphan) found.
block: extroot: no root or overlay mount defined
这段话的意思是,使用jfffs2文件系统完成了格式化。
不用管上面话的意思,先说说分区。
在linux系统中对闪存类存储器是采用MTD(内存技术设备)类设备驱动实现的,MTD是用于访问闪存类设备(ROM,FLASH)的linux驱动子系统。它的主要目的是使Flash闪存类设备更加容易的被访问,为此它在硬件和上层提供了一个抽象的接口使得在操作系统下我们可以像操作硬盘一样操作这类设备。仔细观察过linux启动信息的朋友会看到以下一段话。
[ 1.556000] Creating 5 MTD partitions on "raspi":
[ 1.564000] 0x000000000000-0x000001000000 : "ALL"
[ 1.576000] 0x000000000000-0x000000030000 : "Bootloader"
[ 1.588000] 0x000000030000-0x000000040000 : "Config"
[ 1.600000] 0x000000040000-0x000000050000 : "Factory"
[ 1.612000] 0x000000050000-0x000001000000 : "firmware"
[ 1.624000] 0x0000001853f2-0x000001000000 : "rootfs"
[ 1.632000] mtd: partition "rootfs" must either start or end on erase block boundary or be smaller than an erase block -- forcing read-only
[ 1.660000] mtd: partition "rootfs_data" created automatically, ofs=0x670000, len=0x990000
这段话的意思是,系统在SPI(SPI是我们所使用的flash接口标准,路由器一般都用它)设备上创建了是4个分区,这几个分区的说明如表所示
分区id号 | 分区位置 | 分区大小 | 分区作用 | |
Bootloader | 0x000000000000-0x000000030000 | 192KB | 引导程序 | |
Config | 0x000000030000-0x000000040000 | 64KB | 引导程序配置 | |
Factory | 0x000000040000-0x000000050000 | 64KB | MT7628初始参数 | |
firmware | 0x000000050000-0x000001000000 | 15.68MB | 固件分区 | |
rootfs | 0x0000001853f2-0x000001000000 | 14827KB | 固件分区 文件系统子集 |
|
rootfs_data | 0x000000670000-0x000001000000 | 9792KB | 固件分区 文件系统子集 可写分区子集 |
由于嵌入式的Flash容量很小,没有调整的必要,所以分区都是固定的,也因此不需要"分区表"这种在计算机上有的东西。在路由器的flash中,分区的位置都是固化好的。
MTK7628配置的flash是16MB的,分区如图所示
(1) 分区存在子分区,比如kernel和rootfs就是firmware的子分区。而rootfs_rom,rootfs_data就是rootfs的子分区。
(2)整个分区从0x000000000000开始到0x000001000000结束。
(3)kernel分区的容量计算公式如下,firmware大小减去rootfs大小。
2、查看系统MTD分配
root@OpenWrt:/# cat /proc/mtd
dev: size erasesize name
mtd0: 01000000 00010000 "ALL"
mtd1: 00030000 00010000 "Bootloader"
mtd2: 00010000 00010000 "Config"
mtd3: 00010000 00010000 "Factory"
mtd4: 00fb0000 00010000 "firmware"
mtd5: 00e7ac0e 00010000 "rootfs"
mtd6: 00990000 00010000 "rootfs_data"
3、查看系统mtd的分区
root@OpenWrt:/# cat /proc/partitions
major minor #blocks name
31 0 16384 mtdblock0
31 1 192 mtdblock1
31 2 64 mtdblock2
31 3 64 mtdblock3
31 4 16064 mtdblock4
31 5 14827 mtdblock5
31 6 9792 mtdblock6
4、将非文件系统分区读出来
hexdump -C /dev/mtd2 或者使用dd命令 dd if=/dev/mtd2 of=/tmp/mtd2
5、文件系统
下面开始深入的了解文件系统与上面分区 的关系,系统有rootfs_rom这个隐藏的只读文件系统,也有rootfs_data这个可写的文件分区,它们之间是什么关系?这是Openwrt设计的一个有意思的地方。
①首先,引导程序启动内核完成之后,由内核加载rootfs_rom只读分区部分来完成系统的初步启动。
②rootfs_rom只读分区采用的是linux内核支持的squashFS文件系统(一种只读文件系统),加载完毕后将其挂在到/rom目录(同时也挂载为/根目录)
③系统将使用JFFS2文件系统格式化的rootfs_data可写文件分区并且将这部分挂载到/overlay目录。
④系统再将/overlay 透明挂载为/根目录
⑤最后将一部分内存挂载为/tmp目录
⑥挂载情况如下
root@OpenWrt:/# df
Filesystem 1K-blocks Used Available Use% Mounted on
rootfs 9792 408 9384 4% /
/dev/root 5120 5120 0 100% /rom
tmpfs 63108 92 63016 0% /tmp
/dev/mtdblock6 9792 408 9384 4% /overlay
overlayfs:/overlay 9792 408 9384 4% /
tmpfs 512 0 512 0% /dev
6、透明挂载/根目录
Openwrt设计的一个特点是:系统先将rootfs_rom挂载为/根目录,这样具备了一个完整的系统,然后再将rootfs_data以透明方式挂载在/根目录上。Openwrt透明挂载处理流程如图所示,这样重叠之后的效果是:
①我们所看到的根文件系统是由rootfs_rom和rootfs_data两个分区组合在一起的;
②当我们修改一个任何位置的文件的时候,所做的修改在rootfs_data里会有记录。
③当我们删除一个文件的时候,所做的修改在rootfs_data里会有记录。
④当我们增加一个文件的时候,所做的修改在rootfs_data里会有记录。
⑤当我们读取文件的时候,首先检测rootfs_data里的状态,再检测rootfs_rom里的内容,一直到最后给你一个结果。
这样做的好处和坏处为:
①当对文件进行操作的时候,比如我们修改了一个名字为abc的文件,那么同时存在/rom里面还有修改之前的abc,同时在/overlay里面修改之后的abc,所占的空间是倍增的。
②系统不论任何时候,只要通过简单的删除掉/overlay里所有文件,就能达到复原的效果。