boot関数

boot関数に処理が移ると、やっと見慣れたC言語のコードが出て来ます :-) boot関数内では、ハードベッタリのコードが多くハードの仕様書がなかなか探し当てることが出来ないので苦労したりします。(つうか良くわからん)

boot関数の主な処理は、現在動作しているコンピュータのハードウエアの検出や設定を行ます。それが終了するとboot optionの処理を行い、kernelをロードしkernel側に処理を移行します。

この処理では下記の関数を使用します。

boot

machdep関数をcall

machdep関数ではH/Wの捜査を行います。

Boot バージョンの表示

Boot バージョンをディスプレイに表示します。

Using drive 0 , partition 4 .
Loading........
probing:pc0 com1 com2 apm pci mem[639K 253M a20=on]
disk:fd0 hd0+
>OpenBSD/i386 BOOT 3.01
      

cmd変数を初期化

cmd_state構造体の変数cmdに値をセットします。

この変数には、kernelロード時に必要な情報が格納され、それぞれの変数は次の意味を持ちます。

struct cmd_state {
  char bootdev[16];            /* 起動デバイス名          初期値:"/dev/rhd0a"(devboot関数を参照)*/
  char image[MAXPATHLEN - 16]; /* KernelのFile名          初期値:"/bsd"(KERNELを参照)*/
  int  boothowto;              /* kernel起動オプション    初期値:0(boot commandで変更可 bootparse関数を参照)*/
  char *conf;                  /* boot configuration file 初期値:"/etc/boot.conf" */
  void *addr;                  /* kernelのロードアドレス  初期値:DEFAULT_KERNEL_ADDRESS*/
  int timeout;                 /* タイムアウト値          初期値 : 5s */
	  
  char path[MAXPATHLEN];       /* Kernelの完全なpath名    Ex. "/dev/rhd0a:/bsd" */
  const struct cmd_table *cmd; /* コマンドの関数テーブル  初期値:NULL(cmd_tablecmd_machineを参照)*/
  int argc;
  char *argv[8];               /* XXX i hope this is enough */
};	
cmd.bootdevに起動デバイス名をセット

devboot関数をcallして起動デバイス名を作成しセット。この関数で、以下の文字列がcmd.bootdevにセットされます。

HDDの場合 : "/dev/rhdxa" xはdevice no (例えば 0x81の場合"/dev/rhd1a")
FDDの場合 : "/dev/rfdxa" xはdevice no (例えば 0x00の場合"/dev/rfd0a")
CDの場合  : "/dev/cd0a" device noが0x100の時	
kernelのファイル名をセット

KERNELで定義されたファイル名をcmd.imageにセットします。

boot.confの実行

read_conf関数をcallします。read_conf関数ではcmd.confで指定されたboot.confに書かれているオプションを実行します。

Kernel imageのpathをセット

cmd.pathにKernel imageのpathをセット。

cmd.path = cmd.bootdev + ':' + cmd.image  = "/dev/rhd1a:/kernel"

pathをセットする前に、bootpromptの値を見ていますがbootpromptは0にセットしている所が無いので常に1なのか?

interactive command line

boot.confが存在しなかった場合や読込めなかった場合は、interactive command lineに移行して、オペレータからの入力待になります。

入力プロンプトの表示

入力プロンプトの表示を行う。

Using drive 0 , partition 4 .
Loading........
probing:pc0 com1 com2 apm pci mem[639K 253M a20=on]
disk:fd0 hd0+
>>OpenBSD/i386 BOOT 3.01
boot>_
	  
入力コマンドの実行
getcmd関数をcallして、コマンドの入力処理(readline関数)を行ない、コマンドを実行(docmd関数)する。実行可能なコマンドはcmd_table配列cmd_machine配列に定義される。
このwhile ループから抜出す条件は、
  • boot command実行 Xboot関数が呼ばれ1が戻値になる。
  • return key押下 および 入力タイムアウト Xnop関数が呼ばれ1が戻値になる。(但しKernel load リトライ時には無効になる)

booting表示

booting メッセージの表示を行う。

Using drive 0 , partition 4 ;
Loading........
probing:pc0 com1 com2 apm pci mem[639K 253M a20=on]
disk:fd0 hd0+
>>OpenBSD/i386 BOOT 3.01
boot>
booting /dev/rhd0a:/kernel:
      

loadfile関数をcall

最初にmarks配列イメージのロードアドレスをセットし、loadfile関数をcallします。loadfile関数では、Kernel image をloadしてメモリ上に展開し、配列marksには次の値を返します。

#define LOAD_ALL        0x003f  /* 全てのセッションを読込む */

cmd.path = "/dev/rhd0a:/bsd";                /* Kernelの完全なpath名 */
marks[MARK_START] = DEFAULT_KERNEL_ADDRESS;  /* Kernelの最下位アドレス (IN) */
marks[MARK_ENTRY];                           /* プロセスを開始する仮想アドレスを示す(OUT) */
marks[MARK_NSYM];                            /* 1固定(OUT) */
marks[MARK_SYM];                             /* シンボルテーブルの最初(OUT) */
marks[MARK_END];                             /* Kernelの最上位アドレス(OUT) */
marks[MARK_MAX];                             /* */

loadfile(cmd.path, marks, LOAD_ALL);

そしてloadが成功した場合、whileループから抜出す。

Kernel load失敗時の処理

Kernelの次候補を選択

kernels配列から次候補を選択する。最後(NULL)まで来てしまったら、最初の候補に戻り、try変数をインクリメントする。選択した候補はcmd.imageにセットする。

load失敗を画面表示

kernelのloadが失敗した場合メッセージを表示する。

Using drive 0 , partition 4 .
Loading........
probing:pc0 com1 com2 apm pci mem[639K 253M a20=on]
disk:fd0 hd0+ >>OpenBSD/i386 BOOT 3.01 boot> booting /dev/rhd0a:/kernel: failed(24). will try /obsd
入力タイムアウト値の設定

loadを2セット(try<2)繰り返した場合、タイムアウト無しにする。それ以外の時はタイムアウト値を段々長くする。

run_loadfile関数をcall

Kernelのloadが成功したならば、run_loadfile関数をcallする。

Last modified: Tue Jan 22 18:02:32 2008 JST