Skip to content

Instantly share code, notes, and snippets.

@jannson
Last active August 29, 2015 13:57
Show Gist options
  • Save jannson/9659067 to your computer and use it in GitHub Desktop.
Save jannson/9659067 to your computer and use it in GitHub Desktop.
/*
* 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