ROM ファイルシステム


ザウルス側カーネルの再構築のまえに、ROM ファイルを見ておく。 なんせカーネル入れると同時に ROM ファイルシステムも壊れるらしいから ──

と脅してみた(脅されてみた)が、 ROM の更新の仕方 の注意書きには:

※ updater.pro の注意事項:
zImage または initrd.bin の片方だけをアップデートする場合、 その行の先頭に ";"(セミコロン) を挿入して、コメント行にしてください。 また、改行コードは CRLF です。
とあるから、カーネルだけを更新する (ファイルシステムは破壊しない) ことも出来るんだと思う。

だからといってバックアップとってなかったら実は違う意味でとかなんとかで ファイルシステム壊れたら話にならんので、当面は信用しない。

生きているシステムの様子

とりあえず、df, mount なんぞしてみた。
A300 に入ってないコマンドは Debian potato/arm から取って来て入れたものがある。 df, mount なども標準で入っているが、busybox (← 個人的に好かん) のやつなので さりげなく Debian potato のやつに入れ換えられていたりするかもしれない。

# df
Filesystem           1k-blocks      Used Available Use% Mounted on
/dev/ram1                   44        28        16  64% /dev
/dev/mtdblock1           26865      2930     22502  12% /home
/dev/mmcda1             125344       448    124896   0% /usr/mnt.rom/card
192.168.129.32:/home/src
                      10048840   9326496    211888  98% /home/kuhn

# mount
/dev/root on / type cramfs (ro)
/proc on /proc type proc (rw)
/dev/ram1 on /dev type minix (rw)
/dev/mtdblock1 on /home type ext2 (rw,sync)
none on /dev/pts type devpts (rw)
/dev/mmcda1 on /usr/mnt.rom/card type vfat (rw,noatime)
192.168.129.32:/home/src on /home/kuhn type nfs (rw,v3,rsize=8192,wsize=8192,hard,udp,lock,addr=192.168.129.32)

df では cramfs は見えないのね ...
なお、/usr/mnt.rom/card にマウントされてるのは 128MB の SD カード。NFS mount は mount -t nfs しただけで -o で何かを指定した訳ではないのに ごちゃごちゃオプションがついてきた。どっかで定義されてるんだろう。

/dev/root は symlink で、実体は /dev/mtdblock0. /dev/mtdblock0 が ROM (16MB) で /dev/mtdblock1 が RAM (28MB) らしい。

cat /proc/mtd すると:

dev:    size   erasesize  name
mtd0: 00e60000 00020000 "Filesystem"
mtd1: 01c00000 00000400 "mtdram"
なんてのが得られる。上が ROM で下が RAM (の fs 分). RAM の消去単位が 1024byte になってるのは単にブロックデバイスだからかな。 mtd0 の消去単位は 128kB でとーっても FROM.

ファイルシステム上、/dev/mtdblock0/dev/mtdblock1 との間をひっきりなしに symlink が飛び交って、なかなか苦労のあとがうかがえた。

基本的には /dev/mtdblock0 を / として起動し、 /dev/mtdblock1 を空けたところに /root/.home_default.tar を展開するとファイルシステムの出来上がり、 という形。 ここで /dev/mtdblock0 ならともかく /dev/mtdblock1 まで物理アドレス指定で空けてるのがナンだな。ま、あとでの話。

カーネル upgrade の時に ROM が壊れるかもしれないというわけで /dev/mtdblock0 のバックアップはさっさと取っておく。dd で NFS 先に一気。 15MB ほどあるが、意外に速い。

# dd if=/dev/mtdblock0 of=/home/kuhn/tmp/dev.mtdblock0

母艦上でマウントして中を見ることもできた。

# ls -l dev.mtdblock0
-rw-r--r--    1 nobody   nogroup  15073280 Sep 29 00:20 dev.mtdblock0
# mount -t cramfs -o loop dev.mtdblock0 /mnt
# ls /mnt
bin  boot  dev  etc  home  lib  mnt  opt  proc  root  sbin  tmp  usr  var

ファイルのオーナーが nobody.nogroup になってるけど、 SL-A300 内で root で操作して nfs を越えたなごり。 SL-A300 内が原則 root になってるから、こういうトコでちょっと気持ち悪いことがある。
mkcramfs で再圧縮すると:

# mkcramfs /mnt dev.mtdblock0.rebuild
# ls -l dev.mtdblock0.rebuild
-rw-rw-r--    1 root     root     14356480 Sep 29 01:19 dev.mtdblock0.rebuild

ROM に導入する / ファイルシステムイメージは 14811136 Byte (= 0x00e20000) 以下でなければならない。
updater.pro に 14464 (kByte) と書いてるし、 rootfs-sla300-20020905.tar.bz2 に付属してくる sizecheck.pl の中でも

$maxsize = 14*1024*1024+(128)*1024;
なるチェックが入っている。 一方、導入する先の /dev/mtdblock0 自体は 15073280 Byte (= 0x00e60000) ある。

/dev/mtdblock0 をダンプしたイメージを覗いてみれば分かるが、 後ろは 0xFF でぬりつぶされているので、dd で拾ってきたイメージを再圧縮した時に 14811136 Byte を越える心配はない ... んだと思う。
つーか、細かいチェックとっぱらって真の限界の 15073280 Byte まで書き込めないのかと思わないでもない。

ROM メモリマップ

吸い上げたファイルが cramfs で mount できたことから、これはカーネルを含まない。

SL-A300 特有なカーネルコードは全て linux-2.4.13-ac5-rmk2-iop310.1-sla300-20020905.bz2 に含まれている。そこにあるいくつかのマジックナンバーをひいてくる。たとえば ──

unsigned int *pROMAddress = (unsigned int*)0xe8020000;
unsigned int *except = (unsigned int*)0xe8FC0100;
unsigned int i,crc = 0;
unsigned int uiLen = 16*1024*1024-(256+64)*1024;
とか
#define FLASH_MEM_BASE_SUM     0xe8fc0100
#define FLASH_MEM_BASE_INF     0xe8fc1000
#define FLASH_MEM_BASE_BOOT    0xe8fc2000
とか。

ROM 自体は 16MB ある。実容量としては (256 + 64) x 1024 だけ少なく、 どーやら物理アドレスで 0xe8020000 から 0xe8fcffff まで。 ROM は多分 0xe8000000 から 0xe8ffffff まで。 updater.pro 中のカーネル位置とおぼしき 0x000600000x0015ffff (1 MB) とあわせて ROM の中はこんな感じ?

0xe8000000  ROM 開始。
               (128 kB)
0xe8020000  チェックサムはここから。
               (256 kB)
0xe8060000  カーネル開始。
               (1 MB)
0xe815ffff  カーネル終了。
0xe8160000  CRAMFS 開始。
               (0xe60000 Byte) // initrd.bin としては 14811136 (0xe20000) Byte まで。
0xe8fbffff  CRAMFS 終了。
0xe8fc0000  各部位の version number.
0xe8fc0100  チェックサムスキップ。
0xe8fc1000  INF (ここに "SHARP SL-series xxxx" という文字列が入る)。
0xe8fcffff  チェックサムはここまで。
0xe8fdffff  all.nb0 の実装限界。
             (128 kB)
0xe8ffffff  ROM 終了。

0xe8fc0100が謎だ。チェックサムの計算の時に、ここの 4 バイトを飛ばしている。 チェックサムの計算がかかる領域が upgradable ROM で、その外側が書き込み保護されてるということかな。 でも最後のチェックサム終了アドレスってページの途中なんですが。ラストページ書き換えたら その外側も書き変わるんじゃ ...

0xe8fc1000 からの文字列でカーネル自身がマシンの識別をしていて、 このあたりは ROM revision などのシステム領域っぽい。

RAM メモリマップ

こっちは宝箱Pro に資料がある ... ことになってるが物理アドレスが書いてないのでものの役に立たん。 動的に変わるというならともかく、 カーネル config 中に:
CONFIG_MTDRAM_SABINAL_TOTAL_SIZE=28672
CONFIG_MTDRAM_SABINAL_ERASE_SIZE=1
CONFIG_MTDRAM_SABINAL_ABS_POS=A4400000
などと物理アドレス指定して ramdisk 作ってたりして。 これって 0xa4400000 から 28MB (28672 = 0x1c00000 で 0xa6000000 まで) が ramdisk って意味ですか〜? 物理アドレス直書き(しかもカーネル内に埋め込み) ってすげー気色悪いんですが。つーか、これ、場所を動かして大丈夫なん?

ROM メモリマップ、訂正

arch/arm/mach-cotulla/mm.c にアドレス変換テーブルがあった。 0xe8000000 は仮想アドレスで物理アドレスは 0x00000000 からとのこと。 素通しじゃなかったんね。

てことは ROM の頭のほうのページが BIOS (ROM 書き換え処理その他が入ってる)かな。


[日記へ] [目次へ]