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參數不匹配而導致異常。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章