自己动手写操作系统 第四章总结


自己动手写操作系统 第四章总结

本章主要内容是建立一个功能比较完善的引导扇区也称为 boot sector

首先回顾一下一个操作系统从开机到运行的过程

1.引导
2.加载内核入内存
3.跳入保护模式
4.开始执行内核

可见在内核开始执行前还有很多工作要做,如果全部交给boot sector,512字节很可能不够用,所以我们需要将这个
功能分担出来,这个模块就是loader

现在,boot sector 的功能就是负责把loader加载到内存中,并且把控制权交给它,到此,boot sector就完成任务了
而加载内核的功能就交给了loader
现在再来看看运行过程
1.boot sector引导加载loader程序,并将控制权交给loader
2.loader把内核加载到内存中,并负责进入保护模式(要实现分页等功能),然后将控制权交给内核
3.内核进行接下来的操作


在第四章中我们主要的任务是写一个boot sector,让他来加载loader
同时学习软盘的fat12格式

先大体对程序流程有一个认识
1.首先我们需要一个写一个DOS可以识别的引导盘,注意引导扇区需要有BPB等头信息才能被微软DOS识别,所以加上它
然后通过jmp short LABEL_START:让我们开始执行引导扇区,这里有一个问题需要注意,为什么我们的引导扇区是写在floppy上的,而我们的计算机是怎么能运行它呢?这程序肯定是在内存中的,那么它是什么时候被加载到内存中的呢?
解答,在计算机加电后BIOS回查看软盘的第一个扇区的最后两个字节是不是0xaa55,如果是的话,就认为这个扇区是可引导的,然后将这512字节的内容加载到内存中的07c00h中,然后开始运行,所以我们的boot sector是不需要我们手动进行加载到内存中的,但是我们的loader.bin和kernel却不行,他们只能以文件形式存在软盘的数据区然后我们需要在boot sector中加载loader.bin到内存中,然后将控制权交给它,接着通过loader.bin将kernel加载到内存中,然后将控制权交给内核
2.将loader加载到内存中,这里我们需要用到BIOS的int 13h中断来读取软盘,也就是将软盘数据区的内容加载到内存中来,这个内存是预先设定好的,并要记住这个内存位置,因为当我们将loader从软盘数据区加载到内存中后我们需要jmp到这个位置以便将控制权交给它

这里我们将读取软盘的工作交给一个叫readsector的函数,它接受两个参数,扇区逻辑号,和要读取的扇区数目,要注意的问题是我们里给出的是扇区的逻辑号,但是用int 13h中断需要确切的物理位置,所以在函数中我们要进行这个转换才行
需要注意的地方就是如何将逻辑扇区号转换成可供int 13h调用的物理软盘位置,以及int 13h的调用方法,以及loader将要存储的内存位置

3.当然,要读取loader的内容到内存中,首先最重要的就是在软盘中找到loader的位置才行,否则从哪里将数据转移到内存中,这里需要注意的地方有以下几点
1.如何着手寻找?首先需要了解软盘的结构,包括,boot sector , fat1 表,fat2表,根目录,数据区
2.那么如何下手呢?首先,我们要知道所有数据区的文件的文件名都是在根目录的条目中,这个32位的条目中存放了关于这个文件的各种信息,详见p128,其中现在最重要的就是文件名(条目中的前11个字节,8字节的文件名,3字节的扩展名),以及接下来连续读取的时候需要用到的32字节中偏移0x1Ah处存放的两字节的这个文件的其实簇号(这个簇号与扇区类似,但是又不是一样的,而是有一一对应的映射关系),现在在寻找loader的步骤中我们需要的就是文件名,我们要遍历软盘的根目录区中的每一个条目中的前11字节,看看是不是和我们预先设定号的loader的文件名完全一致(比如loader.bin)
如果一致,那么记住这个根目录中的条目,因为接下来我们要用到这个条目中的之前说的偏移0x1Ah处的文件第一个簇号(通过这个簇号我们可以找到第一个扇区,因为他们是一一对应的),在这个遍历中我们需要三个嵌套循环,第一个是根目录占用的扇区总数,这里是19,所以要遍历19次,它的作用是每次循环将一个扇区取出来存到一个暂时存放扇区的地方,然后下面的循环对这个扇区进行遍历操作,这个循环中嵌套一个循环,这个第二级循环的作用是遍历一个扇区中的每一个条目(512/32次),接下来这个循环又嵌套一个循环,这个第三级循环的作用是遍历这一个条目的前11个字符,判断是不是和我们要找的文件名完全一致,若一致,则跳出循环进行下一个操作,否则将一直遍历(最多19 * (512 / 32) * 11次),若没找到则提示找不到loader
3.若我们在第二步中找到了loader,我们就要对这个根目录条目进行操作了(32位),我们首先确定这个目录的起始位置,然后找到这个目录的偏移1Ah处,这里有最重要的簇号,通过它我们就能找到所有的loader占用的扇区,并将他们加载到一个连续的内存区域,加载完成后就jmp到这个内存地址
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
本书在详细分析操作系统原理的基础上,用丰富的实例代码,一步一步地指导读者用C语言和汇编语言编出一个具备操作系统基本功能的操作系统框架。本书不同于其他的理论型书籍,而是提供给读者一个动手实践的路线图。书中讲解了大量在开发操作系统中需注意的细节问题,这些细节不仅能使读者更深刻地认识操作系统的核心原理,而且使整个开发过程少走弯路。全书共分7章。 本书适合各类程序员、程序开发爱好者阅读,也可作为高等院校操作系统课程的实践参考书。 折叠 作品目录 第1章 马上动手一个最小的"操作系统"1 1.1 准备工作1 1.2 10分钟完成的操作系统1 1.3 Boot Sector3 1.4 代码解释3 1.5 水面下的冰山5 1.6 回顾6 第2章 搭建你的工作环境7 2.1 虚拟计算机(Virtual PC)7 2.1.1 Virtual PC初体验8 2.1.2 创建你的第一个Virtual PC9 2.1.3 虚拟软盘研究12 2.1.4 虚拟软盘实战14 2.2 编译器(NASM & GCC)18 2.3 安装虚拟Linux19 2.4 在虚拟Linux上访问Windows文件夹26 2.5 安装虚拟PCDOS26 2.6 其他要素29 2.7 Bochs29 2.7.1 Bochs vs. Virtual PC vs. VMware30 2.7.2 Bochs的使用方法31 2.7.3 用Bochs进行调试33 2.7.4 在Linux上开发34 2.8 总结与回顾36 第3章 保护模式(Protect Mode)37 3.1 认识保护模式37 3.1.1 GDT(Global Descriptor Table) 42 3.1.2 实模式到保护模式,不一般的jmp45 3.1.3 描述符属性47 3.2 保护模式进阶50 3.2.1 海阔凭鱼跃50 3.2.2 LDT(Local Descriptor Table)58 3.2.3 特权级62 3.3 页式存储82 3.3.1 分页机制概述83 3.3.2 编代码启动分页机制84 3.3.3 PDE和PTE85 3.3.4 cr388 3.3.5 回头看代码88 3.3.6 克勤克俭用内存90 3.3.7 进一步体会分页机制100 3.4 中断和异常107 3.4.1 中断和异常机制109 3.4.2 外部中断111 3.4.3 编程操作8259A113 3.4.4 建立IDT116 3.4.5 实现一个中断117 3.4.6 时钟中断试验119 3.4.7 几点额外说明121 3.5 保护模式下的I/O122 3.5.1 IOPL122 3.5.2 I/O许可位图(I/O Permission Bitmap)123 3.6 保护模式小结123 第4章 让操作系统走进保护模式125 4.1 突破512字节的限制125 4.1.1 FAT12126 4.1.2 DOS可以识别的引导盘131 4.1.3 一个最简单的Loader132 4.1.4 加载Loader入内存133 4.1.5 向Loader交出控制权142 4.1.6 整理boot.asm142 4.2 保护模式下的"操作系统"144 第5章 内核雏形146 5.1 用NASM在Linux下Hello World146 5.2 再进一步,汇编和C同步使用148 5.3 ELF(Executable and Linkable Format)150 5.4 从Loader到内核155 5.4.1 用Loader加载ELF155 5.4.2 跳入保护模式161 5.4.3 重新放置内核170 5.4.4 向内核交出控制权175 5.4.5 操作系统的调试方法176 5.5 扩充内核184 5.5.1 切换堆栈和GDT184 5.5.2 整理我们的文件夹191 5.5.3 Makefile191 5.5.4 添加中断处理200 5.5.5 两点说明218 5.6 小结219 第6章 进程221 6.1 迟到的进程221 6.2 概述222 6.2.1 进程介绍222 6.2.2 未雨绸缪--形成进程的必要考虑222 6.2.3 参考的代码224 6.3 最简单的进程224 6.3.1 简单进程的关键技术预测225 6.3.2 第一步--ring0→ring1227 6.3.3 第二步--丰富中断处理程序243 6.3.4 进程体设计技巧254 6.4 多进程256 6.4.1 添加一个进程体256 6.4.2 相关的变量和宏257 6.4.3 进程表初始化代码扩充258 6.4.4 LDT260 6.4.5 修改中断处理程序261 6.4.6 添加一个任务的步骤总结263 6.4.7 号外:Minix的中断处理265 6.4.8 代码回顾与整理269 6.5 系统调用280 6.5.1 实现一个简单的系统调用280 6.5.2 get_ticks的应用286 6.6 进程调度292 6.6.1 避免对称--进程的节奏感292 6.6.2 优先级调度总结300 第7章 输入/输出系统302 7.1 键盘302 7.1.1 从中断开始--键盘初体验302 7.1.2 AT、PS/2键盘304 7.1.3 键盘敲击的过程304 7.1.4 解析扫描码309 7.2 显示器325 7.2.1 初识TTY325 7.2.2 基本概念326 7.2.3 寄存器328 7.3 TTY任务332 7.3.1 TTY任务框架的搭建334 7.3.2 多控制台340 7.3.3 完善键盘处理346 7.3.4 TTY任务总结354 7.4 区分任务和用户进程354 7.5 printf357 7.5.1 为进程指定TTY357 7.5.2 printf()的实现358 7.5.3 系统调用write()361 7.5.4 使用printf()363 后记366
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值