こちらはアセンブラになります。
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 件のコメント:
コメントを投稿