摘要:首先声明这两个东西不是一个概念cpu分段机制中段的概念确定了在线性地址空间中一个段的用途以及被执行或访问的约束,每个段可以设置在4G线性地址的任何地方,它们可以相互独立也可以完全重叠或部分重叠。而进程的在其逻辑地址空间中代码段和数据段则是由编译器在编译程序和操作系统在加载程序时规定的在进程逻辑地址空间中顺序排列的代码区域、初始化和未初始化的数据区域以及堆栈区域,参考elf文件的格式中头文件及文件头表
阅读全文
摘要:boot代码中指示从0磁头0驱动区号0磁道第2扇区开始读取head代码到0x1000:0处,但是我怎么把编译出来的head代码放到磁盘的该位置呢?dd if=boot of=boot.img bs=32 skip=1此句以BlockSize=32Byte把boot写入boot.img,跳过一个输入Block(32Bytes),也就是跳过boot文件头.dd if=head of=boot.img bs=512 seek=1此句以BlockSize=512Byte把head写入boot.img,跳过一个输出Block,也就是跳过512Byte的boot,写入boot.img
阅读全文
摘要:前两天在QQ群里有人问了这么一个问题:在x86计算机中的内存分布中,有一部分是ROM BIOS,请问那块内存可写不能我当时也没有想明白,群里也没有讨论出一个明确的回答,后来思考了下,我想应该是这样吧,4G可寻址空间应该都是可写的,大家不要被ROM BIOS给吓着,虽说这是ROM但是,BIOS是一个芯片,里面有一个可读的程序,又一联想所有程序都要先加载到内存中,所以我想,应该是把ROM BIOS芯片里面的程序加载到4G当中的某个位置不知道对不对,还望大家批评指正
阅读全文
摘要:第一遍看书时不明白,今天偶然又看到了这一点,顿时豁然开朗linux0.12系统中共用了四种堆栈1. 系统引导初始化时临时使用的堆栈,此时我的理解是系统还在实模式2. 进入保护模式之后提供内核程序初始化使用的堆栈,位于内核代码地址空间固定位置处,该堆栈也是后来任务0的用户态堆栈,个人理解任务0比较特殊,它的内核态堆栈还是用户态堆栈都在内核中。3. 每个任务通过系统调用,执行内核程序时使用的堆栈,我们称之为任务的内核态堆栈,每个人物都有自己的内核态堆栈,内核态堆栈是和任务数据结构一起定义4.任务在用户态执行的堆栈,位于任务逻辑地址空间的末端处。以前有一段时间还怀疑过linux0.12中内核态堆栈和
阅读全文
摘要:原本以为栈就那回事,存放一下临时变量,参与一下函数的调用,但是今天看《程序员的自我修养》又让我对栈加深了了解我这里只想说下我不知道的,至于那些调用惯例我就不多说了,理解起来不是很难除了参数的传递之外,函数与调用方的几哦啊胡还有一个渠道就是返回值,eax是传递返回值的同道,但是eax本身只有4字节,大于4字节的采用edx和eax做返回值,而对于超过8字节的返回类型参照下面的例子 1 typedef struct big_thing 2 { 3 char buf[128]; 4 }big_thing; 5 6 big_thing return_test() 7 { 8 big_t...
阅读全文
摘要:在《自己动手写操作系统》中有一段代码,通过这段代码大致可以让人知道装载是怎么回事(静态链接)首先要分析下elf的文件结构,我就简单的说了,elf首先是一个文件头表,顾名思义,这个文件头表里面保存的是文件的信息,其中一个很重要的信息是程序的入口地址,接着还有若干程序头表,这个比较重要,每一个程序头表对应着elf可执行文件中的一段。程序头表中包含有所描述的段要加载到内存的那个位置,还有段的大小。有了上述这些信息,下面就来说下程序的装载的步骤:1. 检查elf可执行文件格式的有效性,比如魔术,程序头表中段的数量2.根据elf可执行文件的程序头表的描述,对elf文件进行映射,比如代码,数据,只读数据3
阅读全文
摘要:书的脉络其实一个操作系统逐渐完成的过程1. boot 从软盘启动,机器会读软盘的第一个扇区即引导扇区,512字节,所以这个程序会很简单,boot就完成两件事,第一把loader读入内存,第二把控制权交给loader2. loader 中完成了三件事,第一把kernel读入内存,第二跳到保护模式,第三把控制权交给kernel(这一步需要注意一下,程序把kernel的位置从新放置了,这里类似于装载下篇博文会讲到)3. kernel 进入到kernel,其余的就是实现中断4. 进程及进程的切换,注意进程是怎么实现的,以及进程之间的堆栈切换5. 系统调用,说白了也是一种中断,软中断。
阅读全文
摘要:再过两天就要回学校了,在家花了差不多半个月时间(边玩边看)终于把《自己动手写操作系统》的前六章看完了,感觉还不错,因为之前一段时间看了linux0.12内核不少时间,基础知识差不多已经打好了。看了《自己动手》有点心得,这本书其实是很简单的,怎么说呢,它实现的是一个很小的系统,只把重要的大致框架搭起来了,内容其实不是很饱满,对于想亲手实践下的比较好,但是本书不适合新手入门,有些地方没有讲清楚就直接用了,建议大家看第二版。看过之后和linux0.12对比起来,这本书简直是简单的不能再简单了,但本书的保护模式讲的不错,只要懂保护模式,其他就都懂了
阅读全文
摘要:软件或处理器可以用以下方式中的任何一种来调度任务执行: 用 CALL 指令显式地调用任务。 用 JMP 指令显式地跳转到任务。 (由处理器)隐式地调用中断处理程序任务。 隐式地调用异常处理程序任务。 EFLAGS 寄存器的NT 标志置位时的任务返回(由IRET 指令发出)。所有这些调度方法都是用指向任务门或任务TSS 的段选择子来识别被调度的任务的。当用CALL 或JMP 指令调度任务时,指令中的选择子可以直接指向TSS,也可以指向包含TSS 选择子的任务门。通过调度任务来处理中断或异常时,相应中断或异常对应的IDT 项必须包含一个任务门,门中含有指向中断或异常处理程序任务
阅读全文
摘要:当处理器执行一个对异常或中断处理例程的调用时:如果将要执行的处理例程特权级数值较小,就进行栈切换。当栈切换发生时:a.处理程序使用的栈的段选择子和栈指针是从当前运行任务的TSS 中获取的。处理器把被中断例程的栈段选择子和栈指针压入新的栈中。b.处理器随后把EFLAGS 寄存器、CS 寄存器、EIP 寄存器的当前值保存进新栈中c.如果异常同时产生了一个错误码,则把它压入栈中,位于EIP 之后。如果将要执行的处理例程与被中断的例程特权级相同:a.处理器在当前栈中保存当前EFLAGS 寄存器、CS 寄存器和EIP 寄存器的值 b.如果异常的错误码也保存在那里,则把它保存在当前栈的EIP 值之后。
阅读全文
摘要:程序的运行从boot-->loader-->kernel这整个过程中代码都运行在特权级0(最高特权级),进程工作的特权级1(即低特权级),当然这是出于安全性的考虑,如果不考虑安全性,进程完全可以工作在特权级0.1. 第一个问题,要从高特权级向低特权级转变,怎么转变呢?这里用到一个人工模拟的中断返回(iretd),这里有个小疑问根据我的了解,iret和iretd都可以表示中断返回,书中是用的iretd,不知道为什么,当然这并不影响我们对全局的了解,嗯,继续,首先我们要把将要运行在特权级1上的进程所需的寄存器准备好,这个准备好怎么理解呢,具体来说,cs中保存的是将要从ring0跳转到r
阅读全文
摘要:很短,但是感觉有必要把它记下来今天无意中看到一篇日志,http://www.ruanyifeng.com/blog/2013/02/booting.html,上面有句话让我有点感悟,“计算机启动是一个很矛盾的过程:必须先运行程序,然后计算机才能启动,但是计算机不启动就无法运行程序!……必须想尽各种办法,把一小段程序装进内存……”在<<自己动手写操作系统>>中是有那么一段程序,需要把程序的入口地址处的一段代码直接复制到内存的某一位置,然后让程序从该位置开始执行,但不是这篇文章所说的boot,而是loader,我想这应该是某种习惯吧,也不知道对不对,望大家指正
阅读全文
摘要:转自:http://www.cnblogs.com/wanghj-dz/archive/2011/05/14/2046210.html分析的很好; InitKernel ---------------------------------------------------------------------------------bochs断点:0x000905ba; 将 KERNEL.BIN 的内容经过整理对齐后放到新的位置; 遍历每一个 Program Header,根据 Program Header 中的信息来确定把什么放进内存,放到什么位置,以及放多少。; --------------
阅读全文
摘要:自己动手写操作系统中免不了要写软盘镜像,刚开始就知道一个dd命令,但是不好用啊找了半天资料,终于算是知道怎么回事了首先,可以使用本书自带的工具(汗,一直没有注意)还可以下一个winimage,这是个好使的东西,首先你要新建一个软盘,一般是1.44M,然后写引导扇区,即把自己的boot.bin写进去(有一个引导扇区属性),然后才是添加文件,把loader.bin 和kernel.bin都添加进去,你会发现,当查看软盘镜像文件的时候你找不到boot.bin
阅读全文
摘要:甚是蛋疼参考:1首先从这里下载源码(这东西可是有20+MB,慢慢下载喔) 下面详细说一下操作方法: 1 解压insight-6-8-1 sudo tar jvxf insight-6-8-1.tar.bz2 2 修改源代码,然后进入insight-6-8-1/gdb cd insight-6-8-1/gdb sudo gedit i386-linux-nat.c 在头文件部分加上: #include "i387-tdep.h" 保存,退出 3.从新回到 insight 目录,生成Makefile cd .. sudo ./configure() 4 开始编译 sud...
阅读全文
摘要:跟上篇日志中间又隔了好几天,懒惰啊 1 寻找LOADER.BIN文件的大体思路为: 2 LOADER.BIN文件存储在A盘中,我们知道A盘的格式是FAT12格式,具体格式见书本P103,其主要是有引导扇区 3 、FAT1区、FAT2区、根目录区(长度不固定,需要计算)和 数据区组成。引导扇区放的就是我们写的引导代码 4 boot.bin文件,我们的LOADER.BIN文件是放在数据区中的,而文件的文件名是放在根目录中,因此,如果我 5 们想查看该盘是否含有我们想要的文件时,我们应该先到根目录中查看是否含有该文件名,如果有,说明该盘存 6 在该文件,那么下面可以从盘中读取该文件了。 7 文件在盘
阅读全文
摘要:操作步骤,虽然很简单,但是以后要经常用,还是写下笔记吧首先用bximage创建一个1.44M软盘。然后把写好的boot.bin文件写入到软盘的引导扇区具体命令:dd if=boot.bin of=a.img bs=512 count=1然后是写一个配置文件,然后运行,在linux下可以写一个脚本脚本代码是:#!/bin/shbochs -q -f bochsrc.bxrc
阅读全文
摘要:稍微写了下注释 1 ; ========================================== 2 ; pmtest8.asm 3 ; 编译方法:nasm pmtest8.asm -o pmtest8.com 4 ; ========================================== 5 6 %include "pm.inc" ; 常量, 宏, 以及一些说明 7 8 PageDirBase0 equ 200000h ; 页目录开始地址: 2M 9 PageTblBase0 equ ...
阅读全文
摘要:先说下我配的环境,msdos622,vpc2007,当我在执行pmtest7的时候,崩溃,无法执行,在此之后,我又通过bochs配置了环境,可以调试.com程序(见上一篇博客),调试了良久(不太会调试,bochs有些调试还是不会)模模糊糊知道是哪错了,我在下面帖出来,还请高手指正 1 ; ========================================== 2 ; pmtest7.asm 3 ; 编译方法:nasm pmtest7.asm -o pmtest7.com 4 ; ========================================== 5 ...
阅读全文
摘要:1.自己下载一个bochs的安装包,我装的是windows版本的,里面自带的有一个bochsdbg.exe的软件,就是用他来调试我们的保护模式程序2.在oldlinux里面有赵老师提供的一个PMode-FreeDOS-041214.zip包,里面包含着有一个已经编译好了的dos系统,系统里面含有debug.exe的调试工具,软件包里面可能还有其他的东东,但是我暂时还没用到,所以也不是很清楚...3.把你编译好的保护模式的汇编源码文件拷贝到软盘映像里面去,然后创建一个run.bat的批处理文件<"C:\Program Files\Bochs-2.2.1\bochsdbg"
阅读全文