引导程序 - 切换处理器保护模式 [英] bootloader - switching processor to protected mode

查看:219
本文介绍了引导程序 - 切换处理器保护模式的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有理解一个简单的引导加载程序是如何工作的困难。我说的是引导加载程序是由MIT的课程操作系统工程之一。

首先,让我告诉你一个组装件$ C $的c中的BIOS执行:

  [F000:fec3] 0xffec3:lidtw%CS:0x7908
[F000:fec9] 0xffec9:lgdtw%CS:0x7948
[F000:fecf] 0xffecf:MOV CR0%,%EAX
[F000:fed2] 0xffed2:或者$为0x1,%eax中
[F000:fed6] 0xffed6:MOV EAX%,CR0%
[F000:fed9] 0xffed9:ljmpl $ 0x8中,$ 0xffee1

从外观上来看,这code设置中断表和描述符表,然后打开保护模式。


  1. 我们为什么要进入保护模式
    在BIOS?应该不是
    引导程序在实模式下运行(顺便说一句 -
    为什么它需要在实际运行
    模式?)

  2. 我搜查,但没有发现任何地方
    究竟是怎么ljmpl指令
    工作的,并且是的区别
    它和LJMP和定期JMP - 我
    将AP preciate如果有人
    在正确的方向点。

  3. 为什么我们进行跳跃?什么是
    该指令的目的是什么?

移动到引导加载程序code -

 从实到保护模式,使用引导GDT#开关
#和段翻译,使虚拟地址
#等同于它们的物理地址,从而使
#有效存储器映射中的切换期间不会改变。
LGDT gdtdesc
MOVL%CR0,EAX%
ORL $ CR0_PE_ON,EAX%
MOVL%eax中,CR0%#跳转到下一条指令,但是在32位code段。
#交换机处理器成32位模式。
LJMP $ PROT_MODE_CSEG,$ protcseg


  1. 它说,该处理器是
    实模式 - 但我们只是看到,
    BIOS切换到保护模式...
    我很困惑 - 这怎么可能
    可能吗?

  2. 我们如何切换到32位模式?什么
    使处理器进入神奇
    进入32位模式下,由于LJMP
    指令?

和我不明白另一件事 - 当我跟踪引导程序的执行使用gdb我看到正在执行以下指令(这是从引导程序code中的LJMP指令):

  LJMP 0x8中$,$ 0x7c32

但是,当我在.ASM文件看我看到以下内容:

  LJMP $ 0xb866,$ 0x87c32

完全失去了这里 - 如何过来的指令写在.ASM文件并执行指令是不同的?我有一种预感这与受保护的模式做,它是如何转换的地址,但我真的不明白这一点。

我想AP preciate任何帮助!


解决方案

  1. 某些BIOS实现进入保护模式进入bootloader之前。大多数人没有。这可能是BIOS切换到保护模式在短期内并切换回才去引导程序,这将允许它使用一些保护模式的好处(如32位为默认地址大小)。引导加载程序应该在实模式的原因是,大多数BIOS功能仅在实模式下工作,所以你需要在使用它们实模式。


  2. LJMP指定code段除了切换到以跳转到该地址。他们是如此相似,以至于(至少在GAS)汇编器将切换JMP与2个操作数为LJMP你。


  3. LJMP是改变CS寄存器的唯一途径之一。这需要做激活保护模式,如CS寄存器需要包含在GDT一个code段的选择。 (如果你想知道,其他的方法来改变CS是远调用,远回报,中断返回)


  4. 请参阅项目1.无论是BIOS切换回实模式,或此引导器将不具有此BIOS的工作。


  5. 请参阅第3项。它改变了CS指定32位code段,所以处理器进入32位模式。


  6. 当你看了.ASM文件,指令是ptted仿佛地址大小为32位,但GDB间pretted它仿佛地址大小为16位间$ P $。在指令的地址的数据将是0xEA 32 7C 08 00 66 B8中。 EA是跳远运code。在一个32位地址空间,该地址将使用下四个字节,对于0x87C32的地址来指定,但在一个16位地址空间,只有2字节被用于,0x7C32的地址。地址后的2个字节指定要求的code段,这将是0xB866在32位模式和×0008的16位模式。该0x66 B8是下一个指令,该指令是移动一个16位立即值到AX寄存器的开始,可能是设置了保护模式下的数据段。


I'm having difficulties understanding how a simple boot loader works. The boot loader I'm talking about is the one from MITs course "Operating Systems Engineering".

First, let me show you a piece of assembly code the BIOS executes:

[f000:fec3]    0xffec3: lidtw  %cs:0x7908
[f000:fec9]    0xffec9: lgdtw  %cs:0x7948
[f000:fecf]    0xffecf: mov    %cr0,%eax
[f000:fed2]    0xffed2: or     $0x1,%eax
[f000:fed6]    0xffed6: mov    %eax,%cr0
[f000:fed9]    0xffed9: ljmpl  $0x8,$0xffee1

From the looks of it, This code sets up the interrupt table and the descriptor table and then turns on the protected mode.

  1. Why do we go into protected mode in the BIOS? Shouldn't the bootloader run in real mode (btw - why does it need to run in real mode?)
  2. I searched but didn't find anywhere exactly how the ljmpl instruction works, and is the difference between it and ljmp and regular jmp - I would appreciate if someone would point in the right direction.
  3. Why do we perform the jump? What is the purpose of this instruction?

Moving on to the boot loader code -

# Switch from real to protected mode, using a bootstrap GDT
# and segment translation that makes virtual addresses
# identical to their physical addresses, so that the
# effective memory map does not change during the switch.
lgdt    gdtdesc
movl    %cr0, %eax
orl     $CR0_PE_ON, %eax
movl    %eax, %cr0

# Jump to next instruction, but in 32-bit code segment.
# Switches processor into 32-bit mode.
ljmp    $PROT_MODE_CSEG, $protcseg

  1. It says that the processor is in real mode - but we just saw that the BIOS switches to protected mode... I'm confused - how can this be possible?
  2. How do we switch to 32bit mode? What causes the processor to magically go into 32bit mode due to the ljmp instruction?

And another thing that I don't understand - when I track the execution of the bootloader with gdb I see the following instruction being executed (that's the ljmp instruction from the bootloader code):

ljmp   $0x8,$0x7c32

But when I looked in the .asm file I saw the following:

ljmp   $0xb866,$0x87c32

Totally lost here - How come the instruction written in the .asm file and the instruction executed are different? I have a hunch this has to do with the protected mode and how it translates the addresses but I don't really get it.

I would appreciate any help!

解决方案

  1. Some BIOS implementations go into protected mode before entering the bootloader. Most don't. It is possible that BIOS switches to protected mode for a short period and switches back before going to the bootloader, which would allow it to use some of the benefits of protected mode (such as 32 bit being the default address size). The reason that the bootloader should be in real mode is that most BIOS functions only work in real mode, so you need to be in real mode to use them.

  2. ljmp specifies a code segment to switch to in addition to the address to jump to. They are so similar that (at least in GAS) the assembler will switch a jmp with 2 operands to a ljmp for you.

  3. ljmp is one of the only ways to change the cs register. This needs to be done to activate protected mode, as the cs register needs to contain the selector for a code segment in the GDT. (In case you want to know, the other ways to change cs are far call, far return, and interrupt return)

  4. See item 1. Either BIOS switched back to real mode, or this bootloader will not work with this BIOS.

  5. See item 3. It changes cs to specify a 32 bit code segment, so the processor goes into 32 bit mode.

  6. When you looked at the .asm file, the instruction was interpretted as if the address size was 32 bits, but GDB interpretted it as if the address size was 16 bits. The data at the address of the instruction would be 0xEA 32 7C 08 00 66 B8. EA is the long jump opcode. In a 32 bit address space, the address would be specified using the next four bytes, for an address of 0x87C32, but in a 16 bit address space, only 2 bytes are used, for an address of 0x7C32. The 2 bytes after the address specify the requested code segment, which would be 0xB866 in 32 bit mode and 0x0008 in 16 bit mode. The 0x66 B8 is the start of the next instruction, which is moving a 16 bit immediate value into the ax register, probably to set up the data segments for protected mode.

这篇关于引导程序 - 切换处理器保护模式的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆