前几篇好多人都说路由器的内存太小了,FLASH太小了怎么办。那我们这章就介绍下怎么给路由器扩充内存和存储器。
站在玩家兴趣身份上来说,这章的内容会让以后更精彩,操作技术上也存在一些难度,请大家认真操作一次。
实现原理
在M150开发板上我们拥有3个USB接口以及1个TF卡接口,这些接口足够我们连接各种外部存储设备。
使用Linux的SWAP技术(交换内存分区技术,类似Windows虚拟内存)还可以让外部存储设备承担一部分内存工作,慢是慢了点,但是聊胜于无啊。
至于扩展Flash的容量,我们有两种技术:
外部磁盘替换/overlay可写分区,这样不论多大的数据就都是存储在外部磁盘上了。
使用16MB的SPI Flash,这样不用扩展外置磁盘了, 但是要是做网络存储还是不够。
外置磁盘不替换任何存储,只加载为/mnt/extdisk一个文件夹,需要的数据可以移动到/mnt/extdisk中。
关于供电部分,外置磁盘的供电在开发板上三个USB口也就差不多1A,移动硬盘要消耗500ma,而外置音箱也要消耗500ma,如果所接入的外置设备比较多,要解决供电问题,唯一的方法就是采用独立供电。很多外置磁盘带独立供电的,可以单独连接一个电源。
外部磁盘替换FLASH可写分区的原理
在我们没有启用外置磁盘之前系统是这样启动的:
从内核首先启动加载了只读分区部分,然后再挂载可写分区部分,一直到之后的乱七八糟工作......
kernel-->rootfs(/rom)-->FLASH可写分区(/overlay)-->..... (/overlay=mtd3)
在我们启动了外置磁盘之后是这样的顺序:
从内核首先启动加载了只读分区部分,然后再挂载可写分区部分,在可写分区中发现了fstab(文件系统加载配置)配置,通过该配置挂载外部磁盘为可写分区(卸载掉之前挂载的可写分区),一直到之后的乱七八糟工作......
kernel-->rootfs(/rom)-->FLASH可写分区(/overlay)-->fstab-->外部磁盘(/overlay) (/overlay=/dev/sd[N][X])
最大的区别在于,当FLASH可写分区被挂载之后(外部磁盘模式)将通过fstab重新的将外部磁盘挂载为/overlay替换掉FLASH可写分区的位置。
存储器选型介绍
移动硬盘:在M150的电路板上有三个USB2.0接口均可以用来连接移动硬盘,请使用2.5寸或1.8寸移动硬盘,M150的外部供电至少要达到12V 1A才能带动一块硬盘,推荐使用支持独立供电的移动硬盘。硬盘的优势是,没有擦写次数限制,速度快,并且性能也比较好。
FLASH闪存:闪存技术存储现在很普遍,M150支持TF卡和U盘两种闪存存储方式,闪存选购时请注意数据存储技术有区别:
SLC: Single Layer Cell 单层单元, SLC的特点是成本高、容量小、速度快,每个存储单元有1bit数据,每个单元可擦写次数可达到10万次,一般使用在工业级产品和服务器级的SSD中,如果你的设备主要提供频繁擦写,使用SLC比较适合,但是其价格也要贵很多。
MLC: Multi-Level Cell多层单元,在相同的单元密度下可存储2bit数据,这个是目前市面上消费级SSD使用的最主要存储技术,但是由于密度增加和算法原因,每个单元理论可擦写次数为3000-10000次。
TLC: Triple-level cell多倍单元,在相同的单元密度下可存储3bit数据,这个是目前低价位U盘常用的,其特点是密度大成本低,缺点是速度慢,容易损坏,每个单元理论可擦写次数为500-1000次。
所以在这里hoowa推荐,如果你要做网络存储,使用移动硬盘是写文件最快的(最好独立给移动硬盘有一个供电),理论连续写速度可以达到20MB/s(实际在10MB/s以内,USB的限制);如果使用U盘或TF卡,写速度相对比较慢,如果不做网络存储也无所谓了。
让系统识别外置磁盘
在这里到以后的操作流程需要保证设备连接外网,如果你的外网连接有问题,请参考前几章的教程重新排查。
第一步: 安装驱动和工具包
在保证设备已经能连接外网的情况下执行以下指令:
root@SmartRouter:/# opkg update
root@SmartRouter:/# opkg install kmod-usb-core kmod-usb-ohci kmod-usb-uhci kmod-usb2
root@SmartRouter:/# opkg install kmod-usb-storage kmod-usb-storage-extras kmod-fs-ext4 kmod-fs-vfat kmod-nls-utf8 kmod-nls-cp437
root@SmartRouter:/# opkg install usbutils fdisk block-mount e2fsprogs blkid
执行过程中会有很多安装包安装状态提示,只要提示不是报错就不用理会。
重新启动系统使相关驱动加载进入内核:
root@SmartRouter:/# reboot
第二步: 检测外置磁盘
检测U盘和移动硬盘的方法一样,直接插入存储设备,等待片刻后执行以下指令看到(40G 1.8寸移动硬盘举例):
root@SmartRouter:/# fdisk -l
Disk /dev/mtdblock0: 128 KiB, 131072 bytes, 256 sectors
.....Disk /dev/sdb: 37.3 GiB, 40007759872 bytes, 78140156 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: dos
Disk identifier: 0x13015f0b....
检测TF卡方式有点区别,TF卡没有自动上电功能,首先给开发板断电,然后插入TF卡,然后再给开发板上电,之后执行以下指令:
root@SmartRouter:/# fdisk -l
Disk /dev/mtdblock0: 128 KiB, 131072 bytes, 256 sectors
......Disk /dev/sda: 3.7 GiB, 3995074560 bytes, 7802880 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: dos
Disk identifier: 0x00000000....
以上检测其中的Disk /dev/sda的/dev/sda就是外置磁盘的设备符号,这个设备符号不是固定不变的,随着驱动顺序可能会产生变化,但是现在我们要记住这个设备符号。
在我们的开发板上,设备符号总是以/dev/sd[X][n]方式显示的。其中X表明设备符号,n表明分区符号。
每个插入系统的存储设备根据顺序是有变化的,在开发板上:
/dev/sda 第一个插入的USB存储设备,也可能是TF卡
/dev/sda1 第一个插入的USB存储设备的第一个分区
/dev/sda2 第一个插入的USB存储设备的第二个分区
/dev/sdb 第二个插入的USB存储设备,也可能是TF卡
/dev/sdc 第三个插入的USB存储设备,也可能是TF卡
.....
切记:
1. 如果设备重启,顺序可能会产生变化,/dev/sda可能会变成/dev/sdb的,不过后续我们有办法解决。
2. 在下面的操作流程,不论是TF卡,还是U盘或移动硬盘,都是相同的,唯一不同的就是设备符号,每次检查设备符号都要使用fdisk -l这个指令。
3. 再唠叨一次,设备符号是会变化的,每次操作时候要fdisk -l查看。
格式化和分区
hoowa使用了一个320GB的2.5寸移动硬盘做演示,各位用什么都可以,没有硬性规定(硬盘速度快点)。
第一步: 对设备进行分区
hoowa计划的分区结构是这样:2GB SWAP交换内存分区,余下的容量作为新的外置可写分区系统。
我们使用linux下的分区指令fdisk来进行操作,这次启动hoowa磁盘被识别成为了/dev/sda(记住这里要看你自己的设备符号是什么,不能直接抄hoowa的举例):
输入p指令查看当前磁盘分区情况:
输入d指令删除掉旧分区(如果你有多个分区删除程序会让你输入删除哪一个范围是1到4,如果只有一个会默认删除掉):
一直删除到没有分区为止:
输入n指令创建分区:
输入p创建主"分区1":
输入开始位置直接回车,结束位置填写+2G表示容量为2GB:
输入t指令修改这个分区类型为SWAP交换内存(编号为82的分区类型):
再创建第二个分区:
在结束位置这里直接按回车,表示使用全部容量:
查看当前分区是否OK:
保存分区到磁盘上:
重新启动系统,有时候这一步的操作会出现内核表没有更新:
root@SmartRouter:/# reboot
第二步: 格式化
sda2分区是用来存放数据的,因此需要格式化。
hoowa向大家推荐使用ext3或ext4分区类型进行格式化,这样速度和稳定性都比较好。
由于重新启动后磁盘的设备符号可能变化,因此这里hoowa又看了一次当前的状态:
root@SmartRouter:/# fdisk -l
……
这里/dev/sda1的类型为82,Linux swap表示它是交换内存分区;/dev/sda2的类型是83, Linux表示它是文件系统分区。
使用ext4文件系统格式化/dev/sda2作为外置可写分区:
格式化swap交换分区/dev/sda1:
用外置磁盘替换FLASH可写分区
第一步: 将/overlay内容都复制到外置磁盘上
这里hoowa的外置磁盘上根分区设备符号为/dev/sda2(记住上面讲的,要看你自己的设备符号是什么,不能直接抄hoowa的举例sda2)。
创建和挂载外部磁盘的文件分区:
root@SmartRouter:/# mkdir /mnt/extdisk
root@SmartRouter:/# mount /dev/sda2 /mnt/extdisk
复制文件:
root@SmartRouter:/# tar -C /overlay -cvf - . | tar -C /mnt/extdisk -xf -
root@SmartRouter:/# sync
卸载外部磁盘:
root@SmartRouter:/# umount /mnt/extdisk
第二步: 读取出外置磁盘的UUID编号
使用磁盘设备符号挂载太危险了,因为它可能变化,这次是/dev/sda下次你随便接入个其他什么设备可能变成/dev/sdb了,这怎么得了啊。
我们要用UUID了,UUID编号的作用就像身份证,不论磁盘的设备符号怎么变化,UUID是不改变的(如果改变了跟顺序没关系,可能是分区本身有变化了)。
先读出UUID我们下一步要使用:
每个分区的UUID都不同,这里我们记住/dev/sda2的,因为这个是我们要准备做可写分区的部分。在hoowa的这个硬盘上它是"0af3648e-a204-4e8d-b6a1-31cb6e8ce3ed",每台机器不一样,这玩意不能直接抄啊。
第三步: 设置系统启动自动挂载外部磁盘
现在我们写的文件还是FLASH可写分区。/etc/config/fstab配置文件是挂载记录(现在还是修改FLASH可写分区的,只有这么修改才能实现转换,记得10.2咋讲的不)。
文件结构:
#自动挂载部分
config global automount
......
#自动交换区挂载
config global autoswap
......
#静态挂载(匿名段配置,可以有多个相同的)
config mount
......
fstab配置config global automount段 可选参数:
键 值 必须设置 说明
from_fstab 1 是 在hotplug执行的时候挂载,值为1表示打开,可选参数: 0 禁用,1 启用
anon_mount 0 是 当hotplug执行到挂载的时候,自动挂载匿名(无config mount配置)的磁盘到/mnt/下。可选参数: 0 禁用,1 启用fstab配置global autoswap段 可选参数:
键 值 必须设置 说明
from_fstab 1 是 在hotplug执行的时候挂载,值为1表示打开,可选参数: 0 禁用,1 启用
anon_swap 1 是 自动挂载任何一个外置磁盘上的交换区,可选参数: 0 禁用,1 启用fstab配置config mount段 该段为匿名段可重复存在,可选参数:
键 值 必须设置 说明
target 字符串 是 被挂载的位置
device 字符串 否 被挂载的设备符号,如果采用uuid方式挂载可以不配置,可选参数通过fdisk -l查看具体要挂载设备符号
uuid 字符串 否 被挂载的设备UUID号,不能跟device一起使用。
fstype 字符串 是 分区文件系统类型,可选参数: ext4 / ext3 / fat32
options 字符串 否 挂载时候所使用的参数,如果是ext3 / ext4 可以填写: rw,sync 表示同步允许读写,如果是只读修改为ro,sync
enabled 数值 是 是否启用,可选参数: 0 禁用,1 启用
enabled_fsck 数值 是 是否在挂载的时候检测文件系统是否异常,可选参数: 0 禁用,1 启用
举例:使用UCI直接修改/etc/config/fstab配置文件
清理掉fstab旧配置:
root@SmartRouter:/# echo > /etc/config/fstab
root@SmartRouter:/# uci set fstab.automount=global
root@SmartRouter:/# uci set fstab.automount.from_fstab=1
root@SmartRouter:/# uci set fstab.automount.anon_mount=0
root@SmartRouter:/# uci set fstab.autoswap=global
root@SmartRouter:/# uci set fstab.autoswap.from_fstab=1
root@SmartRouter:/# uci set fstab.autoswap.anon_swap=1
root@SmartRouter:/# uci add fstab mount
cfg044d78
上面这个cfg044d78是hoowa这台机器在创建mount时候产生的唯一值,因为mount是属于匿名段(还记得之前章节里介绍过UCI部分的匿名段吗)。也就是说后续的增加参数操作使用这个cfg044d78代表当前mount操作就行,请注意啊各位,这个cfg开头的名字在每台机器上都不一样各位不要直接抄这部分的指令啊,要变通修改为自己的啊。
UUID填写刚才blkid取到的那个UUID,其他参考这个设置:
root@SmartRouter:/etc/config# uci set fstab.cfg044d78.uuid=0af3648e-a204-4e8d-b6a1-31cb6e8ce3ed
root@SmartRouter:/etc/config# uci set fstab.cfg044d78.target=/overlay
root@SmartRouter:/etc/config# uci set fstab.cfg044d78.fstype=ext4
root@SmartRouter:/etc/config# uci set fstab.cfg044d78.options=rw,sync
root@SmartRouter:/etc/config# uci set fstab.cfg044d78.enable=1
root@SmartRouter:/etc/config# uci set fstab.cfg044d78.enabled_fsck=0
保存全部fstab的配置:
root@SmartRouter:/etc/config# uci commit fstab
重新启动系统使一些生效:
root@SmartRouter:/# reboot
/overlay是否已经到磁盘上(如下显示表示挂载):
我们来检测下是否swap已经工作了(Swap部分的free有了值表示生效):
外置磁盘挂载后要注意事项
事项A: 事实就是系统已经变了
从本节开始,到以后我们再也不用操作FLASH原有的可写分区了,也就是说同样的/etc/config/fstab这个文件,上面的修改永久的保存在了FLASH可写分区里,下面我们再做修改就都是针对外置磁盘的了。
事项B: 外置磁盘拔掉会如何
如果拔掉了,系统会默认使用FLASH的可写分区来作为/overlay挂载,这样系统将恢复到10.6节之前的系统了。如果你的系统被玩坏了,你可以重复操作本章的这个流程,这样就相当于重新做系统了。
事项C: 插入其他设备系统报错了
这是因为供电和启动的原因导致磁盘顺序瞬间变化,这个时候hoowa建议你关机,再重新开机。UUID会再次找到你的那个磁盘的。
事项D: 检查你的/etc/config/fstab文件
现在你已经是外置磁盘的文件系统了,而那个文件里可能保留着FLASH上的那个加载/overlay的语法(已经是外置了还加载个鸟)。如果有问题就这么清理(UCI命令举例):
root@SmartRouter:/# echo > /etc/config/fstab
root@SmartRouter:/# uci set fstab.automount=global
root@SmartRouter:/# uci set fstab.automount.from_fstab=1
root@SmartRouter:/# uci set fstab.automount.anon_mount=0
root@SmartRouter:/# uci set fstab.autoswap=global
root@SmartRouter:/# uci set fstab.autoswap.from_fstab=1
root@SmartRouter:/# uci set fstab.autoswap.anon_swap=1
root@SmartRouter:/# uci commit fstab
重启生效:
root@OpenWrt:/# reboot
本章尾记:
经过以上操作以后,我们的系统以后安装软件都将自动安装到外置的磁盘上,而内存也通过Swap方式增加了2G容量。为我们后续玩更多的功能打好了基础。经过这样设置后,这个外置磁盘就不能断开连接,否则系统将崩溃。