庇を貸して母屋を取られる

きっかけは tty

何気にFreeBSDにリモート・ログインしてる端末(PuTTY)上で、こんなコマンドを叩いたんだ。

[sakae@fb ~]$ tty
/dev/pts/2

え、/dev/ptsって、リナでサポートされてるデバイスじゃん。普段は気にする事は無けど、こういう無駄な事をやると、思わぬ拾い物のような気がする。

リナでQEMUした時、コンソールはVGAな奴だったけど、シリアルは/dev/psts/XX だった。

と言う事は、FreeBSDでもシリアルが使えそうだな。

FreeBSD上のqemu

取り敢えず、どんなフレーバーが提供されてるか、確認してみる。まあ、/usr/portsの下にあるMakefileを見れば済む事なんだけど、別角度からって事で。

[sakae@fb ~]$ pkg search qemu
aqemu-0.9.2_3                  Qt5 based QEMU frontend
qemu-guest-agent-5.0.1         QEMU guest-agent utilities
qemu-powernv-3.0.50_4          Fork of QEMU with experimental PowerNV emulation support
qemu-tools-7.1.0               QEMU CPU Emulator (tools only)
qemu6-6.2.0                    QEMU CPU Emulator  - 6.X
qemu6-nox11-6.2.0              QEMU CPU Emulator (without X11) - 6.X
qemu6-tools-6.2.0              QEMU CPU Emulator (tools only) - 6.X
qemu70-tools-7.0.0             QEMU CPU Emulator (tools only) - 7.0.x
u-boot-qemu-arm-2022.04_1      Cross-build das u-boot for model qemu-arm
u-boot-qemu-arm64-2022.04_1    Cross-build das u-boot for model qemu-arm64
u-boot-qemu-riscv64-2022.04_1  Cross-build das u-boot for model qemu-riscv64

こちらの方がMakefileの直当たりよりは、網羅的で見逃しがなさそう。

qemu7なんて言う先走りがあるようだけど、まだ時代は6なんだな。そしてnox11版が有る。emacsもそうなんだけど、リモートで使う人は、Xそんなの関係ねぇって人が多いんで、一定の要求が有るんだな。

オイラーもリモート組なんだ、nox11版数を入れてみる。

Linux と FreeBSD は親戚?

さてqemuを入れてから、DebianとFreeBSDが等価で動くか検証。リナ側からそっくりそのまま、OpenBSDのゲスト環境を持ってくる。 ええ、ディアルブートなんで、両OSをつなぐ回廊を経由してですが。

[sakae@fb ~/QEMU]$ cat boot
#!/bin/sh

SF=
EF=
while getopts "SE" opt; do
        case $opt in
        S)      SF='-S';;
        E)      EF='-hdb ext.img';;
        *)      echo 'Usage: boot [-S] [-E]'
                echo '  -S   cpu Stop at startup'
                echo '  -E   Enable 2nd disk'
                exit 1;;
        esac
done

qemu-system-i386 -m 128 -s  $SF \
  -serial pty  -net nic -net user,hostfwd=tcp::2022-:22 \
  virtual.img  $EF

あら、メモリーはゆったりの設定だった。そんな事より注目は -serial ptyな部分。グラフィックは何も指定していなんで無視されるんだろうな。

ちなみにOpenBSD用は下記。シリアルも無しVGAも無しの謎設定。その代わりダエモン君が外側から手助けする構成。詳細は過去記事参照。

qemu-system-i386 -m 64 -nographic -no-fd-bootchk -s $SF \
  -net nic -net user,hostfwd=tcp::2022-:22  \
  -hda virtual.img $EF
[sakae@fb ~/QEMU]$ ls -lh virtual.img ext.img
-rw-r--r--  1 sakae  wheel   1.0G Oct 16 15:44 ext.img
-rw-r--r--  1 sakae  wheel   597M Oct 17 06:05 virtual.img

ゲストOSの本体DISKであるvirtual.imgは、回廊をそのまま通過出来たけど、ext.imgは大き過ぎて通過出来無かった。しょうがないので圧縮して通過させたよ。このDISKはソース一式が入ったものだ。tgzにして200Mになってった。

普通の起動

[sakae@fb ~/QEMU]$ ./boot &
[1] 1397
[sakae@fb ~/QEMU]$ char device redirected to /dev/pts/3 (label serial0)
VNC server running on ::1:5900

文句を言われずに、このようになるまで、ちょいと小細工が必要だった。問題は2つ。

一つは回線がロックされてるってエラー。/var/spool/lock/ なんたらとか言われた。 多分dialerのグループに加盟しないと駄目そうだったので、/etc/groupに自分のIDを追加。

もう一つは、専用のログファイルが無いよってやつ。aculog ってのを作ったよ。

[sakae@fb /var/log]$ cat aculog
sakae (Mon Oct 19 05:57:18 2022) <cu9600, , /dev/pts/3> call completed

こんな他愛もないのが記録される。

[sakae@fb ~/QEMU]$ cu -l /dev/pts/3
Connected

OpenBSD/i386 (qm.my.domain) (tty00)

login: sakae
Password:
Last login: Mon Oct 18 06:02:59 on tty00
OpenBSD 7.1 (SEE) #1: Sat Oct  8 15:30:33 JST 2022

Welcome to OpenBSD: The proactively secure Unix-like operating system.

qm$ tty
/dev/tty00
qm$ cat /etc/boot.conf
set tty com0
set timeout 5

gdbと協調する

次は、gdbと共演しましょ。それには、ゲストOSで動いてくるカーネルのデバック版が必要。 これは、目下の所OpenBSD(64bit)にしか置いていない。

/usr/src/sys 以下を持ってくれば済む話なんだけど、そこにはFreeBSDの先住者が炒る。 アメリカ人みたいに、先住民を皆殺しにして乗っ取るか。オイラーは平和な人。そんな事はいたしません。

アメリカの黒歴史なんて本を読むと、ヨーロッパでジリ貧の人だとか脛にキズを持つ半端者が、メイフラワー号で新天地をめざした。そして先住民を駆逐したなんてのが出てくる。

で、~/QEMU/sys に入れたよ。TAGSだとかcscopeのあれとかを含んだ大きい所帯だ。移住先で再生出来るのは切り捨てて着の身着の儘って手もあったけど、面倒なので大移動です。

弊害

これでemacsからgdbを使うと、こんな風に怒られた。ソースの場所に齟齬をきたしているんだな。

acpicpu_idle () at /usr/src/sys/dev/acpi/acpicpu.c:1207
1207    /usr/src/sys/dev/acpi/acpicpu.c: No such file or directory.

ならば、立回り先を事前に登録しておくか。 ~/QEMU/sys/arch/i386/compile/SEE/.gdbinit

target remote :1234
dir /home/sakae/QEMU/sys/kern:/home/sakae/QEMU/sys/arch/i386:/home/sakae/QEMU/sys/dev/acpi

これで、裏側でソースの在処を見繕ってくれた。でも、どんどんと立回り先の登録を余儀なくされそう。この先も面倒が続くのは嫌だな。何とかしたいぞ。下記はsys/dev/acpiが検索先に登録されてるんで、無様な表示は無い。

(gdb) bt
#0  acpicpu_idle () at /usr/src/sys/dev/acpi/acpicpu.c:1207
#1  0xd0f25988 in cpu_idle_cycle ()
#2  0xd099998d in sched_idle (v=0xd1181ff8 <cpu_info_full_primary+8184>) at /usr/src/sys/kern/kern_sched.c:190
#3  0xd0f2560d in proc_trampoline ()

庇を貸して母屋を取られる

一番簡単な方法で、逃げる事にする。そう、リンクトリック。使いすぎに注意しましょうモードではあるんですが。

[sakae@fb /usr/src]$ ls -ld sys*
lrwxr-xr-x   1 root  wheel    20 Oct 19 08:00 sys@ -> /home/sakae/QEMU/sys
drwxr-xr-x  53 root  wheel  1024 Sep  9 07:43 sys-FreeBSD/

元々有った sys を、sysu-FreeBSD に変更。空いた sys の権利を、移住してきたOpenBSDに割当てる。そう、NHKでやってる、いいいじゅう 方式ね。これで、gdb に咎められる事も無くなり、周囲の環境に溶け込んだよ。いわゆる、庇を貸して母屋を取られる って状態。

これで当面はいいんだけど、sysの下はカーネル者の常駐場所。先住者の便のため、/ からsysにリンクが貼られているんだ。

[sakae@fb /usr/src]$ ls -l /sys
lrwxr-xr-x  1 root  wheel  11 Apr  9  2021 /sys@ -> usr/src/sys

このままでもいいんだけどね。cd /sys てやると、OpenBSDの世界が表れる。知らない人はびっくり仰天。ちゃんと、FreeBSD向けにリンクを捻じ曲げておこうかな。

まあ、FreeBSDのカーネルは難解だからなあ。OpenBSDのそれを卒業したら、考える事にするか。多分、一生かかっても卒業出来ぬ、生涯学習だろうけどね。

pkg

ついでなので、pkgの諸サブコマンドを調べておく。

info

まずは、入れたパッケージの情報確認。

[sakae@fb ~]$ pkg info qemu6-nox11-6.2.0
 :
WWW            : https://wiki.qemu.org/Main_Page
Comment        : QEMU CPU Emulator (without X11) - 6.X
Options        :
        CAPSTONE       : off
        CDROM_DMA      : on
        CURL           : on
  :
Shared Libs required:
        libzstd.so.1
        libvdeplug.so.3
        libsasl2.so.3
        libpng16.so.16
  :
Flat size      : 493MiB
Description    :
QEMU is a FAST! processor emulator using dynamic translation to achieve
good emulation speed.
QEMU has two operating modes:

    * Full system emulation. In this mode, QEMU emulates a full system
(for example a PC), including a processor and various peripherials.
It can be used to launch different Operating Systems without rebooting
the PC or to debug system code.

オプションの設定情報が出てる。Makefileを見なくても済むな。それから依存ライブラリィー情報も出てる。QEMUみたいに依存が多いと、何が本当に必要か見極めるのが楽になりそう。

[sakae@fb ~]$ pkg info qemu6-6.2.0
pkg: No package(s) matching qemu6-6.2.0

インストールされていない奴は、詳細分かりませんと、当たり前の返答でした。こういう時は、頑張ってMakefileを読むはめになるな。

which

それから、指定したファイルは、何処からやって来たか調べられる。 ふと、llvm-objdumupが正式な場所に入っていて、普通のobjdumpは、責任外の場所に有ったので、調べてみる。

[sakae@fb ~]$ pkg which /usr/local/bin/objdump
/usr/local/bin/objdump was installed by package binutils-2.37_4,1

etc