GDT临时分段
GDT临时分段
GDT临时段说明
现在已经进入了保护模式, 目前的改变
- 可以访问1M以上的内存了
- 可以使用32位的指令操作
问题:
由于以前的是实式下段寄存器寻址方式无法使用了,我们必须切换到使用GDT段方式来寻址
首要的任务就是先建立一个临时的GDT段,以便我们接下来的指令操作
目前准备建立3个段,如下:
Base, Limit, Attr
代码段:0x00000000, 0xfffff, 1100_1001_1010B = db 0x0000ffff, 0x00cf9a00
数据段:0x00000000, 0xfffff, 1100_1001_0010B = db 0x0000ffff, 0x00cf9200
vga显卡内存数据段:x000b8000, 0x07fff, 1100_1001_0010B
GDT解析宏
首先创建一个nasm宏,可以进行GDT解析
参数为GDT的Base, Limit, Attr,也就是段基址(32位),段界限(20位),段描述符(12位),然后生成GDT在内存中的数据
;---------------------------------------------------------
; 描述符
; usage: Gdt_Descriptor Base, Limit, Attr : 段基址(32位),段界限(20位),段描述符(12位)
; Base: dd
; Limit: dd (low 20 bits available)
; Attr: dw (lower 4 bits of higher byte are always 0)
;---------------------------------------------------------
%macro Gdt_Descriptor 3
dw %2 & 0xFFFF
dw %1 & 0xFFFF
db (%1 >> 16) & 0xFF
db %3 & 0xFF
db ((%3 >> 4 ) & 0xF0 ) | ((%2 >> 16) & 0x0F )
db (%1 >> 24) & 0xFF
%endmacro
GDT 描述符属性定义
;-------------- gdt描述符属性 -------------
DESC_G_4K equ 1000_0000_0000b
DESC_D_32 equ 0100_0000_0000b
DESC_L equ 0000_0000_0000b ; 64位代码标记,此处标记为0便可。
DESC_AVL equ 0000_0000_0000b ; cpu不用此位,暂置为0
DESC_P equ 0000_1000_0000b
DESC_DPL_0 equ 000_0000b
DESC_DPL_1 equ 010_0000b
DESC_DPL_2 equ 100_0000b
DESC_DPL_3 equ 110_0000b
DESC_S_CODE equ 1_0000b
DESC_S_DATA equ 1_0000b
DESC_S_SYS equ 0_0000b
DESC_TYPE_CODE equ 1010b ;x=1可执行代码段,c=0普通,r=1可读,a=0已访问位a清0
DESC_TYPE_DATA equ 0010b ;x=0数据段,e=0向高位扩展,w=1可写,a=0已访问位a清0.
;-------------- 选择子属性 ---------------
RPL0 equ 00b
RPL1 equ 01b
RPL2 equ 10b
RPL3 equ 11b
TI_GDT equ 000b
TI_LDT equ 100b
DESC_CODE equ DESC_G_4K + DESC_D_32 + DESC_L + DESC_AVL + DESC_P + DESC_DPL0 + DESC_S_CODE + DESC_TYPE_CODE
DESC_DATA equ DESC_G_4K + DESC_D_32 + DESC_L + DESC_AVL + DESC_P + DESC_DPL0 + DESC_S_DATA + DESC_TYPE_DATA
定义GDT全局描述符表
;---------------------------------
;定义GDT全局描述符表
;code: 0x0000ffff, 0x00cf9a00
;data: 0x0000ffff, 0x00cf9200
;vga:
Gdt_Addr:
dw 8*4-1 ;指定段上限为4(GDT全局描述符表的大小)
dd gdt_table_addr ;GDT全局描述符表的地址
Gdt_Table_Addr:
Gdt_Descriptor 0,0,0
Label_Sel_Code: Gdt_Descriptor 0x00000000, 0xfffff, DESC_CODE ;可以执行的段
Label_Sel_Data: Gdt_Descriptor 0x00000000, 0xfffff, DESC_DATA ;可以读写的段
Label_Sel_VGA: Gdt_Descriptor 0x000b8000, 0x07fff, DESC_DATA ;vga段
dw 0
;--------------------------------
;选择子
Selector_Code equ Label_Sel_Code - Gdt_Table_Addr
Selector_Data equ Label_Sel_Data - Gdt_Table_Addr
Selector_VGA equ Label_Sel_VGA - Gdt_Table_Addr
加载gdt
;---------------------------
;加载GDT
lgdt [Gdt_Addr]
代码
创建常量头文件
创建 boot.inc文件。用来配置常量
;---------------------------------------------------------
; 描述符
; usage: Gdt_Descriptor Base, Limit, Attr : 段基址(32位),段界限(20位),段描述符(12位)
; Base: dd
; Limit: dd (low 20 bits available)
; Attr: dw (lower 4 bits of higher byte are always 0)
;---------------------------------------------------------
%macro Gdt_Descriptor 3
dw %2 & 0xFFFF
dw %1 & 0xFFFF
db (%1 >> 16) & 0xFF
db %3 & 0xFF
db ((%3 >> 4 ) & 0xF0 ) | ((%2 >> 16) & 0x0F )
db (%1 >> 24) & 0xFF
%endmacro
;-------------- gdt描述符属性 -------------
DESC_G_4K equ 1000_0000_0000b
DESC_D_32 equ 0100_0000_0000b
DESC_L equ 0000_0000_0000b ; 64位代码标记,此处标记为0便可。
DESC_AVL equ 0000_0000_0000b ; cpu不用此位,暂置为0
DESC_P equ 0000_1000_0000b
DESC_DPL_0 equ 000_0000b
DESC_DPL_1 equ 010_0000b
DESC_DPL_2 equ 100_0000b
DESC_DPL_3 equ 110_0000b
DESC_S_CODE equ 1_0000b
DESC_S_DATA equ 1_0000b
DESC_S_SYS equ 0_0000b
DESC_TYPE_CODE equ 1010b ;x=1可执行代码段,c=0普通,r=1可读,a=0已访问位a清0
DESC_TYPE_DATA equ 0010b ;x=0数据段,e=0向高位扩展,w=1可写,a=0已访问位a清0.
;-------------- 选择子属性 ---------------
RPL0 equ 00b
RPL1 equ 01b
RPL2 equ 10b
RPL3 equ 11b
TI_GDT equ 000b
TI_LDT equ 100b
DESC_CODE equ DESC_G_4K + DESC_D_32 + DESC_L + DESC_AVL + DESC_P + DESC_DPL_0 + DESC_S_CODE + DESC_TYPE_CODE
DESC_DATA equ DESC_G_4K + DESC_D_32 + DESC_L + DESC_AVL + DESC_P + DESC_DPL_0 + DESC_S_DATA + DESC_TYPE_DATA
;----------- loader const ------------------
LOADER_SECTOR_LBA equ 0x1 ;第2个逻辑扇区开始
LOADER_SECTOR_COUNT equ 9 ;读取9个扇区
LOADER_BASE_ADDR equ 0x9000 ;内存地址0x9200
LOADER1_BASE_ADDR equ 0x9800 ;内存地址0x9200
;-------------------------------------------
loader.asm文件
;ratsos
;TAB=4
%include "boot/boot.inc"
section loader vstart=LOADER_BASE_ADDR ;指明程序的偏移的基地址
[bits 16]
jmp Entry;
;---------------------------------
;定义GDT全局描述符表
;code: 0x0000ffff, 0x00cf9a00
;data: 0x0000ffff, 0x00cf9200
;vga:
Gdt_Addr:
dw 8*4-1 ;指定段上限为4(GDT全局描述符表的大小)
dd gdt_table_addr ;GDT全局描述符表的地址
Gdt_Table_Addr:
Gdt_Descriptor 0,0,0
Label_Sel_Code: Gdt_Descriptor 0x00000000, 0xfffff, DESC_CODE ;可以执行的段
Label_Sel_Data: Gdt_Descriptor 0x00000000, 0xfffff, DESC_DATA ;可以读写的段
Label_Sel_VGA: Gdt_Descriptor 0x000b8000, 0x07fff, DESC_DATA ;vga段
dw 0
;--------------------------------
;选择子
Selector_Code equ Label_Sel_Code - Gdt_Table_Addr
Selector_Data equ Label_Sel_Data - Gdt_Table_Addr
Selector_VGA equ Label_Sel_VGA - Gdt_Table_Addr
;程序核心内容
Entry:
;------------------
;禁止CPU级别的中断,进入保护模式时没有建立中断表
cli
;------------------
;打开A20
in al,0x92
or al,0000_0010B ;设置第1位为1
out 0x92,al
;------------------
;加载GDT
lgdt [Gdt_Addr]
;------------------
;进入保护模式
mov eax,cr0
or eax,0x1 ;设置第0位为1
mov cr0,eax
jmp $
测试
使用bochs执行
打好断点后,执行并查看gtd描述符数据是否正确。
info gdt

GDT临时分段的更多相关文章
- [自制简单操作系统] 2、鼠标及键盘中断处理事件[PIC\GDT\IDT\FIFO]
1.大致介绍: >_<" 大致执行顺序是:ipl10.nas->asmhead.nas->bootpack.c PS: 这里bootpack.c要调用graphic. ...
- MIT 6.828 | JOS | 关于虚拟空间和物理空间的总结
Question: 做lab过程中越来越迷糊,为什么一会儿虚拟地址是4G 物理地址也是4G ,那这有什么作用呢? 解决途径: 停下来,根据当前lab的进展,再回头看上学期操作系统的ppt & ...
- ocp 1Z0-043 131-205题解析
131. Which three methods can you use to run an Automatic Database Diagnostic Monitor (ADDM) analysis ...
- 本地管理表空间(LMT)与自动段空间管理(ASSM)概念
创建表空间时,extent management local 定义本地管理表空间(LMT),segment space management auto 定义自动段空间管理(ASSM). extent ...
- 操作系统篇-分段机制与GDT|LDT
|| 版权声明:本文为博主原创文章,未经博主允许不得转载. 一.前言 在<操作系统篇-浅谈实模式与保护模式>中提到了两种模式,我们说在操作系统中,其实大部分时间是待在保护模式中的. ...
- [fw]GDT是在分段中為了相容real mode 跟 protected mode的產物
在Protected Mode下,一个重要的必不可少的数据结构就是GDT(Global Descriptor Table). 为什么要有GDT?我们首先考虑一下在Real Mode下的编程模型: 在R ...
- (转)GDT与LDT
网址:http://blog.csdn.net/billpig/article/details/5833980 保护模式下的段寄存器 由 16位的选择器 与 64位的段描述符寄存器 构成段描述符寄存器 ...
- Linux的分段和分页机制
1.分段机制 80386的两种工作模式 80386的工作模式包括实地址模式和虚地址模式(保护模式).Linux主要工作在保护模式下. 分段机制 在保护模式下,80386虚地址空间可达16K个段,每 ...
- Linux内存寻址之分段机制
前言 最近在学习Linux内核,读到<深入理解Linux内核>的内存寻址一章.原本以为自己对分段分页机制已经理解了,结果发现其实是一知半解.于是,查找了很多资料,最终理顺了内存寻址的知识. ...
随机推荐
- POJ 3080 Blue Jeans(Java暴力)
Blue Jeans [题目链接]Blue Jeans [题目类型]Java暴力 &题意: 就是求k个长度为60的字符串的最长连续公共子串,2<=k<=10 规定: 1. 最长公共 ...
- fiddler学习总结--通过Fiddler模拟弱网进行测试
弱网测试的目的: 弱网测试可以发现一些因为网络问题导致的交互问题,从而更好的完善应用的性能. 关注点:1.卡死,崩溃,无响应,闪退.2.业务交互数据传输正确性. 通过Fiddler可以模拟弱网进行测试 ...
- Python3 pip命令报错:Fatal error in launcher: Unable to create process using '"'
Python3 pip命令报错:Fatal error in launcher: Unable to create process using '"' 一.问题 环境:win7 同时安装py ...
- CSS 层级选择器
CSS 层级选择器 注:使用空格分隔,塞选到最后一项应用. 标签选择器 下 标签选择器 父标签 --> 指定子标签添加css属性 <html> <head> <!- ...
- Python 协程实现socket并发
socket多并发 socket可以实现单个客户端进行请求访问,它可以通过socketserver来实现并发功能呢,socketserver是通过启用多线程实现并发,在这里我们也可以通过gevent协 ...
- Python Redis set集合
Set操作.Set集合就是不允许重复的列表 (无序集合) sadd(name,values) # name对应的集合中添加元素 scard(name) # 获取name对应的集合中元素个数 sdiff ...
- Linux 系统日志
查看日志服务 大部分Linux发行版默认的日志守护进程为 syslog,位于 /etc/syslog 或 /etc/syslogd 或/etc/rsyslog.d,默认配置文件为 /etc/syslo ...
- 浅析Tomcat、JBOSS、WebSphere、WebLogic、Apache
做任何web项目,都离不开服务器,有钱的公司用WebSphere.WebLogic,没钱公司用nginx+tomcat,不要小瞧nginx+tomcat麻雀虽小,五脏俱全. 服务器的知识,在笔试.面试 ...
- HDU 6088 Rikka with Rock-paper-scissors(NTT+欧拉函数)
题意 \(n\) 局石头剪刀布,设每局的贡献为赢的次数与输的次数之 \(\gcd\) ,求期望贡献乘以 \(3^{2n}\) ,定义若 \(xy=0\) 则,\(\gcd(x,y)=x+y\) 思路 ...
- 大项目小细节---onbeforeunload增强用户体验
微信公众平台编辑数据页面,点击浏览器回退按钮.刷新按钮(包括F5.Ctrl+R).关闭页面.点击其他超链接等操作的时候,会提示弹窗提示. 为增加用户体验,我们也增加类似功能. 代码如下: @if (R ...