随笔分类 -  自己动手写操作系统

操作系统
为什么dos下的com文件都要org 0100h呢?为什么系统启动时要org 07c00h呢
摘要:这是因为.com 载入内存后的起始偏址就是100h. 前面的100h字节是该程序的PSP 部分. 所以,为了程序中对地址引用的正确, 必需加上org 100h语句。-------------------------------------------------------------------------------------------------------------------------------------------------FFFF0h与07C00h,这两个都是机器启动后默认访问的内存地址。曾经让我一度很晕,搞不清他们之间的关系。现在终于搞明白了,写到博客司上与大家分 阅读全文

posted @ 2011-05-12 10:02 wanghj_dz 阅读(2394) 评论(1) 推荐(0)

第四章 boot.asm代码详解
摘要:第四章 boot.asm 代码详解;%define _BOOT_DEBUG %ifdef _BOOT_DEBUG org 0100h %else org 07c00h %endif这段代码的意思是,如果定义了_BOOT_DEBUG 则 org 0100h,如果没有定义则 org 07c00h如果把;%define _BOOT_DEBUG前面的;去掉则该语句执行,_BOOT_DEBUG定义了。如果加上;则被注释掉了,_BOOT_DEBUG没有定义。--------------------------------------------------------------------------- 阅读全文

posted @ 2011-05-11 17:04 wanghj_dz 阅读(2062) 评论(0) 推荐(0)

突破512K字节限制
摘要:512B是软盘第一扇区的大小,称为引导扇区。系统要进入保护模式,512B是不够用的。所以在软盘的其他地方存放一个文件,通过512B的引导扇区,加载到内存,并把控制权交给该它。一个操作系统从开机到开始运行,大致经历“引导---加载内核入内存--跳入保护模式---开始执行内核”这样一个过程。也就是说在内核开始执行之前不但要加载内核,还要准备保护模式等一系列工作,如果全部交给引导扇区来做,512B很可能不够用所以不妨把这个过程交给另外的模块来完成,我们把这个模块叫做Loader。引导扇区负责把Loader加载入内存并且把控制权交给它。其他工作放心地交给Loader来做。整理一下这一章的思路。目的是突 阅读全文

posted @ 2011-05-11 08:41 wanghj_dz 阅读(1093) 评论(0) 推荐(0)

中断门和陷阱门的区别
摘要:对于中断门,在转移过程中把IF置为0,使得在处理程序执行期间屏蔽掉INTR中断(当然,在中断处理程序中可以人为设置IF标志打开中断,以使得在处理程序执行期间允许响应可屏蔽中断);对于陷阱门,在转移过程中保持IF位不变,即如果IF位原来是1,那么通过陷阱门转移到处理程序之后仍允许INTR中断。因此,中断门最适宜于处理中断,而陷阱门适宜于处理异常。 阅读全文

posted @ 2011-05-10 22:14 wanghj_dz 阅读(530) 评论(0) 推荐(0)

中断与异常 代码 总结
摘要:ICW (Initialization Command Word)初始化命令字。主8259A对应的端口地址是20A和21A从8259A对应的端口地址是A0h和A1h。初始化过程:1、往端口20h(主片)或A0h(从片)写入ICW12、往端口21h(主片)或A1h(从片)写入ICW23、往端口21h(主片)或A1h(从片)写入ICW34、往端口21h(主片)或A1h(从片)写入ICW4这4步的顺序是不能颠倒的。ICW1负责启动8259A和进行初始化工作ICW2中断类型号的设置ICW3主从片初始化设置ICW4方式控制设置Init8259A: mov al,011h out 020h,al ;主82 阅读全文

posted @ 2011-05-10 20:18 wanghj_dz 阅读(1057) 评论(0) 推荐(0)

对8259中断控制器
摘要:补充知识:对8259中断控制器的说明23. 8259A的编程因为8259A是可编程的中断控制器,所以它的操作是用软件通过命令进行控制的。8259A的编程命令字有两类:一是初始化命令字(ICW),二是操作命令字(OCW)。相应的8259A的控制部分有一些可编程的位,它们分布在7个8位寄存器中。这些寄存器分成两组,一组用作存ICW,另一组存OCW。当计算机刚开机时,用初始化程序设定ICW,即由CPU按次序发送2~4个不同格式的ICW,用来建立起8259A操作的初始状态,此后的整个工作过程中该状态保持不变。相反操作命令字(OCW)用于动态控制中断处理,是在需要改变或控制8259A操作时发送的。注意: 阅读全文

posted @ 2011-05-10 13:42 wanghj_dz 阅读(1757) 评论(0) 推荐(0)

中断与异常机制
摘要:我们在说到中断通常将它与异常相提并论,实际上它们都是程序执行过程中强制性转移,转移到相应的处理程序。中断通常在程序执行时因为硬件而随机产生,他们通常用来处理处理器外部的事件。异常则通常在处理器执行指令过程中检测到错误时发生,比如遇到零除的情况。处理器检测的错误条件有很多,比如保护违例、页错误等。假设处理器可以处理A、B、C三种中断(异常),分别进行a,b,c三种处理,我们得有一种方法把A、B、C与a、b、c对用起来,实际上解决这个问题的方法就是我们前面提到的中断向量。每一种中断和异常都会对应一个中断向量号,而这个向量号通过IDT就与相应的中断处理程序对应起来。Fault,Trap和Abort是 阅读全文

posted @ 2011-05-10 08:57 wanghj_dz 阅读(639) 评论(0) 推荐(0)

(Pmtest8.asm总结)PagingDemoProc 注意这个这个程序段使用的是LinearAddrDemo线性地址。分页后线性地址要转换
摘要:PagingDemoProc:OffsetPagingDemoProcequPagingDemoProc - $$moveax, LinearAddrDemo ;LinearAddrDemo equ 00401000h ,ProcFoo equ 00401000hcalleax ;跳到foo处执行代码retfLenPagingDemoAllequ$ - PagingDemoProc设计一个Flat段,尽管他的基址为0,这样做的好处是逻辑很清楚,只要用到这个段名,他们涉及到的代码和数据就都在这个段里。这样逻辑就不会混乱。moveax, LinearAddrDemo ;LinearAddrDemo 阅读全文

posted @ 2011-05-09 17:06 wanghj_dz 阅读(440) 评论(0) 推荐(0)

自己动手写操作系统P121 对SelectorFlatRW和SelectorFlatC的描述
摘要:事实上,在pmtest7.asm中我们用两个段分别存放页目录表和页表(LABEL_DESC_PAGE_DIR存放页目录表,LABEL_DESC_PAGE_TBL存放页表)是为了让读者阅读时更加直观和形象。在pmtest8.asm中,我们把它们放到同一个段中,同时把增加的一套页目录和页表也放到这个段中。为了操作方便,我们新增加一个段FLAT,其线性地址空间为0-4GB。由于分页机制启动之前线性地址等同与物理地址,所以通过这个段可以方便地存取特定的物理地址。此段的定义如下:LABEL_DESC_FLAT_C: Descriptor 0,0fffffh,DA_CR|DA_32|DA_LIMIT_4K 阅读全文

posted @ 2011-05-09 15:04 wanghj_dz 阅读(472) 评论(0) 推荐(0)

pmtest8.asm 全
摘要:; ==========================================; pmtest8.asm; 编译方法:nasm pmtest8.asm -o pmtest8.com; ==========================================%include"pm.inc"; 常量, 宏, 以及一些说明PageDirBase0equ200000h; 页目录开始地址:2MPageTblBase0equ201000h; 页表开始地址:2M + 4KPageDirBase1equ210000h; 页目录开始地址:2M + 64KPageTblB 阅读全文

posted @ 2011-05-09 14:25 wanghj_dz 阅读(590) 评论(0) 推荐(0)

pmtest8.asm中的PSwitch代码的理解
摘要:; 切换页表 ------------------------------------------------------------------PSwitch:; 初始化页目录movax, SelectorFlatRWmoves, axmovedi, PageDirBase1; 此段首地址为 PageDirBase1 ,PageDirBase1 equ210000h; xoreax, eaxmoveax, PageTblBase1 | PG_P | PG_USU | PG_RWW movecx, [PageTableNumber].1:stosdaddeax, 4096; 为了简化, 所有页 阅读全文

posted @ 2011-05-09 11:10 wanghj_dz 阅读(1154) 评论(0) 推荐(2)

pmtest8.asm中对PagingDemo程序段的理解
摘要:; 测试分页机制 --------------------------------------------------------------PagingDemo:movax, csmovds, axmovax, SelectorFlatRW ;这应该是selectorFlatRW所对应的段描述符的首地址,参见pmtest7.asmmoves, axpushLenFoo ;0x0000001c sp:0x000001f7pushOffsetFoo ;0x000001a0 sp:0x000001f3pushProcFoo ;ProcFoo equ00401000h sp:0x000001efca 阅读全文

posted @ 2011-05-09 10:06 wanghj_dz 阅读(468) 评论(0) 推荐(0)

pmtest8.asm中lib.inc中MemCpy代码的理解
摘要:PagingDemo:movax, csmovds, axmovax, SelectorFlatRW ;这应该是selectorFlatRW所对应的段描述符的首地址,参见pmtest7.asmmoves, axpushLenFoo;0x0000001c sp:0x000001f7pushOffsetFoo ;0x000001a0 sp:0x000001f3pushProcFoo ;ProcFoo equ00401000h sp:0x000001efcallMemCpy;前面几个push是MemCpy的参数,sp:0x000001eb,call会由系统自动压入参数,所以前面的sp要加4。;这段c 阅读全文

posted @ 2011-05-09 10:04 wanghj_dz 阅读(578) 评论(0) 推荐(0)

pmtest7.asm中 SetupPaging 启动分页代码,根据内存确定页表数。
摘要:SetupPaging:; 根据内存大小计算应初始化多少PDE以及多少页表xoredx, edxmoveax, [dwMemSize]movebx, 400000h; 400000h = 4M = 4096 * 1024, 一个页表对应的内存大小divebxmovecx, eax;此时 ecx 为页表的个数,也即 PDE 应该的个数testedx, edxjz.no_remainderincecx; 如果余数不为 0 就需增加一个页表.no_remainder:pushecx;暂存页表个数; 为简化处理, 所有线性地址对应相等的物理地址. 并且不考虑内存空洞.; 首先初始化页目录movax, 阅读全文

posted @ 2011-05-08 09:04 wanghj_dz 阅读(398) 评论(0) 推荐(0)

LODS,LODSB,LODSW,LODSD 和 STOS,STOSB,STOSW,STOSD 的作用
摘要:LODS,LODSB,LODSW,LODSD 和 STOS,STOSB,STOSW,STOSD 的作用 LODSB LODSW LODSD 将字符串装入累加器(Load Accumulator from string) 将由DS:E(SI)寻址的一个内存字节或字装入累加器(AL, AX 或 EAX)中,如果使用LODS,必须 指定内存操作数.LODSB将一个字节装入AL,LODSW将一个字装入AX.IA-32处理器的LODSD将一 个双字装入EAX.(E)SI根据操作数大小和方向标志值自动增减.如果方向标志(DF)=1,ESI增 加,如果DF=0,ESI减少 摘自INTEL汇编语言程序设计(第 阅读全文

posted @ 2011-05-07 22:19 wanghj_dz 阅读(1364) 评论(0) 推荐(0)

pmtest7.asm中 DispMemSize:代码的解释
摘要:DispMemSize:push esipush edipush ecxmov esi,MemChkBuf//esi=7amov ecx,[dwMCRNumber]; for(inti=0;i<[MCRNumber];i++)//每次得到一个ARDS ecx=6 ,.loop: ; {mov edx,5 ; for(intj=0;j<5;j++)//每次得到一个ARDS中的成员edx=5 mov edi,ARDStruct ;{//依次显示BaseAddrLow,BaseAddrHigh,LengthLow,LengthHigh,Type.1: ;push dword[esi] ; 阅读全文

posted @ 2011-05-05 22:03 wanghj_dz 阅读(420) 评论(0) 推荐(0)

pmtest7.asm中 DispInt (显示一个整数型)的代码解释,DispAL代码的解释
摘要:push dword[esi] ; //push [ds:0x7a],为0x00000000,注意这是指第一次压入堆栈的情况call DispInt //call指令会自动调用堆栈,esp会减4-------------------------------------------------------------------------------------;;显示一个整形数DispInt:mov eax,[esp+4]//注意这里esp+4是因为调入之前的call指令,因为call指令会自动把一些参数入栈,esp要减4,esp+4正好指向了第一次push进去的 0x00000000shr 阅读全文

posted @ 2011-05-05 21:56 wanghj_dz 阅读(624) 评论(0) 推荐(0)

通过一段汇编,加深对寄存器ESP和EBP的理解
摘要:一直对寄存器ESP和EBP的概念总是有些混淆,查看定义ESP是栈顶指针,EBP是存取堆栈指针。还是不能很透彻理解。之后借于一段汇编代码,总算是对两者有个比较清晰的理解。下面是按调用约定__stdcall 调用函数test(int p1,int p2)的汇编代码;假设执行函数前堆栈指针ESP为NNpush p2 ;参数2入栈, ESP -= 4h , ESP = NN - 4hpush p1 ;参数1入栈, ESP -= 4h , ESP = NN - 8hcall test ;压入返回地址 ESP -= 4h, ESP = NN - 0Ch ;//进入函数内{push ebp ;保护先前EBP 阅读全文

posted @ 2011-05-05 09:21 wanghj_dz 阅读(1167) 评论(0) 推荐(0)

pmtest7.asm中DispStr代码的解释,DispReturn代码的解释
摘要:DispStr:push ebp //ebp作为存取堆栈指针(存取堆栈中内容时所用到的指针),esp栈顶指针mov ebp,esp //ebp指向堆栈栈顶push ebx //以后要用到bl,所以要压栈先保护起来push esi //源指针push edi //目标指针 执行到这儿时ebp,esp的值已经不一样了。esp因为又压了三次所以加了12,ebp还是原来的ebp,push ebp后的堆栈指针mov esi,[ebp+8] ;pszInfo //跳进来之前push szPMMessage esp-4,push ebp 后esp又-4,esp赋给ebp 所以ebp加8正好指向szPMMes 阅读全文

posted @ 2011-05-04 22:43 wanghj_dz 阅读(976) 评论(0) 推荐(0)

在linux下制作img文件,windows下使用nasm
摘要:我是先用bximage创建floppy a.img,然后 [root@localhost bochs-2.2.6]# dd if=/root/asm/a/boot.bin of=/usr/local/src/bochs-2.2.6/a.img bs=512 count=1 注意修改boot: floppy [root@localhost bochs-2.2.6]# bochs ... ... 在Bochs屏幕看到Hello World! 自己研究的方法:把书中自带的pm.img用ultralISO软件打开,在linux中用nasm编译成能回到bochs的文件,然后ftp到windows,放到u 阅读全文

posted @ 2011-05-03 16:35 wanghj_dz 阅读(1556) 评论(0) 推荐(0)

导航