qemuでNetBSD/earmを体験する

はじめに

ARMなマシンでNetBSDを体験するには、Raspberry PiとかCubieBoard2とかを買えば良いのですが、まずはARMなNetBSDを触ってみたいだけと言う人もいるかもしれません。
http://mail-index.netbsd.org/port-arm/2013/02/06/msg001739.html
の投稿にあるようにすれば、最新のNetBSD/evbearm current (7.99.2)がqemu-system-armで起動するので、ご紹介したいと思います。
このドキュメントは、
http://wiki.netbsd.org/ports/evbarm/qemu_arm/
に以前に書いた内容をまとめ直したものです。

qemuを準備する

まず、qemuを用意します。

NetBSDにはpkgsrcと言うパッケージ管理システムが用意されています。インストールの際に、pkgsrcのツリーも展開してあれば、以下のようにして、ツリーを更新して、2014年12月4日現在の最新版であるqemu 2.1.2をインストールすることができます。

$ cd /usr/pkgsrc
$ cvs update -dPA # pkgsrcのツリーを更新します。anoncvs.NetBSD.orgと同期させます。
$ cd emulators/qemu
$ make clean && make install # 途中で、rootのパスワードを求められるので、適宜入力してインストールします。

ここまでで、qemu 2.1.2はインストールできました。 qemu 2.1.2以外にも、1.6.2や1.7.0でもNetBSD/earmは動作することが分かっているので、2.1.2以外をインストール済みの方も、そのまま試せると思います。

qemu-system-armコマンドを動かして、どのようなマシンがエミュレートできるのかを確認してみましょう。

$ qemu-system-arm -M ?
Supported machines are:
versatileab          ARM Versatile/AB (ARM926EJ-S)
lm3s811evb           Stellaris LM3S811EVB
sx1                  Siemens SX1 (OMAP310) V2
z2                   Zipit Z2 (PXA27x)
connex               Gumstix Connex (PXA255)
versatilepb          ARM Versatile/PB (ARM926EJ-S)
realview-eb          ARM RealView Emulation Baseboard (ARM926EJ-S)
realview-pb-a8       ARM RealView Platform Baseboard for Cortex-A8
vexpress-a9          ARM Versatile Express for Cortex-A9
cubieboard           cubietech cubieboard
kzm                  ARM KZM Emulation Baseboard (ARM1136)
terrier              Terrier PDA (PXA270)
verdex               Gumstix Verdex (PXA270)
musicpal             Marvell 88w8618 / MusicPal (ARM926EJ-S)
mainstone            Mainstone II (PXA27x)
lm3s6965evb          Stellaris LM3S6965EVB
realview-pbx-a9      ARM RealView Platform Baseboard Explore for Cortex-A9
nuri                 Samsung NURI board (Exynos4210)
xilinx-zynq-a9       Xilinx Zynq Platform Baseboard for Cortex-A9
n810                 Nokia N810 tablet aka. RX-44 (OMAP2420)
borzoi               Borzoi PDA (PXA270)
highbank             Calxeda Highbank (ECX-1000)
smdkc210             Samsung SMDKC210 board (Exynos4210)
integratorcp         ARM Integrator/CP (ARM926EJ-S)
sx1-v1               Siemens SX1 (OMAP310) V1
cheetah              Palm Tungsten|E aka. Cheetah PDA (OMAP310)
n800                 Nokia N800 tablet aka. RX-34 (OMAP2420)
collie               Collie PDA (SA-1110)
vexpress-a15         ARM Versatile Express for Cortex-A15
none                 empty machine
realview-eb-mpcore   ARM RealView Emulation Baseboard (ARM11MPCore)
tosa                 Tosa PDA (PXA255)
midway               Calxeda Midway (ECX-2000)
virt                 ARM Virtual Machine
spitz                Spitz PDA (PXA270)
akita                Akita PDA (PXA270)
canon-a1100          Canon PowerShot A1100 IS

今回は、NetBSD 7.99.2がサポートしているARM Integrator/CPというボードをエミュレートし、その上でNetBSDを動かしたいと思います。

; connexやverdex、cubieboardなどもNetBSDがサポートしているボードですし、
; spitzやakitaなどもサポートしているかもしれませんが、
; 私はそれらでNetBSDを動かせていません…。
; verdexエミュレーションは、qemu 0.15では動いていましたが、qemu 2.1.2では
; qemu 0.15で起動していたLinuxイメージも起動しないので、
; 壊れているのかもしれません。

ちなみに、ARM Integrator/CPというボードについては、
http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0159b/index.html
の最下部からPDFファイルのマニュアルをダウンロードして読むと分かると思います。

NetBSDは、PL181というMMC/SD cardのコントローラーをサポートしていないので、 起動させるにはネットワークブートしかありません。他にもVGAもサポートしていないようなので、シリアルコンソールで動かすことにします。

NetBSD/earmのクロスビルド

クロスビルドとは、ビルドするマシンのアーキテクチャー以外のアーキテクチャー 用のバイナリーファイルを生成することを言うものだと思います。 今回は、NetBSD/amd64 7.99.2上で、NetBSD/evbearm-el 7.99.2のバイナリーファイル を生成しました。みなさんは、好きなPOSIXな環境で実行したら良いと思います。 別にNetBSDでなくても良いはずです。

クロスビルドについての記事もあると思いますので、ここでは詳しくは 説明しません。

以下のようにして、ARM Integrator/CP用のバイナリーファイルを生成します。

/usr/srcにNetBSD currentのソースコードを、展開しているとして説明します。 今回は、Xはビルドしません。 ARM Integrator/CP用のカーネルは、build.sh -m evbearm-el releaseの過程ではビルドされません。 build.sh -m evbearm-el kernel=INTEGRATOR_CPとして別途ビルドする必要があります。

ちなみに、evbearm-elは、ARMなCPUの載った評価用ボード用のEABIなバイナリーでlittle endiannessなものと言う意味です。

# mkdir /usr/world
# chown YOURNAME /usr/world
$ cd /usr/src
$ ./build.sh -U -T /usr/world/evbearm-el/tools -O /usr/world/evbearm-el/obj \
-D /usr/world/evbearm-el/NewWorld -R /usr/world/evbearm-el/release -m evbearm-el -j 5 release
$ ./build.sh -U -T /usr/world/evbearm-el/tools -O /usr/world/evbearm-el/obj \
-D /usr/world/evbearm-el/NewWorld -R /usr/world/evbearm-el/release -m evbearm-el -j 5 kernel=INTEGRATOR_CP
; -j 5の部分は、ビルドするマシンのCPUの数に合わせて変えてください。

これで、インストールに必要なファイルは全て作成できました。

試運転

まだ、ユーザーランドの用意ができていませんが、カーネルだけ起動させて みましょう。ctrl+cでqemuを中断できます。

$ qemu-system-arm -M integratorcp -cpu arm1136 \
-kernel /usr/world/evbearm/obj/sys/arch/evbarm/compile/INTEGRATOR_CP/netbsd.gz.ub -serial stdio

NetBSD/evbarm (EVBARM_BOARDTYPE) booting ...
[ Kernel symbol table missing! ]
Copyright (c) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
    2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014
    The NetBSD Foundation, Inc.  All rights reserved.
Copyright (c) 1982, 1986, 1989, 1991, 1993
    The Regents of the University of California.  All rights reserved.

NetBSD 7.99.2 (INTEGRATOR_CP) #0: Sat Nov 29 02:57:06 JST 2014
        ryo_on@bismuth.elements.tetera.org:/usr/world/current/evbearm/obj/sys/arch/evbarm/compile/INTEGRATOR_CP
total memory = 128 MB
avail memory = 122 MB
sysctl_createv: sysctl_create(machine_arch) returned 17
kern.module.path=/stand/evbarm/7.99.2/modules
mainbus0 (root)
cpu0 at mainbus0 core 0: ARM1136J-S r1p3 (ARM11J V6J core)
cpu0: DC enabled IC enabled WB disabled EABT
cpu0: 4KB/32B 4-way L1 VIPT Instruction cache
cpu0: 64KB/32B 4-way write-through L1 VIPT Data cache
vfp0 at cpu0: VFP11, rounding, exceptions
ifpga0 at mainbus0: Build 0, Rev A, Manufacturer Unknown, ASB, Little-endian,
ifpga0: FPGA unknown, SYSCLK 2.00MHz
ifpga0: vendor 0000 product 0000 (miscellaneous prehistoric)
pci_configure_bus done
sm0 at ifpga0 addr 0xb8000000 irq 27
sm0: SMC91C111, revision 1, buffer size: 8192
sm0: MAC address 52:54:00:12:34:56, default media MII (internal PHY)
plcom0 at ifpga0 addr 0x6000000 irq 1
plcom0: console
plcom1 at ifpga0 addr 0x7000000 irq 2
plrtc0 at ifpga0 addr 0x5000000
pci0 at ifpga0 bus 0
clock: hz=100 stathz = 100 profhz = 500
boot device: <unknown>
root device:

ネットブート環境の準備

さきほど、NetBSD/evbearmのINTEGRATOR_CPカーネルは、内蔵ストレージをサポートしていないと書きました。ですので、ブートはネットワーク経由でする必要があります。

今回は、エミュレートしたARM Integrator/CP上のNetBSDから、外部のネットワーク(The Internet等)にはつながないことにします。 ですので、仮想のEthernetアダプターであるtap0というのを作って、それを使ってNFSサーバーとDHCPサーバー、エミュレートされたARM Integrator/CPのつながったネットワークを作ることにします。

; そもそもこの原稿を書いているマシンには、NetBSDで使える
; Ethernetアダプターが内蔵されていません…。
# ifconfig tap0 create
# ifconfig tap0 inet 192.168.91.2 netmask 255.255.255.0 up
# chown YOURUSERNAME /dev/tap0

これで、tap0ができ、ユーザーから読み書きできるようになりました。qemu上のNetBSD/evbearmは、これを通じて通信をします。

NFSサーバー/DHCPサーバーの準備

ネットブートには、典型的には、カーネルを読み込むtftpサーバーとユーザーランドをホストするNFSサーバー、それらのIPアドレスを通知し、ブートしているマシンにIPアドレスを割り当てるDHCPサーバーが必要です。 しかし、今回はカーネルはqemu-system-armコマンドで直接指定してしまいますので、tftpサーバーは不要です。

NFSサーバー兼DHCPサーバーとして、qemuを動かしているNetBSD環境を使う例を示します。

まず、NFSサーバーを起動させます。 /etc/rc.confに以下のような行を追加します。

# vi /etc/rc.conf
rpcbind=YES
mountd=YES
nfs_server=YES

今回は、/usr/tmp/evbearm-el/root以下にユーザーランドを展開し、qemu上のNetBSD/evbearmのために使います。以下のようにpオプション付きでtar ballsを展開します。

# mkdir -p /usr/tmp/evbearm-el/root
# tar zxvfp /usr/world/evbearm-el/release/evbarm/binary/sets/base.tgz
# tar zxvfp /usr/world/evbearm-el/release/evbarm/binary/sets/etc.tgz
# tar zxvfp /usr/world/evbearm-el/release/evbarm/binary/sets/modules.tgz

/dev以下については、作っておかないとtmpfsがmountされてしまうので、 用意して置いた方が良いでしょう。

# cd dev
# ./MAKEDEV all

また、提供するユーザーランドのツリーをNFSでexportする必要があります。 以下のようなファイルを作ります。

# vi /etc/exports
/usr/tmp/evbearm-el/root -maproot=root:wheel -network 192.168.91.0 -mask 255.255.255.0

NFSサーバーに必要なデーモンを起動させます。

# /etc/rc.d/rpcbind start
# /etc/rc.d/mountd start
# /etc/rc.d/nfsd start

次に、DHCPサーバーを起動させます。

まず、/etc/rc.confに以下のような行を追加します。

# vi /etc/rc.conf
dhcpd=YES dhcpd_flags="tap0"

次に、以下のような内容の/etc/dhcpd.conを作成します。 ここで、qemuのエミュレートするARM Integrator/CPのsm0のMACアドレスを 52:54:00:12:34:56としています。さきほどのカーネルのみの起動の 際に確認できるので、その値を使ってください。

; 特に指定しなければ、どのマシンでも一緒のMACアドレスになるようですが。

subnet 192.168.91.0 netmask 255.255.255.0 {
       range 192.168.91.10 192.168.91.200;

       host integratorcp {
       hardware ethernet 52:54:00:12:34:56;
       next-server 192.168.91.2;
       option root-path "/usr/tmp/evbearm-el/root"
       }
}

これらを設定した上で、以下のようにdhcpdを起動させます。

# /etc/rc.d/dhcpd start

エラーが出ていないことを確認してください。

showmount -eとして、以下のようになっていれば、準備は無事に完了しています。

$ showmount -e
Exports list on localhost:
/usr/tmp/evbearm-el/root           192.168.91.0

最後に、起動後に必要となる設定をしておきます。

# vi /usr/tmp/evbearm-el/root/etc/fstab
192.168.91.2:/usr/tmp/evbearm-el/root / nfs rw 0 0
ptyfs /dev/pts ptyfs rw
# vi /usr/tmp/evbearm-el/root/etc/rc.conf
rc_configured=YES
sshd=YES

起動

では、起動させます。-nographicを付けたくなりますが、付けると必要な入力ができなくなるので、まずは止めておきましょう。

うまく起動したら、sshでログインして使うと、エラーに邪魔されないので快適です。

$ cp /usr/world/evbearm-el/obj/sys/arch/evbarm/compile/INTEGRATOR_CP/netbsd.gz.ub .
$ qemu-system-arm -M integratorcp -cpu arm1136 -kernel netbsd.gz.ub -serial stdio -m 512M \
-net nic -net tap,fd=3 3<>/dev/tap0

statclockhandler: Statclock overrunエラーがたくさん出ますが、 気にしないでおきます。

Copyright (c) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
    2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014
    The NetBSD Foundation, Inc.  All rights reserved.
Copyright (c) 1982, 1986, 1989, 1991, 1993
    The Regents of the University of California.  All rights reserved.

NetBSD 7.99.2 (INTEGRATOR_CP) #0: Sat Nov 29 02:57:06 JST 2014
 ryo_on@bismuth.elements.tetera.org:/usr/world/current/evbearm/obj/sys/arch/evbarm/compile/INTEGRATOR_CP
total memory = 255 MB
avail memory = 246 MB
sysctl_createv: sysctl_create(machine_arch) returned 17
kern.module.path=/stand/evbarm/7.99.2/modules
timecounter: Timecounters tick every 10.000 msec
mainbus0 (root)
cpu0 at mainbus0 core 0: ARM1136J-S r1p3 (ARM11J V6J core)
cpu0: DC enabled IC enabled WB disabled EABT
cpu0: isar: [0]=0x140011 [1]=0x12002111 [2]=0x11231111 [3]=0x1102131, [4]=0x141, [5]=0
cpu0: mmfr: [0]=0x1130003 [1]=0x10030302 [2]=0x1222110 [3]=0
cpu0: pfr: [0]=0x111 [1]=0x1
cpu0: 4KB/32B 4-way L1 VIPT Instruction cache
cpu0: 64KB/32B 4-way write-through L1 VIPT Data cache
vfp0 at cpu0: VFP11, rounding, exceptions
vfp0: mvfr: [0]=0x11111111 [1]=0
ifpga0 at mainbus0: Build 0, Rev A, Manufacturer Unknown, ASB, Little-endian,
ifpga0: FPGA unknown, SYSCLK 2.00MHz
ifpga0: vendor 0000 product 0000 (miscellaneous prehistoric)
pci_configure_bus done
sm0 at ifpga0 addr 0xb8000000 irq 27
sm0: SMC91C111, revision 1, buffer size: 8192
sm0: MAC address 52:54:00:12:34:56, default media MII (internal PHY)
plcom0 at ifpga0 addr 0x6000000 irq 1
plcom0: console
plcom1 at ifpga0 addr 0x7000000 irq 2
plrtc0 at ifpga0 addr 0x5000000
pci0 at ifpga0 bus 0
pci0: i/o space, memory space enabled
timecounter: Timecounter "clockinterrupt" frequency 100 Hz quality 0
clock: hz=100 stathz = 100 profhz = 500
timecounter: Timecounter "ifpga" frequency 62500 Hz quality 100
boot device: 
root device: sm0
dump device: 
file system (default generic): 
root on sm0
nfs_boot: trying DHCP/BOOTP
nfs_boot: DHCP next-server: 192.168.91.2
nfs_boot: my_addr=192.168.91.10
nfs_boot: my_mask=255.255.255.0
nfs_boot: gateway=192.168.91.2
root on 192.168.91.2:/usr/tmp/evbearm-el/root
root file system type: nfs
init path (default /sbin/init): 
init: trying /sbin/init
Tue Dec  2 13:46:10 UTC 2014
Not checking /: fs_passno = 0 in /etc/fstab
Starting file system checks:
random_seed: /var/db/entropy-file: Not present
Setting tty flags.
Setting sysctl variables:
ddb.onpanic: 1 -> 0
Starting network.
/etc/rc: WARNING: $hostname not set.
IPv6 mode: host
Configuring network interfaces:.
Adding interface aliases:.
Waiting for DAD to complete for statically configured addresses...
Building databases: dev, utmp, utmpx, servicesstatclockhandler: Statclock overrun
.
Starting syslogd.
Mounting all file systems...
Clearing temporary files.
Creating a.out runtime link editor directory cache.
Checking quotas: done.
Setting securelevel: kern.securelevel: 0 -> 1
/etc/rc: WARNING: No swap space configured!
/etc/rc.d/swap2 exited with code 1
Starting virecover.
Checking for core dump...
savecore: no core dump (no dumpdev)
Starting local daemons:.
Updating motd.
/usr/sbin/postconf: warning: valid_hostname: empty hostname
/usr/sbin/postconf: fatal: unable to use my own hostname
Dec  2 13:46:40  postfix[1358]: fatal: unable to use my own hostname
/etc/rc.d/postfix exited with code 1
Starting inetd.
Starting cron.
The following components reported failures:
    /etc/rc.d/swap2 /etc/rc.d/postfix
See /var/run/rc.log for more information.
Tue Dec  2 13:46:44 UTC 2014
NetBSD/evbarm (Amnesiac) (console)
login: root
Dec  2 13:46:48  login: ROOT LOGIN (root) on tty console
Copyright (c) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
    2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014
    The NetBSD Foundation, Inc.  All rights reserved.
Copyright (c) 1982, 1986, 1989, 1991, 1993
    The Regents of the University of California.  All rights reserved.

NetBSD 7.99.2 (INTEGRATOR_CP) #0: Sat Nov 29 02:57:06 JST 2014

Welcome to NetBSD!

This system is running a development snapshot of the NetBSD operating system,
also known as NetBSD-current.  It is very possible that it has serious bugs,
regressions, broken features or other problems.  Please bear this in mind
and use the system with care.

You are encouraged to test this version as thoroughly as possible.  Should you
encounter any problem, please report it back to the development team using the
send-pr(1) utility (requires a working MTA).  If yours is not properly set up,
use the web interface at: http://www.NetBSD.org/support/send-pr.html

Thank you for helping us test and improve NetBSD.

Terminal type is vt100.
We recommend that you create a non-root account and use su(1) for root access.
#
最近のマシン上であれば、それなりの速さで動きますので、楽しめると思います。

0 件のコメント:

コメントを投稿

注: コメントを投稿できるのは、このブログのメンバーだけです。

plgarc/wip/llama.cppでpkgsrcのBLASサポートを探る

この記事は、 NetBSD Advent Calendar 2024 の13日目の記事です。 llama.cppを使ってみる 以前に、 NetBSD/amd64でllama.cppを使ってみる という記事で llama.cpp を使ってみていました。 あれか...