突破第一扇区的限制

保护模式的切换

思考

  • bios只拷贝第一扇区的代码到内存中,如何执行更多的代码?
  • 保护模式有什么用?如何进入保护模式?

概念

实模式和保护模式

实模式,cpu刚通电的时候所处的一个cpu模式,段最大偏移为64KB(2^16),由于A20处于关闭状态,所以它只能够访问1M(2^20)内的地址空间。早期的8086cpu有着16根数据线和20根地址总线,后来发展到386有着32根地址总线,访问的空间高达4GB(2^32)。
保护模式,A20处于打开状态,能够访问1M以外的内存地址空间,使用32位段地址和段偏移。段地址由段选择子,gdt来确定。

GDT

全局描述符表,是数据段描述符,代码段描述符,系统描述符,门描述符等等的集合,通过lgdt指令来加载

段选择子

段选择子指示段描述符,由两个字节构成。3-15位是索引,代表在描述符表的序号,第2位是TI标识位,TI=0意味这从GDT获取段描述符,TI=1意味这从LDT获取段描述符。0-1两位是rpl,表示请求等级

  • 附图

BIOS中断

bios中断,可以说是微机系统软件和硬件的一个接口,我们可以通过中断来达到操作硬件的目的。bios初始化的时候,为我们提供了丰富的中断例程,例如0x10号中断显示服务,0x13号中断磁盘操作,我们即将要使用到0x13号中断,从磁盘中copy数据.

代码思路

  1. 使用nasm生成一个两扇区大小的img,第一个扇区有着引导代码,第二个扇区是一段程序,作用是把一段提示信息复制到内存地址0x100000处,这个地址时高于1M的,用来检测是否进入保护模式了
  2. 引导程序把第二扇区加载到0x9000处,然后执行0x9000的代码
  3. 显示0x100000的字符串内容

实现

org 0x7c00

mov ax,0
mov es,ax ;段地址,由于要复制到0:0x9000处,所以这里es设为0
mov ah,2  ;2号子功能
mov al,1  ;复制扇区数量
mov cx,2  ;从第二扇区开始复制一个扇区
mov dx,0  ;磁头,柱面
mov bx,0x9000 ;偏移地址
int 0x13  ;0x13号中断
jnc ok_load ;CF=0代表成功

ok_load:
jmp 0:0x9000


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


;这里开始时第二扇区了
;设置gdt
section_second_start:
;打开20
in al,0x92
or al,2
out 0x92,al

;设置cr0
mov eax,cr0
or eax,1
mov cr0,eax

;由于这个扇区的代码是加载到0x9000的
;所以计算出该处相对于第二扇区开始的偏移量,再加上0x9000
lgdt [vgdt-section_second_start+0x9000]  

;8(1000b),就是index=1,TI=0,指的GDT序号为1的段,由于这时候已经处于保护模式下
;所以cs,ip等值是无效的,这个时候应该重新设置cs和ip的值,所以使用jmp命令
jmp 8:copy_data-section_second_start+0x9000   

;由于代码段时32位的,而nasm默认16位编译,这里要改为32位
bits 32 

;复制数据
copy_data:
mov ax,0x10  ;选择源数据段
mov ds,ax    
mov ax,0x18  ;选择目的数据段
mov es,ax
mov esi,tip-section_second_start+0x9000
xor edi,edi
mov ecx,tip_len
cld
rep movsb ;循环复制

;把0x100000的内存显示出来
mov ax,0x18
mov ds,ax
mov ax,0x20
mov es,ax
mov esi,0
mov edi,0
mov ecx,tip_len
show:
mov al,[esi]
mov byte [es:edi],al
mov byte [es:edi+1],2
inc esi
add edi,2
loop show

jmp $

gdt:
dq 0
dq 0x00409a000000ffff                ;32位代码段 
dq 0x004092000000ffff                ;32位源数据段
dq 0x004092100000ffff                ;32位目的数据段
dq 0x0040920b8000ffff                ;32位显存数据段
gdt_len equ $-gdt

vgdt:
dw gdt_len-1
dd gdt-section_second_start+0x9000

tip:db "Welcome to protect mode!!",0
tip_len equ $-tip


times 1024-($-$$) db 0

运行结果

  • 如图片所示,右上角显示恰好0x3ff,两个扇区
  • 显示出来字符串信息了
    这里写图片描述
  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值