专注于操作系统10之走进保护模式
2012-02-28 22:58
330 查看
首先说一下,从实模式进入保护模式的步骤。
1.建立GDT表,也就是填上段描述符。(此处不考虑描述LDT表的描述符,TSS描述符)。
2.把GDT表的信息,也就是GDT表的基地址,和表限信息装入GDTR。
3.打开A20地址线,因为在实模式下只用了20根地址线,而保护模式下要用32根,所以要将另外的地址线打开。
4.将CR0的PE置1表示CPU处于保护模式下。
5.用JMP指令,从实模式的代码跳入保护模式的代码。
下面是具体的代码,参照了《自己动手写操作系统》。
将编译后的safemodel.img 装入虚拟机VMware,下面是运行结果图。
1.建立GDT表,也就是填上段描述符。(此处不考虑描述LDT表的描述符,TSS描述符)。
2.把GDT表的信息,也就是GDT表的基地址,和表限信息装入GDTR。
3.打开A20地址线,因为在实模式下只用了20根地址线,而保护模式下要用32根,所以要将另外的地址线打开。
4.将CR0的PE置1表示CPU处于保护模式下。
5.用JMP指令,从实模式的代码跳入保护模式的代码。
下面是具体的代码,参照了《自己动手写操作系统》。
;;nasm 2.07 ;;nasm safemodel.asm -o safemodel.img org 07c00H %macro Descriptor 3 ;定义Descriptor结构体宏 dw %2 & 0FFFFh ; 段界限 1 (2 字节) dw %1 & 0FFFFh ; 段基址 1 (2 字节) db (%1 >> 16) & 0FFh ; 段基址 2 (1 字节) dw ((%2 >> 8) & 0F00h) | (%3 & 0F0FFh) ; 属性 1 + 段界限 2 + 属性 2 (2 字节) db (%1 >> 24) & 0FFh ; 段基址 3 (1 字节) %endmacro ; 共 8 字节 DA_C EQU 98h ; 只读代码段的属性值 DA_DRW EQU 92h ; 允许读写的数据段的属性值 DA_32 EQU 4000h ;32位段的属性值 jmp LABEL_BEGIN ;现在进行第一步:建立GDT表 [SECTION .gdt] ;用于放GDT表的段 ;GDT LABEL_GDT: Descriptor 0,0,0 ;空描述符,当一个任务没有LDT时,会把LDTR清空,这时,LDTR便指向空描述符。 LABEL_CODE32: Descriptor 0,SegCode32Len-1,DA_C + DA_32 ; 代码段的描述符 LABEL_VIDEO: Descriptor 0B8000h,0ffffh,DA_DRW ;显存的描述符,0b8000h是显存的首地址 ;GDT 结束 GdtLenth equ $ - LABEL_GDT ;计算GDT表的长度 GdtPtr dw GdtLenth - 1 ; 准备存入GDTR的信息 dd 0 ; 用于存放GDT表的物理地址,后面会计算 ;GDT选择子 SelectorCode32 equ LABEL_CODE32 - LABEL_GDT ;代码段的选择子 SelectorVideo equ LABEL_VIDEO - LABEL_GDT ;显存所在段的选择子 ;[SECTION .gdt]结束 [SECTION .s16] [BITS 16] ;目标处理器模式 LABEL_BEGIN: mov ax,cs mov ds,ax mov es,ax mov ss,ax mov sp,0100h ;初始化32位段的描述符 xor eax,eax ; 同或运算,这里是将eax清零 mov ax,cs shl eax,4 ;左移四位,相当于乘以16,实模式下计算物理地址 add eax,LABEL_SEG_CODE32 ;eax中为32位段的物理地址 mov word [LABEL_CODE32 + 2],ax ;将32位段的物理地址存入段的描述符中 shr eax,16 mov byte [LABEL_CODE32 + 4],al mov byte [LABEL_CODE32 + 7],ah ;计算GDT表的物理地址,将GDT表的物理地址信息存入GdtPtr中 xor eax,eax mov ax,cs shl eax,4 add eax,LABEL_GDT mov dword [GdtPtr + 2],eax ;现在进行第二步:将GDT表的信息加载到GDTR中 lgdt [GdtPtr] ;装载GDTR ;关中断 cli ;现在进行第三步:打开地址线 in al,92h or al,00000010b out 92h,al ;现在进行第四步:置PE为1,表示CPU处于保护模式下 mov eax,cr0 or eax,1 mov cr0,eax ;现在进入第五步:跳到保护模式的代码 jmp dword SelectorCode32:0 ;这里将SelectorCode32存入CS中作为选择子 ;[SECTION .s16] 结束 ;保护模式下的代码,32位代码 [SECTION .s32] [BITS 32] LABEL_SEG_CODE32: mov ax,SelectorVideo ;视频选择子,用于找到显存段的描述符 mov gs,ax mov edi,(80 * 10 + 0)*2 ;屏幕的第10行,第0列 mov ah,0Ch mov al,'p' mov [gs:edi],ax ;将字符‘p’输出到屏幕 jmp $ SegCode32Len equ $ - LABEL_SEG_CODE32 ;计算32位代码段的长度 times 510-($-$) db 0 dw 0aa55H
将编译后的safemodel.img 装入虚拟机VMware,下面是运行结果图。
相关文章推荐
- 《一个操作系统的实现》(四):让操作系统走进保护模式
- 专注于操作系统9之保护模式基础知识b
- 第4章 让操作系统走进保护模式
- 专注于操作系统8之保护模式基础知识a
- 专注于操作系统11之保护模式进阶
- 专注于操作系统29之从loader进入保护模式并分页
- <自已动手写操作系统> 学习扎记让操作系统走进保护模式
- 专注于操作系统7之初识保护模式
- 《一个操作系统的实现》(三):1.认识保护模式
- 《一个操作系统的实现》(三):2.保护模式进阶
- 《Orange’s 一个操作系统的实现》3.保护模式1----pm.inc分析
- 自己动手写操作系统--搭建保护模式下的运行环境:bochs下安装freedos
- WriteOS: 关于操作系统进入保护模式的总结
- 《Orange’s 一个操作系统的实现》3.保护模式2----认识保护模式A
- 《Orange’s 一个操作系统的实现》3.保护模式7-特权级转移(通过调用门转移目标段-无特权级转换)
- 《Orange's 一个操作系统的实现》读书手记3(1)--- [ 保护模式(Protect Mode)]
- 操作系统学习笔记——保护模式——分页机制
- 写操作系统(八)执着 进入保护模式
- 自己动手写操作系统80x86保护模式(4)--分页机制
- 《Orange's 一个操作系统的实现》学习笔记--保护模式进阶