before kernel

ftp and fetch

OpenBSDのftpは拡張されてるって事を前回知った。ならばFreeBSDの場合は? やはり、拡張されてた。横の繋がりは良好だな。でも一抹の不安があったので検証。だって説明によればftpのプロトコルそのもので通信してるっぽいからね。相手先がftp言語を話してくれないと、意思不通になると思ったのさ。

[sakae@fb /tmp]$ ftp https://ftp.jaist.ac.jp/pub/GNU/gforth/gforth-0.7.3.tar.gz
ftp: Can't lookup `https:ftp': Name does not resolve
ftp: Can't connect or login to host `https:?'
[sakae@fb /tmp]$ fetch https://ftp.jaist.ac.jp/pub/GNU/gforth/gforth-0.7.3.tar.gz
gforth-0.7.3.tar.gz                                   2464 kB 1403 kBps    01s

さもありなんと言うエラーだった。よって、FreeBSD特製のfetchを取出したよ。

vbox$ ftp https://ftp.jaist.ac.jp/pub/GNU/gforth/gforth-0.7.3.tar.gz
Trying 150.65.7.130...
Requesting https://ftp.jaist.ac.jp/pub/GNU/gforth/gforth-0.7.3.tar.gz
100% |**************************************************|  2464 KB    00:00
2523433 bytes received in 0.69 seconds (3.48 MB/s)

OpenBSDの方は、何の問題もなく動いた。FreeBSDはfetchがあるから、そちらを使えって事なんだな。勿論OpenBSDには、fetchなんてコマンドは用意されていない。ftp命って事ですな。同じBSD族でも性格が違うのね。

change kernel

boot時にkernelを切り換えられると言うので、試してみる。

boot> boot hd0a:/bsd02
NOTE: random seed is being reused.
booting hd0a:/bsd02: 9304599+2241540+225288+0+1126400 [97+544944+575197]=0xd60a8
entry point at 0x201000

[ using 1120776 bytes of bsd ELF symbol table ]
Copyright (c) 1982, 1986, 1989, 1991, 1993
        The Regents of the University of California.  All rights reserved.
Copyright (c) 1995-2022 OpenBSD. All rights reserved.  https://www.OpenBSD.org

OpenBSD 7.1 (SEE) #0: Mon Oct  3 13:40:16 JST 2022
  :
qm$ ls -l /bsd*
-rwx------  2 root  wheel  17916863 Oct  9 14:23 /bsd*         ;; SEE#1 -O0
-rwx------  2 root  wheel  17916863 Oct  9 14:23 /bsd.booted*
-rwx------  1 root  wheel  14998741 Oct  3 14:10 /bsd.org*     ;; RELEASE
-rw-------  1 root  wheel   4021133 Sep 29 14:09 /bsd.rd
-rwx------  1 root  wheel  12896745 Oct  3 14:09 /bsd02*        ;; SEE#0 -O2    

3種類のカーネルを用意した。

boot> 0
 RETを叩くと、すぐに起動してしまうので注意の事。慌てずにhelpと叩くべし。
help
commands: # boot echo env help hexdump ls machine reboot set stty time
machine: boot comaddr diskinfo memory
boot>
booting hd0a:/bsd: 13912599+2241540+241672+0+1130496 [97+802512+713363]=0x122b3c
entry point at 0x201000

[ using 1516508 bytes of bsd ELF symbol table ]
Copyright (c) 1982, 1986, 1989, 1991, 1993
        The Regents of the University of California.  All rights reserved.
Copyright (c) 1995-2022 OpenBSD. All rights reserved.  https://www.OpenBSD.org

OpenBSD 7.1 (SEE) #1: Sat Oct  8 15:30:33 JST 2022

bootで使えるコマンドを試してみる。

boot> machine diskinfo
Disk    BIOS#   Type    Cyls    Heads   Secs    Flags   Checksum
fd0     0x0     *none*  80      2       36      0x4     0x0
hd0     0x80    label   779     128     63      0x2     0xc26c94d7
boot> machine memory
Region 0: type 1 at 0x0 for 639KB
Region 1: type 2 at 0x9fc00 for 1KB
Region 2: type 2 at 0xf0000 for 64KB
Region 3: type 1 at 0x100000 for 64384KB
Region 4: type 2 at 0x3fe0000 for 128KB
Region 5: type 2 at 0xfffc0000 for 256KB
Low ram: 639KB  High ram: 64384KB
Total free memory: 65023KB
boot> ls
drwxr-xr-x 0,0  512     .
drwxr-xr-x 0,0  512     ..
-rwx------ 0,0  17916863        bsd
-rw------- 0,0  4021133 bsd.rd
drwxr-xr-x 0,0  512     usr
drwxr-xr-x 0,0  512     altroot
drwxr-xr-x 0,0  1024    bin
drwxr-xr-x 0,0  19456   dev
drwxr-xr-x 0,0  1536    etc
drwxr-xr-x 0,0  512     home
drwxr-xr-x 0,0  512     mnt
drwx------ 0,0  512     root
drwxr-xr-x 0,0  1536    sbin
drwxrwxrwt 0,0  512     tmp
drwxr-xr-x 0,0  512     var
-rw-r--r-- 0,0  578     .cshrc
-rw-r--r-- 0,0  468     .profile
stat(hd0a:/./sys): No such file or directory ;; sys@ -> usr/src/sys
-rw-r--r-- 0,0  88304   boot
-rwx------ 0,0  17916863        bsd.booted
-rwx------ 0,0  14998741        bsd.org
-rwx------ 0,0  12896745        bsd02

何だかbootってリナで言うgrubだな。幾つもカーネルを登録しておいて、それを切り換えて使うって発想はgrubでは余り見られないみたいだけど。せいぜい新しいカーネルを作って、それがまずい場合、古いカーネルを起動するって使いかたみたい。そんなんじゃ、もったいないぞ。

patch2

前回は変数領域にある、とある変数を見つけ出す方法をやった。今度はそれを書き換えてみよう。書き換えられたら容易に観測出来るやつを選ぶ事にする。で、目を付けたのがcopyrightな奴。起動時にさりげなく表示されるあれだ。実際に使われるのは、 init_main の中。

ob$ nm bsd | grep copyright
d101ea2c R copyright
d0e41470 T dvd_read_copyright

属性がRになってるのがそれ。ReadOnlyな奴ね。

ob$ objdump -h bsd
Sections:
Idx Name          Size      VMA       LMA       File off  Algn
  2 .rodata       00220f80  d0f45000  00f45000  00d45000  2**4
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
ob$ gdb -q
(gdb) p/x (0xd101ea2c - 0xd0f45000 + 0x00d45000)
$1 = 0xe1ea2c
ob$ hexedit bsd
Ctl-g
                                New position ? 0xe1ea2c
				
00E1EA20   10 4C 29 D0  40 50 29 D0  10 51 29 D0  43 6F 70 79  .L).@P)..Q).Copy
00E1EA30   72 69 67 68  74 20 28 63  29 20 31 39  38 32 2C 20  right (c) 1982,
00E1EA40   31 39 38 36  2C 20 31 39  38 39 2C 20  31 39 39 31  1986, 1989, 1991
00E1EA50   2C 20 31 39  39 33 0A 09  54 68 65 20  52 65 67 65  , 1993..The Rege
00E1EA60   6E 74 73 20  6F 66 20 74  68 65 20 55  6E 69 76 65  nts of the Unive
00E1EA70   72 73 69 74  79 20 6F 66  20 43 61 6C  69 66 6F 72  rsity of Califor
00E1EA80   6E 69 61 2E  20 20 41 6C  6C 20 72 69  67 68 74 73  nia.  All rights
00E1EA90   20 72 65 73  65 72 76 65  64 2E 0A 43  6F 70 79 72   reserved..Copyr
00E1EAA0   69 67 68 74  20 28 63 29  20 31 39 39  35 2D 32 30  ight (c) 1995-20
00E1EAB0   32 32 20 4F  70 65 6E 42  53 44 2E 20  41 6C 6C 20  22 OpenBSD. All
00E1EAC0   72 69 67 68  74 73 20 72  65 73 65 72  76 65 64 2E  rights reserved.
00E1EAD0   20 20 68 74  74 70 73 3A  2F 2F 77 77  77 2E 4F 70    https://www.Op
00E1EAE0   65 6E 42 53  44 2E 6F 72  67 0A 00 CC  00 00 55 AA  enBSD.org.....U.

TABして文字列領域に移動し、カーソルキーで書き換え場所を指定、書き換え、Ctl-x でファイルをセーブ。 書き変わったか確認。

ob$ strings bsd | grep 2050
  :
Copyright (c) 1995-2050 OpenBSD. All rights reserved.  https://www.OpenBSD.org

末永くOpenBSDのプロジェクドが続くように 2022 を 2050 にさりげなく変更した。後はこのカーネルを実機に転送するだけ。書き換えたOSを起動。

[ using 1516508 bytes of bsd ELF symbol table ]
Copyright (c) 1982, 1986, 1989, 1991, 1993
        The Regents of the University of California.  All rights reserved.
Copyright (c) 1995-2050 OpenBSD. All rights reserved.  https://www.OpenBSD.org

バイナリーパッチ大成功。でも、これでいいのか。悪い人が勝手に改変したらどうなる? ELFエリアのチェックサムぐらいは実施して、ファイルの破損を検出して欲しいなあ。

そう言えば、boot やーいって事で楽しんできたけど、その舞台裏はどうなってるの? 少し調べてみるか。

boot OpenBSD

と言う事で、見付たのがこれ。良質な資料を見つけ出すのも技術の一つかな。

A Study of Initialization in Linux and OpenBSD

stand/mbr

起動時のメッセージの痕跡が定義されてた。

Using drive 0, partition 3.  

純粋な悪石向けなんで、目が汚れるな。

stand/biosboot (pbr)

同じく悪石スタイル。必要なら、biosboot(8)を読むべし。

Loading......

stand/boot

ブート時のメッセージ担当。

probing: pc0 com0 apm pci mem[639K 62M a20=on]
disk: fd0 hd0+
>> OpenBSD/i386 BOOT 3.44
 :

これに呼応して、下記の痕跡を発見。ここら辺は機種依存なので、arch/i38/stand/bootとかに鎮座している。

stand/boot/conf.c

const char version[] = "3.44";

struct i386_boot_probes probe_list[] = {
        { "probing", i386_probe1, nitems(i386_probe1) },
        { "disk",    i386_probe2, nitems(i386_probe2) }
};

そして、機種に依存しないコードは、/sys/stand の下。昔ながらのboot/と、新式のefi/に分れている。ここら辺まで來るとC言語になっている。

installboot

mbrにしろpbrにしろbootにしろ、カーネルは全く知らない事だ。でも、これらはDISKの中に鎮座してる必要がある。で、鎮座させる為のプログラムがinstallbootって奴だ。 下記は、それのドライラン。

qm$ installboot -nv wd0
Using / as root
would install bootstrap on /dev/rwd0c
using first-stage /usr/mdec/biosboot, second-stage /usr/mdec/boot
would copy /usr/mdec/boot to //boot
looking for superblock at 65536
found valid ffs2 superblock
//boot is 6 blocks x 16384 bytes
fs block shift 2; part offset 64; inode block 312, offset 12912
expecting 64-bit fs blocks (incr 4)
master boot record (MBR) at sector 0
        partition 3: type 0xA6 offset 64 size 6291392
/usr/mdec/biosboot will be written at sector 64

元ネタは下記にある。色々と対応してるな。

ob$ ls -l /usr/mdec/
total 1188
-r-xr-xr-x  1 root  bin  126464 Apr 12  2022 BOOTIA32.EFI*
-r-xr-xr-x  1 root  bin  141838 Apr 12  2022 BOOTX64.EFI*
-r-xr-xr-x  1 root  bin    5268 Apr 12  2022 biosboot*
-r-xr-xr-x  1 root  bin   88136 Apr 12  2022 boot*
-rw-r--r--  1 root  bin   89300 Apr 12  2022 cdboot
-rw-r--r--  1 root  bin    2048 Apr 12  2022 cdbr
-r-xr-xr-x  1 root  bin   46712 Apr 12  2022 fdboot*
-r-xr-xr-x  1 root  bin     512 Apr 12  2022 mbr*
-rw-r--r--  1 root  bin   98652 Apr 12  2022 pxeboot

mbrは盲腸みたいなもの。昔はbiosbootだけでやってたみたいだけど、互換性の問題で、mbrを挟むようになったらしい。 また一族にBOOTX64.EFIなんてのが伺えるので、GPTにも対応しているんだな。今は、こちらが主流か。

このinstallbootは、インストール時の最後のステップで実行されるようだ。

ob$ cd /usr/src/usr.sbin/installboot
ob$ ls
Makefile                   installboot.8              softraid.c
bootstrap.c                installboot.c              sparc64_installboot.c
efi_installboot.c          installboot.h              sparc64_installboot.h
hppa_installboot.c         landisk_installboot.c      sparc64_softraid.c
i386_installboot.c         loongson_installboot.c     stubs.c
i386_installboot.h         macppc_installboot.c       util.c
i386_nlist.c               octeon_installboot.c
i386_softraid.c            powerpc64_installboot.c

boot FreeBSD

OpenBSDばかりでは、井の中の蛙になっちまうのでFreeBSD方面も調べて億。で、まずは登場人物を確認。 boot(8)

FILES
     /boot.config  parameters for the boot blocks (optional)
     /boot/boot1   first stage bootstrap file
     /boot/boot2   second stage bootstrap file
     /boot/loader  third stage bootstrap
     /boot/kernel/kernel
                   default kernel
     /boot/kernel.old/kernel
                   typical non-default kernel (optional)

簡単な素性調査。

[sakae@fb /boot]$ ls -l boot* loader*
-r--r--r--  1 root  wheel    8192 May 19 07:03 boot
-r--r--r--  1 root  wheel     512 Apr  9  2021 boot0
-r--r--r--  1 root  wheel     512 Apr  9  2021 boot0sio
-r--r--r--  1 root  wheel     512 May 19 07:03 boot1
-r-xr-xr-x  1 root  wheel  125440 May 19 07:03 boot1.efi*
-r--r--r--  1 root  wheel    7680 May 19 07:03 boot2
-r-xr-xr-x  3 root  wheel  495616 Sep  4 05:47 loader*
-r--r--r--  1 root  wheel    7812 Apr  9  2021 loader.4th
-rw-r--r--  1 root  wheel      55 Sep 15 06:58 loader.conf
-r-xr-xr-x  2 root  wheel  824832 Sep  4 05:47 loader.efi*
-r--r--r--  1 root  wheel     394 Apr  9  2021 loader.rc
-r-xr-xr-x  1 root  wheel  434176 Sep  4 05:47 loader_4th*
-r-xr-xr-x  1 root  wheel  750592 Sep  4 05:47 loader_4th.efi*
-r-xr-xr-x  3 root  wheel  495616 Sep  4 05:47 loader_lua*
-r-xr-xr-x  2 root  wheel  824832 Sep  4 05:47 loader_lua.efi*
-r-xr-xr-x  1 root  wheel  372736 Sep  4 05:47 loader_simp*
-r-xr-xr-x  1 root  wheel  690688 Sep  4 05:47 loader_simp.efi*

boot0ってのは多分mbrだろう。loader.4thなんてのがきになる。 loader(8)

NAME
     loader – kernel bootstrapping final stage

DESCRIPTION
     The program called loader is the final stage of FreeBSD's kernel
     bootstrapping process.  On IA32 (i386) architectures, it is a BTX client.
     It is linked statically to libstand(3) and usually located in the
     directory /boot.
      :

フォースの力だけじゃなくて、月の力も利用出来るとな。深入りすると、NHKの沼にはまってから出演依頼が來そうなので止めておく。あそこに出て来るゲストはU20ぐらいの人達だからね。まあ、年寄は呼ばれる事無から安心しろ。

etc