Openwrt 15.05.1增加对MT7620a NAND flash的支持

一、概述

        常见的使用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/下,内容如下
ubinize.cfg:
[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,0 +1, 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,nosuid,nodev,noexec,noatime)

tmpfs on /tmp type tmpfs (rw,nosuid,nodev,noatime)

tmpfs on /tmp/root type tmpfs (rw,noatime,mode=755)

overlayfs:/tmp/root on / type overlay (rw,noatime,lowerdir=/,upperdir=/tmp/root/upper,workdir=/tmp/root/work)

tmpfs on /dev type tmpfs (rw,nosuid,relatime,size=512k,mode=755)

devpts on /dev/pts type devpts (rw,nosuid,noexec,relatime,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参数不匹配而导致异常。


你可能感兴趣的:(OpenWrt)