Last active
August 29, 2015 13:57
-
-
Save jannson/9659067 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* The actual transition into protected mode | |
*/ | |
#include <asm/boot.h> | |
#include <asm/processor-flags.h> | |
#include <asm/segment.h> | |
#include <linux/linkage.h> | |
.text | |
.code16 | |
/* | |
* 这里的entrypoint就是32位kernel启动代码的入口,通过code32_start传入,bootparams是已经整理好的32位的线性地址, | |
* 不需要进一步转换转换。eax是entrypoint,edx是bootparams。 | |
* void protected_mode_jump(u32 entrypoint, u32 bootparams); | |
*/ | |
GLOBAL(protected_mode_jump) | |
movl %edx, %esi # Pointer to boot_params table //保存boot_params的指针 | |
xorl %ebx, %ebx | |
movw %cs, %bx | |
shll $4, %ebx //ebx里面是实模式启动代码所用到的空间上限 | |
addl %ebx, 2f //2f位置的内容是指向in_pm32的相对位移,调整该位移以指向in_pm32在实际内存中的地址。 | |
jmp 1f # Short jump to serialize on 386/486 | |
1: | |
//_BOOT_DS和_BOOT_TSS在arch/x86/include/asm/Segment.h里面定义。 | |
movw $__BOOT_DS, %cx | |
movw $__BOOT_TSS, %di | |
movl %cr0, %edx | |
orb $X86_CR0_PE, %dl # Protected mode | |
movl %edx, %cr0 //CR0的保护模式置位 | |
# Transition to 32-bit mode。//跳转到in_pm32,设置完CR0之后必须使用长跳转来使CPU进入保护模式。 | |
.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 | |
//初始化数据段,ecx=_BOOT_DS,是在go_to_protected_mode里面设定的DS的选择字。 | |
//是相对于GDT头的位移量。在arch/x86/include/asm/Segment.h里面定义。实际上这个选择字指向的是0-4G的所有内存空间,和CS是一样的。 | |
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 //设置Task Stack Segment. %di里面是TSS的选择字。该选择字在GDT里, | |
# 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 //将LDTR设为0 | |
jmpl *%eax # Jump to the 32-bit entrypoint //让我们跳到code32_start吧。 | |
ENDPROC(in_pm32) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment