首页 > 系统相关 >一个操作系统的设计与实现——第20章 加载64位内核,64位显卡驱动与内存管理系统

一个操作系统的设计与实现——第20章 加载64位内核,64位显卡驱动与内存管理系统

时间:2024-08-31 10:15:38浏览次数:9  
标签:20 ELF 虚拟地址 64 内存 显卡 内核

20.1 64位ELF格式

在64位模式下,由于内存地址变宽,ELF格式中的内存地址也要跟着变宽。这并不是一个麻烦的问题,因为ELF格式的整体结构没有发生变化,仍然由一个文件头,加上若干程序头表组成。

对于64位ELF格式的文件头,我们需要关注的信息如下表所示:

偏移量 字节数 含义
0x18 8 程序入口地址
0x20 8 程序头表在ELF文件中的偏移量
0x36 2 程序头表中每个表项的大小
0x38 2 程序头表中表项的数量

对于64位ELF格式的程序头表项,我们需要关注的信息如下表所示:

偏移量 字节数 含义
0x0 4 表项类型,1为可加载的段
0x8 8 当前段在ELF文件中的偏移量
0x10 8 当前段需要被加载到的虚拟地址
0x20 8 当前段在ELF文件中的大小
0x28 8 当前段在内存中的大小

20.2 加载内核

请看本章代码20/Mbr.s

第78~111行,读取硬盘的2~97号扇区,并加载到0x80000处。2~97号扇区存放的是内核ELF文件,1号扇区与98~99号扇区保留给后续章节使用。[0x80000, 0x90000)为内核缓冲区。

第113~116行,从ELF文件头中读取并计算程序头表的地址,表项的大小与数量。这些立即数都没有超过32位,因此是可以直接使用的。

第118~138行,读取每个程序头表项,并将其中的段展开到目标位置。这部分的实现思路与32位操作系统一致,这里不再赘述。

第140行,跳转至内核。同样的,这个立即数没有超过32位,因此是可以直接使用的。

20.3 64位显卡驱动

请看本章代码20/Util.h

第13~16行,定义了va_xxx系列宏。64位GCC使用的是System V AMD64 ABI,该ABI混合使用寄存器与栈传参,笔者不清楚如何在不借助编译器的前提下实现这套功能,因此,直接将这些宏转发到GCC内建的对应功能上。

20/Util.h的剩余部分,以及本章代码20/Util.hpp的实现思路与32位操作系统一致,这里不再赘述。

64位显卡驱动的实现位于本章代码20/Print.h20/Print.hpp中,其实现思路与32位操作系统一致,但有以下区别:

  • 0xb8xxx的虚拟地址是0xffff8000000b8xxx
  • 64位模式下可以使用movsq/stosq指令,一次操作8字节
  • printHex函数,以及printf%x用于打印64位无符号整数,可用于打印指针

20.4 64位内存管理系统

想要实现内存管理系统,就需要先实现位图。位图的实现位于本章代码20/Bitmap.h20/Bitmap.hpp中,其实现思路与32位操作系统一致,这里不再赘述。

接下来,请看本章代码20/Memory.h

第5~9行,声明了内存管理系统的各个接口。

接下来,请看本章代码20/Memory.hpp

第7行,定义了内核虚拟地址的分配起点。

第8行,定义了物理地址的分配起点。

第10行,定义了内核虚拟内存池位图,以及物理内存池位图。

第11行,定义了上述两个位图的缓冲区,每个位图使用一页内存。缓冲区位于BSS段,因此无需手动清零。

memoryInit函数用于初始化两个内存池位图。

__allocateAddr函数用于从内存池位图中分配地址。

__installPage函数用于在虚拟地址与物理地址之间安装映射关系。这个函数的实现原理与二级分页模式一致:反复利用最后一个PML4E进行空兜。只是在四级分页模式下,虚拟地址转换的步骤更多。建议读者使用带二进制功能的计算器构造与检查函数中用到的各种掩码。

allocateKernelPage函数用于在内核地址空间分配连续的pageCount页虚拟地址,这些内存在返回前会被清零。

installTaskPage函数用于在任务地址空间安装虚拟地址。这个函数有两个用途:

  1. 解析任务的ELF文件时,按ELF文件中的要求预先安装虚拟地址
  2. 安装任务的3特权级栈

其中,第二个用途是一定会超出任务的内存池位图范围的,因此,在操作位图时应注意边界。

虚拟地址的安装是以页为单位的,但startAddrstartAddr + memorySize均不保证对齐到页边界,因此,应将startAddr向下对齐到页边界,并将startAddr + memorySize向上对齐到页边界,再进行地址安装。

__deallocateAddr函数用于在内存池位图中回收地址。

deallocateKernelPage函数用于回收内核虚拟页地址。回收地址时,只需要操作PTE即可。

deallocateTaskCR3函数用于回收cr3中前256个PML4E。这个函数的实现原理与二级分页模式一致:反复利用最后一个PML4E进行空兜。只是在四级分页模式下,虚拟地址转换的步骤更多。建议读者使用带二进制功能的计算器构造与检查函数中用到的各种掩码。

20.5 编译与测试

请看本章代码20/Makefile

第4行,编译内核。-fPIC选项用于打开RIP相对寻址。

第5行,链接内核。-N --no-relax均为与-fPIC配合使用的选项,代码段的起始地址为0x0

第7行,将内核从2号扇区开始写入。

本章代码20/Kernel.c测试了显卡驱动与内存管理系统的一些功能。

标签:20,ELF,虚拟地址,64,内存,显卡,内核
From: https://www.cnblogs.com/yingyulou/p/18389915

相关文章

  • WebGL入门(020):WebGLTransformFeedback 简介、使用方法、示例代码
    还是大剑师兰特:曾是美国某知名大学计算机专业研究生,现为航空航海领域高级前端工程师;CSDN知名博主,GIS领域优质创作者,深耕openlayers、leaflet、mapbox、cesium,canvas,webgl,echarts等技术开发,欢迎加底部微信(gis-dajianshi),一起交流。No.内容链接1Openlayers【入门教程】-......
  • 2024/08/31 每日一题
    LeetCode3127构造相同颜色的正方形方法1:模拟classSolution{publicbooleancanMakeSquare(char[][]grid){for(inti=0;i<2;i++){for(intj=0;j<2;j++){intcnt=0;//统计黑色数量cnt+=......
  • Windows Server 2016 OVF, updated Aug 2024 (sysin) - VMware 虚拟机模板
    WindowsServer2016OVF,updatedAug2024(sysin)-VMware虚拟机模板2024年8月版本更新,现在自动运行sysprep,支持ESXiHostClient部署请访问原文链接:https://sysin.org/blog/windows-server-2016-ovf/,查看最新版。原创作品,转载请保留出处。现在都是自动sysprep的......
  • Windows Server 2016 中文版、英文版下载 (updated Aug 2024)
    WindowsServer2016中文版、英文版下载(updatedAug2024)WindowsServer2016Version1607请访问原文链接:https://sysin.org/blog/windows-server-2016/,查看最新版。原创作品,转载请保留出处。本站将不定期发布官方原版风格月度更新ISO。WindowsServer2016直接上链......
  • Windows Server 2019 中文版、英文版下载 (updated Aug 2024)
    WindowsServer2019中文版、英文版下载(updatedAug2024)WindowsServer2019Version1809请访问原文链接:https://sysin.org/blog/windows-server-2019/,查看最新版。原创作品,转载请保留出处。本站将不定期发布官方原版风格月度更新ISO。WindowsServer2019直接上链......
  • 2024.8.30 总结(集训 考 DP)
    上午三个多小时考四道题的DP。赛时会的分:[100](?)+100+[30](?)+100。估分:100+100+0+100。实际分:10+100+0+100。挂巨量的分,挂了120分。下面是一些值得注意的点:T1就是分组背包。DP数组下标要考虑负数可以直接全体加一个值变成非负的,[或者用map之类的](?)(&不......
  • 2024/08/29 每日一题
    LeetCode3142判断矩阵是否满足条件方法1:模拟classSolution{publicbooleansatisfiesConditions(int[][]grid){intn=grid.length,m=grid[0].length;for(inti=0;i<n;i++){for(intj=0;j<m;j++){......
  • 2024/08/30 每日一题
    LeetCode3153所有数对中数位差之和方法1:模拟classSolution{publiclongsumDigitDifferences(int[]nums){intn=nums.length;longans=0;while(nums[0]>0){//遍历每一位inttol=0;//统计总个数i......
  • 【2024HVV结束】这是属于网安人的"春晚" 祝还在现场的师傅们一切顺利 小心二阶段的"Bo
    ......
  • 为什么2024年生意更难做了
    因为暂时看不到新的增长点。甚至说连过去还能稳定运营的生意,也在出问题。因为随着入场人数的增加,竞争加剧的趋势会把所有人都给卷进去。任何行业,只要一卷,就会丧失利润。而2024年,就会是这个情况。2023年的生意就不好做了。可能大家眼里,2023年是全面放开后的第一年,人流恢复......