OS专题-运行32位程序

OS专题-运行32位程序

上一讲我们已经实现好了GDT,现在我们开始在32位保护模式下运行引导程序。要想以32位模式运行,我们要满足以下条件:

  1. 禁用BIOS提供的ISR
  2. 加载我们写好的GDT
  3. 在 CPU 控制寄存器 cr0 上设置一个位
  4. 触发我们写好的GDT来刷新CPU
  5. 更新所有段寄存器
  6. 更新堆栈
  7. 调用写好的32位入口程序

废话不多数,带着个这个思维,我们开始编码。在lib文件夹中新建32_switch.asm文件,代码如下:

; lib/32_switch.asm
[bits 16]
switch_to_pm:
    cli ; 1. 禁用中断
    lgdt [gdt_descriptor] ; 2. 加载GDT描述符
    mov eax, cr0
    or eax, 0x1 ; 3. 在cr0中设置32位模式位
    mov cr0, eax
    jmp CODE_SEG:init_pm ; 4. 用不同的段进行跳转

[bits 32]
init_pm: ; 从这儿开始是32位代码
    mov ax, DATA_SEG ; 5. 初始化段寄存器
    mov ds, ax
    mov ss, ax
    mov es, ax
    mov fs, ax
    mov gs, ax

    mov ebp, 0x90000 ; 6. 初始化栈
    mov esp, ebp

    call BEGIN_PM ; 7. 调用我们自己写好的32位程序

boot文件夹下新建32_mbr.asm,代码如下:

[org 0x7c00]
    mov bp, 0x9000 ; 初始化栈
    mov sp, bp

    mov bx, MSG_REAL_MODE
    call print

    call switch_to_pm
    jmp $

%include "print.asm"
%include "32_gdt.asm"
%include "32_print.asm"
%include "32_switch.asm"

[bits 32]
BEGIN_PM: ; 这将是我们的32位程序入口
    mov ebx, MSG_PROT_MODE
    call print_string_pm ; 他会显示在屏幕左上角
    hlt

MSG_REAL_MODE db "Started in 16-bit real mode", 0
MSG_PROT_MODE db "Loaded 32-bit protected mode", 0

times 510-($-$$) db 0
dw 0xaa55

修改CMakeLists.txt文件,将之前的程序入口文件改为32_mbr.asm。之后编译运行即可。


OS专题-运行32位程序
https://blog.cikaros.top/doc/b4d9c09.html
作者
Cikaros
发布于
2022年9月24日
许可协议