follow me

MT7620AでNANDをrootfsにする (OpenWrt 23.05 kernel 5.15.198)

MT7620AのNANDを真面目に使う話。
OpenWrt 23.05 kernel 5.15.198でNANDを使用できる様にするまでの話は以下。
MT7620AでNANDを使う (OpenWrt 23.05 kernel 5.15.198)

ターゲットの基板はBOCCO基板(mt7620a + SPI Flash + NAND)で、SPI Flashからbootさせて、rootfsをNAND上に配置する構成にしてみます。
これで、SPI Flashの容量不足を気にしなくてよくなります。
SPI Flashは8MB、NAND Flashは512MBあったので、SPI Flashにubootとkernelは残しておきます。
まぁ、eMMCが当たり前になる前の定番構成ですかね。

kernelに渡す起動引数を弄らないと起動完了できない罠はありつつも、なんとか動いたので、
たぶん、ubiでブロックデバイスの生えるタイミングとrootfsのマウントタイミングの話がありそうな予感ですが、引数指定を追加して上手くいっていそう。
これ無しで動かせるならそうしたいけど、方法あるのか解らずにいる。(知ってる人いたら教えてほしい)


では、MT7620AでNANDを使う (OpenWrt 23.05 kernel 5.15.198) で、NANDの認識までできている前提で差分をあげておきます。

差分はこちらになります。
openwrt-23.05_nand_ubi_rootfs.diff


1. nandのパラメータを追加
本来NANDを使用できる様にした際に入れておくべきだったパラメータ。
rootfsで使用するにあたって、入ってないと困る事態になったので気がついた。
target/linux/ramips/dts/mt7620a_yukai_bocco.dts
 	nand {
 		compatible = "mtk,mt7620-nand";
+		#address-cells = <1>;
+		#size-cells = <1>;
+
+		nand-ecc-mode = "hw";
+		nand-ecc-strength = <4>;
+		nand-ecc-step-size = <512>;
+
+		nand-bus-width = <8>;
+
+		page-size = <2048>;
+		block-size = <131072>;

2. mtdのパーティション名 OpenWrtの流儀に合わせる)
NAND全体を1パーティションにしてしまい。ラベルを"ubi"に、
SPI Flashにはrootfsを削ってkernelのみにするので、ラベルを"kernel"に変更。
target/linux/ramips/dts/mt7620a_yukai_bocco.dts
@@ -43,16 +58,8 @@
 			#size-cells = <1>;
 
 			partition@0 {
-				label = "nand0";
-				reg = <0x0 0x17f00000>;
-			};
-			partition@17f00000 {
-				label = "nand1";
-				reg = <0x17f00000 0x100000>;
-			};
-			partition@18000000 {
-				label = "nand2";
-				reg = <0x18000000 0x2000000>;
+				label = "ubi";
+				reg = <0x0 0x20000000>;
 			};
 		};
 	};
@@ -111,8 +118,7 @@
 			};
 
 			partition@50000 {
-				compatible = "denx,uimage";
-				label = "firmware";
+				label = "kernel";
 				reg = <0x50000 0x7b0000>;
 			};
 		};

3. イメージ生成で、rootfsを別けて作成する
target/linux/ramips/image/mt7620.mk
@@ -1387,6 +1387,14 @@ TARGET_DEVICES += youku_yk-l1c
 define Device/yukai_bocco
   SOC := mt7620a
   IMAGE_SIZE := 7872k
+  FILESYSTEMS += ubifs
+  PAGESIZE := 2048
+  BLOCKSIZE := 128k
+  SUBPAGESIZE := 2048
+  IMAGES := kernel.bin rootfs.ubi sysupgrade.bin
+  IMAGE/kernel.bin := append-kernel
+  IMAGE/rootfs.ubi := append-ubi
+  IMAGE/sysupgrade.bin := sysupgrade-tar | append-metadata

4. sysupgrade対応
sysupgradeでkernelをSPI Flashに、rootfsをNANDに別けて書き込む。
パーティションのラベルが合っていれば、ddで無理やりしたりする必要はない。
(NANDをrootfsにしないSPI Flashのみの構成に戻したい時には、ddでSPI Flashに書き込む必要がある。)
target/linux/ramips/mt7620/base-files/lib/upgrade/platform.sh
@@ -38,6 +38,14 @@ platform_do_upgrade() {
 				of=/dev/mtdblock$idx
 		default_do_upgrade "$1"
 		;;
+	yukai,bocco)
+		CI_KERNPART="kernel"
+		kernel_mtd=$(find_mtd_part "$CI_KERNPART")
+		if [ -n "$kernel_mtd" ]; then
+			tar -xf "$1" -O "sysupgrade-yukai_bocco/kernel" > "$kernel_mtd"
+		fi
+		nand_do_upgrade "$1"
+		;;
 	*)
 		default_do_upgrade "$1"
 		;;

5. ubiを使うために
NANDにrootfsを置くためではなく、ubiを使用するためのkernel config修正。
target/linux/ramips/mt7620/config-5.15

6. kernel引数の指定
ここが一番面倒だった、rootfsの指定をブロックデバイスではなく、ubiの名前で行いたかったのだが、rootfsマウントできませんでした。
target/linux/ramips/dts/mt7620a_yukai_bocco.dts
bootargs = "console=ttyS0,57600 root=ubi0:rootfs ubi.mtd=ubi rootfstype=squashfs ro";
という指定をした場合、ブロックデバイスが見つからないという罠。
これは、ubiのデバイス生成タイミングがまだという話なのだと思われる。
こんな感じになってしまいます。
[    1.244841] nand_block_checkbad: offs:2900000 tag: BAD
[    2.814345] nand_block_checkbad: offs:18120000 tag: BAD
[    3.399372] ubi0: scanning is finished
[    3.426114] ubi0: attached mtd0 (name "ubi", size 512 MiB)
[    3.437158] ubi0: PEB size: 131072 bytes (128 KiB), LEB size: 126976 bytes
[    3.450883] ubi0: min./max. I/O unit sizes: 2048/2048, sub-page size 2048
[    3.464420] ubi0: VID header offset: 2048 (aligned 2048), data offset: 4096
[    3.478307] ubi0: good PEBs: 4094, bad PEBs: 2, corrupted PEBs: 0
[    3.490457] ubi0: user volume: 2, internal volumes: 1, max. volumes count: 128
[    3.504858] ubi0: max/mean erase counter: 9/4, WL threshold: 4096, image sequence number: 214342574
[    3.522905] ubi0: available PEBs: 0, total reserved PEBs: 4094, PEBs reserved for bad PEB handling: 158
[    3.542602] ubi0: background thread "ubi_bgt0d" started, PID 165
[    3.556371] block ubiblock0_0: created from ubi0:0(rootfs)
[    3.567410] ubiblock: device ubiblock0_0 (rootfs) set to be root filesystem
[    3.581648] clk: Disabling unused clocks
[    3.591418] ubi0:rootfs: Can't open blockdev
[    3.600033] VFS: Cannot open root device "ubi0:rootfs" or unknown-block(254,0): error -2
[    3.616182] Please append a correct "root=" boot option; here are the available partitions:
[    3.632846] 1f00          524288 mtdblock0
[    3.632862]  (driver?)
[    3.645889] 1f01             192 mtdblock1
[    3.645900]  (driver?)
[    3.658917] 1f02              64 mtdblock2
[    3.658928]  (driver?)
[    3.671942] 1f03              64 mtdblock3
[    3.671954]  (driver?)
[    3.684975] 1f04            7872 mtdblock4
[    3.684987]  (driver?)
[    3.698004] fe00            2108 ubiblock0_0
[    3.698016]  (driver?)
[    3.711378] Kernel panic - not syncing: VFS: Unable to mount root fs on unknown-block(254,0)
[    3.728191] Rebooting in 1 seconds..

また、rootfsのtype指定が必要になります。squashfs指定が必要です。
これは、OpenWrtのイメージ生成の際に、ubi上にsquashfsでrootfsを構成する為です。
squashfsをわざわざ置く必要があるのか?という意見もありそうですが、OpenWrtでは、こちらの方が標準的な模様。
rootfstype=squashfs ro

修正を重ねて動作した設定が以下。
ubiblock0_0と番号指定なので、タイミングで変わってしまう事が無いか気になりましたが、ハード構成、パーティション構成が変わらない限りは変更される事はなさそう。
名前指定の方が、パーティション構成変えたときに気にしなくて良いので、綺麗かというと微妙ではありますが、しかたありません。
target/linux/ramips/dts/mt7620a_yukai_bocco.dts
@@ -7,6 +7,10 @@
 	compatible = "yukai,bocco", "ralink,mt7620a-soc";
 	model = "YUKAI Engineering BOCCO";
 
+	chosen {
+		bootargs = "console=ttyS0,57600 root=/dev/ubiblock0_0 ubi.mtd=ubi ubi.block=0,0 rootfstype=squashfs ro";
+	};
+
 	sound {
 		compatible = "simple-audio-card";
 		simple-audio-card,name = "Audio-I2S";
MT7620AでNANDをrootfsにする (OpenWrt 23.05 kernel 5.15.198) | 0 件のコメント | アカウント登録
サイト管理者はコメントに関する責任を負いません。