《Linux0.11源码解读》理解(五) head之开启分页

先回顾一下地址长度以及组合的演变:16位cpu意味着其数据总线/寄存器也是16位,但是地址总线(寻址能力)与此无关,可能是20位。可以参考:cpu的位宽、操作系统的位宽和寻址能力的关系_cpu位宽_brahmsjiang的博客-CSDN博客

也就因为寄存器和地址总线位数的不对等,于是16位cpu的寻址方式是: 物理地址=段地址×16+偏移地址。这叫做实模式。但随着历史的演进,cpu已经支持32位(地址总线可以36位)、甚至64位(地址总线可以40位)。为了提升寻址能力和安全性,也为了兼容16位系统,在setup阶段就开始准备从16位实模式往32位保护模式做准备。

在32位保护模式下,段寄存器中存储是段选择子。根据段选择子的索引去查询全局描述符表以获得段描述符,其中存储着基地址物理地址=基地址+偏移地址

一旦开启了分段机制,还要多一步: 

 

程序员写代码时给出的地址叫逻辑地址,其中包含段选择子和偏移地址两部分。通过分段后得到的叫线性地址,线性地址通过分页后得到的叫物理地址。比如我们得到的线性地址是32位,分页机制大概是这样运作的:

线性地址被分为高 10 位、中间 10 位、后 12 位。高 10 位在页目录表中找到一个页目录项,这个页目录项的值加上中间 10 位拼接后的地址去页表中去寻找一个页表项,这个页表项的值,再加上后 12 位偏移地址,就是最终的物理地址。这个过程是由硬件MMU(内存管理单元)完成的。

现在我们继续上一节,将head程序跳转至setup_paging开启分页:

setup_paging:mov ecx,1024*5    ;用来计数xor eax,eaxxor edi,edipushf             ;保存所有标志, 这里主要为了DF(方向标志位)cld               ;让DF=0,用于串操作指令中。决定内存地址递增rep stosd         ;重复执行后面的指令stos。每次执行时从ecx-1,直到ecx=0则结束重复mov eax,_pg_dir   ;设置页目录中的项,仅需4个。_pg_dir为页表目录标号(0地址开始)mov [eax],pg0+7   ;pg0+7表示:0x00001007,是页目录表中的第1项mov [eax+4],pg1+7 mov [eax+8],pg2+7mov [eax+12],pg3+7mov edi,pg3+4092mov eax,00fff007h ;16Mb-4096+7 (r/w user,p)std
L3: stosd             ;将eax的内容复制到edi,复制4字节,并将edi加/减4个字节sub eax,00001000hjge L3popfxor eax,eaxmov cr3,eaxmov eax,cr0or  eax,80000000hmov cr0,eaxret

上述代码的意义就是在内存中一次写好页目录表和页表,之后开启cr0寄存器的分页开关。

首先按当前分页机制:

页目录项有10位,最多可以指示1K项的页表
页表项也有10位,最多可以指示1K项的页起始地址
线性地址低12位,最多可以指示4K偏移地址,4K为一个页。
分页后总共可访问的虚拟内存空间为:1024*1024*4K=4G。但当时Linux 0.11认为,总共可使用的内存不会超过16M。于是4(页表数)* 1024(页表项数) * 4KB(一页大小)= 16MB,即1个页目录表 + 4个页表就可搞定。这也就是ecx计数器设为1024*5的原因,意在通过rep stosd将5个页结构全部清0。

接着填写页目录中的项,共有4个页表只需设置4项(页目录和每个页表项本身也占据4K,每项4byte,一共可以设置1k个项/条目)。来看mov [eax],pg0+7
回顾下在实模式下,ds基地址,eax偏移地址所代表的内存单元:ds×16+eax
在保护模式下,ds段选择子,如0x10指向的是全局描述符表中的第二个段描述符(数据段描述符),里面内容中的段基址是 0。exa偏移地址所代表的内存单元:0+eax (这里+4/+8/+12是因为每一项4字节,32位)。
而页目录项结构与页表中项结构一样,"pg0+7"表示:0x00001007,是页目录表中的第1项。则
第1个页表所在的地址 = 0x00001007 & 0xfffff000 = 0x1000
第1个页表的属性标志 = 0x00001007 & 0x00000fff = 0x07,表示该页存在、用户可读写。
于是我们用此方法把所需4个页目录项的地址、属性给设置了。

接着填写页表(非页目录)中的项,共有:4(页表)*1024(项/页表)=4096 项(0 - 0xfff),也即能映射物理内存4096*4K = 16M。
每项内容是:当前项映射的实际物理内存地址+该页的标志。我们从最后一个页表的最后一项始按倒退填写。一个页表的最后一项在页表中的偏移地址是1023*4 = 4092(表项从0到1023,偏移地址=序号*4)。因此最后一页页表的最后一项的位置就是$pg3+4092。这里edi作为stosd的目的地址被写入,充当了地址变量的作用。然后作为16M内存的最后一页的物理地址是16Mb - 4096 = 0xfff000,加上属性标志7,即为0xfff007。这里eax作为stosd的写入内容,每次写入递减0x1000。

等上述内容全部写入完毕,设置页目录基址寄存器cr3的值,即在0x0000处。然后开启分页(cr0 的PG 标志,位31)。大功告成!大概整个内存效果图是这样:

接下来终于可以进入main.c了! 

 

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/28298.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Android TextView 在最后一行末尾加图标

当前有个需求.显示一段文本,文本最多显示两行,点击展开后才显示完全。当没有显示完全的时候,需要在文本的第二行末尾显示图标,点击图标和文本,文本展开。难点在于图标需要和第二行文本显示在同一行,高度和文…

oracle 如何连同空表一起导出成dmp的方法

1、oracle导出dmp文件的时候,经常会出现一些空表,没有一并被导出的情况。 执行sql select alter table ||table_name|| allocate extent; from user_tables where num_rows0 or num_rows is null; 新建一个sql窗口,把查询结果的sql&#…

Pytorch自动求导机制详解

目录 1. 自动求导 1.1 梯度计算 1.1.1 一阶导数 1.1.2 二阶导数 1.1.3 向量 1.2 线性回归实战 1. 自动求导 在深度学习中,我们通常需要训练一个模型来最小化损失函数。这个过程可以通过梯度下降等优化算法来实现。梯度是函数在某一点上的变化率,可以告…

[黑苹果EFI]Lenovo ThinkPad T490电脑 Hackintosh 黑苹果引导文件

原文来源于黑果魏叔官网,转载需注明出处。(下载请直接百度黑果魏叔) 硬件型号驱动情况 主板Lenovo ThinkPad T490 处理器Intel Intel Core i5 8265U (Quad Core)已驱动 内存16 GB:8 GB Samsung DDR 4 2666 Mhz *2已驱动 硬盘PC SN520 NVM…

CentOS7中安装docker并配置阿里云加速器

文章目录 一、docker的安装二、docker的卸载三、配置加速器四、docker-compose安装五、docker-compose卸载六、docker-compose相关命令七、常用shell组合 一、docker的安装 参考:https://docs.docker.com/engine/install/centos 本文内容是基于:CentOS L…

文件IO 文件属性获取,目录操作

文件属性获取 int stat(const char *path, struct stat *buf); 功能:获取文件属性参数: path:文件路径名 buf:保存文件属性信息的结构体返回值: 成功:0 失败:-1struct stat {ino_t st_ino;…

批发小程序怎么做

批发订货小程序功能介绍 我们的批发订货小程序是一个集订货浏览权限、一客一价、业务员端口、代客下单、订单汇总和订单打印等功能于一体的专业平台。以下是对这些功能的详细描述: 1. 订货浏览权限:我们的小程序可以为不同用户分配不同的订货浏览权限。…

在LLM的支持下使游戏NPC具有记忆化的方法

问题 使用GPT这样的LLM去处理游戏中的NPC和玩家的对话是个很好的点子,那么如何处理记忆化的问题呢。 因为LLM的输入tokens是有限制的,所以伴随着问题的记忆context是有窗口大小限制的,将所有的记忆输入LLM并不现实。 所以这里看到了stanfo…

TOWE智能PDU是如何帮助机房安然度夏的?

最近,全国各地纷纷进入高温“火炉”模式,炎炎夏日,数据中心的工作温度不应该超过一定的限度。数据中心机房不仅要确保在高温多雨天气下安全、稳定的运维,还要承受降低企业总体运营成本的压力。这种需求下,相较于传统基…

【Matlab】智能优化算法_遗传算法GA

【Matlab】智能优化算法_遗传算法GA 1.背景介绍2.数学模型3.文件结构4.详细代码及注释4.1 crossover.m4.2 elitism.m4.3 GeneticAlgorithm.m4.4 initialization.m4.5 Main.m4.6 mutation.m4.7 selection.m4.8 Sphere.m 5.运行结果6.参考文献 1.背景介绍 遗传算法(Ge…

Python基础合集 练习28 (数值运算函数)

from this import d x -120 x的绝对值 x1 abs(x) 同时输出商和余数 y 7 y1 divmod(x1, y) print(y1) /进行幂余运算 z可以省略 (x**y)%z pow(x,y[,z]) pow(3, pow(3, 99), 10000) 四舍五入函数 d是保留小数位数,默认为0 round(x,[,d]) print(round…

uniapp安卓签名证书生成,签名证书的SHA1,SHA256,MD5获取

uniapp安卓证书生成有两种方式,一种是去dcloud开发者中心生成证书,另一种是安装jre环境,自己生成证书 第一种 dcloud生成证书 去该项目对应的应用处,生成证书需要等几分钟,生成后可以查看证书信息 第二种 自己生成…