春雨日記 about me tags

G-Cluster続きですが,Alpineを動かしながら触っていたらNANDから起動する事ができました.

前準備

元々のドライバではG-Clusterのパーティションがフルで埋まっているため,破壊的な変更をする必要があります.

生け贄が複数台あるため,とりあえず事故は考えないとして,適当に切り取ってみたところすんなり自由な領域を手に入れる事ができました.

https://git.haru3.me/haru/linux-dsm232/commit/3667690d43c273bb51f8262fde5228200699309d

単純な変更でもミスると再起不能だから怖すぎ…

使いやすいようにカーネル8MB,rootfs100MB程度に切ってあります.

カーネルが少ないと不満なら各自でSZ_16Mに変更してくれ.

今のカーネルで6MB要らないしカーネルモジュールも使えば全然足りるんじゃないかと思いますが.

パーティションのフォーマット

今回は起動時に乗り換えろと警告されまくっていたUBIFSを使ってみます. ディストリは問わないので,UBIFSとmtdを使えるようにして下さい.

Alpineだと

1
apk add mtd-utils

で入ります.多分debianもじゃなかろうか.

次,mtdをフォーマットします.

現在のカーネルだとmtd12がrootfsなので

1
2
3
4
5
flash_erase /dev/mtd12 0 0
ubiformat /dev/mtd12
ubiattach -p /dev/mtd12
ubimkvol /dev/ubi0 -Nrootfs -m
mount -t ubifs ubi0:rootfs /mnt

でフォーマットして/mntにマウントできます.

ありがとう: https://blog.csdn.net/chenliang0224/article/details/123018518

rootfsインストール

それでは,現在のrootfsを/mntにコピーします.

1
2
3
4
5
6
7
for i in bin etc home lib media opt root run sbin srv usr var
do
cp -ar /$i /mnt/
done

cd /mnt
mkdir sys tmp proc dev

※これはAlpineの場合です.環境に合わせて下さい.

カーネルインストール

u-bootコンソールにて

・USBよりインストール対象のuImageをロード

1
2
3
4
5
6
7
8
CNCl800L> usb start
(Re)start USB...
USB:   scanning bus for devices... 2 USB Device(s) found
       scanning bus for storage devices... 1 Storage Device(s) found
CNCl800L> fatload usb 0 ${RAM} uImage_2
reading uImage_2
..................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................
5924387 bytes read

この5924387 bytes readの数字を16進に変換します. 今回は5924387なので0x5a6623です.

・宛先を消去

1
CNCl800L> nand erase 0x400000 0x800000

・宛先に書き込み

1
CNCl800L> nand write ${RAM} 0x400000 0x5a6623

ここで先ほどの変換した値を使います.

・環境変数の変更

1
2
3
4
CNCl800L> env set bootargs "root=ubi0:rootfs ubi.mtd=12 rw rootfstype=ubifs"
CNCl800L> env set bootcmd "nand read ${RAM} 0x400000 0x800000;bootm ${RAM}"
CNCl800L> env save
CNCl800L> reset

これで,次回よりUSBメモリ無しで起動するようになります.

おわりに

これで単体で動く事が可能となりました.

なぜかコピー後のAlpineのサイズが20MB程度になっており余裕を見せつけております.

70MBを超えたのはapkのキャッシュですかね.

ともあれ,128MBしか無いNANDもこのコンパクトさがあれば乗り切る事ができそうです.

おまけ: アドレスの計算方法

u-bootにて書き込む際に出てきたオフセットアドレスは何処から出てきた物なのでしょうか.

https://git.haru3.me/haru/linux-dsm232/src/branch/master/drivers/mtd/nand/raw/cnc1800l-nand.c のSZ_*というのがサイズを表しており,オフセットはそこまでのサイズを全て足し合わせた値です.

しかし,あまりにも見づらいので,/proc/mtdの16進表記を足していった方が早いです.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
$ cat /proc/mtd
dev:    size   erasesize  name
mtd0: 00020000 00020000 "cavm_miniloader"
mtd1: 00080000 00020000 "cavm_uboot1"
mtd2: 00080000 00020000 "cavm_uboot1_pad"
mtd3: 00020000 00020000 "cavm_nvram_factory"
mtd4: 00020000 00020000 "cavm_nvram_factory_pad"
mtd5: 00020000 00020000 "cavm_nvram1b"
mtd6: 00020000 00020000 "cavm_nvram2"
mtd7: 00020000 00020000 "cavm_nvram2b"
mtd8: 00200000 00020000 "cavm_splash"
mtd9: 00020000 00020000 "cavm_all_img1_info"
mtd10: 00020000 00020000 "cavm_all_img1_info_pad"
mtd11: 00800000 00020000 "kernel"
mtd12: 07400000 00020000 "rootfs"

サイズはそのままパーティションのサイズです.

なぜnandにカーネルを書き込む際に読み取ったバイト数を使用しているのかというと,それ以降の値は保証が無いので,折角イレースした所に目一杯ゴミを書き込むことになってしまうためです.おそらく後方にパディングがあるので多少ゴミがあっても大丈夫じゃないかと思いますが,無いに超したことはありません.

おまけ2: なぜu-bootから書き換えるのか

Linuxとu-bootでECCの実装?書き込み方?が違うせいで,お互いで書き込んだデータを正しく読み合う事ができません(爆笑)(そんな事あっていいのか)

しかし,色々試してみましたがパーティションを超えて何か書き込んだりといった事は無く,使用するシーンも全くかぶっていないのでまあいっか,といった所です.

カーネルの実装が間違ってるのは多分間違いないので心して使ってくれ…

おまけ3: u-bootの書き込み手順全景

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
CNCl800L> usb start
(Re)start USB...
USB:   scanning bus for devices... 2 USB Device(s) found
       scanning bus for storage devices... 1 Storage Device(s) found
CNCl800L> fatload usb 0 ${RAM} uImage_2
reading uImage_2
..................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................
5924387 bytes read
CNCl800L> nand erase 0x400000 0x800000

NAND erase: device 0 offset 0x400000, size 0x800000

Erasing at 0x400000 --   1% complete.
Erasing at 0x420000 --   3% complete.
Erasing at 0x440000 --   4% complete.
Erasing at 0x460000 --   6% complete.
Erasing at 0x480000 --   7% complete.
Erasing at 0x4a0000 --   9% complete.
Erasing at 0x4c0000 --  10% complete.
Erasing at 0x4e0000 --  12% complete.
Erasing at 0x500000 --  14% complete.
Erasing at 0x520000 --  15% complete.
Erasing at 0x540000 --  17% complete.
Erasing at 0x560000 --  18% complete.
Erasing at 0x580000 --  20% complete.
Erasing at 0x5a0000 --  21% complete.
Erasing at 0x5c0000 --  23% complete.
Erasing at 0x5e0000 --  25% complete.
Erasing at 0x600000 --  26% complete.
Erasing at 0x620000 --  28% complete.
Erasing at 0x640000 --  29% complete.
Erasing at 0x660000 --  31% complete.
Erasing at 0x680000 --  32% complete.
Erasing at 0x6a0000 --  34% complete.
Erasing at 0x6c0000 --  35% complete.
Erasing at 0x6e0000 --  37% complete.
Erasing at 0x700000 --  39% complete.
Erasing at 0x720000 --  40% complete.
Erasing at 0x740000 --  42% complete.
Erasing at 0x760000 --  43% complete.
Erasing at 0x780000 --  45% complete.
Erasing at 0x7a0000 --  46% complete.
Erasing at 0x7c0000 --  48% complete.
Erasing at 0x7e0000 --  50% complete.
Erasing at 0x800000 --  51% complete.
Erasing at 0x820000 --  53% complete.
Erasing at 0x840000 --  54% complete.
Erasing at 0x860000 --  56% complete.
Erasing at 0x880000 --  57% complete.
Erasing at 0x8a0000 --  59% complete.
Erasing at 0x8c0000 --  60% complete.
Erasing at 0x8e0000 --  62% complete.
Erasing at 0x900000 --  64% complete.
Erasing at 0x920000 --  65% complete.
Erasing at 0x940000 --  67% complete.
Erasing at 0x960000 --  68% complete.
Erasing at 0x980000 --  70% complete.
Erasing at 0x9a0000 --  71% complete.
Erasing at 0x9c0000 --  73% complete.
Erasing at 0x9e0000 --  75% complete.
Erasing at 0xa00000 --  76% complete.
Erasing at 0xa20000 --  78% complete.
Erasing at 0xa40000 --  79% complete.
Erasing at 0xa60000 --  81% complete.
Erasing at 0xa80000 --  82% complete.
Erasing at 0xaa0000 --  84% complete.
Erasing at 0xac0000 --  85% complete.
Erasing at 0xae0000 --  87% complete.
Erasing at 0xb00000 --  89% complete.
Erasing at 0xb20000 --  90% complete.
Erasing at 0xb40000 --  92% complete.
Erasing at 0xb60000 --  93% complete.
Erasing at 0xb80000 --  95% complete.
Erasing at 0xba0000 --  96% complete.
Erasing at 0xbc0000 --  98% complete.
Erasing at 0xbe0000 -- 100% complete.
OK
CNCl800L> nand write ${RAM} 0x400000 0x5a6623

NAND write: device 0 offset 0x400000, size 0x5a6623
 5924387 bytes written: OK
CNCl800L> env set bootargs "root=ubi0:rootfs ubi.mtd=12 rw rootfstype=ubifs"
CNCl800L> env set bootcmd "nand read ${RAM} 0x400000 0x800000;bootm ${RAM}"
CNCl800L> env save
Saving Environment to SPI Flash...
Sector Erase from 0xc000 to 0xe000 ...   ok!
Page Write from 0xd256e3c to 0xc000 ...   ok!