debian Jessie in arm

ネットをうろうろしてたら、 システム奮闘記 なんてのに出会った。このサイト、普通の事務員さんが開設してるサイトで、シス管に なって、右往左往する日常を綴ってる。今流行りの、ねーちゃんが、黒板にコマンドを 一つ書いて、解説してくってのとは違い、体当たりしながらいろいろやってく所に 共感を覚える。昔、よく読んだものだ。健在で何より。

その100にある 婚活 Yahooお見合い データマッチングと婚活 なんてのは、哀愁が漂うな。 本音が出てますよ。頑張ってください。

この方、事務員と強調されてるのに、電気回路入門とか、無線LANの基礎なんて原稿を 書かれていて、職業詐称してないかと疑っちゃうぞ。

無線LANは、2.4G帯と5.2G帯があるとな。2.4G帯は電子レンジとか青歯で使ってる帯域と かちあうとな。

おいらからの補足で、ドローンの制御をしてる電波ともかちあうぞ。強力な無線LANを 持ってくると、ドローンを落とせるぞ。ドローンって雄蜂って意味らしいけど、電波で 狂わされるのね。蚊を寄せ付けないようにするには、超音波だけど、ドローンを寄せ付け ないようにするには、2.4G電波が良く効きますぜ。> キンチョーさん。

先進な露天風呂には、ドローン避けが設置してあるらしい。更に、衛星から送られるくる GPS電波を上書きして、ドローンを操れるらしい。

操れるって言っても自由自在ってわけでもないけどね。ドローンが制御を失った時に ホームポジションに帰ってくるように、進化したドローンは出来てるらしい。 頼りにするのがGPSによる位置の確認。

GPS電波を騙して、首相官邸をホームポジションにしちゃうとか、ホームポジションのZ軸 を、高度1万メートルとかに設定しちゃうとかやると、大変だな。

その為には、GPSの電波形式とかを勉強しとかなきゃならない。この無線LANのページは、 とっかかりに最適ですぜ。そういう目的意識を持って、閲覧しましょう。

膨大なリンクが必見ですよ。

debian Jessie

2年ぶりとなるdebainのメジャーバージョンアップが出た。2年ぶりって事は、ウブの長期保守版と 同じだな。ウブの14.04はあと1年間は保障があるけど、保険のために入れておいてもいいかな。 で、今回の売りは、boot時間が短縮されるsystemdの採用にあるようだ。

boot時間短縮で嬉しいのは、arm版ですよ。今は160秒もかかっているから、これが短くなれば いらいらも減るだろう。早速入れてみるか。nettoboot用のCDが提供されてた。これを取って きて、-cdromで指定すればいいんだな。

やってみた。そして撃沈。bootしないでqemu-system-armw.exe が終了しちゃうんだ。エラー でも出してくれれば手がかりが得られるのに。

で、今動いてるのの設定を見ると、オプションにいろいろ設定されてる。-kernelは、そのままカーネルの 設定って事は肯けるけど、-initrdで指定してるのは何? こんなオプションを設定しなくても、 -hdaで指定するハードディスクの中に必要な物が入っているだろうに。

で、initrd.gzとは何ぞやと、ネットをさ迷ってみたのさ。そして、冒頭で書いた、懐かしい ページに行き着いたって訳。なるほど、そういう訳だったのね。特にarmなんてのは、ハードが ごまんとあるから、それに全部対応させようとすると、カーネルが肥大してとんでもない事に なる。それを避けるため、ramdiskに必要なものを放り込んでおいて、boot中はそれを使うとな。

そういう理屈が分かれば、起動に必要なカーネルと、インストールに特化したinitrdを手に 入れる必要がある。そういう方針で、ネットを検索してみた。

天泣記のページにヒントを得て必要なものを、 download してみた。

Windowsでやった方が多少なりとも速いだろうってんで、やってみた。eth0にDHCPサーバーから IPを振ってもらうんだけど、これが失敗する。何で?

しょうがないので、ウブでやる事にした。インストールの最後で、ハードディスク内に インストールされた、initrdを取り出す必要がある。ALT-F2でシェルに落ちろとなってるけど、 旨くいくか?

旨く行かない事を想定して、ネットを検索してみたら、 QemuでARM上にDebianをインストールしたので なんてのが出てきた。

install debian 8

早速インストールしてみる。気になるdisk容量はけちけち作戦で、1200Mに設定。待つ事4時間かかって、 最後の難関、ALT-F2を使う場面が来た。それまではほっておけばいいかと思うと、そうでなくて ちょくちょく入力を求められるので、パソコンから離れられないんだ。

ちゃんとALT-F2キーを使えて、bootの内容を吸い出せた。吸い出した後、ALT-F1キーで、再び インストール画面に戻り、reboot実施。再度、インストールが始まったらqemuを強制終了。

こうして出来上がったのをWindowsへ持って行った。起動スクリプトは次のようにしたよ。

c:\app\qemu\qemu-system-armw.exe ^
 -M versatilepb ^
 -kernel boot\vmlinuz ^
 -initrd boot\initrd.img ^
 -append "root=/dev/sda1" ^
 -redir tcp:2222::22 ^
 -hda hdd.img 

最後に改行をきちんと入れておかないと、最終行が正しく認識されないので注意。 気になる起動時間だけど、dmesgの最後を見ると

[   77.029465] FS-Cache: Loaded
[   77.214854] FS-Cache: Netfs 'nfs' registered for caching
[   77.525305] Installing knfsd (copyright (C) 1996 okir@monad.swb.de).

こんな風になってたから、debian7の頃より半減したって事でいいんかな。デフォで インストールした(sshdとsystemのユーティリティは入れた)状態なんで、NFSやらRPCやら メールが起動してるけど、こいつらをdisableにすると若干は起動が速くなるかな。

どうやってsystemdを手なずけるんだっけな? 以前やったぞ、って事で自分のサイトを 検索してみる。

site:http://space.geocities.jp/hamesspam/ sshd enable

うろ覚えで、sshdをenableしたんだっけな。siteとURLはくっつけるのがコツか。

sakae@arm:~$ df
Filesystem     1K-blocks   Used Available Use% Mounted on
/dev/sda1        1072880 725228    275104  73% /
udev               10240      0     10240   0% /dev
tmpfs              24740   4328     20412  18% /run
tmpfs              61844      0     61844   0% /dev/shm
tmpfs               5120      0      5120   0% /run/lock
tmpfs              61844      0     61844   0% /sys/fs/cgroup

容量をけちったせいで残り少ないな。これだけの容量で、gcc,gdb,make,lv,nkf,sudo,unzip等が入るかしらん?

一番の大物gccは、80Mぐらいだった。後は大した事ないかな。残りの物は30M必要だった。 ケチるとろくな事ないな。これらを入れた後は

sakae@arm:~$ df
Filesystem     1K-blocks   Used Available Use% Mounted on
/dev/sda1        1072880 874904    125428  88% /

あれ? aptが報告してきた消費量と結果が違うな。まあ、このマシンは社会の底辺 もとえ、 CPUの底辺で生きる為の設備だから、これで十分と思わなければいけないな。いけね、screenを入れるの 忘れてた。それから、メインメモリーをもう少し増量しとこう。swapが発生してたから。時代と供に 肥大化してくのは避けられないな。

最近は、RaspberryPiで学ぶ ARMデバイスドライバープログラミング なんて本が出てたり、こういう指南サイトが有ったり Creating a Basic LED Driver for Raspberry Pi 環境構築で、 Raspberry Piのデバイスドライバ開発環境の構築 されてたりする。けど、使われる言語なみんなC語なんだよな。あえて底辺のアセンブラーって 酔狂な人は見かけない。そうさ、オイラーは酔狂な人になってやるぞ。

C語なんて言う上の世界を扱うなら何を使っても一緒。日本にLispを広めた有名な中西先生は、 アセンブラとLispをやっておけば、後はどんな言語でもその間にしか無いから、習得は容易と 達観されてたぞ。

diskを覗く

折角なので、作ったDISKの中を覗いてみる。

sakae@uB:~/jessie$ fdisk -lu hdd.img

Disk hdd.img: 1258 MB, 1258291200 bytes
255 heads, 63 sectors/track, 152 cylinders, total 2457600 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x65f51ede

  Device Boot      Start         End      Blocks   Id  System
hdd.img1            2048     2248703     1123328   83  Linux
hdd.img2         2250750     2455551      102401    5  Extended
hdd.img5         2250752     2455551      102400   82  Linux swap / Solaris

ループマウントしたら中を覗けるのね。

sakae@uB:~/jessie$ sudo mount -t ext4 -o loop,offset=1048576 hdd.img /mnt
sakae@uB:~/jessie$ ls /mnt/boot
config-3.16.0-4-versatile      System.map-3.16.0-4-versatile
initrd.img                     vmlinuz
initrd.img-3.16.0-4-versatile  vmlinuz-3.16.0-4-versatile
sakae@uB:~/jessie$ sudo umount /mnt

upgradeして、カーネルが新しくなったら、こうやっておいてから取り出せばいいんだな。 勉強になったよ。

ラズパイもどき

をしてみる。長く使ってた万次郎Linuxは、垢が溜まって肥大化しすぎてたんだ。で、リフレッシュも 兼ねて鳥を変えてみようって寸法。Debian8です。LXDEを入れてみた。

使いもしないと思われるものが入っていたので、封も切らずに返却したい。どんなものが 入っているか、記念に目録作成。

sakae@debian:~$ dpkg  --get-selections >install.log

何とかオフィス一族を削除。そして、代わりにemacs24を入れた。LXDEは自由度が無いと 言うか、メニューの編集方法が分からない。rootで入れたら、一般ユーザーのメニューにemacs24が出てこない。 しょうがないから、一度消して、一般ユーザーから入れなおした。

それで、LXDEの不自由さに呆れて、どうせ不自由ならもっと不自由な軽いやつを選んでみよーてんで、 LinuxのGUI環境としてウィンドウマネージャーawesomeを使う をチョイスしてみた。

Mod4-Return :ターミナルを起動する
Mod4-r : コマンド入力をメニューに開く
Mod4-左ドラッグ :ウィンドウの位置を調整する
Mod4-右ドラッグ :ウィンドウの大きさを変更する
Mod4-n  :n番のタグへ移動する
Mod4-w  :メニューを出す
Mod4-Ctrl-R  :awesomeを再起動する
Mod4-Shift-Q  :awesomeを終了する

詳細は、ウィンドウマネージャawesomeの基本操作 とか 今日からあなたもawesomeで快適ウインドウマネージャ生活! を参照の事。

また、ラズパイみたいに、startxしてみたいなって事になって、どうやるんだ? Fedora 21をCUIで起動する方法 の方法で良いのかな。

sakae@debian:~$ systemctl list-unit-files | grep dm
initrd-udevadm-cleanup-db.service          static
lightdm.service                            enabled

lightdm.serviceを殺せばいいんだな。そして、.xinitrcに

#exec startlxde
exec awesome

と書いておけとな。で、lightdm.serviceをdisableしても、再起動すると生き返っちゃう。しぶとい奴め。 上のawesomを試せないじゃん。でも、lightdmのグラフィックログインが出てる所で、CTL+ALT+F1-6の キーで、CUI画面に移行出来るのね。そこからstartxすればOK。

グラフィックログインに移行するには、CTL+ALT+F7でOKだった。少々面倒くさい。

ARM Indexed Addressing Mode

ARMは面白い石でRISCよりもCISCっぽい所が有る。そのうちの一つにメモリーからレジスターに 値を持ってくる(逆もしかり)場合の、メモリーアドレス(EA)の決定方法に3種類ある。 これを上手に使うと効率の良いプログラミングが出来る。

一つは Pre-indexdと呼ばれる普通のやつ

[Rn, #offset]      EA = [Rn] + offset
[Rn, +-Rm,shift]   EA = [Rn]+-[Rm] shifted

次は、Pre-indexed with writeback EAを求めた後、Rnを更新

[Rn, #offset]!     EA = [Rn] + offset;        Rn=[Rn]+offset
[Rn, +-Rm,shift]!  EA = [Rn]+-[Rm] shifted;   Rn=[Rn]+-[Rm] shifted

もう一種類は、Post-indexedと呼ばれるやつ。EAは素直に[Rn]だけど、Rnを使った後で更新。

[Rn], #offset      EA = [Rn];   Rn=[Rn]+offset
[Rn], +-Rm,shift   EA = [Rn];   Rn=[Rn]+-[Rm] shifted

Block Copy

サブルーチンへ入った時に、レジスターをpushし出る時にpopするのは知ってたけど、 下記のようにすると、4x12Byte単位で、高速にデータ移動が出来るのね。四角い頭を 丸く使うって例だな。アセンブラーは、工夫のしどころが一杯。

; r12 points to the start of the source data
; r13 points to the start of the destination data
; r14 points to the end of the source data

loop   LDMIA  r12!, {r0-r11}     ; load 48 bytes
       STMIA  r13!, {r0-r11}     ; and store them
       CMP    r12, r14           ; check for the end
       BNE    loop               ; and loop until done

上記が特殊な技法かと思ったら、そうでもなかった。FreeBSDのカーネルソースの中にも 出てきていたぞ。発見現場は、/sys/arm/arm/bcopy_page.S

#define COPY_CHUNK \
        PREFETCH_NEXT_CHUNK ; \
        ldmia   r0!, {r3-r8,ip,lr} ; \
        stmia   r1!, {r3-r8,ip,lr}
#endif /* ! COPY_CHUNK */

一回で32Byte転送するようになってた。読んで書いてってだけでなく、ZEROで埋めるのに、 各RegにZEROを入れておいて、後はstmiaでまとめてメモリーに書いて行くって事もやってた。

Block copyとは関係ないけど、カーネルへの入り口をlocore.Sに見つけたので記念に貼っておく。由来は、NetBSDって 書いてあったぞ。FreeBSDもarm出来るんだな。

/*
 * On entry for FreeBSD boot ABI:
 *      r0 - metadata pointer or 0 (boothowto on AT91's boot2)
 *      r1 - if (r0 == 0) then metadata pointer
 * On entry for Linux boot ABI:
 *      r0 - 0
 *      r1 - machine type (passed as arg2 to initarm)
 *      r2 - Pointer to a tagged list or dtb image (phys addr) (passed as arg1 initarm)
 *
 * For both types of boot we gather up the args, put them in a struct arm_boot_params
 * structure and pass that to initarm.
 */
        .globl  btext
btext:
ASENTRY_NP(_start)
        STOP_UNWINDING          /* Can't unwind into the bootloader! */

        mov     r9, r0          /* 0 or boot mode from boot2 */
        mov     r8, r1          /* Save Machine type */
        mov     ip, r2          /* Save meta data */
        mov     fp, r3          /* Future expantion */

        /* Make sure interrupts are disabled. */
        mrs     r7, cpsr
        orr     r7, r7, #(I32_bit|F32_bit)
        msr     cpsr_c, r7
         :

arm on FreeBSD

FreeBSD/ARM on Raspberry Pi

How to Build a Disk Image バイナリーサイズが大きいのでも130Mぐらいしか無いから、試そうと思えば簡単だな。

FreeBSD/armv6 in QEMUを参考に、prebuilt kernelを 頂いてきて、やってみたけど、起動画面を拝めず。

[sakae@fedora arm]$ qemu-system-arm -M versatilepb -cpu ?
Available CPUs:
  arm1026
  arm1136
  arm1136-r2
  arm1176
  arm11mpcore
  arm926
  arm946
  cortex-a15
  cortex-a8
  cortex-a9
  cortex-m3
  pxa250
  pxa255
  pxa260
  pxa261
  pxa262
  pxa270-a0
  pxa270-a1
  pxa270
  pxa270-b0
  pxa270-b1
  pxa270-c0
  pxa270-c5
  sa1100
  sa1110
  ti925t

ラズパイに載ってるarm1176は対象になってるし。。。 一体どんなイメージになってるの?

[sakae@fedora arm]$ fdisk -lu zed.img

Disk zed.img: 953.7 MiB, 1000000000 bytes, 1953125 sectors
単位: セクタ (1 * 512 = 512 バイト)
セクタサイズ (論理 / 物理): 512 バイト / 512 バイト
I/O サイズ (最小 / 推奨): 512 バイト / 512 バイト
ディスクラベルのタイプ: dos
ディスク識別子: 0x00000000

Device     Boot  Start     End Sectors   Size Id Type
zed.img1   *        63  131102  131040    64M  c W95 FAT32 (LBA)
zed.img2        131103 1953062 1821960 889.6M a5 FreeBSD

2つのパーテションに分かれてて、最初はDOS用。後ろにFreeBSD用があるな。そなら、 DOS用を探索。

[sakae@fedora ~]$ sudo mount -t vfat -o loop,offset=32256 zed.img /mnt
  :
[sakae@fedora mnt]$ ls -l
合計 672
-rwxr-xr-x. 1 root root 408156 11月 12  2014 BOOT.BIN
-rwxr-xr-x. 1 root root    202 11月 12  2014 LICENSE.TXT
-rwxr-xr-x. 1 root root 250655 11月 12  2014 UBLDR
-rwxr-xr-x. 1 root root    441 11月 12  2014 UENV.TXT
-rwxr-xr-x. 1 root root  10687 11月 12  2014 ZEDBOARD.DTB
-rwxr-xr-x. 1 root root   2997 11月 12  2014 ZEDBOARD.DTS
[sakae@fedora mnt]$ cat UENV.TXT
kernel_addr=0x100000
ubldr_addr=0x100000
dtb_addr=0x1000
dtb_name=zedboard.dtb
uenvcmd=echo Booting FreeBSD from SD...; mmcinfo ; fatload mmc 0 ${ubldr_addr} ubldr ; fatload mmc 0 ${dtb_addr} ${dtb_name} ; fdt addr ${dtb_addr} ; bootelf ${ubldr_addr}
tftpboot=echo Booting FreeBSD via tftp...; tftp ${kernel_addr} kernel.bin ; tftp ${dtb_addr} ${dtb_name} ; fdt addm ${dtb_addr} ; go ${kernel_addr}
ipaddr=192.168.1.11
serverip=192.168.1.10
[sakae@fedora mnt]$ file UBLDR
UBLDR: ELF 32-bit LSB executable, ARM, EABI5 version 1 (SYSV), statically linked, not stripped

ubootとか言うローダーが入っているとな。ひょっとしてネットブート用なのかな?

次は、残りのパーテションを見るか。

[sakae@fedora ~]$ sudo mount -t ufs -o loop,offset=67124736,ufstype=44bsd zed.img /mnt
mount: /dev/loop0 は書き込み禁止です、読み込み専用でマウントします
mount: 何らかのエラーにより、マウントが失敗しました。
       ファイルシステムタイプ, オプション, /dev/loop0 上のスーパー
       ブロック, 必要なコードページ指定/ヘルパープログラム
       など、何らかの設定が間違っているものと思われます。

       syslog 内に記録された情報が手助けになるものと思います -
       dmesg | tail などを実行してお読みください
[  1778.585813] ufs_read_super: bad magic number

LinuxはFreeBSDと言うかBSD系には冷たいのかな。さっさと切り上げて、FreeBSDに母艦を 移しましょ。んで、FreeBSDにループデバイスなんて有るんか? 調べたら、mdconfigがその任に当たるようなんだけど、イメージの途中からマウントって 出来ないようだぞ。ならば、最初のDOS部分を削除したらどう?

[sakae@fb10 ~/bsd]$ dd if=zed.img of=yyy skip=131102
mdconfig -f yyy -u0
mount /dev/md0 /mnt
mdconfig -d -u0

これが何故か失敗。manをうろうろしてたら、素敵なコマンドに出会った。

[sakae@fb10 ~/bsd]$ sudo mdmfs -X -P -F zed.img mds1b /mnt
DEBUG: running: /sbin/mdconfig -a -t vnode -f zed.img
DEBUG: running: /sbin/mount /dev/md3s1b /mnt
mdmfs: mount exited with error code 1

手動でやったら、マウント出来た。だんだん思い出してきたぞ。DOSで言うパーテションの 事をFreeBSDでは、スライスって言うんだった。基本スライスが1から4。今回は2番目の 最初のパーテション a をマウントする。尚、必要なデバイスは勝ってに作られるぞ。

[sakae@fb10 ~]$ ls /dev/md*
/dev/md0        /dev/md0s1      /dev/md0s2      /dev/md0s2a     /dev/mdctl
[sakae@fb10 ~/bsd]$ sudo mount /dev/md0s2a /mnt
[sakae@fb10 ~/bsd]$ ls /mnt
COPYRIGHT       etc/            mnt/            sbin/           var/
bin/            lib/            proc/           sys@
boot/           libexec/        rescue/         tmp/
dev/            media/          root/           usr/

ちょいと/etc/rc.confを覗いておく

hostname="zedboard"
ifconfig_cgem0="DHCP"
sshd_enable="YES"
 :

これを見ると、外からsshで接続出来るっぽい。で抜き出したkernelを使ってbootしてみると

qemu: fatal: Trying to execute code outside RAM or ROM at 0xc0100100

R00=00000000 R01=00000000 R02=00000000 R03=00000000
R04=00000000 R05=00000000 R06=00000000 R07=00000000
R08=00000000 R09=00000000 R10=00000000 R11=00000000
R12=00000000 R13=00000000 R14=00000000 R15=c0100100
PSR=400001d3 -Z-- A svc32
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
FPSCR: 00000000

見事にブルー画面が出現しましたよ。残念!!

qemuのkernelオプションで渡してる、freebsd-versatilepb.flashって何者? 特製データみたい。

rm -f $FLASH

# set r0..r3 to zero
/usr/bin/printf "\0\0\240\343" > /tmp/first_commands       # mov r0,#0
/usr/bin/printf "\0\020\240\343" >> /tmp/first_commands
/usr/bin/printf "\0\040\240\343" >> /tmp/first_commands
/usr/bin/printf "\0\060\240\343" >> /tmp/first_commands
# jump to kernel entry point
/usr/bin/printf "\001\366\240\343" >> /tmp/first_commands  # mov pc,0x100000

dd of=$FLASH bs=1M count=4 if=/dev/zero
dd of=$FLASH bs=1 conv=notrunc if=/tmp/first_commands
dd of=$FLASH bs=64k oseek=15 conv=notrunc if=$KERNELBIN
rm -f /tmp/first_commands

uboot-toolsにあるmkimageコマンドとは違うのかな?

[sakae@fedora bsd]$ mkimage -a 0xc0100100 -e 0xc0100100 -A arm -O freebsd -T kernel -d kernel uk
Image Name:
Image Type:   ARM FreeBSD Kernel Image (gzip compressed)
Data Size:    6612118 Bytes = 6457.15 kB = 6.31 MB
Load Address: c0100100
Entry Point:  c0100100