FreeBSD-arm を Pandaboard に乗せてみた (3) FreeBSD-arm 起動イメージを作成してみた
さて、いよいよFreeBSD-armの起動イメージを作成し、Pandaboradで 動かしてみます。 FreeBSD-armの起動イメージ作成手順は大変複雑です。 この複雑な手順の大半を自動化してくれる スクリプトを、Tim Kientzleさんという方が作成して下さっています。 ここでは、このスクリプトfreebsd-beagleboneを使用して行きます。
FreeBSD-arm 導入のおおまかな流れ
Intel系アーキテクチャ環境にFreeBSDを導入する際に使用した bsdinstallは、arm環境にはありません。 インストールの全ては、基本的には手作業で行わねばなりません。 ちょうどNetBSDやGentooを導入するようなものでしょうか。
このインストールのおおまかな流れは以下のようなものです。
- arm用クロスコンパイル環境を作成する
armで動作するOSバイナルリは一般では配布されていません。 そこで自分でコンパイルする必要があります。 コンパイルする際にも、まだpandaboardではコンパイラはおろかOSも入っていませんから、 手元の母艦でコンパイルします。 母艦はインテルアーキテクチャであり、デフォルトではインテル系CPUのバイナリしか コンパイルできません。 そのため、armで動作するバイナリを出力するコンパイラ(クロスコンパイラ)を、 まず導入してやります。 ちなみに、このコンパイラやリンカなどのセットをツールチェインとも呼びます。 - ブートローダをコンパイルする
arm環境ではu-bootという汎用のブートローダを使いFreeBSDのローダであるubldrを起動し、 そこからFreeBSDのカーネルを起動する、という起動手順を取ります。 そのブートローダを先に作成したツールチェインでコンパイルします。 - 必要ならば、FreeBSDのOSソースにpatchをあてます。 稼働させるためにまだcommitされていないpatchが必要、という事態はよくある話です。
- make buildworldします。もちろん、arm用バイナリを得たいので、クロスコンパイルします。
- make buildkernelします。やはりarm用のkernelを得るためなので、クロスコンパイルします。
- SDHCカードにパーティションを設定し、フォーマットします。armではブートローダの制約で 先頭にブートローダを置くfatフォーマットのパーティション、残りにUFSのFreeBSD本体を収める パーティションを設定します。
- SDHCカードのfatパーテョションにブートローダなどを入れます。
- SDHCカードのUFSパーティションにmake installkernel/make installworldします。
- SDHCカード上の/etc/fstabなど必要なファイルの設定を行います。
以上が手動で導入を行う際のおおまかな手順となります。
freebsd-beaglebone を入手する
freebsd-beaglebone は Tim Kientzle さんが作成したシェルスクリプトです。 先の手順の多くを自動化し、必要な手順が行われているか否かをチェックしてくれます。 以下の環境用の起動イメージを作成出来ます。
- Beaglebone
- Rasbery Pi
- Pandaboard
freebsd-beagleboneはgithubで公開されています。 以下のようにして、github からclone します。
% git https://github.com/kientzle/freebsd-beaglebone.git % cd freebsd-beaglebone
Pandaboard 用の設定を行う
入手したら、README ファイルを熟読しましょう。 その後で、 Pandaboard 用の設定を行います。 設定ファイルはconfig.sh です。サンプルファイルからコピーして設定を開始します。
% cp config.sh.sample config.sh % vi config.sh
以下、設定のポイントをまとめます。
# REQUIRED: # Uncomment one to choose the default configuration for your board # # board_setup BeagleBone # board_setup RaspberryPi board_setup PandaBoard
board_setup は、どの環境用のイメージを作成するかを指定します。 ここではPandaboard用のイメージを作成したいので最後の行のコメントを外します。
# REQUIRED: SD_SIZE # ... # # SD_SIZE=$((100 * MB)) # for kernel-only images # SD_SIZE=$((1950 * MB)) # for 2 Gigabyte card # SD_SIZE=$((3900 * MB)) # for 4 Gigabyte card SD_SIZE=$((7900 * MB)) # for 8 Gigabyte card # SD_SIZE=$((15900 * MB)) # for 16 Gigabyte card # SD_SIZE=$((31900 * MB)) # for 32 Gigabyte card
SD_SIZE は使用するSDカードのサイズを指定します。 大容量サイズのカードを使いたくなるのは人情ですが、 このサイズのイメージファイルを作成して書き込みを行いますので、 容量が大きいほど書き込み時間が必要になります。
ここでは8GBカードの設定を選択しています。
以上が必須の設定項目です。以下は使うと嬉しいかもしれない項目です。
# KERNCONF=MYCONF
KERNCONF はカーネル設定ファイルを指定出来ます。Pandaboardでの デフォルト値はPANDABOARDで、これは /usr/src/sys/arm/conf/PANDABPARD にあります。 カスタマイズしたい場合はこれを変更します。
# FREEBSD_SRC=/usr/src
armで使用する場合、ソースにpatchをあてることが多くなります。 インテル系の母艦のOSメンテナンスに影響を与えたくない場合は、 ソース木を分離してしまうといいでしょう。 例えばarm用ソース木は/usr/headにsvn coしておき、 そのパスをFREEBSD_SRCで指定するのです。
# INSTALL_USR_SRC=yes
コメントを外すと、起動イメージ中に/usr/src も入ります。 デフォルトは入りません。 入れておけば、Pandaboard上でmake buildworld に挑戦出来ます。
# INSTALL_USR_PORTS=yes
コメントを外すと起動イメージ中に/usr/portsもインストールされます。 Pandaboard上でportsを使った導入を行えます。
以上が主な設定項目です。この他いくつかの項目が存在します。 詳細はファイルのコメントに書かれていますので参照してください。
起動イメージを作成する
いよいよ起動イメージを作成します。その手順は、以下のとおりです。
1.クロスコンパイル環境を構築する
FreeBSDでは、クロスコンパイル環境のソースコードも/usr/src に収められています。 そこでコンパイルするだけで、必要なクロスコンパイル環境を入手出来ます。 以下のコマンドをrootになって実行します。
# cd /usr/src # make xdev XDEV=arm XDEV_ARCH=arm
これでarm用ツールチェインが/usr/arm-freebsd 下に導入されます。 なお特に環境変数などを設定しなくとも、デフォルトのmakeファイルに必要な設定は書かれていますので 使用できます。
2.ブートローダu-bootのソースを準備する
u-bootのソースを取得し、freebbsd-beaglebone直下に展開します。
# cd freebsd-beaglebone # fetch ftp://ftp.denx.de/pub/u-boot/u-boot-2012.07.tar.bz2 # bzcat u-boot-2012.07.tar.bz2 | tar xvf - # mv u-boot-2012.07 u-boot-panda
3.FreeBSDのソースにpatchをあてる
2013年1月中旬現在、FreeBSD-10.0-CURRENT revision 245505 では、patchをあてることなく Pandaboard 上で起動することはできないようです。 起動途中でpanic を起こしkernel が abort します。
現時点で起動させるためには、まだcommit されていないpatch をあてる必要があります。
なお、これらpatch はいずれcommit されるかと思われます。 その場合、ここにある手順でpatchあてしようとしてもrejectされるでしょう。 あくまでも参考にのみしてください。
# cd ~ # mkdir patch # cd patch
まず、arm/174461 にsend-pr されているキャッシュメンテナンスルーチンの 問題を修正するpatch です。これはIan Lepore さんが書かれています。
# fetch -o PR174461-patch 'http://www.freebsd.org/cgi/query-pr.cgi?pr=174461;cat=&getpatch=1'
次にOleksandr Tymoshenko さんが書かれた一連のpatch を取得します。
# fetch http://people.freebsd.org/~gonzo/patches/queue/arm-autotune-fix.diff # fetch http://people.freebsd.org/~gonzo/patches/queue/locore.diff # fetch http://people.freebsd.org/~gonzo/patches/ehci-bug-detect.diff
それぞれ、kernelが確保するメモリ量の問題、CPUの初期化の問題、イーサドライバの問題を修正します。
これらのpatch を当てて行きます。
# cd /usr/src # pacth < ~/patch/PR174461-patch # cd /usr/src/sys # pacth < ~/patch/arm-autotune-fix.diff # cd /usr/src/sys/arm/arm # patch < ~/patch/locore.diff # cd /usr/src/sys # pacth < ~/patch/ehci-bug-detect.diff
4.必要なportsを導入しておく
u-bootのコンパイルにGNU sed が必要になるため、これを導入しておきます。
# cd /usr/ports/textproc/gsed # make install && make clean
5.起動イメージを作成する
いよいよ起動イメージを作成します。
# cd freebsd-beaglebone # sh beaglebone.sh
この様にスクリプトbeaglebone.sh を実行するだけです。 あとはこのスクリプトが、残る必要なコンパイルと、その結果を用いた起動イメージファイルを 作成してくれます。 この処理には非常に時間がかかります。少なくとも3時間程度は見たほうがいいでしょう。 無事終了したならば、work/FreeBSD-PANDABOARD.img に起動イメージが生成されます。
6.SDカードに焼く
あとは、このイメージをSDカードに焼くだけです。 USBメモリカードリーダにSDカードをつけて母艦に接続し、FreeBSDに認識させたらば、 以下のコマンドを実行して書き込みます。
# dd if=work/FreeBSD-PANDABOARD.img of=/dev/da0 bs=10m
bs引数は10m程度までは指定できるようです。この数値は大きいほうが書き込み時間を短縮出来ます。
7.起動する
カードに焼けたならば、Pandaboard に取り付けて起動しましょう。 このような起動メッセージが得られるはずです。
Texas Instruments X-Loader 1.41 (Sep 29 2011 - 10:43:53) OMAP4460: 1.2 GHz capable SOM Starting OS Bootloader from MMC/SD1 ... U-Boot 2012.07 (Jan 14 2013 - 18:28:46) CPU : OMAP4460 ES1.1 Board: OMAP4 Panda I2C: ready DRAM: 1 GiB MMC: OMAP SD/MMC: 0 Using default environment In: serial Out: serial Err: serial Net: No ethernet found. Hit any key to stop autoboot: 0 reading ubldr 242850 bytes read ## Starting application at 0x88000054 ... Consoles: U-Boot console Compatible API signature found @bfef4258 Number of U-Boot devices: 1 FreeBSD/armv6 U-Boot loader, Revision 1.2 (armdevel@PandaMother-01, Wed Jan 16 23:32:23 JST 2013) DRAM: 1024MB Device: disk - /boot/kernel/kernel data=0x3da838+0x1f2fc syms=[0x4+0x78f60+0x4+0x63ab6] Hit [Enter] to boot immediately, or any other key for command prompt. Booting [/boot/kernel/kernel]... fdt_start: 0x005B31D0 Kernel entry at 0x80200100... Kernel args: (null) KDB: debugger backends: ddb KDB: current backend: ddb Copyright (c) 1992-2013 The FreeBSD Project. Copyright (c) 1979, 1980, 1983, 1986, 1988, 1989, 1991, 1992, 1993, 1994 The Regents of the University of California. All rights reserved. FreeBSD is a registered trademark of The FreeBSD Foundation. FreeBSD 10.0-CURRENT #0 r245505M: Wed Jan 16 23:42:05 JST 2013 armdevel@PandaMother-01:/home/armdevel/freebsd-beaglebone/work/obj/arm.armv6/usr/src/sys/PANDABOARD arm CPU: Cortex A9-r2 rev 10 (Cortex-A core) Supported features: ARM_ISA THUMB2 JAZELLE THUMBEE ARMv4 Security_Ext WB disabled EABT branch prediction enabled LoUU:2 LoC:1 LoUIS:2 Cache level 1: 32KB/32B 4-way data cache WB Read-Alloc Write-Alloc 32KB/32B 4-way instruction cache Read-Alloc real memory = 1073741824 (1024 MB) avail memory = 1043931136 (995 MB) Texas Instruments OMAP4460 Processor, Revision ES1.1 random device not loaded; using insecure entropy simplebus0: <Flattened device tree simple bus> on fdtbus0 gic0: <ARM Generic Interrupt Controller> mem 0xe8241000-0xe8241fff,0xe8240100-0xe82401ff on simplebus0 gic0: pn 0x390, arch 0x1, rev 0x2, implementer 0x43b nirqs 160 l2cache0: <PL310 L2 cache controller> mem 0xe8242000-0xe8242fff irq 32 on simplebus0 l2cache0: Part number: 0x3, release: 0x7 l2cache0: L2 Cache: 1024KB/32B 16 ways mp_tmr0: <ARM Generic MPCore Timers> mem 0xe8240200-0xe82402ff,0xe8240600-0xe82406ff irq 27,29 on simplebus0 Timecounter "ARM MPCore Timecounter" frequency 504000000 Hz quality 1000 Event timer "ARM MPCore Eventtimer" frequency 504000000 Hz quality 1000 uart0: <16750 or compatible> mem 0xe8020000-0xe8020fff irq 106 on simplebus0 uart0: console (115384,n,8,1) ti_scm0: <TI Control Module> mem 0xd62d9000-0xd62d9fff on simplebus0 setting internal 4 for usbb1_ulpiphy_stp setting internal 10c for usbb1_ulpiphy_clk setting internal 10c for usbb1_ulpiphy_dir setting internal 10c for usbb1_ulpiphy_nxt setting internal 10c for usbb1_ulpiphy_dat0 setting internal 10c for usbb1_ulpiphy_dat1 setting internal 10c for usbb1_ulpiphy_dat2 setting internal 10c for usbb1_ulpiphy_dat3 setting internal 10c for usbb1_ulpiphy_dat4 setting internal 10c for usbb1_ulpiphy_dat5 setting internal 10c for usbb1_ulpiphy_dat6 setting internal 10c for usbb1_ulpiphy_dat7 omap4_prcm0: <TI OMAP Power, Reset and Clock Management> mem 0xd62da000-0xd62dbfff,0xd62dc000-0xd62dcfff,0xd62dd000-0xd62e4fff on simplebus0 gpio0: <TI General Purpose I/O (GPIO)> mem 0xd62e5000-0xd62e5fff,0xe8055000-0xe8055fff,0xe8057000-0xe8057fff,0xe8059000-0xe8059fff,0xe805b000-0xe805bfff,0xe805d000-0xe805dfff irq 61,62,63,64,65,66 on simplebus0 gpioc0: <GPIO controller> on gpio0 gpiobus0: <GPIO bus> on gpio0 ehci0: <TI OMAP USB 2.0 controller> mem 0xd62e6c00-0xd62e6cff,0xd62e7000-0xd62e76ff,0xd62e8000-0xd62e8fff irq 109 on simplebus0 ehci0: Starting TI EHCI USB Controller ehci0: UHH revision 0x50700100 ehci0: OMAP_UHH_SYSCONFIG: 0x00000014 ehci0: UHH setup done, uhh_hostconfig=0x8000001c usbus0: EHCI version 1.0 usbus0 on ehci0 iichb0: <TI I2C Controller> mem 0xe8070000-0xe80700ff irq 88 on simplebus0 iichb0: I2C revision 4.0 iicbus0: <OFW I2C bus> on iichb0 iic0: <I2C generic I/O> on iicbus0 ti_sdma0: <TI sDMA Controller> mem 0xd62e9000-0xd62e9fff irq 44,45,46,47 on simplebus0 ti_sdma0: sDMA revision 00010900 ti_mmchs0: <TI MMC/SD/SDIO High Speed Interface> mem 0xe809c000-0xe809cfff irq 115 on simplebus0 mmc0: <MMC/SD bus> on ti_mmchs0 Timecounters tick every 10.000 msec usbus0: 480Mbps High Speed USB v2.0 ugen0.1: <Texas Instruments> at usbus0 uhub0: <Texas Instruments EHCI root HUB, class 9/0, rev 2.00/1.00, addr 1> on usbus0 mmcsd0: 7580MB <SDHC SU08G 8.0 SN 447764317 MFG 07/2012 by 3 SD> at mmc0 25.0MHz/4bit/1-block Root mount waiting for: usbus0 Root mount waiting for: usbus0 uhub0: 3 ports with 3 removable, self powered Root mount waiting for: usbus0 ugen0.2: <vendor 0x0424> at usbus0 uhub1: <vendor 0x0424 product 0x9514, class 9/0, rev 2.00/2.00, addr 2> on usbus0 uhub1: MTT enabled Root mount waiting for: usbus0 uhub1: 5 ports with 4 removable, self powered ugen0.3: <vendor 0x0424> at usbus0 smsc0: <vendor 0x0424 product 0xec00, rev 2.00/2.00, addr 3> on usbus0 Trying to mount root from ufs:/dev/mmcsd0s2 [rw,noatime]... smsc0: chip 0xec00, rev. 0002 miibus0: <MII bus> on smsc0 ukphy0: <Generic IEEE 802.3u media interface> PHY 1 on miibus0 ukphy0: none, 10baseT, 10baseT-FDX, 100baseTX, 100baseTX-FDX, auto ue0: <USB Ethernet> on smsc0 ue0: Ethernet address: 0e:60:33:b1:46:01 warning: no time-of-day clock registered, system time will not be set accurately Setting hostuuid: 3cb350f6-5feb-11e2-8bd9-0e6033b14601. Setting hostid: 0xcdd5b164. No suitable dump device was found. Entropy harvesting: interrupts ethernet point_to_point kickstart. Starting file system checks: /dev/mmcsd0s2: FILE SYSTEM CLEAN; SKIPPING CHECKS /dev/mmcsd0s2: clean, 1796048 free (1512 frags, 224317 blocks, 0.1% fragmentation) Mounting local file systems:. Writing entropy file:. Setting hostname: pandaboard. smsc0: chip 0xec00, rev. 0002 ue0: link state changed to DOWN Starting Network: lo0 ue0. lo0: flags=8049<UP,LOOPBACK,RUNNING,MULTICAST> metric 0 mtu 16384 options=600003<RXCSUM,TXCSUM,RXCSUM_IPV6,TXCSUM_IPV6> inet 127.0.0.1 netmask 0xff000000 ue0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> metric 0 mtu 1500 options=80001<RXCSUM,LINKSTATE> ether 0e:60:33:b1:46:01 media: Ethernet autoselect (none) status: no carrier Starting devd. Waiting 30s for the default route interface: .....(no carrier) Creating and/or trimming log files. Starting syslogd. realpath: /dev/dumpdev: No such file or directory /etc/rc: WARNING: Dump device does not exist. Savecore not run. ELF ldconfig path: /lib /usr/lib /usr/lib/compat Clearing /tmp (X related). Updating motd:. Performing sanity check on sshd configuration. Starting sshd. Starting cron. Starting background file system checks in 60 seconds. Wed Jan 16 15:32:20 UTC 2013 FreeBSD/arm (pandaboard) (ttyu0) login:
これで起動しました。あとは独自にカーネルをHackするなり、 portsの導入を試みるなりと、さまざまな物事に挑戦出来ます。 Tear-1なインテルアーキテクチャでしたら、portsのソフトウェアも導入できて 当たり前ですが、arm環境ではそうも行きません。 様々な問題が立ちふさがってくれるでしょう。
ちょっとした情報
イメージの再作成と初回以降の起動イメージ作成時間の短縮
起動イメージを作成する際にいろいろ試していると、カーネルのソースコードだけを 書き換えて再作成することがよくあります。
こうした場合に、いちいちmake buildworldしていると、気が狂いそうになれます。 カーネルだけをいじってるのですから、buildkernelだけにしてほしいものです。
そこで、以下のようにして起動イメージを再作成するとよいでしょう。
# rm work/_.built-kernel # sh beaglebone.sh
なお、u-bootのコンパイルを除く全てをやり直したい場合は、以下のようにして 実行します。
# rm -rf work/* # sh beaglebone.sh
workディレクトリの下の掃除をしないと、コンパイルが実行されませんので 注意しましょう。
ここまでのまとめ
Pandaboard 上でFreeBSD-arm を起動させました。 armではソースコードの修正で簡単に動作しなくなります。 一度動作したソース木はバックアップを取るか、 少なくとも動作したrevision番号は記録し、 その際のsvn diffを残しておきましょう。 これを忘れて不用意にsvn up すると、とても悲しいことになります。