NetBSD@LinkStationでPlan9portを動かす(その1)

今年の冬休みにやっていたのが、BuffaloのNAS LinkStation(LS-H1.0TGL)にNetBSDを載せて、Plan9portを動かそうというプロジェクト。完全な手順ではないが、(Plan9portに興味がなくても、NetBSDインストールメモとして有用かもしれないので)メモを残しておく。

LS-H1.0TGLはMarvellのARM9 SoC(orion)を搭載したNASで出荷時にはミニマムなLinuxが動いている*1。ブツ的には玄箱/PROとほぼ同じものだと思われる。最初はDebianを載せようかとも思ったのだけど、身近なNetBSD開発者に協力してもらえそうなので、NetBSD 5を選択した。


ちなみに母艦はMacBookである。

前準備

まず以下のものを用意した。

まず、シリアルコンソールは必須である。これがないと詰まったときに何もできなくなる。SCON-KIT/PROにはFTDIのUSBシリアルチップが載っており、Mac OS X用のドライバは同社のページからダウンロードできる。このドライバをインストールすると/dev/tty.usbserial-XXXXというデバイスが生成されるので、screenなどから

$ sudo screen /dev/tty.usbserial-XXXX 115200

と実行すればコンソールにアクセスできる。まずは動作試験も兼ねてLinuxのブートログをながめてみるとよい。

LS-H1.0TGLはもともと1 TBのSATA HDDを搭載しており、そこにNetBSDをインストールしてもよいのだけれど、念のため別途500 GBのHDDを用意した。インストール作業は母艦であるMacBookから行うので、接続用にSATA to USBのコンバータも用意した。

あとはファイルシステムの構築やクロス開発環境としてNetBSD環境が必要になるので、VMWare Fusion上にNetBSD 5.0.1をインストールした。


U-Boot

U-Bootは組込み機器でよく使われるブートローダである。LS-H1.0TGLでも電源を入れるとまずU-Bootが起動する。出荷時の設定では、まずTFTPでカーネルを探し、タイムアウトしたならばHDDからカーネルをロードするという手順になっている。今回はTFTP、DHCPNFSなど外部サーバは利用しないことにしたので、この2nd stepでLinuxカーネルの代わりにNetBSDカーネルをロードすることになる。ここで注意が必要なことはU-Bootはext2ファイルシステムしか認識しないことだ。つまりHDD上にext2用のパーティションを切って、そこにNetBSDカーネルを置く必要がある(詳細は後述)。幸いなことにNetBSDext2の読み書きができる。

TFTPトライアル時にCtrl-cで処理を止めるとU-Bootのプロンプトが現れる。ここでprintenvで設定パラメータを確認しておこう。パラメータ設定を間違えたときのために、その内容をメモっておくとよい。今回修正が必要なのは、bootcmdパラメータだ*2。パラメータの変更はsetenv、保存はsaveenvである。

Marvell>> printenv
:
bootcmd=ide reset ; ext2load ide 0:1 0x00100000 /uImage ; setenv bootargs netconsole=6666@192.168.11.150/,@192.168.11.149/ root=/dev/sda2 rw ; bootm 0x00100000

Marvell>> setenv bootcmd 'ide reset; ext2load ide 0:1 0x00100000 /uImage.buffalo ; bootm 0x00100000'
Marvell>> saveenv
Marvell>> boot

"ext2load ide 0:1 0x00100000 /uImage.buffalo"はHDDの最初のパーティションの/uImage.buffaloをアドレス0x0010000にロードすることを意味している。ext2パーティションがx番目にあれば"0:x"になる(が、最初に置いておくのが無難だと思う)。"bootm 0x0010000"は0x00100000番地から実行を開始することを意味している。

NetBSDインストール

ここからはVMWare上のNetBSDから操作する。おおまかな手順はこんな感じ。

  • パーティション作成およびフォーマット
    • fdisk -u sd0
    • disklabel -i /dev/sd0
    • newfs /dev/rsd0a
  • インストール
    • ユーザランド((base|etc|comp|man).tgz)を展開
    • cd dev; ./MAKEDEV all
    • chmod 1777 /tmp
    • chmod 1777 /var/tmp
  • 設定ファイル編集
    • /etc/rc.conf
    • /etc/ntp.conf
    • /etc/fdisk
    • rootパスワードをつぶす

500 GBのHDDをMacBookに接続すると/dev/sd0として見える。fdiskでHDDの先頭1 GB*3ext2用に確保して、残りをNetBSDで使うようパーティションを切る。

Partition table:
0: Linux native (sysid 131)
start 63, size 2008062 (980 MB, Cyls 0-124)
PBR is not bootable: All bytes are identical (0x00)
1: NetBSD (sysid 169)
start 2008125, size 974765039 (475959 MB, Cyls 125-60801/80/59)
PBR is not bootable: All bytes are identical (0x00)
2:
3:
No active partition.

disklabelで以下のようにBSDパーティションを切った。あとext2パーティションがsd0aだとうざいので、sd0eに移動した。

5 partitions:
# size offset fstype [fsize bsize cpg/sgs]
a: 972800000 2008125 4.2BSD 0 0 0 # (Cyl. 980*- 475980*)
b: 1965039 974808125 swap # (Cyl. 475980*- 476940*)
d: 976773164 0 unused 0 0 # (Cyl. 0 - 476940*)
e: 2008062 63 Linux Ext2 0 0 # (Cyl. 0*- 980*)

(よく考えたらext2パーティションの作成、フォーマットはLinux上で作業した気がしてきた。たぶんNetBSDでもできるのだろう。要確認。)

sd0aをnewfsするが、最初raw deviceを指定しなければいけないことに気づかず悩んでしまった。

# newfs /dev/rsd0a
# mount /dev/sd0a /mnt/disk

ユーザランドftp://ftp.jp.netbsd.org/pub/NetBSD-daily/netbsd-5/200912200000Z/evbarm/binary/sets/などからtar ballをダウンロードし、展開する(-pオプションの指定を忘れないこと。setuidなどの情報が落ちてしまう)。あとはデバイスファイルを作成したり、/etcの下を編集したり。HDDのデバイス名はsd0ではなくwd0になるので注意。

# cat /mnt/disk/etc/rc
:
# Add local overrides below
#
dhclient=YES
sshd=YES
ntpd=YES

# cat /mnt/disk/etc/fstab
# NetBSD /etc/fstab
# See /usr/share/examples/fstab/ for more examples.
/dev/wd0a / ffs rw 1 1
/dev/wd0b none swap sw 0 0
#kernfs /kern kernfs rw
ptyfs /dev/pts ptyfs rw
#procfs /proc procfs rw

クロス開発環境の構築

ソースコードftp://ftp.jp.netbsd.org/pub/NetBSD-daily/netbsd-5/200912200000Z/source/sets/からtar ballをダウンロードする。またはcvsupでnetbsd5-branchを取ってくる。前者の場合、必要なのは(src|syssrc|gnusrc|sharesrc).tgzあたりだろうか。

orion用のパッチは清原さんにより開発されているのだが、まだマージされていないようだ。そこで@naobsdさんがメンテされているパッチを使わせていただくことにした。

ロスコンパイル用のtoolchainやカーネルのビルドはbuild.shで行う。

# ./build.sh -m evbarm tools

カーネルをビルドする前にpcidevs.hを更新する必要があった。

# (cd sys/dev/pci && make -f Makefile.pcidevs)
# ./build.sh -m evbarm kernel=KUROBOX_PRO

これでsys/arch/evbarm/compile/obj/KUROBOX_PRO以下にnetbsd*というファイルがいくつか作られる。HDDブート用のカーネルnetbsd-wd0で、U-Boot用に変換されたものがnetbsd-wd0.imgである。このnetbsd-wd0をext3fsのルートディレクトリにuImage.baffaloの名前でコピーする。

# mount -t ext2 /dev/sd0e /mnt/boot
# file netbsd-wd0.img
netbsd-wd0.img: u-boot/PPCBoot image
# cp netbsd-wd0.img /mnt/boot/uImage.baffalo
# umount /mnt/boot

ディスクの準備が終わったらLinkStationに接続し、電源を入れる。うまくいけば次のようなブートログが表示されるはずである。

ちなみにリブートはできないので、OSの再起動にはコールドブートが必要である。

*1:詳しいスペックは検索すればいろいろ出てくると思う。ちなみに最近話題のSheevaPlugには次世代のARM SoCであるKirkwoodが搭載されている。

*2:Linuxの場合bootargsパラメータでカーネルコマンドライン引数を与えることができるが、NetBSDでは使えない。

*3:割り当て過ぎという気もするが。。。