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が横取りしちゃう。しょうがないので、 左右キーに変更。それに伴い元々の左右キーを上下キーに追いやった。

一息ついて

とあるエンジニアの備忘log

Cortex-A入門編

uboot

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みたいな 感覚で、コマンドを増やせるぞ。