BIOS 找到了这个启动区之后干嘛呢?哦,前面说过了是加载,就是把这 512 个字节的内容,一个比特都不少的全部复制到内存的 0x7c00 这个位置 。怎么复制的?当然是指令啦 。哪些指令呢?这里我只能简单说指令集中是有 in 和 out 的,用来将外设中的数据复制到内存,或者将内存中的数据复制到外设,用这两个指令,以及外设给我们提供的读取方式,就能做到这一点啦 。
启动区内容此时已经被 BIOS 程序复制到了内存的 0x7c00 这个位置,然后呢?这个其实也不难猜测,启动区的内容就是我们自己写的代码了,复制到这里之后,就开始执行呗,之后我们的程序就接管了接下来的流程,BIOS 的使命也就结束啦 。所以复制完之后,接下来应该是一个跳转指令吧!没错,正是这样,PC 寄存器的值变为 0x7c00,指令开始从这里执行 。
咦?不知道你有没有发现,我们似乎不知不觉又把之前的一句魔法语言翻译成人话了,开头我们说:
BIOS 把控制权转交给排在第一位的存储设备 。【全网最硬核解读计算机启动原理】所以这句话是什么意思呢?就是 BIOS 把启动区的 512 字节复制到内存的 0x7c00 位置,并且用一条跳转指令将 pc 寄存器的值指向 0x7c00 。你看,这不是也没多几个字嘛,就把这个问题说得明明白白,简简单单 。
哦,对了,现在似乎就剩下一个问题了,为什么非要是 0x7c00 呢?好问题,当然答案也很简单,那就是人家 BIOS 开发团队就是这样定的,之后也不好改了,不然不兼容 。为什么不好改?我们看一个简单的启动区 512 字节的代码 。(代码摘抄自《30 天自制操作系统》)
; hello-os; TAB=4ORG0x7c00;程序加载到内存的 0x7c00 这个位置;程序主体entry:MOVAX,0;初始化寄存器MOVSS,AXMOVSP,0x7c00MOVDS,AX;段寄存器初始化为 0MOVES,AXMOVSI,msgputloop:MOVAL,[SI]ADDSI,1CMPAL,0;如果遇到 0 结尾的,就跳出循环不再打印新字符JEfinMOVAH,0x0e;指定文字MOVBX,15;指定颜色INT0x10;调用 BIOS 显示字符函数JMPputloopfin:HLTJMPfinmsg:DB0x0a,0x0a;换行、换行DB"hello-os"DB0x0a;换行DB0;0 结尾RESB 0x7dfe-$;填充0到512字节DB 0x55, 0xaa;可启动设备标识
我们看第一行:ORG0x7c00
这个数字就是刚刚说的启动区加载位置,这行汇编代码简单说就表示把下面的地址统统加上 0x7c00 。正因为 BIOS 将启动区的代码加载到了这里,因此有了一个偏移量,所以所有写启动区代码的人就需要在开头写死一个这样的代码,不然全都串位了 。然后正因为所有写操作系统的,启动区的第一行汇编代码都写死了这个数字,那 BIOS 开发者最初定的这个数字就不好改了,否则它得挨个联系各个操作系统的开发厂商,说唉我这个地址改一下哈,你们跟着改改 。在公司推动另一个团队改个代码都得大费周折,想想看这样的推动得耗费多大人力 。况且即使改了,之前的代码也都不兼容了,这不得被人们骂死啊 。
再看最后一行:
DB 0x55, 0xaa
这也验证了我们之前说的这 512 字节的最后两个字节得是 0x55 0xaa,BIOS 才会认为它是一个启动区,才会去加载它,仅此而已 。回过头来说 0x7c00 这个值,它其实就是一个规定死的值,但还是会有人问,那必然有它的合理性吧 。其实,我的解释也只能说是人家规定了这个值,后人们替他们解释这个合理性,并不是说当初人家就一定是这样想的,就好比我们做语文的阅读理解题一样 。
第一个 BIOS 开发团队是 IBM PC 5150 BIOS,当时被认为的第一个操作系统是 DOS 1.0 操作系统,BIOS 团队就假设是为它服务的 。但操作系统还没出,BIOS 团队假设其操作系统需要的最小内存为 32 KB 。BIOS 希望自己所加载的启动区代码尽量靠后,这样比较“安全”,不至于过早的被其他程序覆盖掉 。可是如果仅仅留 512 字节又感觉太悬了,还有一些栈空间需要预留,那扩大到 1 KB 吧 。这样 32 KB 的末尾是 0x8000,减去 1KB(0x400),刚好等于 0x7c00 。哇塞,太精准了,这可以是一种解释方式 。
七、启动区里的代码写了啥其实写到这,我这篇文章就应该戛然而止了,因为最初的那个问题已经解决了,CPU 已经开始马不停蹄地从我们预期的位置跑起来了,万事开头难,剩下的内容,就是操作系统想怎么玩就怎么玩了 。
但我觉得还不够味,似乎还有些问题萦绕在你脑海里 。比如说这个问题:
启动区里的代码写了啥?就 512 字节就是全部操作系统内容了?这是一个好问题,512 个字节确实干不了啥,现在的操作系统怎么也得按 M 为单位算吧,512 个字节远远不够呢,那是怎么回事呢?
推荐阅读
- Centos7系统内核优化脚本
- 付解读 《App Store审核指南》更新内容发布
- 苏联核电站事故切尔诺贝利核事故 切尔诺贝利核泄漏事故原因
- 确定不了解一下Spring两大核心之一的IOC容器嘛
- 云计算核心技术Docker教程:docker-compose使用多个配置文件
- 桃核|桃核也能盘出包浆 红透的美感也会惊艳到你
- 中越战争为什么不用核弹
- 世界防治结核病日知识问答?宣传和普及结核病知识的世界结核病日
- OPPO|首发269元!OPPO Enco Air2 Pro蓝牙耳机发布:双核主动降噪
- 杨梅核是否能吃?