Chinaunix首页 | 论坛 | 博客
  • 博客访问: 17793
  • 博文数量: 8
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 0
  • 用 户 组: 普通用户
  • 注册时间: 2014-04-23 17:20
文章分类
文章存档

2015年(6)

2014年(2)

我的朋友
最近访客

分类: LINUX

2015-01-27 09:46:54

进入保护模式的代码相当短,在pmjump.S中。我们就来一点一点看到底是如何进入保护模式的。

  1. /*
  2. * The actual transition into protected mode
  3. */
  4. #include
  5. #include
  6. #include
  7. #include
  8. .text
  9. .code16
  10. /*
  11. * void protected_mode_jump(u32 entrypoint, u32 bootparams);  这里的entrypoint就是32位kernel启动代码的入口,通过code32_start传入,bootparams是已经整理好的32位的线性地址,不需要进一步转换转换。eax是entrypoint,edx是bootparams。
  12. */
  13. GLOBAL(protected_mode_jump)
  14. movl %edx, %esi # Pointer to boot_params table //保存boot_params的指针
  15. xorl %ebx, %ebx
  16. movw %cs, %bx
  17. shll $4, %ebx  //ebx里面是实模式启动代码所用到的空间上限
  18. addl %ebx, 2f  //2f位置的内容是指向in_pm32的相对位移,调整该位移以指向in_pm32在实际内存中的地址。
  19. jmp 1f # Short jump to serialize on 386/486
  20. 1:
  //_BOOT_DS和_BOOT_TSS在arch/x86/include/asm/Segment.h里面定义。
  1. movw $__BOOT_DS, %cx
  2. movw $__BOOT_TSS, %di
  3. movl %cr0, %edx
  4. orb $X86_CR0_PE, %dl # Protected mode
  5. movl %edx, %cr0 //CR0的保护模式置位
  6. # Transition to 32-bit mode。//跳转到in_pm32,设置完CR0之后必须使用长跳转来使CPU进入保护模式。
  7. .byte 0x66, 0xea # ljmpl opcode
  8. 2: .long in_pm32 # offset
  9. .word __BOOT_CS # segment
  10. ENDPROC(protected_mode_jump)
  11. .code32
  12. .section ".text32","ax"
  13. GLOBAL(in_pm32)
  14. # Set up data segments for flat 32-bit mode 
  15. //初始化数据段,ecx=_BOOT_DS,是在go_to_protected_mode里面设定的DS的选择字。是相对于GDT头的位移量。在arch/x86/include/asm/Segment.h里面定义。实际上这个选择字指向的是0-4G的所有内存空间,和CS是一样的。
  16. movl %ecx, %ds
  17. movl %ecx, %es
  18. movl %ecx, %fs
  19. movl %ecx, %gs
  20. movl %ecx, %ss
  21. # The 32-bit code sets up its own stack, but this way we do have
  22. # a valid stack if some debugging hack wants to use it.
  23. addl %ebx, %esp //初始化堆栈。将原先实模式启动代码的空间全部用作堆栈。
  24. # Set up TR to make Intel VT happy
  25. ltr %di //设置Task Stack Segment. %di里面是TSS的选择字。该选择字在GDT里
  26. # Clear registers to allow for future extensions to the
  27. # 32-bit boot protocol
  28. xorl %ecx, %ecx
  29. xorl %edx, %edx
  30. xorl %ebx, %ebx
  31. xorl %ebp, %ebp
  32. xorl %edi, %edi
  33. # Set up LDTR to make Intel VT happy
  34. lldt %cx  //将LDTR设为0
  35. jmpl *%eax # Jump to the 32-bit entrypoint  //让我们跳到code32_start吧。
  36. ENDPROC(in_pm32)
阅读(544) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~