摘要: 先来看一个简单的Makefile,我们把它放在目录/boot下,可以用来编译boot.bin和loader.bin。 以字符#开头的行是注释。=用来定义变量,这里的ASM和ASMFLAGS就是两个变量,要注意的是,使用它们的时候要用$(ASM)和$(ASMFLAGS),而不是它们的原型。 .PHON 阅读全文
posted @ 2016-04-20 19:54 是非猫 阅读(428) 评论(0) 推荐(0) 编辑
摘要: 现在把esp、GDT等内容放进内核中,我们现在可以用C语言了,只要能用C,我们就避免用汇编。 下面看切换堆栈和GDT的关键代码: 最后这4个语句完成了切换堆栈和更换GDT的任务。StackTop定义在.bss段中,堆栈大小为2KB。 函数首先把位于Loader中的原GDT全部复制给新的GDT,然后把 阅读全文
posted @ 2016-04-20 17:51 是非猫 阅读(541) 评论(0) 推荐(0) 编辑
摘要: 【版权所有,转载请注明出处。出处:http://www.cnblogs.com/joey-hua/p/5402599.html 】 此方案的目的是隐藏源码防止直接性的反编译查看源码,原理是加密编译好的最终源码文件(dex),然后在一个新项目中用新项目的application启动来解密原项目代码并加载 阅读全文
posted @ 2016-04-19 10:11 是非猫 阅读(4643) 评论(7) 推荐(1) 编辑
摘要: 实际上,我们要做的工作是根据内核的Program header table的信息进行类似下面这个C语言语句的内存复制: memcpy(p_vaddr, BaseOfLoaderPhyAddr+p_offset, p_filesz); 复制可能不止一次,如果Program header有n个,复制就进 阅读全文
posted @ 2016-04-17 18:47 是非猫 阅读(1885) 评论(0) 推荐(0) 编辑
摘要: 现在,内核已经被我们加载进内存了,该是跳入保护模式的时候了。 首先是GDT以及对应的选择子,我们只定义三个描述符,分别是一个0~4GB的可执行段、一个0~4GB的可读写段和一个指向显存开始地址的段: 在之前学习保护模式时,大部分描述符的段基址都是运行时计算后填入相应位置的,因为那时我们的程序是由BI 阅读全文
posted @ 2016-04-17 14:50 是非猫 阅读(648) 评论(0) 推荐(0) 编辑
摘要: Loader要做两项工作,我们先来做第一项,把内核加载到内存: 1.加载内核到内存。 2.跳入保护模式。 首先编译无内核时: nasm boot.asm -o boot.bin nasm loader.asm -o loader.bin dd if=boot.bin of=a.img bs=512 阅读全文
posted @ 2016-04-17 12:50 是非猫 阅读(540) 评论(0) 推荐(0) 编辑
摘要: ELF文件的结构如下图所示: ELF文件由4部分组成,分别是ELF头(ELF header)、程序头表(Program header table)、节(Sections)和节头表(Section header table)。 实际上,一个文件中不一定包含全部这些内容,而且它们的位置也未必如上图所示这 阅读全文
posted @ 2016-04-16 00:02 是非猫 阅读(1175) 评论(0) 推荐(0) 编辑
摘要: a.我们先来体验一下在Linux下用汇编编程的感觉,见代码 编译方法: nasm -f elf hello.asm -o hello.o ld -m elf_i386 -s -o hello hello.o ./hello 运行结果是打印出Hello, world! 入口点默认的是_start,我们 阅读全文
posted @ 2016-04-15 17:38 是非猫 阅读(690) 评论(0) 推荐(0) 编辑
摘要: 一个操作系统从开机到开始运行,大致经历“引导—>加载内核入内存—>跳入保护模式—>开始执行内核”这样一个过程。也就是说,在内核开始执行之前不但要加载内核,而且还有准备保护模式等一系列工作,如果全都交给引导扇区来做,512字节很可能是不够用的,所以不妨把这个过程交给另外的模块来完成,我们把这个模块叫做 阅读全文
posted @ 2016-04-14 19:31 是非猫 阅读(863) 评论(0) 推荐(0) 编辑
摘要: 外部中断的情况复杂一些,因为需要建立硬件中断与向量号之间的对应关系。外部中断分为不可屏蔽中断(NMI)和可屏蔽中断两种,分别由CPU的两根引脚NMI和INTR来接收。如下图所示: 可屏蔽中断与CPU的关系是通过对可编程中断控制器8259A建立起来的。8259A可以认为它是中断机制中所有外围设备的一个 阅读全文
posted @ 2016-04-13 19:05 是非猫 阅读(7255) 评论(0) 推荐(2) 编辑
摘要: a.概述 中断门和陷阱门的作用机理几乎是一样的,只不过使用调用门时使用call指令,而这里我们使用int指令。中断门和陷阱门的结构如下图: TYPE的4位将变为0xE(中断门)或0xF(陷阱门)。 指令int n产生中断时的情形如下图所示,n即为向量号,它类似于调用门的使用。 b.建立IDT 每个描 阅读全文
posted @ 2016-04-13 18:25 是非猫 阅读(890) 评论(0) 推荐(0) 编辑
摘要: a.概述 页尺寸是4KB,页表每个表项占4字节,CR3寄存器给出了页目录的物理基地址;页目录给出了所有页表的物理地址,而每个页表给出了它所包含的页的物理地址。 处理器的页部件专门负责线性地址到物理地址的转换工作。它首先将段部件送来的32位线性地址截成3段,分别是高10位、中间的10位和低12位。高1 阅读全文
posted @ 2016-04-12 16:21 是非猫 阅读(1386) 评论(0) 推荐(0) 编辑
摘要: CPL——当前执行的程序或任务的特权级,它被存储在cs和ss的第0位和第1位上。 DPL——段或者门的特权级,如果是数据段DPL则规定了可以访问此段的最低特权级 RPL——通过段选择子的第0位和第1位表现出来的。处理器通过检查RPL和CPL来确认一个访问请求是否合法。RPL保证了操作系统不会越俎代庖 阅读全文
posted @ 2016-04-11 12:07 是非猫 阅读(914) 评论(0) 推荐(0) 编辑
摘要: 一直以来,我们把所有的段描述符都放在GDT中,而不管它属于内核还是用户程序,为了有效地在任务之间实施隔离,处理器建议每个任务都应当具有自己的描述符表,称为局部描述符表LDT,并且把专属于自己的那些段放到LDT中。 和GDT一样,LDT也是用来存放描述符的。不同之处在于,LDT只属于某个任务。或者说, 阅读全文
posted @ 2016-04-09 22:30 是非猫 阅读(1722) 评论(0) 推荐(0) 编辑
摘要: 在上一篇中我们虽然成功进入了保护模式,但是并没有体验到保护模式带给我们的便利。其实在保护模式下寻址空间可以达到4GB,实模式下1MB的寻址能力差得太远了。那么下面,我们就把程序稍作修改,体验一下它对超过1MB内存的访问能力。 我们来试验一下读写大地址内存。在前面程序的基础上,新建一个段,这个段以5M 阅读全文
posted @ 2016-04-09 14:02 是非猫 阅读(712) 评论(0) 推荐(0) 编辑