2019-09-23

FreeBSDのブートプロセスをみる』(白崎博生、UNIX MAGAZINE COLLECTION、2006年)を追体験しながら、カーネルを勉強することにしました。まず最初にカーネルのリモートデバッグができる環境をVirtualBoxを使って準備しました。書籍ではFreeBSD 5.1が使われていますが、今更古いバージョンを用意するのもなんなので、最新のFreeBSD 12.0を使うつもりです。記事の記述とは合わないところが出てくるかもしれませんが、それも含めて勉強です。

まずは第1回「Boot Manager」から始めます。記事ではboot0のソースがboot/i386/boot0/boot0.sと書かれていますが、stand/i386/boot0/boot0.Sに変わっていました。コメントも記事とは変わっているようですが、ロジックは変化していません。

まず最初に「自分自身を00600Hへ移動する」処理があります。レジスタを適切に設定してrepプレフィックスをつけたmovswで転送する訳ですが、ここで疑問が生じました。該当箇所は次のようになっています。
   181  start:          cld                             # String ops inc
   182                  xorw %ax,%ax                    # Zero
   183                  movw %ax,%es                    # Address
   184                  movw %ax,%ds                    #  data
   185                  movw %ax,%ss                    # Set up
   186                  movw $LOAD,%sp                  #  stack
   187 
   188          /*
   189           * Copy this code to the address it was linked for, 0x600 by default.
   190           */
   191                  movw %sp,%si                    # Source
   192                  movw $start,%di                 # Destination

ここでSIレジスタには転送元、DIレジスタには転送先が入っています。$LOADというのは、上述したソースコードのちょっと前で「.set LOAD,0x7c00」のように定義されています。しかし$startというのはラベルとして定義されているだけです。しかもコードの最初にあるので0x0000ではないのでしょうか。どうして0x0600として扱われるのでしょうか。すくなくとも、このファイルには(コメントに0x600と書かれているだけで)なんの定義もありません。これが疑問でした。

Webを検索しても、boot0を解説している情報は幾つか見つかりますが、この疑問に答えてくれる情報がなかなか見つかりませんでした。

Webで検索を続けていると『FreeBSD Architecture Handbook』に次のような記述があることを知りました。
It is worth looking at the Makefile for boot0 (sys/boot/i386/boot0/Makefile ), as it defines some of the runtime behavior of boot0. For instance, if a terminal connected to the serial port (COM1) is used for I/O, the macro SIO must be defined (-DSIO). -DPXE enables boot through PXE by pressing F6. Additionally, the program defines a set of flags that allow further modification of its behavior. All of this is illustrated in the Makefile. For example, look at the linker directives which command the linker to start the text section at address 0x600, and to build the output file “as is” (strip out any file formatting):
そしてMakefileでは以下のように記述されていると書かれています。
BOOT_BOOT0_ORG?=0x600
LDFLAGS=-e start -Ttext ${BOOT_BOOT0_ORG} \
-Wl,-N,-S,--oformat,binary
そういうことなのか、と思いましたが、Makefileには次のような記述があるだけでした。
BOOT_BOOT0_ORG?=        0x600
ORG=${BOOT_BOOT0_ORG}
考え方は変わっていないのだと思いますが、実現方法が変わったのでしょう。今回は、そこまでは追いかけませんでした。しかしともすれば見過ごしてしまう点を追及できました。

0 件のコメント:

コメントを投稿