2009年7月23日木曜日

protected_mode_jump

go_to_protected_mode関数で最後に呼んでいるのは「protected_mode_jump」です。
こちらはアセンブラになります。

arch/x86/boot/pmjump.S
=====
protected_mode_jump:
movl %edx, %esi # ブートパラメータ構造体のアドレスをESIにセット

xorl %ebx, %ebx #EBXをクリア
movw %cs, %bx  #CSの値をBXへ
shll $4, %ebx   #EBXの値を4ビット左シフト
addl %ebx, 2f   #EBXの値にラベル「2」のアドレスを加算
jmp 1f # ラベル「1」へジャンプ
1:

movw $__BOOT_DS, %cx #CXに__BOOT_DSの値(24)をセット
movw $__BOOT_TSS, %di #DIに__BOOT_TSSの値(32)をセット

movl %cr0, %edx #CR0の値をEDXにセット
orb $X86_CR0_PE, %dl # OR演算でプロテクトモードフラグを立てる
movl %edx, %cr0   #更新したEDXの値をCR0にセットする

# Transition to 32-bit mode
.byte 0x66, 0xea # キャッシュをクリアするためジャンプして次へ

#ラベル「2」は値の定義です
2: .long in_pm32 # offset
.word __BOOT_CS # segment

.size protected_mode_jump, .-protected_mode_jump

.code32
.type in_pm32, @function

in_pm32:
# セグメントレジスタをECXの値で初期化
movl %ecx, %ds
movl %ecx, %es
movl %ecx, %fs
movl %ecx, %gs
movl %ecx, %ss
# スタックはEDXで初期化
addl %ebx, %esp

# TRレジスタDIの値をセット
ltr %di

# 汎用レジスタをクリア
xorl %ecx, %ecx
xorl %edx, %edx
xorl %ebx, %ebx
xorl %ebp, %ebp
xorl %edi, %edi

# 割り込みディスクリプタテーブル(ここではダミー)をロード
lldt %cx

 #プロテクトモードでのエントリポイントへジャンプ
jmpl *%eax # Jump to the 32-bit entrypoint

.size in_pm32, .-in_pm32
=====
最後にジャンプしているエントリポイントは「protected_mode_jump」関数の第1パラメータで指定しています。
呼び出しもとの「go_to_protected_mode」を見てみると

protected_mode_jump(boot_params.hdr.code32_start,
    (u32)&boot_params + (ds() << 4));
}


となっています。
ブートパラメータのcode32_startメンバはheader.Sで定義した値を読み込んだものでs。

======
code32_start: # here loaders can put a different
# start address for 32-bit code.
#ifndef __BIG_KERNEL__
.long 0x1000 # 0x1000 = default for zImage
#else
.long 0x100000 # 0x100000 = default for big kernel
#endif

======
となっていて、通常のbzImageであれば0x100000へジャンプしています。
で、それはどこなのだ?というのは次回。

0 件のコメント:

コメントを投稿