[055][x86汇编语言]16.3.2 使用高端1MB线性地址0x80000000~0x800FFFFF

学习笔记

《x86汇编语言:从实模式到保护模式》
//www.greatytc.com/p/d481cb547e9f

将内核映射到高端地址

说明

  • 任务的4GB空间
任务的4GB包括:局部空间和全局空间
4G虚拟内存空间的线性地址


高端2G 是 0x8000 0000~0xFFFF FFFF 
用于 全局空间 用于指向内核的页表

低端2G 是 0x0000 0000~0x7FFF FFFF 
用于 局部空间 用于指向任务的页表

实现

  • 一、需要修改页目录
在内核的页目录表中,创建一个和 线性地址 0x 8000 0000
(高端2G空间起始线性地址 )相对应的目录项,并使它指向指定的页表。

对内核程序而言,内核程序的任务也是内核程序自己,
意味着 属于内核程序的页表 和 内核任务的页表 是同一个页表。
  • 二、需要修改与内核有关的段描述符
需要依次修改有关的段描述符
#  初始代码段
#  初始栈段
#  文本模式显存
#  公用例程段
#  内核数据段
#  内核代码段
#  GDT

效果

  • 完成上面的实现步骤,可以达到这样的效果:在任何任务内,如果段部件发出的线性地址高于或者等于0x8000 0000,指向和访问的就是全局地址空间,或者说内核

一、需要修改页目录

什么叫"页目录也是一个物理页"?

  • 对内存而言,数据是数据,代码也是数据,一切都只是数据;
  • 分页,就是按照4KB(4K Byte = 4096字节 = 0x1000 字节)为单位算作一个页;
  • 1个任务有且只有只需要1个页目录,页目录里是1024个页表的物理地址,1个物理地址需要4字节存储,可知,1个页目录的大小正好就是4KB,那么本质上就是内存中的某个物理页被拿来当做页目录了而已,这是标题的意思;
  • 1个页表,里面是1024个也页的物理地址,那么1个页表的大小也正好是4KB,所以在内存里也有某些物理页,成为了页表;
  • 能不能既是页目录又是页表?可以的。
1.对不同的任务而言,这完全就是同一块内存被反复覆盖刷新使用而已,
你把某个物理页当页目录,我把它当页表或者其他,
再顺理成章不过了,内存就是这样重复用的;

2.同一个任务呢?其实,也是可以的!
只要在页目录的某个表项填入页目录自己本身的物理地址,
使得经过由 
段部件生成线性地址→取高10位做页目录表偏移量→取得页表的物理地址时,
拿到的页表物理地址是页目录自己的物理地址,
再继续
取中10位做页表的偏移地址,
此时页表就是页目录,页目录就是页表。

举例说明

回顾:通过 段部件 以及 页部件 的 线性地址 转 物理地址 计算过程

  • 完全理解检测点16.1的计算过程,知道取高10位、取中10位以及取低12位的计算过程,才能理解下面的举例说明

检测点16.1 参见 //www.greatytc.com/p/704044463b52

举例:前提是在页目录的最后一个表项已经填入了页目录自己的物理地址

填入页目录自己的物理地址过程见
//www.greatytc.com/p/4bb9514c4500

图解过程取自 16.3.2 节


使用线性地址访问和修改页目录表
  • 对应配书代码包,源码文件:c16_core.asm (第969~973行)
;在页目录内创建与线性地址0x80000000对应的目录项
mov ebx,0xfffff000                 ;页目录自己的线性地址 
mov esi,0x80000000                 ;映射的起始地址
shr esi,22                         ;线性地址的高10位是目录索引
shl esi,2
mov dword [es:ebx+esi],0x00021003  ;写入目录项(页表的物理地址和属性)
                                   ;目标单元的线性地址为0xFFFFF200
  • 0x0800的意义是什么?
0x00021003 是第一个页表的物理地址
在图解的最开始就已经被填入到了页目录的第一个表项之中

4G虚拟内存空间的线性地址
高端2G 是 0x8000 0000~0xFFFF FFFF
低端2G 是 0x0000 0000~0x7FFF FFFF


对于页目录而言
页目录最大4KB 也就是0x1000
从页目录表项的偏移量来看,
最后一个表项就是 0x0FFC~0x0FFF (占用4个字节)
而第一个表项是 0x0000~0x0003(占用4个字节)

为什么 高端2G和低端2G 切在了页目录偏移量 0x0800处
其实就是除以2   0x1000 ÷ 2 = 0x0800

代码最终的目的就是,
在页目录表偏移量0x0800处写上0x0002 1003(第一个页表的物理地址)


谁是因?
最根本的原因在于,高端2G 和 低端2G的五五开,
由此而来就是偏移量的五五开,0x0000~0x07FF 和 0x0800~0x0FFF
那么 低端2G 要用 页表,就在偏移量0x0000 处开始填写页表的物理地址
同时,高端2G 要用 页表,就需要在偏移量0x0800处填写相同的页表物理地址

0x0800由此而来.
  • 偏移量0x0800最后和谁结合?
处理器遵从的规矩是:你访问的是页目录表,
但却还要通过页目录表进行地址转换之后才能访问。

即,要符合 “从段部件发出线性地址 经过 取高10位 取中10位 
以及 取最后偏移量,最后经由页部件算出来的物理地址”,
这个物理地址才是 目标 页目录表偏移量0x0800所在的 物理地址。

其实也就是说,要注意到 0x0800最后是和谁结合?
恰恰就是 页目录 自己的物理地址!

为什么是这样?
对于 段部件 发出的线性地址 0xFFFFF200 而言,
取高10位,取到的是 0x3FF ,乘以4就是 0xFFC ,
这就是页目录表的最后一个表项;
取中10位,取到的仍旧是 0x3FF,乘以4还是0xFFC,
依旧是页目录表的最后一个表项;

段部件发出的线性地址,是我们精心设计的,
只要是 0x FFFF??? 前20位全是1,
那么,取高10位 和 取中10位 就一定是一样的值。

加之,前提是在页目录的最后一个表项已经填入了页目录自己的物理地址,
所以,就能找到 页目录偏移量0x0800所在的物理地址。

说白了

  • 整个通过 段部件 和页部件 从 线性地址 到 物理地址 的过程没有动,动的只是 一开始的线性地址,程序员知道,后面的转换过程,所以在凑那个0x0800,为什么不一开始就给一个偏移量0x0800,是因为高位必须是0xffff,这样才能找到最后一个页目录表项,经过移位恰恰还有个0x200的偏移量,刚好乘以4就能得到0x800不然我估计作者会显式地赋值,因为必须遵从原理,让处理器固件走一趟取高10位,中10位的操作,把自己的地址写在自己身上,本质上取中10位的偏移量还是访问自己了。

结果

  • 不同的线性地址,可以指向同一个页表!注意是页表!不是页!页的物理地址填写早在映射操作之前就完成了,就不改变了。

二、需要修改与内核有关的段描述符

  • 修改:与内核有关的段描述符统统要改
从数学角度上来说就是 全部加上 0x8000 0000
因为高端2G就是从线性地址 0x8000 0000 开始的


;下面这些将GDT中的段描述符映射到线性地址0x80000000

;先取出GDT的物理地址 用来访问GDT
sgdt [pgdt]
mov ebx,[pgdt+2]

;依次修改
;#  初始代码段
or dword [es:ebx+0x10+4],0x80000000
;#  初始栈段
or dword [es:ebx+0x18+4],0x80000000
;#  文本模式显存
or dword [es:ebx+0x20+4],0x80000000
;#  公用例程段
or dword [es:ebx+0x28+4],0x80000000
;#  内核数据段
or dword [es:ebx+0x30+4],0x80000000
;#  内核代码段
or dword [es:ebx+0x38+4],0x80000000

;最后修改GDT本身描述符
add dword [pgdt+2],0x80000000 ;GDTR也用的是线性地址
lgdt [pgdt]

GDT布局参考 //www.greatytc.com/p/4a420617c5db

  • 刷新 :使段寄存器生效,通过重新加载一次对应的段描述符,使得段寄存器CS SS DS的高速缓存刷新
         jmp core_code_seg_sel:flush        ;刷新段寄存器CS,启用高端线性地址 
                                             
   flush:
         mov eax,core_stack_seg_sel
         mov ss,eax
         
         mov eax,core_data_seg_sel
         mov ds,eax
  • 结果:旁边的地址都是线性地址
    映射到高端地址后的系统核心布局

举例说明:段部件发出的线性地址高于或者等于 0x8000 0000

举例:线性地址 0x80007E00 与 线性地址 0x0000 7E00 如何指向指向同一个页表.png
  • 线性地址0x80007E00 与 线性地址 0x0000 7E00 如何指向指向同一个页表
  • 加上 0x8000 0000的操作,所影响的是只是取高10位计算出来的页目录偏移量,后面从取中10位以及最后低12位偏移量都是不变的;
  • 不要觉得 0x200 * 4 = 0x800 这里乘以4很奇怪,要回想起来页目录表存的是页表的物理地址,一个物理地址是一个双字,占用4个字节,偏移量0x800起始偏移地址,从0x800开始的0x800 0x801 0x802 0x803四个内存空间一起才是表示一个物理地址,所以是要乘以4的,而且这是处理器固件的设计,是焊死在芯片里的设计,不是程序员的编程;
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,657评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,662评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,143评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,732评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,837评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,036评论 1 291
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,126评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,868评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,315评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,641评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,773评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,470评论 4 333
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,126评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,859评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,095评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,584评论 2 362
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,676评论 2 351

推荐阅读更多精彩内容

  • 转载:http://blog.csdn.net/yusiguyuan/article/details/966488...
    桥寻阅读 2,229评论 0 2
  • 1 内存寻址 1.1 物理地址、虚拟地址以及线性地址 物理地址: 物理内存的内存单元地址 虚拟地址: 程序员看到的...
    疯狂小王子阅读 2,795评论 3 21
  • 1. 基础知识 1.1、 基本概念、 功能 冯诺伊曼体系结构1、计算机处理的数据和指令一律用二进制数表示2、顺序执...
    yunpiao阅读 5,275评论 1 22
  • 转眼来到科锐学习已经超过一年的时间了,眼看三阶段已经进入尾声,内核的学习也快要结束,记录一下笔记和心得,也给刚接触...
    五行猫阅读 1,093评论 0 0
  • 今天下午,妈妈带我去大姨家玩。 大姨给我们捉了一只螳螂,螳螂的颜色是绿色的,他好像一片树叶。为了保护自己他挥舞着两...
    静如思阅读 211评论 1 1