永久保存版(OpenBSD 6.6)
今までずっと追いかけていた @IT さんから、 ついに完成「Windows Terminal」の機能と使い方まとめ が出てきた。
新しい、Speed Test 統計学っぽい表示で通の人向け。
永久保存版
前回は、VMWareに入れたamd64とi386なOpenBSDを仮想シリアルライン(named pipe)で接続して、gdbを動かそうとした。 あえなく失敗。どうもOpenBSDでは、kgdbをサポートしていない風。2017/05/13の記事を見ると、OpenBSD 6.1の時代には、KGDBが有ったようだ。それでも、使えなかったようだけど。記憶がすっかり風化してるぞ。
んな訳で、OpenBSDのカーネル観光を行う最適な方法は、qemuを動かして、カーネルをアプリのごとくgdbする方法がベストと思われる。
それもOpenBSD 6.6 までね。6.6は、2020/09までしか陳列されない。新しい6.8が出ると同時に古い(6.6)は削除されちゃうからね。セキュリティー重視だから、古い物は棄てるのを潔しとする方針。って事で、永久保存版を作っておきましょ。
作り方
親機はamd64にしてあげるんで、普通にインストール。src,sysのソースを一式入れる。 pkg_add
で、何はともあれqemuとgdbを入れる。後は好みでemacsを入れる。
子の方はi386版。qemu上に入れる。なんたって32Bitなんで、HEXデータをgdb上で見せられても、おろおろしなくて済む。
親の方で、i386のカーネルをgdbオプション付きでコンパイル。bsdってファイルが出来上がるので、scpを使って子に転送。それを/に置けば出来上がり。
o66$ df -h Filesystem Size Used Avail Capacity Mounted on /dev/wd0a 2.3G 783M 1.4G 35% / mfs:17988 61.9M 2.0K 58.8M 0% /tmp
qemu上で動いているOSが認識してるDiks。十分に余裕を持った設定。更に気持ちRAM Diskも用意した。これで、多少はコンパイルが速くなるかな。
see66$ ls -lh disk -rw-r--r-- 1 sakae sakae 1.1G May 29 15:54 disk
こちらは母艦のDiskファイル。頑張ってRAM DISKを拡張すれば、これ自身もRAMに載るな。
使い方
ob$ cat .gdbinit target remote :1234
こんなのを、bsd.gdbの有る所に置いておけば、gdb bsd.gdb で起動すると同時に、カーネルがgdbの制御下に入り、便利に観光出来る。
see66$ find . -type d -name CVS -exec rm -rf {} +
これ、各Dirに置いてあるCVSってdirが目障りなんで、一気に消してしまう方法。コマンド列の最後に昔は訳の分からない文字を書いていたけど、すっきりさせる例が出てたんで使ってみた。
永久保存版なんで、SDメモリーに保存しておいた。これで、多少無茶な使い方をしても、即座に元に戻せる。
other way
そもそも、こんな永久保存版なんて言い出したのは、qemu上で、OpenBSD 6.7 を上手くセットアップ出来なかったからだ。内製化は、時間がかかって失敗すると言う、良い見本。
ならば、発想を変えて、OpenBSD 6.7の入ったdiskを外注したらどうだろう。条件はただ一つ。そのdiskがqemu上で動く事。
VirtualBox 6.0.22
何でも、6.0系の最後の版らしい。記念に使ってみる。昔のvboxはOpenBSDと相性が悪くて、インストール中に、 必ず コケタものだけど、版を重ねてからは大丈夫。OSでその他を選ぶと、32/64Bitのどちらもサポートされてた。
普通にインストールすれば良いんだけど、一点注意が必要。それは、後の面倒を避ける為、汎用性のある Virtual Disk フォーマット(vhd)を選んでおく事だ。カッコよい名前が付いているけど、何の事は無い、ファイルサイズが固定の生ファイルだろう。
普通は、diskに書き込みをすると、それにつれてファイル容量が増えて行くタイプになってる。 大きなDiskが必要な場合は有り難いわな。でも、今回は用途が決まっているんで、えいやっと、容量を決めてしまった。
qemuに組み込む
組み込むって言っても、今まで使っていたスクリプト中のdisk名をちょっと変更しただけ。
ob$ cat boot qemu-system-i386 -m 256 -s \ -serial pty -net nic -net user,hostfwd=tcp::2022-:22 \ disk.vhd
diskの正体
ob$ file disk.vhd disk.vhd: x86 boot sector; partition 4: ID=0xa6, active, starthead 1, startsector 64, 2681216 sectors
例によって、ちょいと警告が出てきてるけど、無事に動いている。
WARNING: Image format was not specified for 'disk.vhd' and probing guessed raw. Automatically detecting the format is dangerous for raw images, write operations on block 0 will be restricted. Specify the 'raw' format explicitly to remove the restrictions. char device redirected to /dev/ttyp3 (label serial0)
スクリプトをちょっと変更すれば、この警告は消えるはずだけど、どうやるんだったかな?
-drive file=disk.vhd,index=0,media=disk,format=raw
diskの正体を、上記のように書いておけば良いんだな。
emacsのtips
やはりカーネルを自前でコンパイル。今回は頑張って、いらないデバイス群であるUSBを一気に 無効にした。ええ、定義をコメント化ね。多数有るので、viのマクロの登場
:map v 0i##^v[j
vと言うマクロを定義。カーソルを0で行頭へ移動、入力モードに変更してシャープを2個入力。コマンドモードに戻りたいんでESCを入力したいんだけど、Ctl-vを前置する。そして次の行へ行け。久しぶりなんで、viの本を見ちゃったぞ。
そりゃ、emacsな人じゃないな。ええ、lispモードの時は、コメント化したい行を選んでおいて、M-; すれば良いって知ってましたよ。そんな技Makefile用ファイルで使えるのか?
makefile-mode にする。コメント化したい行を選択。M-; で、コメント化出来た。アンコメントも同様な方法できる。これは便利。
src博物館
OpenBSDのソースもきっとgitに挙げられているに違い無いと思って探した。そしたら、 openbsd/src が有ったぞ。これで歴代のソースを確認出来るだろう。
期待してたんだけど、release毎のtagが打たれている訳でもなく、gitの超初心者としては茫然としております。どうやったら、過去のファイルを閲覧出来るのだろう?
それとも、CVSなシステムから遡った方が速い?
cvs
CVS の使い方 - 便利編 を参考にしてみる。各ファイルのログを確認って事で、sys/Makefileを点検
see66$ cvs log Makefile RCS file: /cvs/src/sys/Makefile,v Working file: Makefile head: 1.50 branch: locks: strict access list: symbolic names: OPENBSD_6_7: 1.50.0.6 OPENBSD_6_7_BASE: 1.50 OPENBSD_6_6: 1.50.0.2 OPENBSD_6_6_BASE: 1.50 OPENBSD_6_5: 1.49.0.10 OPENBSD_6_5_BASE: 1.49 OPENBSD_6_4: 1.49.0.8 OPENBSD_6_4_BASE: 1.49 OPENBSD_6_3: 1.49.0.2 OPENBSD_6_3_BASE: 1.49 OPENBSD_6_2: 1.49.0.6 OPENBSD_6_2_BASE: 1.49 OPENBSD_6_1: 1.49.0.4 OPENBSD_6_1_BASE: 1.49 OPENBSD_6_0: 1.45.0.2 OPENBSD_6_0_BASE: 1.45 : OPENBSD_2_0_BASE: 1.1.1.1 netbsd_1_1: 1.1.1.1 keyword substitution: kv total revisions: 57; selected revisions: 57 description: ---------------------------- revision 1.50 date: 2019/05/11 07:18:15; author: deraadt; state: Exp; lines: +2 -2; commitid: v014nE8gOoqL5tny; socppc makes an extended visit to the bigbucket. ok kettenis ---------------------------- revision 1.49 date: 2017/01/11 20:43:15; author: deraadt; state: Exp; lines: +2 -2; commitid: kqchOmVxixWrkXOi; safe to enter arm64 ---------------------------- :
なる程、これが歴史と言うものか。netbsdな人達と喧嘩して、フォークしたんだな。スタートはきりの良いOpenBSD 2.0 からか。詳細は、ウィキペディアで、OpenBSD をどうぞ。
cd /tmp cvs export -r OPENBSD_6_0_BASE sys
これで、任意のverを取得出来るんだな。
Anonymous CVS にも参考になる事が書いてある。
export CVSROOT='anoncvs@anoncvs.ca.openbsd.org:/cvs'
試すなら、こういう設定が必要。世の中の git とは、無縁な世界。OpenBSDらしい。
stty
前回Windows terminalのダイナミックにフォントサイズを動的に変えられた件で、sttyを使って調べた。で、今回はsttyコマンドを紐解いてみる。
コードを参考に、核心部分を抜き出してみた。きっと、 termios(4) tcgetattr(3) なんてのが、関係者になってるだろうけど。
see66$ cat rows.c // from stty.c #include <stdio.h> #include <termios.h> #include <unistd.h> #include <sys/ioctl.h> int fd; struct winsize win; int main(){ fd = STDIN_FILENO; ioctl(fd, TIOCGWINSZ, &win); printf(" %d rows; %d columns;\n", win.ws_row, win.ws_col); return (0); }
走らせてみる。
see66$ ./a.out 39 rows; 80 columns; see66$ ./a.out 34 rows; 73 columns; see66$ stty -e speed 115200 baud; 34 rows; 73 columns; lflags: icanon isig iexten echo echoe -echok echoke -echonl echoctl -echoprt -altwerase -noflsh -tostop -flusho pendin -nokerninfo -extproc -xcase iflags: -istrip icrnl -inlcr -igncr -iuclc ixon -ixoff ixany imaxbel -ignbrk brkint -inpck -ignpar -parmrk oflags: opost onlcr -ocrnl -onocr -onlret -olcuc -oxtabs -onoeot cflags: cread cs8 -parenb -parodd hupcl -clocal -cstopb -crtscts -mdmbuf discard dsusp eof eol eol2 erase intr kill lnext ^O ^Y ^D <undef> <undef> ^? ^C ^U ^V min quit reprint start status stop susp time werase 1 ^\ ^R ^Q <undef> ^S ^Z 0 ^W
最初はデフォのフォントサイズ。次は、C-= して、フォントサイズを大きくしてみた。正式板のstty共、一致が取れている。
ioctlが肝になりそうなので、gdbで追うもソースが無いとのたまう。ひょっとしてあちら側に依頼してるのかな?
キーワードになりそうな、TIOCGWINSZ で、/sysの下に探りを入れると、kern/tty.cで見つかった。これはもう、カーネル観光ですな。
/* * Ioctls for all tty devices. Called after line-discipline specific ioctl * has been called to do discipline-specific functions and/or reject any * of these ioctl commands. */ int ttioctl(struct tty *tp, u_long cmd, caddr_t data, int flag, struct proc *p) : case TIOCGWINSZ: /* get window size */ *(struct winsize *)data = tp->t_winsize; break;
ttioctlにBPを置いて実行していみる。
#0 ttioctl (tp=0xd1e7d200, cmd=2150396949, data=0xf357c910 "\002+", flag=3, 0xd1cd230c) at /usr/src/sys/kern/tty.c:721 #1 0xd09d959a in wsdisplayioctl (dev=3072, cmd=2150396949, data=0xf357c910 "\002+", flag=3, p=0xd1cd230c) at /usr/src/sys/dev/wscons/wsdisplay.c:1064 #2 0xd0890ee5 in spec_ioctl (v=0xf357c648) at /usr/src/sys/kern/spec_vnops.c:370 #3 0xd080a418 in VOP_IOCTL (vp=0xd1e14500, command=2150396949, data=0xf357c910, fflag=3, cred=0xffffffff, p=0xd1cd230c) at /usr/src/sys/kern/vfs_vops.c:290 #4 0xd02e59d2 in cttyioctl (dev=256, cmd=2150396949, addr=0xf357c910 "\002+", flag=3, p=0xd1cd230c) at /usr/src/sys/kern/tty_tty.c:143 #5 0xd0890ee5 in spec_ioctl (v=0xf357c768) at /usr/src/sys/kern/spec_vnops.c:370 #6 0xd080a418 in VOP_IOCTL (vp=0xd1e37f80, command=2150396949, data=0xf357c910, fflag=3, cred=0xd1e4a960, p=0xd1cd230c) at /usr/src/sys/kern/vfs_vops.c:290 #7 0xd0dc5c4d in vn_ioctl (fp=0xd1e2a730, com=2150396949, data=0xf357c910 "\002+", p=0xd1cd230c) at /usr/src/sys/kern/vfs_vnops.c:536 #8 0xd08546a8 in sys_ioctl (p=0xd1cd230c, v=0xf357ca84, retval=0xf357ca7c) at /usr/src/sys/kern/sys_generic.c:517
win.ws_col = 77; ioctl(fd, TIOCSWINSZ, &win);
セットする時は、自前の構造体に値を用意して、ioctlを呼べばよい。TIOCG.. がゲットする時で、TIOCS… はセットする時に使う。ぼーとしてると、動かないおかしいって悩むはめになる。(オイラーは、ぼーしてて1日悩んだ口)