arm開発環境 15.04版
とある早朝、散歩に出かけた。毎日の事だけどこの時期は気持ちがよい。 が、不穏な音が。。。
救急車だった。続いて消防車も。あれーー。早朝の火事かな。朝っぱらから騒々しいな。 散歩を続けます。あたりは田んぼやら果樹園やらビニールハウスが立ち並ぶ、のどかな田園地帯。
で、先ほどの救急車と消防車がパトライトを点滅させながら、農道に止まってたぞ。 なんで? 火事でもないしね。それよりなんで、セットで来るの?
さりげなく散歩を装って、現場へ急行してみれば疑問は氷解するだろうけど、それじゃ 野次馬認定されちゃうので、思いとどまった。
なぜセットか? とっさに考えたのは、交通事故で、けが人が車に閉じ込められちゃったかなあ? 救急車にはサバイバルキットなんて積んでないから、カッターとかの装備してる消防車が 同行した?
でも、遠目でも交通事故の様相は呈していない。それに、交通事故なら、警察車も来る はずだけど、一向に来る気配は無い。
畑で農作業してたおじいちゃんも首をかしげていたぞ。遠目で見ると、担架を畦道に 下ろして、何かやってた。それしか分からず。こういう時のために、オペラグラスが 必要だな。
ええ、家にあるオペラグラスは、競馬だかお船の競争に明け暮れていた人が、場内で 配っていたってやつをたくさん貰ってきて、職場でおすそわけしてくれたやつです。 けっして、オペラを観に行ったのではありません。
どうも、正確な理由が分からないので、ぐぐってみたぞ。
PA連携って言うんか。今回の事例はどういう根拠だったのだろう? 誤って、農薬でも かぶってしまい、意識朦朧かな。それで、 『同時出場する消防隊には、救急処置に必要な酸素吸入器や人工呼吸器などの救急資器材が積載されており』 消防車が同行なんだろうな。きっとそうだろう、そういう事にしておこう。
Awesome on Lubuntu 15.04
ひょいとxspimをウブ14.04で使おうと思った。Windows7に入れておいたXmingを起動させて おいてから、xspimって叩いたら、あろう事か、フォントが無いから駄目って言われた。 そうか、Windows側にフォントが必要なのか。面倒だな。
で、ウブにXを入れてやってみる? 今更古いウブでそこまでやるのは気が引けるなあ。 どうせなら、ウブをX込みで新しくしちゃえ!
正真正銘のウブは貧乏人のマシンではキツイので、貧者のウィンドウ マネージャと言われる LXDE版にしよう。はて、何処から落としてくれば良いの? 海の向こうからじゃ遅いしな。 日本国内のダウンロードサイトからだな。 Lubuntuってのが、LXDE版らしい。落としてきて、VMWAREに入れてあげたよ。
英語版なので、日本語フォントを入れてあげた。凝ってもしょうがないので素直に fonts-takao だけ 入れた。
ファイルマネージャは追加で awesome にした。けど、こいつを起動すると、画面サイズが 膨らまず、800x600までしかいかない。大きい画面欲しいな。何たって、タイル表示するんだから。 (これって、株屋の画面ですな)
それには、特製xorg.confを X -configure して作らないとならない。ALT+CTL+F1 で、 CUI画面からやると、よそでXが動いてるから駄目って怒られた。邪魔なlightdm.serviceをstop させればいいんだな。 そうしておいて、xorg.confを作った。 それを修正。
Section "Monitor" Identifier "Monitor1" VendorName "Monitor Vendor" ModelName "Monitor Model" ### For VMware HorizSync 1-10000 VertRefresh 1-10000 ### 04:03 ModeLine "800x600" 100 800 900 1000 1100 600 700 800 900 ModeLine "1024x768" 100 1024 1100 1200 1300 768 800 900 1000 ModeLine "1360x768" 100 1360 1460 1560 1660 768 868 968 1068 EndSection Section "Screen" : SubSection "Display" Viewport 0 0 Depth 24 Modes "1360x768" EndSubSection EndSection
後は、これを/etc/X11/xorg.conf に入れるだけ。fedoraも22が出てたんで新しくした。 あれ? マウスが固まってる。こういう時は、
vmmouse.present = "FALSE"
vmwareの設定ファイルに上記を追加してから、再起動すれば良いそうだだ。長年慣れ親しんだ yumがメイン開発者が亡くなった、ドキュメントが無い所が有るってんで、新しいパッケージ マネージャになってた。dnfってのがそれらしい。使い方はyumに倣ってるけど、一応 dnf help してねって事みたい。
ああ、Gaucheを入れなければ。あれのInfoを作るには、確かmakeinfoが必要だったはずだけど、 どのパッケージに所属してたかな?
sakae@uB:~$ apt-cache search makeinfo texi2html - Convert Texinfo files to HTML
Fedoraも同じ事かな。
次は、awesomeのカスタマイズ
--- /etc/xdg/awesome/rc.lua 2014-01-23 23:28:30.000000000 +0900 +++ rc.lua 2015-06-05 15:21:51.535652871 +0900 @@ -40,7 +40,8 @@ beautiful.init("/usr/share/awesome/themes/default/theme.lua") -- This is used later as the default terminal and editor to run. -terminal = "x-terminal-emulator" +terminal = "xterm -fn 8x16 " +-- terminal = "x-terminal-emulator" editor = os.getenv("EDITOR") or "editor" editor_cmd = terminal .. " -e " .. editor @@ -56,16 +57,16 @@ { awful.layout.suit.floating, awful.layout.suit.tile, - awful.layout.suit.tile.left, - awful.layout.suit.tile.bottom, - awful.layout.suit.tile.top, - awful.layout.suit.fair, +-- awful.layout.suit.tile.left, +-- awful.layout.suit.tile.bottom, +-- awful.layout.suit.tile.top, +-- awful.layout.suit.fair, awful.layout.suit.fair.horizontal, awful.layout.suit.spiral, - awful.layout.suit.spiral.dwindle, - awful.layout.suit.max, - awful.layout.suit.max.fullscreen, - awful.layout.suit.magnifier +-- awful.layout.suit.spiral.dwindle, +-- awful.layout.suit.max, +-- awful.layout.suit.max.fullscreen, +-- awful.layout.suit.magnifier } -- }}} @@ -197,8 +198,8 @@ -- {{{ Key bindings globalkeys = awful.util.table.join( - awful.key({ modkey, }, "Left", awful.tag.viewprev ), - awful.key({ modkey, }, "Right", awful.tag.viewnext ), + awful.key({ modkey, }, "Up", awful.tag.viewprev ), + awful.key({ modkey, }, "Down", awful.tag.viewnext ), awful.key({ modkey, }, "Escape", awful.tag.history.restore), awful.key({ modkey, }, "j", @@ -232,8 +233,8 @@ awful.key({ modkey, "Control" }, "r", awesome.restart), awful.key({ modkey, "Shift" }, "q", awesome.quit), - awful.key({ modkey, }, "l", function () awful.tag.incmwfact(0.05) end), - awful.key({ modkey, }, "h", function () awful.tag.incmwfact(-0.05) end), + awful.key({ modkey, }, "Right", function () awful.tag.incmwfact( 0.05) end), + awful.key({ modkey, }, "Left", function () awful.tag.incmwfact(-0.05) end), awful.key({ modkey, "Shift" }, "h", function () awful.tag.incnmaster( 1) end), awful.key({ modkey, "Shift" }, "l", function () awful.tag.incnmaster(-1) end), awful.key({ modkey, "Control" }, "h", function () awful.tag.incncol( 1) end),
ターミナルのフォントサイズが小さかったので、少し大きくした。ウィンドウの配置方法が 色々有りすぎて面喰らったので、少なくした。ウィンドウの横幅を変更するのに、WindowsKey+l ってのが 定義されるんだけど、このキーシーケンスをWindows7が横取りしちゃう。しょうがないので、 左右キーに変更。それに伴い元々の左右キーを上下キーに追いやった。
一息ついて
armのまね
ウブも新しくしたんで、armのエミュレータも入れなおした。
alias qemu-arm='qemu-arm-static -L /usr/arm-linux-gnueabi '
こんなエイリアスを設定。qemu-armってのは、strace機能を内蔵してるそうだ。
sakae@uB:~/arm$ qemu-arm -strace a.out 10377 brk(NULL) = 0x00022000 10377 uname(0x407ffb78) = 0 : 10377 open("/lib/i386-linux-gnu/libc.so.6",O_RDONLY|O_CLOEXEC) = 3 10377 read(3,0x407ff878,512) = 512 10377 close(3) = 0 10377 open("/lib/arm-linux-gnueabi/tls/neon/vfp/libc.so.6",O_RDONLY|O_CLOEXEC) = -1 errno=2 (No such file or directory) 10377 stat64("/lib/arm-linux-gnueabi/tls/neon/vfp",0x407ff7a0) = -1 errno=2 (Nosuch file or directory) : 10377 write(1,0x4098c000,14)fact(5) = 120 = 14 10377 exit_group(14)
一生懸命にarm用のライブラリィーを探して、見つからないのでlibcで代用してるのが分かる。 代用の取り成しをqemuがやってるんだな。
次は、gdbの使い方。gdbは自前でarm用に作ったのだ。前回やったsim/armの中に出来るrunが 目当てなんだけど、それだけじゃもったいないので、arm-gdbで登録しといた。
gdbを使う形態は、リモートデバックになる。まず、ターゲットを起動する。
sakae@uB:~/arm$ qemu-arm -g 1234 a.out
1234ポートで、gdbからの接続を待ってまーす。こうしておいて、arm用のgdbを別端末で起動する。
sakae@uB:~/arm$ arm-gdb a.out This GDB was configured as "--host=i686-pc-linux-gnu --target=arm-elf". Reading symbols from a.out...done. : (gdb) target remote localhost:1234 Remote debugging using localhost:1234 (gdb) b fact Breakpoint 1 at 0x10454: file fact.c, line 4. (gdb) c Continuing. Breakpoint 1, fact (n=5) at fact.c:4 4 if ( n == 0 ){ (gdb) c Continuing. Breakpoint 1, fact (n=4) at fact.c:4 4 if ( n == 0 ){ (gdb) bt #0 fact (n=4) at fact.c:4 #1 0x00010478 in fact (n=5) at fact.c:7 #2 0x000104a0 in main () at fact.c:12
後は、objdumpによる逆アセンブルだな。
sakae@uB:~/arm$ arm-linux-gnueabi-objdump -d a.out 00010444 <fact>: 10444: e92d4800 push {fp, lr} 10448: e28db004 add fp, sp, #4 1044c: e24dd008 sub sp, sp, #8 10450: e50b0008 str r0, [fp, #-8] 10454: e51b3008 ldr r3, [fp, #-8] 10458: e3530000 cmp r3, #0 1045c: 1a000001 bne 10468 <fact+0x24> 10460: e3a03001 mov r3, #1 10464: ea000006 b 10484 <fact+0x40> 10468: e51b3008 ldr r3, [fp, #-8] 1046c: e2433001 sub r3, r3, #1 10470: e1a00003 mov r0, r3 10474: ebfffff2 bl 10444 <fact> 10478: e1a03000 mov r3, r0 1047c: e51b2008 ldr r2, [fp, #-8] 10480: e0030392 mul r3, r2, r3 10484: e1a00003 mov r0, r3 10488: e24bd004 sub sp, fp, #4 1048c: e8bd8800 pop {fp, pc} 00010490 <main>: 10490: e92d4800 push {fp, lr} 10494: e28db004 add fp, sp, #4 10498: e3a00005 mov r0, #5 1049c: ebffffe8 bl 10444 <fact> 104a0: e1a03000 mov r3, r0 104a4: e59f000c ldr r0, [pc, #12] ; 104b8 <main+0x28> 104a8: e1a01003 mov r1, r3 104ac: ebffff8b bl 102e0 <printf@plt> 104b0: e1a00003 mov r0, r3 104b4: e8bd8800 pop {fp, pc} 104b8: 0001052c .word 0x0001052c
これだけ使えれば、純粋なarmの石の上で、どうこうする事無いな。便利な世の中だなあ。
sim/arm用のMakefile
続いてgdb由来のsim/arm用のワークベンチと言うか開発環境を作ってみた。使うのは、emacs上から。 Makefileを書いておくと、M-x compile で、makeを呼び出して、コンパイルと言うかアセンブル 出来る。構文間違いが有るとエラーを出してくれるんで、そんな時は、C-x ` で、エラー行へカーソルを飛ばせるので、楽でいいぞ。
いちいち、コンパイルって打ち込むのが面倒なら、init.elに、
(define-key mode-specific-map "c" 'compile) ;; C-c c to compile
と書いておくと、楽出来る。
Makefileは見よう見まねで書いたやつ。使う時は、各コマンドのインデントをTABにしておく事。 unexpandで、スペースをTABに変換出来るぞ。
[sakae@fedora z]$ unexpand --first-only dlmake > Makefile
上記はdlmakeって名前でコピペした場合の変換例。これをやっておかないと、下記のような 指導的警告が出てくる。
[sakae@fedora z]$ make help Makefile:16: *** 分離記号を欠いています (8 個の空白でしたが, TAB のつもりでした か?). 中止.
余は苦しゅうないぞ、佳きに計らえって事になるのは何時の事だ。腹立ちますなあ。
ああ、注意のコメントを入れておいたけど、PROGの所のccはターゲット名に利用してるんで、 変更しないでね。この結果ccって名前の実行バイナリーが作成されるけど、笑って許してね。Makeの都合が 有りますののですから、こんな名前にしてます。
## for sim/arm SRC = fact.c PROGRAM = me PROG = cc # Don't change CC = arm-linux-gnueabi-gcc AS = arm-linux-gnueabi-as LD = arm-linux-gnueabi-ld OBJDUMP = arm-linux-gnueabi-objdump RUN = qemu-arm-static -L /usr/arm-linux-gnueabi SIM = arm-run GDB = arm-gdb $(PROGRAM): $(SRC) $(AS) -o /tmp/MyAsWork.out $(SRC) $(LD) -o $(PROGRAM) /tmp/MyAsWork.out .PHONY: sim sim: $(PROGRAM) $(SIM) -d -t -z $(PROGRAM) # Don't use on emacs. .PHONY: simg simg: $(PROGRAM) $(GDB) -q -x .gdbsim -n $(PROGRAM) ## for qemu-arm $(PROG): $(SRC) $(CC) -g -o $(PROG) $(SRC) .PHONY: dis dis: $(PROG) $(OBJDUMP) -d $(PROG) .PHONY: run run: $(PROG) $(RUN) ./$(PROG) # on other terminal: arm-gdb -q cc .PHONY: rung rung: $(PROG) $(RUN) -g 1234 ./$(PROG) .PHONY: help help: @echo Now source = $(SRC) @echo 'make as and ld, (gen me)' @echo 'make sim sim with trace' @echo 'make simg sim into debug' @echo 'make cc compile c-prog (gen cc)' @echo 'make dis disassemble c-prog' @echo 'make run running c-prog' @echo 'make rung run and wait gdb. other terminal arm-gdb cc'
最初、アセンブルだけ出来ればいいと思ってたけど、欲が出てきて、C語も扱えるように しちゃった。
gdbを呼び出した時に行うお決まりな事は、.gdbinitや.gdbsimに書いておくと楽だ。最近のgdbは、 セキュリティ上の理由からか、ホームdir下の.gdbinitで読み込む.gdbinitを指定しておかないと、無視されるようだ。 そこで、例のように、wbって所で使うように設定してみた。
sakae@uB:~/wb$ cat ~/.gdbinit add-auto-load-safe-path /home/sakae/wb/.gdbinit
sakae@uB:~/wb$ cat .gdbsim display/i $pc target sim load b _start sakae@uB:~/wb$ cat .gdbinit target remote localhost:1234
用意は整ったので、ちょいと走らせてみる
sakae@uB:~/wb$ cat dis.s .text .global _start _start: and r3, pc, r0 .word 0xe3a00000 .long 0xe3a03000 .long 0xe3a0f601 nop
こんな謎コードが有ったとすると、頭を巡らせて逆変換するより、走らせてしまえ。 MakefileのSRCの所にdis.sってアセンブラソースを指定。
sakae@uB:~/wb$ make sim arm-linux-gnueabi-as -o /tmp/MyAsWork.out dis.s arm-linux-gnueabi-ld -o me /tmp/MyAsWork.out arm-run -d -t -z me pc: 10054, and r3, pc, r0 pc: 10058, mov r0, #0 pc: 1005c, mov r3, #0 pc: 10060, mov pc, #1048576 ; 0x100000 pc changed to 100000 pc: 100000, sakae@uB:~/wb$
出来上がった実行ファイルをobjdumpしても、ソースと同じものしか出てこないので、結構 便利です。今度はgdbしてみます。
pc: 100000, sakae@uB:~/wb$ make simg arm-gdb -q -x .gdbsim -n me Reading symbols from me...(no debugging symbols found)...done. Connected to the simulator. Loading section .text, size 0x14 vma 0x10054 Start address 0x10054 Transfer rate: 160 bits in <1 sec. Breakpoint 1 at 0x10054 (gdb) run Starting program: /home/sakae/wb/me Breakpoint 1, 0x00010054 in _start () 1: x/i $pc => 0x10054 <_start>: and r3, pc, r0 (gdb) si 0x00010058 in _start () 1: x/i $pc => 0x10058 <_start+4>: mov r0, #0 (gdb) q
次は、ソースをfact.cに切り替えて、実行してみます。
sakae@uB:~/wb$ make cc arm-linux-gnueabi-gcc -g -o cc fact.c sakae@uB:~/wb$ make run qemu-arm-static -L /usr/arm-linux-gnueabi ./cc fact(5) = 120 Makefile:39: recipe for target 'run' failed make: *** [run] Error 14
ここで出て来るMakeのエラーは、何なんでしょうね? オイラーには意味不ですよ。 次は、gdbです。
sakae@uB:~/wb$ make rung qemu-arm-static -L /usr/arm-linux-gnueabi -g 1234 ./cc
こうしておいて、別端末から実行。あるいはemacs上でM-x gdbして、出て来るgdbをarm-gdbに変更 してから実行も可。emacsから実行すると、ソースが表示されるんで、とっても便利。
sakae@uB:~/wb$ arm-gdb -q cc warning: A handler for the OS ABI "GNU/Linux" is not built into this configuration of GDB. Attempting to continue with the default armv5t settings. Reading symbols from cc...done. warning: Can not parse XML target description; XML support was disabled at compile time 0x40801ad0 in ?? () (gdb) b fact Breakpoint 1 at 0x10454: file fact.c, line 4. (gdb) c Continuing. Breakpoint 1, fact (n=5) at fact.c:4 4 if ( n == 0 ){ (gdb) c Continuing. Breakpoint 1, fact (n=4) at fact.c:4 4 if ( n == 0 ){ (gdb) bt #0 fact (n=4) at fact.c:4 #1 0x00010478 in fact (n=5) at fact.c:7 #2 0x000104a0 in main () at fact.c:12
Makefileにターゲットを付け足せば、いろいろ出来て便利だな。まるでbusyboxみたいな 感覚で、コマンドを増やせるぞ。