OpenBSD/sgi、カーネルのクロスコンパイルと起動方法について

この記事はOpenBSD Advent Calendar 2015 247 日目目の記事です。
もう2015年も247日過ぎてしまったんですね(白目)。

最近、(また)OpenBSD/sgiをいじっています。
MIPS R8000という変態MIPSで遊ぶためです。

R8000 - Wikipedia

"命令キャッシュは16KBで、ダイレクトマップ方式、仮想インデックス・仮想タグ方式で、ラインサイズは32バイトである。"
とか
"TLBはデュアルポートで384エントリあり、3ウェイセットアソシアティブ方式になっている。"
とか
"ストリーミングキャッシュは外付けの1MBから16MBのキャッシュで、R8000の二次キャッシュ、R8010の一次データキャッシュとして機能する。"

が変態度が高くて良い感じです。

とかもMIPSっぽく無い感じ。

イカスぜ!

現在のところR8000が完全に動くOSはIRIXだけです。
キャッシュハンドリング、基板(メモリ)のファーストモード、スローモードの設定、TLBの設定を正しく実装すれば
OpenBSDでも起動するはず...
一年計画で動けば良いなぁ...

んで、OpenBSD/sgiをいじるにあたり、基本的な事を備忘録としてまとめておきました。

カーネルのクロスコンパイルについて

MIPSは(現代のCPUに比べて)とっても遅いので、←重要
実機でカーネルコンパイルをしまくるような場合はとっても時間がかかって大変です。
そこで、クロスコンパイル環境を構築してカーネルコンパイルをします。
ビバ、INTEL

やりかたは、

しゅううさんの記事

d.hatena.ne.jp

に書いてあるのですが、

make obj

TARGET=sgi make cross-tools

cd /usr/src/sys/arch/sgi/conf;config コンフィグ名

cd ../compile/コンフィグ名

make CC=/usr/cross/sgi/usr/mips64-unknown-openbsd4.5/bin/mips64-unknown-openbsd4.5-cc LD=/usr/cross/sgi/usr/mips64-unknown-openbsd4.5/bin/mips64-unknown-openbsd4.5-ld depend

make CC=/usr/cross/sgi/usr/mips64-unknown-openbsd4.5/bin/mips64-unknown-openbsd4.5-cc LD=/usr/cross/sgi/usr/mips64-unknown-openbsd4.5/bin/mips64-unknown-openbsd4.5-ld

エラーが出ずにコンパイルが終了すればOK

http://d.hatena.ne.jp/syuu1228/20090805

でOKです。

/compile/コンフィグ名のディレクトリにbsdという名前でカーネルが出来ています。

カーネルの起動方法について(サーバ編)

カーネルコンパイルしたら、コンパイルしたカーネルをネットブートで起動させましょう。

まずはサーバ編です。
サーバOSはNetBSDを選択しました。

やりかたは

Setting up the tftpd server, Diskless NetBSD HOW-TOの記事

Setting up the tftpd server, Diskless NetBSD HOW-TO

に書いてあるのですが、

/etc/inetd.confを編集して、

/tftpboot/にコンパイルしたカーネルを置いて

$ ls /tftpboot/
bsd.rd.IP26         hack.bsd.rd.IP26    kernel_5_3          kernel_5_7

/etc/bootptabにネットブートさせる為の記述をします。

iris:\
  :ht=ether:\
  :hn:\
  :bs=auto:\
  :bf=bsd.rd.IP26:\
  :ip=192.168.1.11:\
  :sm=255.255.255.0:\
  :rp=/tftpboot/:\
  :ha=080069********:

MACアドレス

                         Running power-on diagnostics...


Initialized tod clock.

System Maintenance Menu

1) Start System
2) Install System Software
3) Run Diagnostics
4) Recover System
5) Enter Command Monitor

Option? 5
Command Monitor.  Type "exit" to return to the menu.
>> hinv
                   System: IP26
                Processor: 75 Mhz R8000, with FPU
     Primary I-cache size: 16 Kbytes
     Primary D-cache size: 16 Kbytes
     Secondary cache size: 2 Mbytes
              Memory size: 512 Mbytes
                 Graphics: GR5-XZ
                SCSI Disk: scsi(0)disk(1)
                    Audio: Iris Audio Processor: version A2 revision 1.1.0

>> printenv
AutoLoad=Yes
rbaud=9600
TimeZone=PST8PDT
console=g
diskless=0
dbaud=ÿÿÿÿÿ
volume=80
sgilogo=y
autopower=y
netaddr=192.168.2.13
eaddr=08:00:69:**:**:**
boottune=1
cpufreq=75
SystemPartition=scsi(0)disk(1)rdisk(0)partition(8)
OSLoadPartition=scsi(0)disk(1)rdisk(0)partition(0)
OSLoadFilename=/unix
OSLoader=sash
NoAutoLoad=CONSOLE OPEN FAILED.
ConsoleOut=serial(0)
ConsoleIn=serial(0)

で確認します。

自分の環境だけ?かもしれませんが、
/tftpbootにカーネルを置いても

>> bootp()bsd.rd.IP26

TFTP error: Access violation (code 2)
Unable to execute bootp()bsd.rd.IP26: invalid argument

といって起動しない事がありました。
そう言う場合は、/tftpbootに置くカーネルパーミッションをchmod 755などで変更したら、うまく起動しました。

カーネルの起動方法について(クライアント編)

クライアント編です。

やりかたは

OpenBSD/sgiのサイトの記事

INSTALL.sgi

に書いてありますが、

The PROM, by default, will configure itself to use the IP address set in
the `netaddr' environment variable. To force the PROM to always get an
address from a bootp or dhcp server, clear the variable (`unsetenv netaddr')
before attempting to boot from the network. Alternatively, you may want to
make sure the value of this variable is correct.

Note that, if the `netaddr' variable is unset, the PROM will initialize it
to the address obtained from the bootp or dhcp server.

http://ftp.openbsd.org/pub/OpenBSD/snapshots/sgi/INSTALL.sgi

が注意点で
unsetenv netaddrをしないと

>> bootp()bsdr.d.IP26
Warning: 'netaddr' is set to the default address 192.0.2.1.
Use 'setenv' to reset it to an Internet address on your network.
No server for bsdr.d.IP26.  
Your netaddr environment variable may be set incorrectly, or
the net may be too busy for a connection to be made.
Unable to execute bootp()bsdr.d.IP26:  could not connect to server

とダダをこねます。

OSをインストールしたら、

Option? 5
Command Monitor.  Type "exit" to return to the menu.
>> setenv OSLoadFilename /bsd
>> setenv SystemPartition dksc(0,3,8)
>> setenv OSLoadPartition dksc(0,3,0)
>> dksc(0,3,8)boot

1024+36576+3920+1544+320 entry: 0xa8000000012f4000

OpenBSD/sgi-IP27 ARCBios boot version 1.6
arg 0: dksc(0,3,8)boot
arg 1: ConsoleIn=/dev/tty/ioc30
arg 2: ConsoleOut=/dev/tty/ioc30
arg 3: SystemPartition=dksc(0,3,8)
arg 4: OSLoader=sash
arg 5: OSLoadPartition=dksc(0,3,0)
arg 6: OSLoadFilename=/bsd
arg 7: OSLoadOptions=
Boot: dksc(0,3,0)/bsd
cannot open dksc(0,3,0)/etc/random.seed: Unknown error: code 20
6495848+726200 [78+328872+204365]=0x765928
ARCS64 Firmware
Found SGI-IP35, setting up.

な感じで起動させましょう

カーネルのリリースイメージの作成について

OpenBSDではクロスコンパイル環境でリリースイメージ or インストールカーネルを作る事ができません。
(自分が不勉強なだけ?ご存知のかたがいらっしゃったら教えてください)

時間がかかりますけど、実機でリリースイメージをつくります。

はっやーい!

やりかたは

OpenBSDのサイトの記事

www.openbsd.org

に書いてありますが、

素の状態だと、/usr/rel以下にはR8000を起動させる為に必要なIP26のカーネルは作成されません。
また、不要なsgiの機種のカーネルがもりもり作成されます。

/usr/rel
$ ls
INSTALL.sgi  boot64       bsd.IP28     bsd.rd.IP22  bsd.rd.IP30  game57.tgz
SHA256       bootecoff    bsd.IP30     bsd.rd.IP27  man57.tgz
base57.tgz   bsd.IP22     bsd.IP32     bsd.rd.IP28  cd57.iso
boot32       bsd.IP27     bsd.mp.IP30  bsd.rd.IP32  comp57.tgz

不要なsgiの機種のカーネルを作る時間はもったいないので、
OpenBSDのソースを"ALLIP"で検索して

Super User's BSD Cross Reference: /OpenBSD/etc/etc.sgi/Makefile.inc
Super User's BSD Cross Reference: /OpenBSD/distrib/sgi/ramdisk/Makefile

機種を追加したり、削ったりして、必要な機種のカーネルのみコンパイルするように設定しましょう。

ありがたいコメントを頂きました。

また、カーネルコンパイルするマシンの時間がずれていると、コンパイルにコケルので

で時刻をあわせましょう。

@tokudahiroshiさん、@ao_kenjiさん、ありがとうございます!