【日拱一卒行而不辍20220926】自制操作系统
分页原理
在汇编文件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】自制操作系统相关推荐
- 【日拱一卒行而不辍20220921】自制操作系统
8086内存安排 8086实模式的寻址范围只有1MB.其中: 系统硬件使用的存储器地址被安排在高端,地址从0xA0000H(684KB)开始的384KB中,其中有用于显示的视频缓冲区: 内存低端安排了 ...
- 【日拱一卒行而不辍20220925】自制操作系统
下面这段系统联调的代码始终没有调通.需要进一步排查. 在汇编层面,下述代码已经进入了综合的深水区. ; ========================================== ; pmt ...
- 【日拱一卒行而不辍20221010】自制操作系统
多进程 修改后的如下chapter6E的Makefile如下所示如下 ######################### # Makefile for Orange'S # ############# ...
- 【日拱一卒行而不辍20220924】自制操作系统
8086内存地址变换过程 80x86在从逻辑地址到物理地址变换过程中使用了分段和分页二种机制. 第一阶段使用分段机制将程序的逻辑地址变换成可寻址内存空间的线性地址. 第二阶段用分页机制把线性地址转换成 ...
- 日拱一卒,功不唐捐 | 每日思考俱乐部 专栏更新通知
缘起 在 2019 年七月份,我写了一篇文章<我为什么要写反思录>.文中提到了我做记录和思考的初衷,起初写在了自己的私密仓库中,也就是其他人都看不到. 持续了一段时间后,我发现,没有分享的 ...
- 日拱一卒,“功不唐捐
据说,世界上只有两种动物能够登上金字塔顶,一种是老鹰,一种是蜗牛.他们是如此不同,老鹰矫健,敏捷,蜗牛弱小,迟钝,可是蜗牛仍然与老鹰一样能达到金字塔顶端.它凭的就是永不停息的执着精神. "日 ...
- 社区人物志|李昊鹏:日拱一卒,功不唐捐
「社区人物志」是 Apache Doris 社区推出的系列专栏,我们关注每一个对 Doris 做出过贡献的 Contributor ,会定期从对 Doris 做出突出贡献的小伙伴中选出一位「社区之星」 ...
- #研发解决方案#大数据协作平台魔盒——日拱一卒,功不唐捐
郑昀 创建于2017/6/29 最后更新于2017/6/30 关键词:大数据,Spark,SparkSQL,HBase,HDFS,工作流,任务,Flow,Job,监控报警 提纲: 为什么要大数据协作? ...
- 日拱一卒,集小胜为大胜; 学以致用,在战争中学习战争;
项目,证明自己的学习能力: 短期掌握尽可能多的知识,并且连线总结成为网络 : 日拱一卒,集小胜为大胜: 学以致用,在战争中学习战争: 投入足够的时间: 学习中的总结,理解 ,应用,等编程套路: 目的性 ...
最新文章
- 2022新冠两大毒王合体?印媒炒作高危变异毒株缝合怪「Delmicron」
- 上交张伟楠副教授:基于模型的强化学习算法,基本原理以及前沿进展(附视频)
- 关注:诺奖得主被爆40多篇论文P图造假!涉及国内“杰青”
- Eclipse中设置在创建新类时自动生成注释的方法
- MQTT在游戏运营发行中的实践
- react-redux草稿
- (最新)面向科研人员的免费遥感数据集
- 软件测试-禅道下载及安装-测试人员必会工具
- 三星note9刷Android9,【极光ROM】-【三星NOTE9 N960X-9810】-【V21.0 Android-Q-THB】
- 微信表情包像素不合适的解决办法
- LM358运放(比较器、跟随器)输出最高电压问题的探讨
- 某城郊110kV降压变电站监控系统设计
- 2021年10月数学一及第十三届大数赛部分复习
- 为什么公司宁愿花15k去重招一个应届生,也不愿意加薪5k留住老程序员?
- linux清理硬盘工具,linux磁盘清理方法 Linux 下垃圾清理工具 BleachBit
- apache mod_rewrite 简略说明
- vue3 setup语法糖与原始写法对比
- 武汉2022专技公需课必修答案
- docker学习篇(二)---- 基础篇
- java内部类的作用分析