一、概述
? ? ? ? 常见的使用MT7620a的路由中,几乎没有使用到nand flash的,在openwrt中也并不直接支持使用nand flash的ralink系列CPU。但在其他系列如ar71xx、lantiq等有使用nand flash的路由。只要openwrt本身支持使用nand flash,就可以参考现有的配置实现自己的需求。本文详细记录openwrt实现对MT7620a NAND falsh的支持过程及遇到的问题的原因。使用nand flash就需要使用到ubi和ubifs,需要对相关概念也有所了解。
二、软件环境
? ? ? ??linux发行版:ubuntu 14.04LTS
? ? ? ??Openwrt版本:15.05.1
? ? ? ??硬件:MT7620a+128MB DDR2+1GB NAND
三、配置过程
? ? ? ??3.1?target/linux/ramips/mt7620/target.mk
? ? ? ??? ? ? ??FEATURES增加nand和ubifs,否则相关配置在make menuconfig时不可见。
#
# Copyright (C) 2009 OpenWrt.org
#
SUBTARGET:=mt7620
BOARDNAME:=MT7620 based boards
ARCH_PACKAGES:=ramips_24kec
FEATURES+=usb
nand ubifs
CPU_TYPE:=24kec
CPU_SUBTYPE:=dsp
DEFAULT_PACKAGES += kmod-rt2800-pci kmod-rt2800-soc
define Target/Description
? ? ? ? Build firmware images for Ralink MT7620 based boards.
endef
? ? ? ??3.2 target/linux/ramips/mt7620/profiles/demo.mk
? ? ? ??? ? ? ??(demo.mk替换成实际使用的profile)
? ? ? ??? ? ? ??UBIFS_OPTS和UBI_OPTS的定义
define Profile/DEMO
? ? ? ? NAME:=DEMO router
endef
define Profile/DEMO/Description
? ? ? ? Default package set compatible with DEMO
endef
DEMO_UBIFS_OPTS:="-m 2048 -e 124KiB -c 1024"
DEMO_UBI_OPTS:="-m 2048 -p 128KiB -s 2048"
$(eval $(call Profile,DEMO))
? ? ? ??? ? ? ??-m指定nand flash的page大小,对于K9K8G08U0A,page大小是2KB,erase block是128KB。-e指定逻辑块的大小,-c指定最大逻辑块数量。针对不同的nand,-e参
数可能不一样,根据运行openwrt时出现的错误提示可相应修改。
? ? ? ??3.3 target/linux/ramips/dts/DEMO.dts
? ? ? ??? ? ? ??将SPI的MTD分区替换成NAND的MTD分区。整个spi@b00删除,与chosen并列位置添加nand配置
compatible = "LYNXUS,ZGW","ralink,mt7620a-soc";
model = "LYNXUS ZGW";
chosen {
bootargs = "console=ttyS1,57600";
};
nand {
#address-cells = <1>;
#size-cells = <1>;
compatible = "mtk,mt7620-nand";
partition@0 {
label = "u-boot";
reg = <0x00000000 0x00080000>;
read-only;
};
partition@80000 {
label = "u-boot-env";
reg = <0x00080000 0x00080000>;
};
factory: partition@100000 {
label = "factory";
reg = <0x00100000 0x00040000>;
read-only;
};
partition@140000 {
label = "secure";
reg = <0x00140000 0x00040000>;
};
partition@180000 {
label = "reserved";
reg = <0x00180000 0x00080000>;
};
partition@200000 {
label = "firmware";
reg = <0x00200000 0x08000000>;
};
partition@8200000 {
label = "data1";
reg = <0x08200000 0x04000000>;
};
partition@C200000 {
label = "data2";
reg = <0x0C200000 0x08000000>;
};
partition@14200000 {
label = "data3";
reg = <0x14200000 0x08000000>;
};
partition@1C200000 {
label = "data4";
reg = <0x1C200000 0x23E00000>;
};
};
? ? ? ??3.4 ubinize配置文件ubinized.cfg和ubinized-overlay.cfg
? ? ? ??? ? ? ??ubinize用于生成能够直接烧录到nand flash的镜像,即ubi文件。将其他架构下的ubinize.cfg和ubinize-overlay.cfg拷贝到target/linux/ramips/image/下,内容如下
[rootfs]
# Volume mode (other option is static)
mode=ubi
# Source image
image=root.ubifs
# Volume ID in UBI image
vol_id=0
# Allow for dynamic resize
vol_type=dynamic
# Volume name
vol_name=rootfs
# Autoresize volume at first mount
vol_flags=autoresize
ubinize-overlay.cfg:
[rootfs]
# Volume mode (other option is static)
mode=ubi
# Source image
image=root.squashfs
# Volume ID in UBI image
vol_id=0
# Allow for dynamic resize
vol_type=dynamic
# Volume name
vol_name=rootfs
[rootfs_data]
# Volume mode (other option is static)
mode=ubi
# Volume ID in UBI image
vol_id=1
# Allow for dynamic resize
vol_type=dynamic
# Volume name
vol_name=rootfs_data
vol_size=8MiB
# Autoresize volume at first mount
vol_flags=autoresize
? ? ? ??? ? ? ??其实主要用到的是ubinize-overlay.cfg,rootfs_data中vol_size可调整,如果过小,系统会提示错误。
? ? ? ??3.5 target/linux/ramips/image/Makefile
? ? ? ??? ? ? ??生成最终镜像的规则全在这个Makfile中,贴出主要的代码
define BuildFirmware/Demo/ubifs
$(call MkImageLzmaDtb,$(2),$(3),$(4))
dd if=$(KDIR)/vmlinux-$(2).uImage of=$(KDIR)/vmlinux-$(2).uImage.align.128k bs=128k conv=sync
endef
define BuildFirmware/Demo/ubi
$(eval output_name=$(IMG_PREFIX)-$(2)-squashfs-sysupgrade.ubi)
(
dd if=$(KDIR)/vmlinux-$(2).uImage.align.128k;
dd if=$(KDIR)/root-overlay.ubi
) > $(KDIR)/$(output_name)
$(CP) $(KDIR)/$(output_name) $(BIN_DIR)/$(output_name)
endef
...
Image/Build/Profile/DEMO=$(call BuildFirmware/Demo/$(1),$(1),demo,DEMO)
ifeq ($(SUBTARGET),mt7620)
define Image/Build/Profile/Default
....
$(call Image/Build/Profile/XIAOMI-MIWIFI-MINI,$(1))
$(call Image/Build/Profile/ZTE-Q7,$(1))
$(call Image/Build/Profile/ZBT-WA05,$(1))
$(call Image/Build/Profile/ArcherC20i,$(1))
$(call Image/Build/Profile/MicroWRT,$(1))
$(call Image/Build/Profile/DEMO,$(1))
endef
endif
? ? ? ??3.6 drivers/mtd/maps/ralink_nand.c bug
? ? ? ??? ? ? ??在ralink_nand.c中有一处bug,需要在mtk_nand_probe()中ranfc_mtd的初始化后增加ranfc_mtd->writebufsize = CFG_PAGESIZE;如果直接修改源码,clean后需要
再次修改。最好的办法是增加一个patch,但比较复杂。有个简单的办法就是直接修改target/linux/ramips/patches-3.18/0043-mtd-ralink-add-mt7620-nand-driver.patch,当然,
这不是规范的做法。
修改方法:
? ? ? ??? ? ? ??1)将patch的37行由‘@@ -0,0 +1,2136‘’ @@‘修改为‘@@ -0,2137 @@’
? ? ? ??? ? ? ??2)在patch的2096行之后添加
ranfc_mtd->writebufsize = CFG_PAGESIZE;
? ? ? ??3.7?target/linux/generic/files/drivers/mtd/mtdsplit
? ? ? ??? ? ? ??该目录下的文件需要合并最新的trunk下相应的代码,opewnrt才能正确识别ubi和rootfs。可以从下面连接中获取:?
? ? ? ??? ? ? ??? ? ? ??https://github.com/openwrt/openwrt/tree/master/target/linux/generic/files/drivers/mtd/mtdsplit
? ? ? ??3.8 openwrt和kernel配置
? ? ? ??? ? ? ??1)menuconfig,Target Profile选择你的profile,本例中为demo。Target Images中将squashfs和ubifs都选中。
? ? ? ??? ? ? ??2)kernel_menuconfig
? ? ? ??? ? ? ??? ? ? ??Device Drivers->Memory Technology Deivce (MTD) support->Enable UBI - Unsorted block images及之下的Read-only block devices on top of UBI volumes一定要选中。
? ? ? ??? ? ? ??? ? ? ??File systems->Miscellaneous filesystems->UBIFS file system support
四、遇到的问题
? ? ? ? 1.rootfs无法识别
? ? ? ? ? ? ? ? firmware分区未被split成kernel和rootfs,导致rootfs无法识别,错误如下
UBIFS error (pid 1): ubifs_mount: cannot open "ubi0:rootfs",error -19
VFS: Cannot open root device "(null)" or unknown-block(0,0): error -6
Please append a correct "root=" boot option; here are the available partitions:
1f00 ? ? ? ? ? ? 512 mtdblock0 ?(driver?)
1f01 ? ? ? ? ? ? 512 mtdblock1 ?(driver?)
1f02 ? ? ? ? ? ? 256 mtdblock2 ?(driver?)
1f03 ? ? ? ? ? ? 256 mtdblock3 ?(driver?)
? ? ? ? ? ? ? ? 原因:mtdsplit驱动无法识别ubi,参考3.7合并最新mtdsplit驱动
? ? ? ? 2.bad write buffer szie,导致rootfs无法识别,错误如下
UBI: auto-attach mtd7
UBI: attaching mtd7 to ubi0
UBI error: io_init: bad write buffer size 0 for 2048 min. I/O unit
UBI error: ubi_auto_attach: cannot attach mtd7
UBIFS error (pid 1): ubifs_mount: cannot open "ubi0:rootfs",error -19
VFS: Cannot open root device "(null)" or unknown-block(0,0): error -6
Please append a correct "root=" boot option; here are the available partitions:
1f00 ? ? ? ? ? ? 512 mtdblock0 ?(driver?)
1f01 ? ? ? ? ? ? 512 mtdblock1 ?(driver?)
1f02 ? ? ? ? ? ? 256 mtdblock2 ?(driver?)
1f03 ? ? ? ? ? ? 256 mtdblock3 ?(driver?)
? ? ? ? ? ? ? ? 原因:writebuffersize未被正确设置,参考3.6做修改
? ? ? ? 3.无法识别rootfs,代码都正确,错误如下
UBI: auto-attach mtd7
UBI: attaching mtd7 to ubi0
UBI: scanning is finished
UBI: attached mtd7 (name "ubi",size 126 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: 1013,bad PEBs: 0,corrupted PEBs: 0
UBI: user volume: 2,internal volumes: 1,max. volumes count: 128
UBI: max/mean erase counter: 0/0,WL threshold: 4096,image sequence number: 2143562307
UBI: available PEBs: 745,total reserved PEBs: 268,PEBs reserved for bad PEB handling: 160
UBI: background thread "ubi_bgt0d" started,PID 235
VFS: Cannot open root device "(null)" or unknown-block(0,0): error -6
Please append a correct "root=" boot option; here are the available partitions:
1f00 ? ? ? ? ? ? 512 mtdblock0 ?(driver?)
1f01 ? ? ? ? ? ? 512 mtdblock1 ?(driver?)
1f02 ? ? ? ? ? ? 256 mtdblock2 ?(driver?)
1f03 ? ? ? ? ? ? 256 mtdblock3 ?(driver?)
1f04 ? ? ? ? ? ? 512 mtdblock4 ?(driver?)
? ? ? ? ? ? ? ? 原因:我们使用的根文件系统仍然是squashfs,只不过是承载与ubi之上,必须选中Read-only block devices on top of UBI volumes才能识别squashfs,参考3.8.
? ? ? ? 4.overlay未被正确挂载,为只读,错误如下
UBIFS: read-only UBI device
UBIFS error (pid 365): mount_ubifs: can't format empty UBI volume: read-only UBI volume
mount_root: failed to mount -t ubifs /dev/ubi0_1 /tmp/overlay: Read-only file system
mount_root: overlay filesystem has not been fully initialized yet
mount_root: switching to jffs2 overlay
mount_root: switching to jffs2 failed - fallback to ramoverlay
root@OpenWrt:/# mount
rootfs on / type rootfs (rw)
/dev/root on /rom type squashfs (ro,relatime)
proc on /proc type proc (rw,nosuid,nodev,noexec,noatime)
sysfs on /sys type sysfs (rw,noatime)
tmpfs on /tmp type tmpfs (rw,noatime)
tmpfs on /tmp/root type tmpfs (rw,noatime,mode=755)
overlayfs:/tmp/root on / type overlay (rw,lowerdir=/,upperdir=/tmp/root/upper,workdir=/tmp/root/work)
tmpfs on /dev type tmpfs (rw,relatime,size=512k,mode=755)
devpts on /dev/pts type devpts (rw,mode=600)
debugfs on /sys/kernel/debug type debugfs (rw,noatime)
? ? ? ? ? ? ? ? 原因:uimage未对齐就与ubi合并成sysupgrade文件,参考3.5中dd if=$(KDIR)/vmlinux-$(2).uImage of=$(KDIR)/vmlinux-$(2).uImage.align.128k bs=128k conv=sync
128K为nand flash的eraseblock的大小。
五、注意事项
1.UBIFS_OPTS和UBI_OPTS
这两个配置的参数需要注意,可能与nand flash参数不匹配而导致异常。