我很难理解一个简单的引导加载程序是如何工作的。我正在谈论的引导加载程序是 MIT 课程“操作系统工程”中的引导加载程序。
首先,让我向您展示一段 BIOS 执行的汇编代码:
[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
从它的外观来看,这段代码设置了中断表和描述符表,然后打开了保护模式。
- 为什么我们在 BIOS 中进入保护模式?引导加载程序不应该在实模式下运行(顺便说一句 - 为什么它需要在实模式下运行?)
- 我搜索但没有找到 ljmpl 指令的确切工作原理,以及它与 ljmp 和常规 jmp 之间的区别 - 如果有人指出正确的方向,我将不胜感激。
- 我们为什么要进行跳跃?这条指令的目的是什么?
继续引导加载程序代码 -
# 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
- 它说处理器处于实模式 - 但我们刚刚看到 BIOS 切换到保护模式......我很困惑 - 这怎么可能?
- 我们如何切换到 32 位模式?是什么导致处理器由于 ljmp 指令神奇地进入 32 位模式?
还有一件事我不明白 - 当我使用 gdb 跟踪引导加载程序的执行时,我看到正在执行以下指令(这是引导加载程序代码中的 ljmp 指令):
ljmp $0x8,$0x7c32
但是当我查看 .asm 文件时,我看到了以下内容:
ljmp $0xb866,$0x87c32
完全迷失在这里 - 为什么写在.asm文件中的指令和执行的指令不同?我有一种预感,这与保护模式以及它如何转换地址有关,但我并没有真正理解。
我将不胜感激任何帮助!