老师推荐的参考阅读书籍是:
于渊. Orange’s: 一个操作系统的实现, 电子工业出版社, 2009
毛德操, 胡希明. LINUX内核源代码情景分析(上册),浙江大学出版社,2001.09
实地址模式(Real Address Mode)
通过20位地址分段访问1MB地址空间
程序可以直接访问BIOS中断和外设
硬件层不支持任何内存保护或者多任务处理
80286之后的所有x86CPU加电自举(加电自检和磁盘引导)时首先进入实模式
两个16位逻辑地址(段地址:偏移地址)组合成20位物理地址
原因:一个段的起始地址总是16的倍数
逻辑如图:
硬件为系统软件实现虚拟内存、分页机制、安全的多任务处理的功能支持
提供操作系统对应用程序的控制功能:特权级、实模式应用程序兼容、虚拟8086模式
段基址(Segment Base Address)被放在段描述符(Segment Descriptor)中,==GDT(Global Descriptor Table)==保存着所有段描述符的信息,段选择子(Selector)是指向某个段描述符的索引。
在保护模式下,虽然段值仍然由原来16位的cs、ds等寄存器表示,但此时它仅仅变成了一个索引,这个索引指向一个数据结构的一个表项,表项中详细定义了段的起始地址、界限、属性等内容。这个数据结构就是GDT(或LDT)
寻址只需要给出(段选择子:偏移地址)
段寄存器(CS、DS、ES、SS、FS、GS)中存放的是选择子(Selector)
选择子是指向某个段描述符的索引
描述符(Descriptor)是一个64bit的数据结构(包含段起始地址、限界、属性)
G位 段界限粒度(Granularity)位。G=0时,段界限粒度为字节;G=1时,段界限粒度为4KB。
D位 D=0时,使用16位地址及16位或8位操作数;D=1时,使用32位地址及32位或8位操作数。
P位(Present)存在位。P=1表示段在内存中存在;P=0表示段在内存中不存在。
DPL 描述符特权级(Descriptor Privilege Level)。特权级可以是0、1、2或者3.数字越小特权级越大。
S 指明描述符是数据段/代码描述符(S=1)还是系统段/门描述符(S=0)。
类型 段类型和保护。(见《Orange’s: 一个操作系统的实现》P36)
GDT的第一个段通常设置为0,使其成为空段(null segment)。这个段被Intel保留,不可被访问。如果加载该空段,则将产生通用保护异常(General Protection Exception)。通过写64位0来填充空段。
gdt: ; Address for the GDT
gdt_null: ; Null Segment
dd 0 //数据段为零(4字节)
dd 0 //double world即定义一个8字节全为0
/*填写代码段Descriptor*/
gdt_code: ;Code segment, read/execute, nonconforming
;根据Descriptor的结构,开始的16位设置段偏移(Limit, ;15-0)。保护模式下段偏移可以达到4GB(总共0ffffH的偏移量)
;16 bits segment offset = 0xffff = 4G in protected mode, Limit(15-0)
dw 0FFFFh
;接下来设置基地址为0(内存起始地址,Base 15-0):
dw 0 ;16 bits base address = 0, Base (15-0)
db 0 ;8 bit base address = 0, Base(23-16)
db 10011010b ;Access rights: A=0; R=1; C=0; E=1; S=1;
;DPL=00; P=1
db 11001111b ;G=1; D=1; AV=0; Limit=1111=0xfh
db 0 ;8 bit base address = 0, Base (31-24)
/*填写数据段Descriptor*/
gdt_data : ;Data segment, read/write, expand down
dw 0FFFFh
dw 0
db 0 ;前8位为0
db 10010010b ;Access rights: A=0; W=1; ED=0; E=0;
;S=1; DPL=00; P=1
db 11001111b ;G=1; D=1; AV=0; Limit=1111=0xfh
db 0 ;8 bit base address = 0, Base (31-24)
一些注释:
详细代码以及解释见《Orange’s: 一个操作系统的实现》第39页
Descriptor宏用比较自动化的方法把段基址、段限界和段属性安排在描述符中合适的位置。
实模式到保护模式的代码
待补充
Video段代码示例
CodeA
[section .la]
ALIGN 32
[BITS 32]
LABEL_CODE_A:
mov ax, SelectorVideo
mov gs, ax ;视频段选择子
mov edi, (80 * 12 + 0) * 2 ;屏幕第 10 行,第 0 列。
mov ah, 0Ch ;0000:黑底 1100:红字
mov al, 'L'
mov [gs:edi], ax
;准备经由16位代码段跳回实模式
jmp SelectorCode16 : 0
CodeALen equ $ - LABEL_CODE_A
; END of [SECTION .la]
以上代码可以实现屏幕中第10行,第0列上出现一个“L”。
早期的80286只能从是地址模式转入保护模式,却不能从保护模式转回实地址模式。