OS专题-运行32位程序
OS专题-运行32位程序
上一讲我们已经实现好了GDT,现在我们开始在32位保护模式下运行引导程序。要想以32位模式运行,我们要满足以下条件:
- 禁用BIOS提供的ISR
- 加载我们写好的GDT
- 在 CPU 控制寄存器 cr0 上设置一个位
- 触发我们写好的GDT来刷新CPU
- 更新所有段寄存器
- 更新堆栈
- 调用写好的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