函式呼叫原型:
protected_mode_jump(boot_params.hdr.code32_start, (u32)&boot_params + (ds() << 4));
其程式碼:
/*
* void protected_mode_jump(u32 entrypoint, u32 bootparams);
*/
GLOBAL(protected_mode_jump)
movl %edx, %esi # Pointer to boot_params table
xorl %ebx, %ebx
movw %cs, %bx
shll $4, %ebx
addl %ebx, 2f
jmp 1f # Short jump to serialize on 386/486
1:
movw $__BOOT_DS, %cx
movw $__BOOT_TSS, %di
### 設定x86之cr0暫存器的PE位元,如此便能進入proctected-mode
movl %cr0, %edx
orb $X86_CR0_PE, %dl # Protected mode
movl %edx, %cr0
# Transition to 32-bit mode
.byte 0x66, 0xea # ljmpl opcode
2: .long in_pm32 # offset
.word __BOOT_CS # segment
ENDPROC(protected_mode_jump)
.code32
.section ".text32","ax"
GLOBAL(in_pm32)
# Set up data segments for flat 32-bit mode
movl %ecx, %ds
movl %ecx, %es
movl %ecx, %fs
movl %ecx, %gs
movl %ecx, %ss
# The 32-bit code sets up its own stack, but this way we do have
# a valid stack if some debugging hack wants to use it.
addl %ebx, %esp
# Set up TR to make Intel VT happy
ltr %di
# Clear registers to allow for future extensions to the
# 32-bit boot protocol
xorl %ecx, %ecx
xorl %edx, %edx
xorl %ebx, %ebx
xorl %ebp, %ebp
xorl %edi, %edi
# Set up LDTR to make Intel VT happy
lldt %cx
## 跳至code32_start的標籤
jmpl *%eax # Jump to the 32-bit entrypoint
ENDPROC(in_pm32)
至於code32_start在哪裡呢? 此標籤定義在arch/x86/boot/header.S,如下所示:
code32_start: # here loaders can put a different
# start address for 32-bit code.
.long 0x100000 # 0x100000 = default for big kernel
也就是說,核心已做完real-mode Linux程式碼該做的事情,並跳至protected-mode Linux程式碼的起始位址 (1MB),請看下圖:
[Reference]
【The Kernel Boot Process】
【Linux Kernel Source 2.6.31】
沒有留言:
張貼留言