osdev
文章平均质量分 59
poclist
软件开发工程师。
展开
-
Makefile浅尝
【0】READMEmakefile定义: 一个工程中的源文件不计其数,其按类型、功能、模块分别放在若干个目录中,makefile定义了一系列的规则来指定,哪些文件需要一先编译,哪些文件需要后编译,哪些文件需要重新编译;【1】看个荔枝荔枝解析-Analysis:loader.bin : loader.asm include/load.inc include/fat12hd转载 2016-08-27 22:04:35 · 505 阅读 · 0 评论 -
os引导程序boot从扇区拷贝os加载程序loader文件到内存(boot copy kernel to mem in the same method)
README0.1) 本代码旨在演示 在boot 代码中,如何 通过 loader文件所在根目录条目 找出该文件的 在 软盘所有全局扇区号(簇号),并执行内存中的 loader 代码;0.2) 此代码非常重要,关系到bootloader的加载和运行(打印字母 L)(干货)0.3) source code from orange’s implemention of a os and for转载 2016-08-27 22:24:54 · 854 阅读 · 0 评论 -
《一个操作系统的实现》——pmtest1.asm详解
段机制轻松体验 内存寻址: 实模式下的内存寻址: 让我们首先来回顾实模式下的寻址方式 段首地址×16+偏移量 = 物理地址 为什么要×16?因为在8086CPU中,地址线是20位,但寄存器是16位的,最高寻址64KB,它无法寻址到1M内存。于是,Intel设计了这种寻址 方式,先缩小4位成16位放入到段寄存器,用到时候,再将其扩大到20位,这也造成了段的首地址必须是16的倍数的转载 2016-08-27 22:25:52 · 992 阅读 · 1 评论 -
实模式和保护模式下的地址计算方式
关于保护模式下的寻址方式,是众所周知的,比如: mov edi, [dwDispPos] ;dwDispPos是一个标识数据的label 首先通过ds中的选择子所存的偏移和gdtr找到段描述符,然后取出段描述符中的基址加上dwDispPos所指示的偏移(此偏移是相对于cs段基址的,因此为了正确地取得数据,ds段基址应该与cs段基址相同)。之后再通过分页机制将所得的线性地转载 2016-08-27 22:27:33 · 2203 阅读 · 1 评论 -
图示逻辑地址转换到物理地址
ds:esi (ds中保存有 Selector_x ,esi中是逻辑地址(相对地址)) ↓ ↓ ↓ →→→→→→→→→------------------------------转载 2016-08-27 22:28:59 · 1554 阅读 · 0 评论 -
硬盘和软盘的引导扇区结构
一、 硬盘MBR MBR(Master Boot Record,或Main Boot Record),中文意为主引导区记录,位于磁盘0磁道的第一个扇区,大小正好为512字节,所以又称为主引导扇区。 MBR构成如下图所示: 从图中看出,MBR被分为三个部分: 1) 第一部分为Bootloader(主引导信息),占446字节,它包括两项内容:转载 2016-08-27 22:29:43 · 2054 阅读 · 0 评论 -
段界限为什么要减1
在orange's一个操作系统的实现,第3章,pmtest1.asm中,有如下代码 GdtPtr dw GdtLen - 1 ; GDT界限我们知道一个描述符中包含段基址和段界限,那么如果GdtLen是GDT的长度,为什么段界限要-1呢?因为段界限表达的是段内的最大偏移,而不是段的最大长度。一个简单的例子,加入一个段有如下内存:var1 db 0x01转载 2016-08-27 22:30:38 · 994 阅读 · 0 评论 -
A20地址线
A20地址线并不是打开保护模式的关键,只是在保护模式下,不打开A20地址线,你将无法访问到所有的内存(具体参考下面的第5点)用于80286与8086兼容用于80286处于实模式下时,防止用户程序访问到100000h~10FFEFh之间的内存(高端内存)8086模式,A20关闭的情况下,访问超过1MB内存时,会自动回卷8086模式下,A20打开的情况下,访问超过1MB内存,就转载 2016-08-27 22:31:35 · 781 阅读 · 0 评论 -
实模式跳转保护模式,代码全注释
最近正在阅读《orange's,一个操作系统的实现》,真是相见恨晚啊,那么多年就没有一本真正深入浅出弄点代码让我们入门和实践一下的书,感谢作者于渊。下面是第3章pmtest1.asm的全注释总结执行过程如下:初始化32位代码段的段基址,并存储到GDT中对应的描述符中准备GDT的基地址,并通过LGDT指令加载到GDTR寄存器中cli关中断打开地址线A20将CR0寄存器的PE位置1,进转载 2016-08-27 22:33:57 · 1088 阅读 · 0 评论 -
自己动手写操作体统 pmtest1.asm 详细解释
本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/wangshenwq/archive/2008/09/14/2927636.aspx段机制轻松体验 内存寻址: 实模式下的内存寻址: 让我们首先来回顾实模式下的寻址方式 段首地址×16+偏移量 = 物理地址 为什么要×16?因为在8086CPU中,地址线是20位,但寄存器是16位的,最高寻址转载 2016-08-27 22:38:52 · 749 阅读 · 0 评论 -
自己动手写操作系统 笔记
《自己动手写操作系统》学习笔记目录(持续更新) http://www.techbulo.com/832.html实模式跳转到保护模式实模式------>保护模式有了上一节的基础,那我们开始编码,看看如何实现先前描述的内容首先,既然我们需要一个数组,全局描述符表,那我们就定义一块连续的结构体:[SECTION .gdt] ;为了代码可读性,我们将这个数组放到一个节转载 2016-08-27 22:43:31 · 1264 阅读 · 0 评论 -
GDT,LDT,GDTR,LDTR 详解,包你理解透彻
一、引入保护模式下的段寄存器 由 16位的选择器 与 64位的段描述符寄存器 构成段描述符寄存器: 存储段描述符选择器:存储段描述符的索引段寄存器PS:原先实模式下的各个段寄存器作为保护模式下的段选择器,80486中有6个(即CS,SS,DS,ES,FS,GS)80位的段寄存器。由选择器CS对应表示的段仍为代码段,选择器SS对应表示的段仍为堆栈段。二、详解先说明转载 2016-08-27 22:44:50 · 1493 阅读 · 0 评论 -
一个操作系统的实现重点 ---pmtest1.asm详解
段机制轻松体验 内存寻址: 实模式下的内存寻址: 让我们首先来回顾实模式下的寻址方式 段首地址×16+偏移量 = 物理地址 为什么要×16?因为在8086CPU中,地址线是20位,但寄存器是16位的,最高寻址64KB,它无法寻址到1M内存。于是,Intel设计了这种寻址 方式,先缩小4位成16位放入到段寄存器,用到时候,再将其扩大到20位,这也造成了段的首地址必须是16的倍数的转载 2016-08-27 22:42:14 · 676 阅读 · 0 评论 -
选择符与描述符表寄存器
2.3.5 选择符与描述符表寄存器在实模式下,段寄存器存储的是真实的段地址,在保护模式下,16位的段寄存器无法放 下32位的段地址,因此,它们被称为选择符,即段寄存器的作用是用来选择描述符。选择符的结构如图2.16所示: 图 2.16选择符的结构可以看出,选择符有三个域:第转载 2016-08-31 19:38:59 · 435 阅读 · 0 评论 -
段选择符 段寄存器
突然在书上看到CS、DS、SS、ES叫做段选择符,不知所云,google了下,疑云终于解开:8086中有4个16位的段寄存器:CS、DS、SS、ES,分别用于存放可执行代码的代码段、数据段、堆栈段和其他段的基地址。在80386中,有6个16位的段寄存器,但是,这些段寄存器中存放的不再是某个段的基地址,而是某个段的选择符(Selector)。因为16位的寄存器无法存放32位的转载 2016-08-31 19:39:35 · 1149 阅读 · 0 评论 -
80386的寄存器组成
写这篇文章,完全是因为学习保护模式需要这些知识,读者完全可以走马观花,大致看看有什么内容,知道需要的时候来查这篇文章就可以了,完全没有必要抵抗着困意非要把这篇文章认真看完,记住里面每一个寄存器里每一位的定义,但是以后的文章如果需要,一定要记得回来查查相关的内容。 80386共提供7种类型的32位寄存器,如下:通用寄存器(EAX、EBX、ECX、EDX、ESP、EBP、ES转载 2016-08-31 19:40:28 · 780 阅读 · 0 评论 -
段描述符高速缓冲寄存器
在实模式下,段寄存器含有段值,为访问存储器形成物理地址时,处理器引用相应的某个段寄存器并将其值乘以16,形成20位的段基地址。在保护模式下,段寄存器含有段选择子,如上所述,为了访问存储器形成线性地址时,处理器要使用选择子所指定的描述符中的基地址等信息。为了避免在每次存储器访问时,都要访问描述符表而获得对应的段描述符,从80286开始每个段寄存器都配有一个高速缓冲寄存器,称之为段描述符高速缓冲寄存器转载 2016-08-31 19:41:23 · 1733 阅读 · 0 评论 -
DPL,RPL,CPL 之间的联系和区别
这篇文章写的太好了!!这是保护模式完整的权限检查,其实当今的操作系统也不会弄的这么复杂…… 特权级是保护模式下一个重要的概念,CPL,RPL和DPL是其中的核心概念,查阅资料无数,总结如下: 简单解释:--------------------------------------------------------------------------------转载 2016-08-31 19:54:33 · 761 阅读 · 0 评论 -
GDT(全局描述符表)和LDT(局部描述符表)
每个程序都有自己的LDT,但是同一台计算机上的所有程序共享一个GDT。LDT描述局部于每个程序的段,包括其代码、数据、堆栈等。GDT描述系统段,包括操作系统本身。①全局描述符表GDT(Global Descriptor Table)在整个系统中,全局描述符表GDT只有一张(一个处理器对应一个GDT),GDT可以被放在内存的任何位置,但CPU必须知道GDT的入口,也就是基地址放在哪里,Intel转载 2016-08-31 22:35:13 · 1666 阅读 · 0 评论 -
GDT(Global Descriptor Table)全局描述符表
在IA32下,CPU有两种工作方式:实模式和保护模式。当我们按下开机按钮以后,CPU是工作在实模式下的,经过某种机制以后才进入保护模式。 Intel 8086是16为的CPU,有16为的寄存器、16位的数据总线以及20位的地址总线,因此它有1M的寻址空间,一个地址是又段和偏移两部分组成的,物理地址计算方法是: Physical Address = (Segme转载 2016-08-31 22:36:33 · 1799 阅读 · 0 评论 -
全局描述符表(GDT)——《x86汇编语言:从实模式到保护模式》
在进入保护模式之前,我们先要学习一些基础知识。今天我们看一下全局描述符表(Global Descriptor Table, 简称GDT)。同实模式一样,在保护模式下,对内存的访问仍然使用段地址加偏移地址。但是,在保护模式下,在每个段能够访问之前,必须先登记。这就好比像C语言中,“对变量的使用必须先定义”一样。每个段在能够使用之前,都要为这个段建立一个描述符。每个描述符占8个字节,这些描述符转载 2016-09-01 09:28:41 · 1137 阅读 · 0 评论 -
数据段描述符和代码段描述符(一)
一、段描述符的分类在上一篇博文中已经说过,为了使用段,我们必须要创建段描述符。80X86中有各种各样的段描述符,下图展示了它们的分类。看了上图,你也许会说:天啊,怎么这么多段描述符啊!我可怎么记住呢? 别担心,我会在以后的博文中,跟随原书的作者,为您逐步介绍。我们的学习是循序渐进的,所以不要求一下子掌握所有东西。我们的原则是:用到什么学什么。我们今天的重点是“存储段描述符”。二、段转载 2016-09-01 09:30:06 · 5410 阅读 · 2 评论 -
数据段描述符和代码段描述符(二)
这篇博文,我们编写一个C语言的小程序,来解析数据段或者代码段描述符的各个字段。这样我们阅读原书的代码就会方便一点,只要运行这个小程序,就可以明白程序中定义的数据段或者代码段的描述符了。这段代码,我用了“位字段”的知识,这还是第一次使用C语言的这个特性呢,如果有不对的地方,欢迎博友斧正。写代码之前,我们再复习一下数据段描述符和代码段描述符的格式。(图片选自赵炯老师的《Linux内核完全剖析》转载 2016-09-01 09:30:45 · 1141 阅读 · 0 评论 -
进入保护模式(一)
之前已经做了一些理论上的铺垫,这次我们就可以看代码了。一、代码清单 ;代码清单11-1 ;文件名:c11_mbr.asm ;文件说明:硬盘主引导扇区代码 ;创建日期:2011-5-16 19:54 ;设置堆栈段和栈指针 mov ax,cs mov转载 2016-09-01 09:37:10 · 972 阅读 · 0 评论 -
进入保护模式(二)
首先来段题外话:之前我发现我贴出的代码都没有行号,给讲解带来不便。所以从现在起,我要给代码加上行号。我写博客用的这个插入代码的插件,确实不支持自动插入行号。我真的没有找到什么好方法,无奈之下,只能按照网友的说法,在VIM中给每行代码加上行号,然后再贴出来。在VIM中每一行都添加上行号的方法是::%s/^/\=line(".")/对,只要执行这个命令就可以了。至于为什么这样写,可以参考我转载 2016-09-01 09:37:44 · 850 阅读 · 0 评论 -
进入保护模式(三)
(十)保护模式下的栈76 ;以下用简单的示例来帮助阐述32位保护模式下的堆栈操作 77 mov cx,00000000000_11_000B ;加载堆栈段选择子78 mov ss,cx79 mov esp,0x7c00第77~79行用来初始保护模式下的栈。栈段描述符是GDT中第3个(从0开始数)描转载 2016-09-01 09:38:16 · 1628 阅读 · 1 评论 -
任务和特权级保护(一)
本文及后面的几篇文章是原书第14章的读书笔记。1.LDT(局部描述符表)在之前的学习中,不管是内核程序还是用户程序,我们都是把段描述符放在GDT中。但是,为了有效实施任务间的隔离,处理器建议每个任务都应该有自己的描述符表,称为局部描述符表LDT(Local Descriptor Table),并且把专属于这个任务的那些段描述符放到LDT中。和GDT一样,LDT也是用来存放段描述符的。不转载 2016-09-01 10:34:57 · 1138 阅读 · 0 评论 -
保护的详尽意义:通过调用门转移特权级
摘要:在汇编语言的编程和操作系统的编写过程中,我们经常能听说到“保护模式”这个名词。为什么要叫“保护模式”呢?保护 二字的含义何在?本文主要探讨,“保护模式”下面各种具体的保护机制,这些保护机制产生的原因和具体的影响。阅读本文之前,读者需要了解基本的处理器相关知识,知道分段和分页机制的基本原理,熟悉一些基本的数据结构(段选择符、描述符、GDT、页表、CR系列寄存器等),另外也需要懂一些基本的汇编知转载 2016-09-01 12:29:53 · 797 阅读 · 0 评论 -
特权级和调用门
在IA32的分段机制中,总共有4个特权级别,从高到低分别是0、1、2、3。处理器通过识别下面3中特权级进行特权级检验1.CPL(Current Privilege Level)CPL是当前执行的程序或者任务的特权级,它被存储在CS和SS的第0位和第1位上,通常情况下,CPL等于代码所在的段的特权级,但是有一个例外是如果在遇到一致代码段时,当处理器访问一个与CPL特权级不同的代码段时,CPL不会转载 2016-09-01 12:31:11 · 546 阅读 · 0 评论 -
特权级2——不通过调用门
特权级检查的时间 在选择子没有被装入CS之前进行检查,如果检查成功则将选择子装入CS寄存器。相应的RPL变为CPL。我觉得这个检查的机制就像是数据库的对内容的约束检查,或者说更像是一个before类型的触发器。当CPL、RPL、DPL都通过检查后,CPU将选择子装入相应的寄存器中。否则产生一个通用保护异常。 特权级检查的几种情况: ● 访问数据段只要将选择子装入对应的数转载 2016-09-01 15:59:27 · 318 阅读 · 0 评论 -
特权级3——调用门
调用门的作用gate简单来说可以想象成政府为人民提供的一个政府诉求中心,它可以集中收集人民对政府的要求和投诉,然后把这些诉求发给相关的政府部门来处理。 门提供了受保护的间接调用,为任务内的特权转移提供了安全可靠的方法。由于程序不可能进入具有更高优先级段中的任何位置。如果他们一定要进入,则只能使用调用门进入到调用门描述符指定的位置。而操作系统中定义了系统中的全部门,因此也就保证了所有的门转载 2016-09-01 16:00:18 · 601 阅读 · 1 评论 -
特权指令
特权指令是指保护方式下只有当前特权级CPL=0时,才可执行的指令。如果CPL不等于0而执行它们,那么会引起通用保护异常。从上面介绍的操作系统类指令可归纳出如下表所示的80386特权指令。这些特权指令在构成完善的保护机制方面起了重要的作用。 指令功能CLTS清除CR0中的TS位LTR装入TR寄转载 2016-09-01 16:01:54 · 5422 阅读 · 0 评论 -
(第三章 10)“代码段间跳转” 和 “访问数据段”
下面说明代码段和数据段的访问:一、代码段间跳转1、普通(直接)跳转:JMP Selector:0 或 CALL Selector:01)一致代码段(JMP&CALL)要求:CPL>=DPL,RPL不作检查特权变化:跳转后程序CPL=跳转前程序CPL2)非一致代码段(JMP&CALL)要求:CPL=DPL & RPL特权变化:跳转后程序CPL=目标转载 2016-09-01 16:17:14 · 664 阅读 · 0 评论 -
(第三章 9)“调用门” 和 “利用调用门在高低特权级的转移”
在此之前,先要熟悉汇编指令“长/短jmp”、“长/短call”、ret、retf. 一、调用门“纯粹”作为入口地址 调用门本质上就是个入口地址,只是增加若干属性而已。例子pmtest5a.asm完全将其作为一个地址使用。 二、使用调用门,在不同特权级间转移 使用调用门分为以下两个阶段,难点无非就是“TSS”和“堆栈的变化”。本质上,TSS就是记录了不同特权级堆栈转载 2016-09-01 16:18:34 · 705 阅读 · 1 评论 -
(第三章 8 )特权级——保护模式的特权级检查(DPL,RPL,CPL, 一致代码段,非一致代码段)
特权级是保护模式下一个重要的概念,CPL,RPL和DPL是其中的核心概念,查阅资料无数,总结如下。 一、CPL、RPL、DPL简单解释 CPL是当前进程的权限级别(Current Privilege Level),是当前正在执行的代码所在的段的特权级,存在于cs寄存器的低两位。 RPL说明的是进程对段访问的请求权限(Request Privilege Level),是对于段转载 2016-09-01 16:20:18 · 392 阅读 · 0 评论 -
调用门详解
说明:此文是我将以前的两篇博文(读书笔记28和29)中的部分内容综合而来,如遇重复,请您自行跳过。1. 调用门描述符的格式调用门用于在不同特权级之间实现受控的程序控制转移,通常仅用于使用特权级保护机制的操作系统中。本质上,它只是一个描述符,一个不同于代码段和数据段的描述符,可以安装在GDT或者LGT中,但是不能安装在IDT(中断描述符表)中。注意:Linux Kernel 0.12转载 2016-09-01 16:35:58 · 1281 阅读 · 0 评论 -
调用门的定义+调用
【0】写在前面0.1)本代码,添加了门描述符的相关代码,旨在说明 怎样 对门转移的目标段 进行定义,调用;0.2)本文 只对 与 门相关的 代码进行简要注释,言简意赅;0.3)文末总结是干货(from orange’s implemention of a os),前面代码仅供参考的,且source code from orange’s implemention of a os.;转载 2016-09-01 16:48:48 · 1182 阅读 · 0 评论 -
操作系统篇之-通过调用门和TSS进行不同特权级之间的代码跳转
前面几篇文章我们知道了有很多段,GDT段、LDT段等,通过jmp或者call进行直接代码段间转移我们比较熟悉。但是那只限于同样特权级别的代码段之间跳转。要知道,在IA32的分段机制中,操作系统代码的特权级总共有4个,从高到低分别是0,1,2,3。数字越小代表的特权级别越大。 处理器通过识别下面3种特权级进行特权级检验: CPL(Current PrivilegeLevel):当前转载 2016-09-01 16:57:46 · 1637 阅读 · 0 评论 -
TSS任务状态段
任务状态段(Task State Segment)是保存一个任务重要信息的特殊段。任务状态段描述符用于描述这样的系统段。任务状态段寄存器TR的可见部分含有当前任务的任务状态段描述符的选择子,TR的不可见的高速缓冲寄存器部分含有当前任务状态段的段基地址和段界限等信息。 TSS在任务切换过程中起着重要作用,通过它实现任务的挂起和恢复。所谓任务切换是指,挂起当前正在执行的任务,恢复或启动另一任务的转载 2016-09-01 17:10:14 · 1070 阅读 · 0 评论 -
任务寄存器(Task Register)
任务寄存器(Task Register) 任务寄存器(TR)通过指向一个TSS,寻址了当前正在执行的任务。图7-3显示了处理器如何访问当前任务的TSS。 任务寄存器有一个“可见部分”(也就是说,可以被指令读写的部分)和一个“不可见部分”(由处理器操作,对应着可见部分,不可以通过指令来读写)。可见部分的选择子部分选择了一个在GDT中的TSS。处理器用不可见转载 2016-09-01 17:28:34 · 2987 阅读 · 0 评论