と同時に、一度リアルタイムオペレーティングシステムと言うのを試してみたいとも思っていた。
そこで、arm-none-eabi-*を使ってビルドすることになっているTOPPERS kernelを試してみることにした。ビルドしたら、そのバイナリーが正しく動作するか確認しないといけない。私はRaspberry PiとCubieboard 2を持っているのだが、TOPPERS/JSP、TOPPERS/ASP、TOPPERS/FMPともに、これらのボードには移植されていないようである。
Skyeye のARMエミュレーション用に移植されているのだが、どうやらCodeSourcery Liteが必要らしく、CodeSourcery Liteは既に無料で配布されていないし、それをNetBSDで動かすのも面倒に違いないので、Skyeye用は試すこともしなかった。
エミュレーターと言えばqemuと思って検索してみると、TOPPERS/FMP kernelは、qemu 1.3.0にパッチを当てたものに移植されているらしい。
https://www.toppers.jp/fmp-e-download.html
に、QEMU Versatile Express Cortex-A9 (4 cores)簡易パッケージとして、TOPPERS/FMP 1.2.2が掲載されている。
TOPPERS/FMPの最新版は1.3.0なので、最新版でないのは少し引っかかるが、試してみることにした。
まず、TOPPERS新世代カーネル用コンフィギュレーターと言うものをビルドしないといけないらしい。
https://www.toppers.jp/cfg-download.html
によると、最新版は1.9.4なので、それを試してみることにした。
Makefile中でGNU makeをmakeとして呼んでいるので、そこを$(MAKE)に変更すれば、NetBSD/amd64 currentでも他には修正は必要ない。
パッチは、
https://www.toppers.jp/TOPPERS-USERS/2015-October/004251.html
に投稿しておいた。
pkgsrcからboostをインストールしてある場合には、以下のようにしたら良い。
$ tar zxvf cfg-1.9.4.tar.gz $ cd cfg $ ./configure --with-libraries=/usr/pkg/lib --with-headers=/usr/pkg/include $ patch < diff $ gmake LDFLAGS=-Wl,-R/usr/pkg/lib $ tar zxvf fmp_vexpressa9_gcc-20121214.tar.gz $ cd fmp $ cp ../cfg/cfg cfg/ $ mkdir build $ perl ../configure -g ../cfg/cfg/cfg -T vexpressa9_gcc $ PATH=/usr/pkg/cross-arm-none-eabi/bin:${PATH} gmake ENABLE_G_SYSLOG=false PRC_NUM=4 KERNEL_FUNCOBJS=
fmpというのが、kernelとサンプルアプリケーションが含まれたものになるので、それを実行してみる。
$ qemu-system-arm -cpu cortex-a9 -M vexpress-a9 -smp 4 -serial vc:80Cx40C -serial vc:80Cx40C -serial vc:80Cx40C -serial vc:80Cx40C -no-reboot -icount auto -m 1024M
表示されたGUIの画面で、Ctrl+Alt+4から7を入力することで、タイマー動いているのを確認することができる。
これには、qemu 1.3.0にパッチを当てたものを使用したのだが、qemu 2.4.0.1に替えてみると、タイマーが動き出さず、しばらくしたらメインメモリーアクセスの違反でcore dumpしてしまう。
qemu: fatal: Trying to execute code outside RAM or ROM at 0x04000000
このエラーメッセージで検索してみると、
http://blog.3mdeb.com/2014/08/07/debugging-coreboot-for-qemu-armv7-vexpress-a9-emulated-mainboard/
で同じ問題が解析されている。
私の場合はどうかとqemuで、実行している命令をダンプしてみると、以下のようになっている。-d in_asmをqemu-system-armの引数として加えると、実行している命令をディスアセンブルして表示できる。
---------------- IN: 0x6000591c: e5901014 ldr r1, [r0, #20] 0x60005920: e5801010 str r1, [r0, #16] 0x60005924: e3510000 cmp r1, #0 ; 0x0 0x60005928: 0a000001 beq 0x60005934 ---------------- IN: 0x6000592c: e591d018 ldr sp, [r1, #24] 0x60005930: e591f01c ldr pc, [r1, #28] ---------------- IN: 0x60005984: e32ff013 msr CPSR_fsxc, #19 ; 0x13 ---------------- IN: 0x00000018: 00000000 andeq r0, r0, r0 0x0000001c: 00000000 andeq r0, r0, r0 (snip) 0x03fffff8: 00000000 andeq r0, r0, r0 0x03fffffc: 00000000 andeq r0, r0, r0 qemu: fatal: Trying to execute code outside RAM or ROM at 0x04000000 R00=6004d314 R01=6004e15c R02=00000001 R03=6004d314 R04=00000000 R05=00000000 R06=00000000 R07=00000000 R08=00000000 R09=00000000 R10=00000000 R11=60033994 R12=600000d3 R13=00000000 R14=6000598c R15=04000000 PSR=00000192 ---- A irq32 s00=00000000 s01=00000000 d00=0000000000000000 s02=00000000 s03=00000000 d01=0000000000000000 s04=00000000 s05=00000000 d02=0000000000000000 s06=00000000 s07=00000000 d03=0000000000000000 s08=00000000 s09=00000000 d04=0000000000000000 s10=00000000 s11=00000000 d05=0000000000000000 s12=00000000 s13=00000000 d06=0000000000000000 s14=00000000 s15=00000000 d07=0000000000000000 s16=00000000 s17=00000000 d08=0000000000000000 s18=00000000 s19=00000000 d09=0000000000000000 s20=00000000 s21=00000000 d10=0000000000000000 s22=00000000 s23=00000000 d11=0000000000000000 s24=00000000 s25=00000000 d12=0000000000000000 s26=00000000 s27=00000000 d13=0000000000000000 s28=00000000 s29=00000000 d14=0000000000000000 s30=00000000 s31=00000000 d15=0000000000000000 s32=00000000 s33=00000000 d16=0000000000000000 s34=00000000 s35=00000000 d17=0000000000000000 s36=00000000 s37=00000000 d18=0000000000000000 s38=00000000 s39=00000000 d19=0000000000000000 s40=00000000 s41=00000000 d20=0000000000000000 s42=00000000 s43=00000000 d21=0000000000000000 s44=00000000 s45=00000000 d22=0000000000000000 s46=00000000 s47=00000000 d23=0000000000000000 s48=00000000 s49=00000000 d24=0000000000000000 s50=00000000 s51=00000000 d25=0000000000000000 s52=00000000 s53=00000000 d26=0000000000000000 s54=00000000 s55=00000000 d27=0000000000000000 s56=00000000 s57=00000000 d28=0000000000000000 s58=00000000 s59=00000000 d29=0000000000000000 s60=00000000 s61=00000000 d30=0000000000000000 s62=00000000 s63=00000000 d31=0000000000000000 FPSCR: 00000000
どうやら、アドレス0x000000018に何らかの理由でジャンプしたらそこが0で埋められていて、それを順々に実行して、0x04000000に到達してエラーでcore dumpしていることが分かった。
では、0x000000018に何があるのかと言うと、0x60000018がマッピングされていることが想定されていて、irq_vectorと言うのがあると期待されている。これは、
$ arm-none-eabi-objdump -D fmp fmp: file format elf32-littlearm Disassembly of section .text: 60000000 <__text>: 60000000: e59ff018 ldr pc, [pc, #24] ; 60000020 <_kernel_vector_ref_tbl> 60000004: e59ff018 ldr pc, [pc, #24] ; 60000024 <undef_vector> 60000008: e59ff018 ldr pc, [pc, #24] ; 60000028 <swi_vector> 6000000c: e59ff018 ldr pc, [pc, #24] ; 6000002c <prefech_vector> 60000010: e59ff018 ldr pc, [pc, #24] ; 60000030 <data_abort_vector> 60000014: e59ff004 ldr pc, [pc, #4] ; 60000020 <_kernel_vector_ref_tbl> 60000018: e59ff014 ldr pc, [pc, #20] ; 60000034 <irq_vector> 6000001c: e59ff014 ldr pc, [pc, #20] ; 60000038 <fiq_vector> 60000020 <_kernel_vector_ref_tbl>: 60000020: 6000003c andvs r0, r0, ip, lsr r0 60000024 <undef_vector>: 60000024: 60003c68 andvs r3, r0, r8, ror #24 (snip)
で確認することができる。
さきほどのウェブサイトによると、
http://git.qemu.org/?p=qemu.git;a=commit;h=6ec1588e09770ac7e9c60194faff6101111fc7f0
によって、0x60000000が0x00000000にマッピングされなくなっているらしい。
そう言うことであれば、割込みベクターの位置を0x60000000にすれば良いと考えられる。
http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0388fj/CIHGDDEI.html
にあるVBARレジスターを0x6000000に設定すれば良いように見える。
vexpressa9_gccターゲットをTOPPERS/FMP 1.3.0に移植し、qemu 2.4.0.1で動くようにしたソースコードを、
https://github.com/ryo-on/toppers-fmp-for-qemu-vexpress-a9
に置いておいた。
しかし、VBARの部分は、移植性を無視した形になっているので、他の方法を考えないといけないように思う。
とりあえず、pkgsrc/cross/arm-none-eabi-*が正しいバイナリーを生成していそうであるのは確認できたので良いことにする。
0 件のコメント:
コメントを投稿
注: コメントを投稿できるのは、このブログのメンバーだけです。