#include <inc/mmu.h> // mmu.h 内含有需要使用的宏定义与函数
# Start the CPU: switch to 32-bit protected mode, jump into C. // 这些代码的作用为转换到 32 位保护模式,然后跳转到 main.c
# The BIOS loads this code from the first sector of the hard disk into // BIOS 读取硬盘第一扇区的内容到 0x7c00
# memory at physical address 0x7c00 and starts executing in real mode // 设置 CS、IP 寄存器,执行实模式
# with %cs=0 %ip=7c00.
.set PROT_MODE_CSEG, 0x8 # kernel code segment selector // 内核代码段 selector,用于寻找 GDT 条目
.set PROT_MODE_DSEG, 0x10 # kernel data segment selector // 内核数据段 selector,用于寻找 GDT 条目
.set CR0_PE_ON, 0x1 # protected mode enable flag // 用于设置 CR0 的 PE 位,目的为开启保护模式
.globl start // 设置全局符号 start
start:
.code16 # Assemble for 16-bit mode // 16位指令
cli # Disable interrupts // 屏蔽中断,Bootloader 执行过程中不响应中断
cld # String operations increment // 从低地址到高地址
# Set up the important data segment registers (DS, ES, SS). // 初始化段寄存器
xorw %ax,%ax # Segment number zero
movw %ax,%ds # -> Data Segment // 数据段寄存器
movw %ax,%es # -> Extra Segment // 附加段寄存器
movw %ax,%ss # -> Stack Segment // 栈段寄存器
# Enable A20:
# For backwards compatibility with the earliest PCs, physical
# address line 20 is tied low, so that addresses higher than
# 1MB wrap around to zero by default. This code undoes this.
seta20.1:
inb $0x64,%al # Wait for not busy
testb $0x2,%al
jnz seta20.1
movb $0xd1,%al # 0xd1 -> port 0x64
outb %al,$0x64
seta20.2:
inb $0x64,%al # Wait for not busy
testb $0x2,%al
jnz seta20.2
movb $0xdf,%al # 0xdf -> port 0x60
outb %al,$0x60
以上代码用于打开 A20 gate,先来简单介绍下 A20 gate
在 8086 中有 20 根地址总线,通过 CS:IP 对的方式寻址,最大访问地址为 1MB
然而,FFFFH:FFFFH = 10FFEFH,也就是说从 100000H 到 10FFEFH 无法访问
当访问这段地址时,会产生 wr