操作系统
文章平均质量分 72
qq_52484093
这个作者很懒,什么都没留下…
展开
-
进阶操作系统
什么是操作系统?操作系统是直接运行在硬件上的计算机程序。操作系统用于管理和控制计算机的硬件和软件资源。操作系统为用户软件的开发提供了必要的服务和接口。BIOS-Base Input & Output SystemBIOS是计算机上电第一个运行的程序。BIOS首先会检测硬件状态,检测通过后立即进行硬件初始化。BIOS会在内存中建立中断向量表(提供硬件访问的方法)。BIOS最后将控制权交由主引导程序执行。BIOS不是软件,而是固件。固件是固化在...原创 2021-10-17 18:48:05 · 742 阅读 · 0 评论 -
Hello,DTOS
主引导程序是软件还是固件?如果是软件,那么由谁开发?如何开发?主引导程序一段存储在主引导区(MBR)中的有效代码。 并不固化于硬件,属于操作系统代码的一部分。 启动操作系统内核的桥梁,由汇编程序写成。 代码总量不能超过512字节(包括0x55aa)。课程实验编写一个主引导程序(汇编语言)可独立运行于x86架构的主机(无操作系统)运行后在屏幕上打印"HELLO,DTOS!"org 0x7c00start: mov ax, cs mov ss, ax mov ds,原创 2021-10-17 18:53:51 · 184 阅读 · 0 评论 -
调试环境的搭建
如何调试主引导区的代码?Bochs(另一款优秀的虚拟机软件)- 专业模拟x86架构的虚拟机- 开源且高度可移植,由C++编写完成- 支持操作系统开发过程中的断点调试- 通过简单配置就能运行绝大数主流的操作系统...原创 2021-10-18 08:40:40 · 95 阅读 · 0 评论 -
主引导程序的拓展(上)
我们知道主引导程序只能存在第一扇区中,而BIOS只会将第一扇区拷贝到内存执行,第一扇区之后的程序是不会被BIOS加载到内存中的,而这512字节的程序不可能完成整个操作系统的功能,因此,我们要突破这种限制。这512字节只能完成最基本的功能,我们这样来规划它的功能:1、首先完成最基本的初始化;2、从存储介质中加载程序到内存中;3、将控制权交给新加载的程序。以上三步如下图所示:那么怎么加载存储介质中的程序呢?我们平时写应用程序时,可以使用read这种系统调用来读取文件,而这种方法.原创 2021-10-18 09:03:33 · 151 阅读 · 0 评论 -
主引导程序的拓展(下)
在上一节中,我们成功的将虚拟软盘进行了格式化,而且将文件存入其中,那么如何在根目录区中查找文件呢?为了方便起见,再次给出FAT12文件系统的格式,如下所示:在FAT12文件系统中,一簇包含一个扇区。从上图可见,目录文件项的偏移为19个扇区,其本身大小占用了14个扇区。根目录区中是一个一个的目录项,目录项的具体成员与分布如下所示:每一个目录项代表根目录中一个文件的索引,其大小为32字节,根据目录项中文件开始的簇号和文件大小,我们可以找到文件的具体内容。下面我们先来读取一下FAT12文件系统根.原创 2021-10-19 10:14:55 · 79 阅读 · 0 评论 -
突破512字节的限制(上)
前几节我们介绍了FAT12文件系统,制作了虚拟软盘文件a.img,并在Qt Creater中进行了文件内容的读取实验。那些读取都是使用外部的程序实现的,实际应用中,我们需要用主引导程序来实现文件的读写,主引导程序存在于主引导扇区MBR中,也就是说程序和文件是存在一张盘上的,而且这些主引导程序需要使用汇编语言实现。接下来,我们就来实现具有读取功能的主引导程序。为了验证文件读取的正确性,我们需要在主引导程序中先实现一个字符串打印函数。BIOS已经将中断向量写到了内存的指定位置处,这其中就有能实现字符串打印的原创 2021-10-20 08:42:24 · 278 阅读 · 0 评论 -
突破512字节的限制(中)
上一节我们写了字符串打印的函数和软盘读取函数,在软盘读取函数中,我们是直接给定了要读的逻辑扇区号,这一节我们来实现一个查找文件的功能,也就是根据给定的文件名,在根目录区中查找指定的文件是否存在,涉及到文件名的查找,就会涉及到内存的比较,因此,我们需要实现两个函数,分别为内存比较函数和根目录区查找函数。整体的流程如下:首先将根目录区加载到内存中的指定位置上,这里面包含了一定数目的根目录项,而根目录项的前11个字节为文件名,因此,查找文件的工作就可以进行了,我们只需要将目标文件名和每一个根目录项的前原创 2021-10-20 09:20:26 · 159 阅读 · 0 评论 -
突破512字节的限制(下)
上一节我们进行了文件的查找实验,文件查找成功了,这一节,我们将文件的内容加载进内存,再一次将整体的流程给出如下:读取文件的内容时,我们需要根据FAT表找到存储文件内容的每一个扇区,然后进行内容的读取,在上一节中,我们将整个目录区的内容加载到了内存并根据文件名找到了所在的目录项,为了节省内存,我们将找到的目录项拷贝到另一片内存区域中,因为这个目录项中还有我们需要的内容,比如文件的起始扇区号等。而原来加载目录区的那一部分内存便可以另作他用,比如可以将FAT表加载到该区域。目标文件的目录信息如下:原创 2021-10-21 16:49:27 · 481 阅读 · 0 评论 -
主引导程序控制权的转移
这一节,我们来真正的读取文件中的内容到内存中,首先来看一下内存布局是什么样的,如下所示:Boot占用了512字节,Fat Table占用了4KB,而真正的文件中的内容,我们把它存在0x9000开始的内存地址处。加载文件内容的过程如下:实验步骤如下:1、在虚拟软盘中创建体积较大的文本文件,使之内容大小超过一个扇区。2、将文件的内容加载到BaseOfLoader地址处。3、打印加载的内容,判断是否加载完全。读取文件内容的代码如下所示start: mov ax, .原创 2021-10-22 08:56:28 · 159 阅读 · 0 评论 -
实模式到保护模式(上)
远古时期的程序开发是直接操作物理内存的,CPU指令的操作数直接使用实地址(实际内存地址),程序员拥有绝对的权利,可以随意访问内存的任意一个地址,可以说是指哪打哪。使用绝对的物理地址会带来很多问题,例如:1、难以重定位,程序每次都需要同样地址的内存来运行,所以从一台机器移植到另一台内存大小不同的机器上需要修改源码中的地址。2、给多道程序设计带来了障碍,也就是说,不管内存多大,但凡一个字节被其他程序占用都无法执行。为了解决以上的问题,英特尔开发出了8086 CPU处理器,其引入了如下特性:1原创 2021-10-22 12:20:54 · 112 阅读 · 0 评论 -
实模式到保护模式(中)
为了解决内存访问越界的问题,英特尔发明了80286处理器,这款处理器引入了保护模式,为现代操作系统和应用程序奠定了基础,但是80286在设计上有些奇葩,例如:段寄存器为24位,通用寄存器为16位,这样显得不伦不类,80286上电时处于实模式,段寄存器只用到了16位,进入保护模式后,段选择子也不会用到24位,因此24位寄存器有些浪费。理论上,段寄存器中的数值可以直接作为段基址。80286中16位寄存器最多访问64K的内存,为了访问16M的内存,必须不停的切换段基址。80286是一款试水的产品,80原创 2021-10-23 08:59:22 · 205 阅读 · 0 评论 -
实模式到保护模式(下)
这节课我们来深入保护模式:定义显存段为了显示数据,必须存在两大硬件:显卡 + 显示器显卡:为显示器提供需要显示的数据,控制显示器的模式和状态显示器:将目标程序以可见的方式呈现在屏幕上显存的概念和意义:1、显卡拥有自己内部的数据存储器,成为显存2、显存在本质上和普通内存无差别,用于存储目标数据3、操作显存中的数据,将导致显示器上内容的改变显卡有文本模式和图形模式两种工作模式,在不同的模式下,显卡对显存的内容解释是不同的,可以使用专属指令或int 0x10中断改变显卡工作模式。原创 2021-10-23 09:06:47 · 219 阅读 · 0 评论 -
从保护模式返回实模式
上节课我们从实模式进入了保护模式,并在保护模式下打印了2个字符串。我们并没有设置sp寄存器,却能够正常的进行函数调用。我们需要通过反编译来查看sp寄存器的值。我们通过ndisasm -o 0x9000 loader > loader.txt命令来进行反编译。我们在66行这条指令的地址处打上断点,这条指令是从16位实模式跳转到32位保护模式所对应的指令,我们查看16位实模式下的sp寄存器和32位保护模式下sp寄存器的值。通过下图我们观察到16位实模式下sp寄存器的值为0x7c...原创 2021-10-14 16:17:45 · 496 阅读 · 0 评论 -
局部段描述符表的使用
什么是局部段描述符表(LDT)?1. 本质是一个段描述符表,用于定义段描述符2. 与GDT类似,可以看作"段描述符的数组"3. 通过定义选择子访问局部段描述表中的元素LDT选择子和GDT选择子的结构相同,但LDT选择子的第二位恒为1.局部段描述符表需要在全局段描述符表中注册(添加描述项)通过对应的选择子加载局部段描述符(lldt)局部段描述符表从第0项开始使用(different from GDT)LDT的意义代码层面的意义:分级管理功能相同,意义不同的段(如:.原创 2021-10-15 12:32:23 · 399 阅读 · 0 评论 -
保护模式中的特权级(上)
a原创 2021-10-16 12:11:42 · 175 阅读 · 0 评论 -
保护模式中的特权级(中)
门描述符通过门描述符可以在不同特权级的代码间进行跳转。根据应用场景的不同,门描述符可以分为:调用门(Call Gates)、中断门(Interrupt Gate)、陷阱门(Trap Gate)、任务门(Task Gate)。门描述符的内存结构1. 每一个门描述符占用8字节内存。2. 不同类型的门描述符的内存含义不同。通过调用门选择子可以得到门描述符里段选择子,通过段选择子我们可以得到这个段的段基地址,段基地址加上偏移地址就是函数的入口地址。当我们需要执行该段之外的函数..原创 2021-10-16 15:48:07 · 240 阅读 · 0 评论 -
保护模式中的特权级(下)
使用调用门如何实现不同特权级代码之间的跳转(如:从高特权级到低特权级)?调用门只支持从低特权级跳转到高特权级执行。无法利用调用门从高特权级跳转到低特权级执行。调用门的特权级跳转分析1. 通过远调用(call far) : 低特权级 --> 高特权级2. 通过远返回(retf) : 高特权级 --> 低特权级函数的调用过程需要提前知道的事实1. x86处理器对于不同的特权级需要使用不同的栈。2. 每一个特权级对应一个私有的栈(最多4个栈)..原创 2021-10-17 10:31:24 · 1341 阅读 · 0 评论 -
深入特权级转移(上)
初识任务状态段(Task State Segment)处理器所提供的硬件数据结构,用于实现多任务解决方案TSS中保存了关键寄存器的值以及不同特权级使用的栈在进行不同特权级的切换时,需要把重要的寄存器信息保存下来,切换回来后,再恢复相关寄存器的信息。特权级转移时栈变化低特权级 --> 高特权级(调用门) 从TSS中获取高特权级目标栈段,将低特权级栈信息压入高特权级栈中高特权级 --> 低特权级(retf) 将低特权级栈信息从高...原创 2021-10-18 18:20:11 · 159 阅读 · 0 评论 -
深入特权级转移(中)
处理器通过什么规则来判断资源请求或代码跳转是否合法?数据段的访问规则(数据段无可执行属性)访问者权限(CPL) 高于或等于数据段特权级(DPL) 请求特权级(RPL)高于或等于数据段特权级(DPL) 即 : (CPL <= DPL) && (RPL <= DPL)%include "inc.asm"org 0x9000jmp ENTRY_SEGMENT[section .gdt]; GDT definition;原创 2021-10-19 17:28:38 · 92 阅读 · 0 评论 -
深入特权级转移(下)
关于调用门的注意事项调用门支持特权级同级转移调用门同级转移被处理为普通函数调用或直接跳转call通过调用门能提升特权级,jmp通过调用门只能同级转移(这是因为jmp跳转之后就不会再返回了,如果从低特权级的代码片段跳转到高特权级的代码片段,但是不能返回的话,就一直处于高特权级状态,那么特权级就失去了意义)通过调用门降级返回(retf)时对目标代码段以及栈段进行特权级检查 对相关段寄存器强制清零(指向高特权级数据的段寄存器)测试代码如下%include "inc.asm"o..原创 2021-10-20 17:57:40 · 76 阅读 · 0 评论 -
特权级与内核安全示例
既然通常情况下选择子中的RPL与对应描述符中的DPL相同,那么是否可以取缔RPL?RPL是保证内核数据安全的关键要素之一;在内核代码中有决定性作用,绝对不能取缔!用户程序怎么获得内核的私密数据呢?下面我们来进行实验%include "inc.asm"org 0x9000jmp ENTRY_SEGMENT[section .gdt]; GDT definition; 段基址, 段界限原创 2021-10-21 12:43:07 · 123 阅读 · 0 评论 -
页式内存管理(上)
段式内存管理回顾这里的段指的是一段连续的内存空间为什么会有段式内存管理?程序的各个部分相对独立(代码段、数据段) 早期x86处理器无法通过一个寄存器访问所有内存单元 解决早期程序运行时的重定位问题段式内存管理的应用在x86系列的处理器中,硬件对段式内存管理进行了直接支持另外,段式内存管理也可以用纯软件来实现核心:段首地址 + 段内偏移地址 = 内存单元地址操作系统只使用段式内存管理是否足够?硬件技术计算机部件独立化(硬件接口相同,可任意组装) 计算机配置差异.原创 2021-10-22 12:07:00 · 160 阅读 · 0 评论 -
页式内存管理(下)
操作系统如何管理实际的物理内存?页框与页表(Frame and Page)页框(Frame) : 物理内存空间中的页(物理页) 页表(Page) : 逻辑内存空间中的页(逻辑页)页框用于存储页面内容,而页面内容来自于逻辑内存空间操作系统对物理内存的管理操作系统必须知道物理内存的使用情况建立结构对物理内存进行管理(Frame Table) 结构记录包括 : 页框是否可用,被谁使用,等 为具体的应用程序分配页表操作系统对物理内存的管理(方式之一)任务表 : 操作..原创 2021-10-23 12:46:19 · 368 阅读 · 0 评论 -
实战页式内存管理(上)
课程设计目标用代码描述:页表,页框表,任务结构用代码实现:页请求,页置换模拟任务的页面访问过程(访问虚拟内存)模拟操作系统中的任务调度(拓展)实现的关键点一页框表是全局唯一的,用于记录内存页使用情况页表是任务私有的,用于记录虚拟页到内存页的映射关系每一个任务需要一个结构体进行表示实现的关键点二页分配操作:int GetFrameItem();页请求操作:int RequestPage(int pid, int page);页交换操作:int Swap.原创 2021-10-24 16:13:45 · 156 阅读 · 0 评论 -
实战页式内存管理(中)
课程设计目的处理运行结束的任务实现FIFO页面交换算法实现LRU页面交换算法目标一:处理运行结束的任务将任务结构从任务表中移除回收任务所使用的页框释放任务结构所占用的内存目标二:实现FIFO页交换算法目标三:实现LRU页交换算法整体代码如下#include <QCoreApplication>#include <iostream>#include <QList>#include <QQueue...原创 2021-10-25 11:56:29 · 123 阅读 · 0 评论 -
实战页式内存管理(下)
PageTable类的本质是一维数组,那么,为什么PCB类中的页表成员不直接使用一维数组?因为页表的表现方式可能会发生变化,我们将未来可能发生出现的代码变动封装到局部,这样的话只需要将局部的代码改动,只要它提供的接口不变,即使内部代码改变,我们也不需要变更程序的其他代码。根据程序运行的局部性原理多数情况下,页表为稀疏状态单级页表会浪费大量内存二级页表把页号分为2段:页目录 + 二级页号如果下级页表的所有表项为空,那么页目录为空具体设计由于最大页号为0xFF,因此原创 2021-10-26 10:16:06 · 120 阅读 · 0 评论 -
x86系统上的内存分页
x86系列处理器上的页式内存管理硬件层直接支持内存分页机制默认情况下不使用内存分页机制(段式内存管理)分页机制启动后,使用二级页表对内存进行管理x86系列处理器的分页方式x86分页机制示意图x86系列处理器的分页方式一些重要结论(针对32位x86处理器)页目录占用1内存页(可访问1024个子页表)单个子页表占用1内存页(可访问1024个页面)页面起始地址按4K字节对齐(总是4096整数倍)分页后可访问的虚拟内存空间为:4K * (1024 * 1...原创 2021-10-27 15:42:16 · 397 阅读 · 0 评论 -
畅游x86分页机制(上)
有趣的问题1.进入32位保护模式代码后,应该在什么时候启动分页机制,并建立页表?2.在位置<1>和位置<2>调用SetupPage的执行效果是否相同?为什么?经实验后,调用页表的函数无论放在两个打印函数的上面、中间还是下面,程序都能正常正确的执行,打印出正常结果。那么,会不会是没有开启分页机制呢?我们把之前的页目录项的值给修改了,运行程序时处理器产生了异常,说明调用SetupPage确实是开启了分页机制。当前页面的构建方式剖析假设当前的虚地址位0x008.原创 2021-10-29 13:54:16 · 126 阅读 · 0 评论 -
畅游x86分页机制(中)
在保护模式下,如何在指定的物理内存处写入数据?当今处理器一个通用寄存器为32位,我们将段寄存器的值设为0,可以通过一个通用寄存器访问0-4G的地址空间,这样访问的就是实际物理地址的0-4G空间。平坦内存模型将整个物理地址作为一个段处理因此,段起始地址为0,段大小为物理内存容量保护模式下,可定义平坦内存段描述符(最多访问4G内存)平坦内存模式示例本节课的实验内容为将同一虚地址映射到不同的物理地址实现思路准备数据在地址0x501000处写入字符串("D.T..原创 2021-10-30 13:27:21 · 93 阅读 · 0 评论 -
畅游x86分页机制(下)
页表映射实验我们来到了最后一步:加载不同的页表,并读取同一虚拟地址中的内容。页表映射实验流程图%include "inc.asm"ObjectAddrX equ 0x401000TargetAddrY equ 0x501000TargetAddrZ equ 0x601000PageDirBase0 equ 0x200000PageTblBase0 equ 0x201000PageDirBase1 equ 0x原创 2021-10-31 12:36:31 · 143 阅读 · 0 评论 -
获取物理内存容量(上)
前几节课我们完成了页表的实验。我们知道在没有空闲页框的时候会进行页置换,那么怎么知道还剩多少页框?一共还有多少页框也用?所以,我们需要获取系统物理内存的大小如何获取系统物理内存的大小?BIOS提供的相关中断基础功能(eax = 0xE801)分别检测低15MB和高16MB - 4GB的内存 最大支持4GB内存检测高级功能(eax = 0xE820)遍历主机上所有的内存范围 获取各个内存范围的详细信息由于我们是在32位系统上做实验,所以基础功能够用了int 0x15 基原创 2021-11-01 12:01:19 · 527 阅读 · 0 评论 -
获取物理内存容量(下)
我们这节课BIOS提供的(int 0x15)号中断的高级功能(eax = 0xE820),遍历主机上所有的内存范围(内存地址段),获取各个内存范围的详细信息int 0x15 进阶版功能中断参数eax = 0xE820 (固定值) edx = 0x534D4150 (固定值) ebx --> 初始参数必须为0,终止标志 ecx --> ARDS 结构体大小 (20字节) es : di --> ARDS 结构体数组 (每个元素占用20字节)地址范围描述结构 (Ad原创 2021-11-02 19:03:59 · 328 阅读 · 0 评论 -
深入浅出x86中断机制(上)
中断的概念和意义概念正在执行任务时,出现某个请求暂停当前任务,转而处理这个请求 处理结束后继续任务的执行意义中断是提高系统整体性能的重要方式处理器与外设的拓扑结构中断与外设中断时一种处理器与外设进行通信的机制用于通知处理器外部有重要事件发生一般情况下中断需要被处理器响应本质操作系统是中断驱动的死循环处理器,中断,操作系统 本质剖析假设当前键盘按下'f'按键,键盘就会向处理器发出一个中断请求,处理器接受到这个中断请求后,就会根据按键被按.原创 2021-11-09 11:04:08 · 661 阅读 · 0 评论 -
深入浅出x86中断机制(下)
实模式下的中断处理使用中断向量表映射不同中断与中断服务程序中断向量表 (Interrupt Vector Table)起始于物理地址0,长度为1KB 每个单元4字节,连续256个单元 每个单元存放中断服务程序的入口地址中断向量表 (IVT)处理器接受到中断信号时,能够询问到中断向量 (中断类型号);通过中断向量查找IVT,获取ISR入口地址;之后,跳转执行 (类似函数调用)。中断响应与处理你不知道的故事x86系列处理器上电后直接进入实模式硬件设计将RO.原创 2021-11-10 13:19:57 · 522 阅读 · 0 评论 -
中断代理-8259A
不同外设怎么向处理器发送中断信号?当多个外设同时产生中断时,如何进行处理?想象中的连接方式处理器只有一个INTR引脚,超高速的处理器也没有必要和超低速的外设直接相连,所有就需要一个中间代理8259A 。处理器的中断代理 (8259A)8259A是处理器的中断功能模块,用于管理和裁决外部设备的中断请求。8259A是专为处理器设计的中断管理芯片可通过编程对8259A进行功能配置屏蔽外设中断,对中断进行优先级裁决向处理器提供中断向量对8259A的编程控.原创 2021-11-11 12:50:11 · 278 阅读 · 0 评论 -
8259A控制编程
一般来说x86系统中使用2个8259A级联作为中断代理1个8259A只能管理8个外设,所以如果需要管理超过8个外设,则需要级联更多的8259A。当2个8259A级联时,通常主8259A使用特殊完全嵌套方式;从8259A使用完全嵌套方式。这样,当处理器正在处理从8259A的低优先级的中断时,从8259A的高优先级中断可以打断当前处理器正在执行的低优先级中断。8259A的设置与控制初始化命令字 (Initialization Command Word)用于确定是否需要级联,设置.原创 2021-11-12 11:06:41 · 2068 阅读 · 1 评论 -
中断编程实践
实践内容预备工作8259A初始化,读写IMR寄存器,发送EOI控制字,等实践一自定义软中断的实现 (内部中断处理)实践二时钟中断的响应及处理 (外部中断处理)预备工作编写延迟函数 (Delay)编写8259A初始化函数 (Init8259A)编写8259A中断屏蔽寄存器读写函数 (ReadIMR;WriteIMR)编写8259A中断结束符写入函数 (WriteEOI)Init8259A读写IMR寄存器使用OCW1设置IMR的目标值写入对.原创 2021-11-13 13:39:04 · 252 阅读 · 0 评论 -
中断处理与特权级转移
问题8259A在中断特殊完全嵌套方式下,同一个引脚的新中断是否可以打断旧中断的处理?问题剖析假设:时钟请求周期为5ms,对应的中断服务程序执行时间为10ms;那么中断服务程序是否会被新的时钟请求打断?我们初始化8259A时,将主片的中断方式设置为特殊完全嵌套方式,同一个引脚的新中断可以打断旧中断的处理。理应来说,处理器在处理时钟的中断服务程序时,会响应8259A新发送来的时钟请求,打断当前的执行,从而去执行新的时钟中断服务程序,但事实上却不是这样的。关于中断优先级中断优.原创 2021-11-14 13:50:19 · 541 阅读 · 0 评论 -
c语言与汇编语言混合编程
如何从汇编语言过渡到c语言?从编译过程谈起编译小知识源代码编译后得到目标文件 (二进制文件)不同语言可编译得到相同格式的目标文件链接器负责将目标文件组装得到可执行文件老生常谈的问题。。。c语言中的函数调用是如何进行的?栈上的秘密cdecl 调用约定 (C语言默认调用约定)参数从右向左入栈函数调用者负责参数的入栈出栈函数本身根据约定使用栈中参数gcc编译器使用的栈帧布局ebp是函数调用以及函数返回的核心寄...原创 2021-11-15 12:25:47 · 2316 阅读 · 0 评论 -
从bootloader到内核雏形
整体设计问题为什么不能从boot直接加载kernel,并跳转运行?设计思路boot必须小于512字节,无法完成过多功能kernel需要运行在32位保护模式 (汇编 + c语言)使用loader中转:获取必要硬件信息,进入保护模式bootloader重构方案文件功能定义org 0x7c00define: BaseOfStack equ 0x7c00 BaseOfTarget equ 0x9000 RootE...原创 2021-11-16 13:47:41 · 272 阅读 · 0 评论