分页原理

在汇编文件chapter3/f/pmtest6.asm中,关于分页设置的代码如下。

此时还未开启多进程,仅有的一个进程中这个表有什么作用吗?页表需要进行切换吗?

每一个进程都会形成这样一个完整的页表。x86处理器中的CR3寄存器便是用来记录当前任务的页表位置的。当程序访问某一线性地址时,CPU会根据CR3寄存器找到当前任务使用的页表,然后根据预先定义的规则查找物理地址。

32位处理程序,一共可以操作的内存为2^32B=4GB。所以1K个表项,每一个表项管理1K个页,每一个页的大小为4K,则总共刚好为1K×1K×4K=4GB,覆盖了所有的完整的可操作的物理内存的地址空间。不管后续如何进行优化,让页表更省存储空间,基本原理还是如上所示。

; 启动分页机制 --------------------------------------------------------------
SetupPaging:; 为简化处理, 所有线性地址对应相等的物理地址.; 首先初始化页目录mov  ax, SelectorPageDir ; 此段首地址为 PageDirBasemov es, axmov   ecx, 1024       ; 共 1K 个表项xor   edi, edixor eax, eaxmov eax, PageTblBase | PG_P  | PG_USU | PG_RWW
.1:stosdadd eax, 4096       ; 为了简化, 所有页表在内存中是连续的.loop   .1; 再初始化所有页表 (1K 个, 4M 内存空间)mov ax, SelectorPageTbl ; 此段首地址为 PageTblBasemov es, axmov   ecx, 1024 * 1024    ; 共 1M 个页表项, 也即有 1M 个页xor   edi, edixor eax, eaxmov eax, PG_P  | PG_USU | PG_RWW
.2:stosdadd eax, 4096       ; 每一页指向 4K 的空间loop  .2mov   eax, PageDirBasemov cr3, eaxmov eax, cr0or  eax, 80000000hmov   cr0, eaxjmp short .3
.3:nopret
; 分页机制启动完毕 ----------------------------------------------------------

一共有1M个表项,每一个表项占据4个字节4B空间,如下所示。

所以在未经优化的情况下,一个进程为了实现页管理,最多需要的存储空间为4MB

第一次的分页机制实现

为了最多程度减少nasm中$与$$等在理解与实际操作中可能产生的错误,以下关于操作系统的实践均在512字节中去实现。如果实在不能在第一扇区去实现,再根据前几日的扇区复制int 13/02来挪动。

最基本的开启分页机制的代码如下。

; ==========================================
; pmtest2.asm
; 编译方法:nasm pmtest2.asm -o boot.bin
; ==========================================;----------------------------------------------------------------------------
; 描述符类型值说明
; 其中:
;       DA_  : Descriptor Attribute
;       D    : 数据段
;       C    : 代码段
;       S    : 系统段
;       R    : 只读
;       RW   : 读写
;       A    : 已访问
;       其它 : 可按照字面意思理解
;----------------------------------------------------------------------------
DA_32       EQU 4000h   ; 32 位段
DA_LIMIT_4K EQU 8000h   ; 段界限粒度为 4K 字节DA_DPL0       EQU   00h   ; DPL = 0
DA_DPL1     EQU   20h   ; DPL = 1
DA_DPL2     EQU   40h   ; DPL = 2
DA_DPL3     EQU   60h   ; DPL = 3
;----------------------------------------------------------------------------
; 存储段描述符类型值说明
;----------------------------------------------------------------------------
DA_DR       EQU 90h ; 存在的只读数据段类型值
DA_DRW      EQU 92h ; 存在的可读写数据段属性值
DA_DRWA     EQU 93h ; 存在的已访问可读写数据段类型值
DA_C        EQU 98h ; 存在的只执行代码段属性值
DA_CR       EQU 9Ah ; 存在的可执行可读代码段属性值
DA_CCO      EQU 9Ch ; 存在的只执行一致代码段属性值
DA_CCOR     EQU 9Eh ; 存在的可执行可读一致代码段属性值
;----------------------------------------------------------------------------
; 系统段描述符类型值说明
;----------------------------------------------------------------------------
DA_LDT      EQU   82h   ; 局部描述符表段类型值
DA_TaskGate EQU   85h   ; 任务门类型值
DA_386TSS   EQU   89h   ; 可用 386 任务状态段类型值
DA_386CGate EQU   8Ch   ; 386 调用门类型值
DA_386IGate EQU   8Eh   ; 386 中断门类型值
DA_386TGate EQU   8Fh   ; 386 陷阱门类型值
;----------------------------------------------------------------------------
; 选择子类型值说明
; 其中:
;       SA_  : Selector AttributeSA_RPL0        EQU 0   ; ┓
SA_RPL1     EQU 1   ; ┣ RPL
SA_RPL2     EQU 2   ; ┃
SA_RPL3     EQU 3   ; ┛SA_TIG       EQU 0   ; ┓TI
SA_TIL      EQU 4   ; ┛
;----------------------------------------------------------------------------;----------------------------------------------------------------------------
; 分页机制使用的常量说明
;----------------------------------------------------------------------------
PG_P        EQU 1   ; 页存在属性位
PG_RWR      EQU 0   ; R/W 属性位值, 读/执行
PG_RWW      EQU 2   ; R/W 属性位值, 读/写/执行
PG_USS      EQU 0   ; U/S 属性位值, 系统级
PG_USU      EQU 4   ; U/S 属性位值, 用户级
;----------------------------------------------------------------------------; 宏 ------------------------------------------------------------------------------------------------------
;
; 描述符
; usage: Descriptor Base, Limit, Attr
;        Base:  dd
;        Limit: dd (low 20 bits available)
;        Attr:  dw (lower 4 bits of higher byte are always 0)
%macro Descriptor 3dw   %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 字节
;
; 门
; usage: Gate Selector, Offset, DCount, Attr
;        Selector:  dw
;        Offset:    dd
;        DCount:    db
;        Attr:      db
%macro Gate 4dw (%2 & 0FFFFh)               ; 偏移 1              (2 字节)dw    %1                  ; 选择子               (2 字节)dw    (%3 & 1Fh) | ((%4 << 8) & 0FF00h) ; 属性                    (2 字节)dw    ((%2 >> 16) & 0FFFFh)         ; 偏移 2              (2 字节)
%endmacro ; 共 8 字节
; ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^PageDirBase      equ 200000h ; 页目录开始地址: 2M
PageTblBase     equ 201000h ; 页表开始地址: 2M+4Korg 07c00hjmp   LABEL_BEGIN[SECTION .gdt]
; GDTLABEL_GDT:     Descriptor  0,          0, 0           ;
LABEL_DESC_CODE32:  Descriptor  0,  SegCode32Len - 1, DA_C + DA_32;
LABEL_DESC_VIDEO:   Descriptor  0B8000h,           0ffffh, DA_DRW        ;
LABEL_DESC_PAGE_DIR:    Descriptor  PageDirBase, 4095, DA_DRW;Page Directory
LABEL_DESC_PAGE_TBL:    Descriptor  PageTblBase, 1023, DA_DRW|DA_LIMIT_4K;Page Tables; GDT 结束GdtLen     equ $ - LABEL_GDT   ; GDT长度
GdtPtr      dw  GdtLen - 1  ; GDT界限dd   0       ; GDT基地址; GDT 选择子
SelectorCode32      equ LABEL_DESC_CODE32   - LABEL_GDT
SelectorVideo       equ LABEL_DESC_VIDEO    - LABEL_GDT
SelectorPageDir equ LABEL_DESC_PAGE_DIR - LABEL_GDT
SelectorPageTbl equ LABEL_DESC_PAGE_TBL - LABEL_GDT
; END of [SECTION .gdt][SECTION .s16]
[BITS   16]
LABEL_BEGIN:mov ax, csmov   ds, axmov   es, axmov   ss, axmov   sp, 0100h; 初始化 32 位代码段描述符xor    eax, eaxmov ax, csshl   eax, 4add   eax, LABEL_SEG_CODE32mov    word [LABEL_DESC_CODE32 + 2], axshr    eax, 16mov  byte [LABEL_DESC_CODE32 + 4], almov    byte [LABEL_DESC_CODE32 + 7], ah; 为加载 GDTR 作准备xor  eax, eaxmov ax, dsshl   eax, 4add   eax, LABEL_GDT      ; eax <- gdt 基地址mov  dword [GdtPtr + 2], eax    ; [GdtPtr + 2] <- gdt 基地址; load GDTRlgdt    [GdtPtr]; close interruptcli; open A20in    al, 92hor   al, 00000010bout    92h, al; perpare to switch to PMmov eax, cr0or  eax, 1mov   cr0, eax; inter PMjmp   dword SelectorCode32:0  ; 执行这一句会把 SelectorCode32 装入 cs,; 并跳转到 Code32Selector:0  处
; END of [SECTION .s16][SECTION .s32]; 32 位代码段. 由实模式跳入.
[BITS   32]LABEL_SEG_CODE32:call    SetupPagingmov  ax, SelectorVideomov    gs, ax          ; 视频段选择子(目的)mov edi, (80 * 11 + 0) * 2 ; 屏幕第 11 行, 第 79 列。mov  ah, 0Ch         ; 0000: 黑底    1100: 红字mov   al, 'P'mov    [gs:edi], ax; 启动分页机制 --------------------------------------------------------------
SetupPaging:; 为简化处理, 所有线性地址对应相等的物理地址.; 首先初始化页目录mov  ax, SelectorPageDir ; 此段首地址为 PageDirBasemov es, axmov   ecx, 1024       ; 共 1K 个表项xor   edi, edixor eax, eaxmov eax, PageTblBase | PG_P  | PG_USU | PG_RWW
.1:stosdadd eax, 4096       ; 为了简化, 所有页表在内存中是连续的.loop   .1; 再初始化所有页表 (1K 个, 4M 内存空间)mov ax, SelectorPageTbl ; 此段首地址为 PageTblBasemov es, axmov   ecx, 1024 * 1024    ; 共 1M 个页表项, 也即有 1M 个页xor   edi, edixor eax, eaxmov eax, PG_P  | PG_USU | PG_RWW
.2:stosdadd eax, 4096       ; 每一页指向 4K 的空间loop  .2mov   eax, PageDirBasemov cr3, eaxmov eax, cr0or  eax, 80000000hmov   cr0, eaxjmp short .3
.3:nopret
; 分页机制启动完毕 ----------------------------------------------------------; 到此停止jmp  $times  261 db 0dw  0xaa55SegCode32Len  equ $ - LABEL_SEG_CODE32
; END of [SECTION .s32]

运行效果如下所示

开启了分页之后,单进程涉及的开启32位保护模式、分段机制、分页机制已全部完成。

后续就是进入了多进程操作系统的设计。主要包含了配置任务数据结构、生成新的进程、设置时间切片中断三个主要任务了。

根据512字节内容布局,目前已经使用了240个字节,还有270个字节可以使用。

as@as-virtual-machine:~/osdir/chapter3H$ hexdump -Cv boot
00000000  e9 31 00 00 00 00 00 00  00 00 00 00 6f 01 00 00  |.1..........o...|
00000010  00 98 40 00 ff ff 00 80  0b 92 00 00 ff 0f 00 00  |..@.............|
00000020  20 92 00 00 ff 03 00 10  20 92 80 00 27 00 00 00  | ....... ...'...|
00000030  00 00 00 00 8c c8 8e d8  8e c0 8e d0 bc 00 01 66  |...............f|
00000040  31 c0 8c c8 66 c1 e0 04  66 05 90 7c 00 00 a3 0e  |1...f...f..|....|
00000050  7c 66 c1 e8 10 a2 10 7c  88 26 13 7c 66 31 c0 8c  ||f.....|.&.|f1..|
00000060  d8 66 c1 e0 04 66 05 04  7c 00 00 66 a3 2e 7c 0f  |.f...f..|..f..|.|
00000070  01 16 2c 7c fa e4 92 0c  02 e6 92 0f 20 c0 66 83  |..,|........ .f.|
00000080  c8 01 0f 22 c0 66 ea 00  00 00 00 08 00 00 00 00  |...".f..........|
00000090  e8 13 00 00 00 66 b8 10  00 8e e8 bf e0 06 00 00  |.....f..........|
000000a0  b4 0c b0 50 65 66 89 07  66 b8 18 00 8e c0 b9 00  |...Pef..f.......|
000000b0  04 00 00 31 ff 31 c0 b8  07 10 20 00 ab 05 00 10  |...1.1.... .....|
000000c0  00 00 e2 f8 66 b8 20 00  8e c0 b9 00 00 10 00 31  |....f. ........1|
000000d0  ff 31 c0 b8 07 00 00 00  ab 05 00 10 00 00 e2 f8  |.1..............|
000000e0  b8 00 00 20 00 0f 22 d8  0f 20 c0 0d 00 00 00 80  |... ..".. ......|
000000f0  0f 22 c0 eb 00 90 c3 eb  fe 00 00 00 00 00 00 00  |."..............|
00000100  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
00000110  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
00000120  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
00000130  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
00000140  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
00000150  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
00000160  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
00000170  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
00000180  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
00000190  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
000001a0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
000001b0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
000001c0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
000001d0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
000001e0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
000001f0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 55 aa  |..............U.|
00000200

【日拱一卒行而不辍20220926】自制操作系统相关推荐

  1. 【日拱一卒行而不辍20220921】自制操作系统

    8086内存安排 8086实模式的寻址范围只有1MB.其中: 系统硬件使用的存储器地址被安排在高端,地址从0xA0000H(684KB)开始的384KB中,其中有用于显示的视频缓冲区: 内存低端安排了 ...

  2. 【日拱一卒行而不辍20220925】自制操作系统

    下面这段系统联调的代码始终没有调通.需要进一步排查. 在汇编层面,下述代码已经进入了综合的深水区. ; ========================================== ; pmt ...

  3. 【日拱一卒行而不辍20221010】自制操作系统

    多进程 修改后的如下chapter6E的Makefile如下所示如下 ######################### # Makefile for Orange'S # ############# ...

  4. 【日拱一卒行而不辍20220924】自制操作系统

    8086内存地址变换过程 80x86在从逻辑地址到物理地址变换过程中使用了分段和分页二种机制. 第一阶段使用分段机制将程序的逻辑地址变换成可寻址内存空间的线性地址. 第二阶段用分页机制把线性地址转换成 ...

  5. 日拱一卒,功不唐捐 | 每日思考俱乐部 专栏更新通知

    缘起 在 2019 年七月份,我写了一篇文章<我为什么要写反思录>.文中提到了我做记录和思考的初衷,起初写在了自己的私密仓库中,也就是其他人都看不到. 持续了一段时间后,我发现,没有分享的 ...

  6. 日拱一卒,“功不唐捐

    据说,世界上只有两种动物能够登上金字塔顶,一种是老鹰,一种是蜗牛.他们是如此不同,老鹰矫健,敏捷,蜗牛弱小,迟钝,可是蜗牛仍然与老鹰一样能达到金字塔顶端.它凭的就是永不停息的执着精神. "日 ...

  7. 社区人物志|李昊鹏:日拱一卒,功不唐捐

    「社区人物志」是 Apache Doris 社区推出的系列专栏,我们关注每一个对 Doris 做出过贡献的 Contributor ,会定期从对 Doris 做出突出贡献的小伙伴中选出一位「社区之星」 ...

  8. #研发解决方案#大数据协作平台魔盒——日拱一卒,功不唐捐

    郑昀 创建于2017/6/29 最后更新于2017/6/30 关键词:大数据,Spark,SparkSQL,HBase,HDFS,工作流,任务,Flow,Job,监控报警 提纲: 为什么要大数据协作? ...

  9. 日拱一卒,集小胜为大胜; 学以致用,在战争中学习战争;

    项目,证明自己的学习能力: 短期掌握尽可能多的知识,并且连线总结成为网络 : 日拱一卒,集小胜为大胜: 学以致用,在战争中学习战争: 投入足够的时间: 学习中的总结,理解 ,应用,等编程套路: 目的性 ...

最新文章

  1. 2022新冠两大毒王合体?印媒炒作高危变异毒株缝合怪「Delmicron」
  2. 上交张伟楠副教授:基于模型的强化学习算法,基本原理以及前沿进展(附视频)
  3. 关注:诺奖得主被爆40多篇论文P图造假!涉及国内“杰青”
  4. Eclipse中设置在创建新类时自动生成注释的方法
  5. MQTT在游戏运营发行中的实践
  6. react-redux草稿
  7. (最新)面向科研人员的免费遥感数据集
  8. 软件测试-禅道下载及安装-测试人员必会工具
  9. 三星note9刷Android9,【极光ROM】-【三星NOTE9 N960X-9810】-【V21.0 Android-Q-THB】
  10. 微信表情包像素不合适的解决办法
  11. LM358运放(比较器、跟随器)输出最高电压问题的探讨
  12. 某城郊110kV降压变电站监控系统设计
  13. 2021年10月数学一及第十三届大数赛部分复习
  14. 为什么公司宁愿花15k去重招一个应届生,也不愿意加薪5k留住老程序员?
  15. linux清理硬盘工具,linux磁盘清理方法 Linux 下垃圾清理工具 BleachBit
  16. apache mod_rewrite 简略说明
  17. vue3 setup语法糖与原始写法对比
  18. 武汉2022专技公需课必修答案
  19. docker学习篇(二)---- 基础篇
  20. java内部类的作用分析

热门文章

  1. 华为与复旦大学合作开发全国首个医学人工智能课程
  2. 使用libusb读取鼠标数据
  3. 日语数量词及时间表示
  4. linux创建用户命令-----useradd
  5. word公式编号及交叉引用技巧
  6. 编译原理实验 -- 文法分析
  7. USB_HID协议基础
  8. Java五子棋最全教程
  9. Java入门之Digital eigenvalue
  10. etcher制作linux启动盘,使用Etcher来创建可启动盘的方法