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

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

问题描述

我很难理解一个简单的引导加载程序是如何工作的.我正在谈论的引导加载程序是 MIT 课程操作系统工程"中的引导加载程序.

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".

首先,让我给你看一段 BIOS 执行的汇编代码:

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. 为什么要进入保护模式在 BIOS 中?不应该引导加载程序以实模式运行(顺便说一句 -为什么需要真实运行模式?)
  2. 我搜索了但没有找到任何地方ljmpl 指令到底如何工作,是之间的区别it 和 ljmp 和常规 jmp - I如果有人愿意,将不胜感激指向正确的方向.
  3. 我们为什么要进行跳跃?什么是这条指令的目的是什么?

转到引导加载程序代码 -

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. 它说处理器在实模式 - 但我们刚刚看到BIOS 切换到保护模式...我很困惑——这怎么可能可能吗?
  2. 我们如何切换到 32 位模式?什么导致处理器神奇地运行由于 ljmp 进入 32 位模式指导?

还有一件事我不明白 - 当我使用 gdb 跟踪引导加载程序的执行时,我看到正在执行以下指令(这是引导加载程序代码中的 ljmp 指令):

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

但是当我查看 .asm 文件时,我看到了以下内容:

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

ljmp   $0xb866,$0x87c32

完全迷路了——为什么写在.asm文件中的指令和执行的指令不一样?我有一种预感,这与保护模式以及它如何转换地址有关,但我真的不明白.

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.

我将不胜感激!

推荐答案

  1. 某些 BIOS 实现在进入引导加载程序之前会进入保护模式.大多数没有.BIOS 可能会在短时间内切换到保护模式并在进入引导加载程序之前切换回来,这将允许它使用保护模式的一些好处(例如 32 位是默认地址大小).引导加载程序应该处于实模式的原因是大多数 BIOS 功能只能在实模式下工作,因此您需要处于实模式才能使用它们.

  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.

ljmp 指定除了要跳转到的地址之外要切换到的代码段.它们非常相似,以至于(至少在 GAS 中)汇编器会为您将带有 2 个操作数的 jmp 转换为 ljmp.

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.

ljmp 是更改 cs 寄存器的唯一方法之一.这需要完成以激活保护模式,因为 cs 寄存器需要包含 GDT 中代码段的选择器.(如果你想知道,改变cs的其他方法是far call、far return和interrupt return)

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)

参见第 1 项.要么 BIOS 切换回实模式,要么此引导加载程序无法与此 BIOS 一起使用.

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

参见第 3 项.它将 cs 更改为指定 32 位代码段,因此处理器进入 32 位模式.

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

当您查看 .asm 文件时,该指令被解释为地址大小为 32 位,但 GDB 将其解释为地址大小为 16 位.指令地址处的数据为 0xEA 32 7C 08 00 66 B8.EA 是跳远操作码.在 32 位地址空间中,地址将使用接下来的四个字节指定,地址为 0x87C32,但在 16 位地址空间中,仅使用 2 个字节,地址为 0x7C32.地址后的 2 个字节指定请求的代码段,在 32 位模式下为 0xB866,在 16 位模式下为 0x0008.0x66 B8 是下一条指令的开始,它将一个 16 位立即数移动到 ax 寄存器中,可能是为了将数据段设置为保护模式.

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天全站免登陆