进入保护模式

Posted mlzrq

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了进入保护模式相关的知识,希望对你有一定的参考价值。

目录

进入保护模式

进入保护模式

进入保护模式的步骤:

  1. 关闭中断,打开地址线A20GATE,使得CPU可以访问1M以上的内存空间。
  2. 设置CR0寄存器,进入保护模式。
  3. 加载临时GDT
  4. 进入保护模式后,首先执行jmp指令。因为内存寻址方式改变,需要刷新指令流水线

打开A20Gate

1. A20Gate的作用

在实模式下,A20Gate是关闭的,意味着只能使用20根地址线,需要通过打开A20Gate,访问第21根以上的总线。

A20Gate关闭时侯的内存访问:

A20Gate关闭式,只能使用20根总线,所以寻址范围位 0x00000 ~ 0xFFFFF,总共1M的地址范围。

当访问的地址大于这个范围,高位的值将被截取掉,导致超出1M的地址访问会使得CPU回滚到1M内地址范围的现象

例如

当使用 [0xFFFF :0xFFFF ] 内存地址,得到的地址位 0x10FFEF 。但是在实模式下,由于20根总线的限制,最高位的1是无效的,实际的访问地址回绕到 [0x0FFEF]。

A20Gate打开后的内存访问:

打开A20Gate, 可以使用到32位的地址总线,内存地址访问也达到了1<<32 的4G范围。

实际上开启A20Gate,总线的寻址能力达到了4G,但是cpu的内存访问能力因为16位段寄存器,和16位偏移地址的限制,并不能协调工作。

所以需要进入保护模式突破cpu的内存访问限制。

2. 开启A20Gate

开启A20Gate,只要设置io端口0x92的第一位为1就可以了。

;------------------
;打开A20
cli                         ;禁止CPU级别的中断
in      al,0x92
or      al,0000_0010B           ;设置第1位为1
out     0x92,al

设置CR0寄存器,进入保护模式

CR0寄存器

CR0寄存器是一个32位的寄存器

设置CR0寄存器的最高位为0,最低位为1,则可以进入保护模式。

CR0寄存器的作用

  • 改变段寻址方式,使用段描述符方式寻址。
  • 实模式指令的操作数默认为16位,保护模式指令的操作数默认为32位。

代码:

;------------------
;进入保护模式
mov     eax,CR0
or      eax,0x00000001            ;设置第0位为1
mov     CR0,eax

loader.asm完整代码如下

;Rats OS
;Tab=4
[bits 16]

section loader vstart=LOADER_BASE_ADDR ;指明程序的偏移的基地址

;----------- loader const ------------------
LOADER_BASE_ADDR        equ 0x9000  ;内存地址0x9000
;---------------------------------------    
    jmp Entry
    
    
;程序核心内容
Entry:
    

    ;------------------
    ;禁止CPU级别的中断
    cli                         

    ;------------------
    ;打开A20
    in      al,0x92
    or      al,0000_0010B       ;设置第1位为1
    out     0x92,al
    

    ;------------------
    ;进入保护模式
    mov     eax,cr0
    or      eax,0x00000001      ;设置第0位为1
    mov     cr0,eax



;程序挂起       
    jmp $           ;让CPU挂起,等待指令?

使用bochs调试

在0x7c00打断点,输入c跳转执行

$ pb 0x7c00

$ c

输入显示切换模式命令

$ show mode

输入c继续执行

$ c

可以看到控制他输出:

00017609546: switched from ‘real mode‘ to ‘protected mode‘

说明系统成功的从实模式切换到保护模式

技术分享图片

查看CR0的PE位

$ creg

技术分享图片

以上是关于进入保护模式的主要内容,如果未能解决你的问题,请参考以下文章

从DOS程序进入保护模式

进入保护模式

尝试使用片段保存夜间模式状态

Lab_1:练习3——分析bootloader进入保护模式的过程

Linux 0.11-进入保护模式前最后一次折腾内存-05

进入保护模式