我们马上进入正题!
开机!
启动!
等等,我们的操作系统是怎么开始运行的呢?这个问题一定是你马上就想知道的吧!
所有计算机开机后,即打开电源,首先是BIOS的自检等等,确保每个必要的部件都能正常工作,这个过程我就不再详述了,反正与我们的工作没多大关系。BIOS在找到你的计算机可以进行启动的管道时,就将控制权转移。例如:我们现在大多数电脑都有这几种常启动途径,软盘、硬盘、U盘、网格,最常见的就是硬盘了。BIOS将硬盘或软盘的第一个扇区读取到内存地址 07C00 处,然后再将控制权转移到刚读入的代码开始,这时我们的操作系统的第一个代码开始执行。
我又有软盘又有硬盘,而且我的硬盘不止一个,每个硬盘上都有若干分区,电脑怎么判断就是引导扇区呢?首先是你的BIOS设置的启动盘顺序,如果这个盘上的第一个扇区最后两个字节为‘55 AA’,那就是你了,不管你是不是操作系统、还是病毒程序,我就认准你了,呵呵,读到内存。
* 一个扇区的字节数为 512 个字节,一个字节为8位,即表示从 0 – FF值 (十进制为 0 - 256)。
从此,这510个字节就是我们万里长城的开始了。咦~!不是512个字节吗?对啊~!最后两个不是标记不能使用嘛~!呵呵!不忘了,不能超过这个界限的!
最对这510个字节该怎么安排呢?目前只能靠它把真正的加载配置程序读到内存,而且现在是在实模式状态下,我们可以利用中断进行读取软盘或硬盘。
首先我们先确定用什么文件系统,是跟着Win走呢?还是Liunx?要不我们自己建一套文件系统吧!我是这样想的,我们先用Dos的Fat12模式,因为一开始我们先从软盘开始,从最普通的,最简单的开始,等我们有了功底了,了解并熟悉了文件系统,硬盘的文件系统就可以自己定了,好,就这么办。
有些同学可能很想立即进入代码中,但在写代码前必须了解一下操作系统方面的一些知识!
先讲讲引导过程。只有510个字节不可能完成很多工作,一般操作系统的引导过程仅加载一个加载配置程序,很多初使化工作是在加载配置程序中完成的,包括对硬件的初使化、传入保护模式、加载内核程序、加载各项驱动、加载字库等等。
加载配置程序的时候我们又碰到了一个问题:如何加载?
你可能要说了,用中断加载呗!
但我说的是,盘号我们知道了,但从这个磁盘的哪里开始呢?
你可能会想到,从引导代码后面开始嘛!就是从第2个扇区了!
我再问:加载多长的代码呢?
……
你不知道,呵呵,我也不知道,但总会知道的,不是吗?
这里就要提到文件数据保存结构,就是我们常说的Fat12,Fat16,Fat32,NTFS,这都是微软DOS和Windows所用的文件格式,还有Linux的EXT文件格式,我就不一一列举了。
这里我们先简单的讲一讲Fat12格式,其他格式用到的时候再说。
保存一个文件数据需涉及以下几个方面的数据:
目录
文件名及基本属性
文件数据
要加载文件数据先要知道数据从什么地方开始到什么地方结束,是不是连续保存的,还是间隔的保存,间隔的保存又如何加载;要知道数据从什么地方开始、文件长度是多少就要先知道文件的属性,这些数据应该保存在文件属性信息里,文件属性信息是一个固定长度的数据结构,也就是我们所你的目录项信息,这样就方便在目录区里查找,我们找到目录区就可以确定文件的属性了,文件目录区放在什么位置呢?目录区应该安排多大的空间呢?这都是我们在一开始就要考虑好的问题。
Fat12格式下的磁盘数据安排如下:
扇区号 数据内容
1 引导扇区
2-10 FAT1
11-19 FAT2,与FAT1内容一样。
20-34 目录区
34-? 数据区
第1个扇区为引导扇区(注意!所有的磁道、柱面都是从0号开始,唯有扇区是从1号开始!BIOS中断就是这么设定的,不要问我为什么?我也不知道!但为了全部统一从0编号,在编程时要注意,使用中断服务读取时扇区号要加1)。
Fat-1区,固定长度,从2-10扇区
Fat-2区(也称备份区,与Fat-1区内容一样),固定长度,从11-19扇区
目录区,基本固定,因为不同容量的磁盘,目录区的长度不一样,一般相同容量的磁盘,目录区长度一样,它的长度是可以计算出来的。
——计算公式:用FAT12数据头中的BPB_RootEntCnt即根目录文件最大数(224)* 每个文件目录项字节数(32字节Byte)/ 每扇区字节数(512字节Byte)= 14 ;
所以一般情况下FAT12格式的1.44M软盘目录区占14个扇区。
数据区,一般在这之后都属于文件数据区,也有的操作系统,会保留一部分数据区。所以1.44M软盘是从第34号扇区开始。
Fat12格式一般应用于软盘,所以不含分区信息。到后面需要时我们再讲分区信息。
在Fat12格式中FAT表每12位元表示一个簇号(0-FFF),这就是为什么叫Fat12后面12的意思,顾名思义,Fat16和Fat32就是以16位的字或32位的双字表示一个簇号。这里一个簇就是一个扇区,当然也可以是其他长度,这里不多做讨论。在数据保存时是以簇为单位,即不满512个字节也占用一簇的存储空间。
在Fat区中每一条Fat项的值是指向下一簇的簇号,每一个簇号对应磁盘上的一个簇(这里也是扇区,但是要知道扇区号与簇号不是一回事,扇区号是从引导扇区开始编号,而簇号是从数据区开始编号,这个一定要记住),如果簇号值大于FF7则该簇为坏簇,如果簇号值大于等于FF8则表示为结束。12位的簇号最多能表示4086个簇,而Fat区所占9个扇区,可以保存6142条Fat信息,1.44M软盘共有2880个扇区,所以不管是簇号还是Fat项在1.44M软盘下是肯定够用的。
——注意!第0个和第1个Fat项不使用,所有从第2个Fat项开始有效,即FAT(2)对应的是数据区的第一个簇数据的性质,如果小于FF7,则表示数据未完,该值为下一簇的簇号,否则表示文件数据已经结束。FAT(0)与FAT(1)始终为0xFF0、0xFFF。
Fat表的组织方式如下:
从上表中可以看出,每12个位元组成一个簇号,那么知道簇号怎么算字节号(偏移量)或者说知道簇号如何计算出该簇号对应的值?(簇号对应的值就是下一个簇号或结束标志。)
——计算公式:簇号 * 3 / 2 = 商为字节号,余数为1则为高位开始,余数为0则为低位开始。
例:
(1) 求簇号1对应的值,1*3/2=1余1,则可知从字节1高4位为簇号1的低4位,字节2的8位为簇号1的高8位组成12位的簇号1对应的值。
(2) 求簇号2对应的值,2*3/2=3余0,则可知从字节3的8 位为簇号2的低8位,字节4的低4位为簇号2的高4位组成12位的簇号2对应的值。
电脑在加载引导代码前的内存情况如下:
0x00000 ~ 0x003FF 中断向量表
0x00400 ~ 0x004FF BIOS数据区
0x00500 ~ 0x07BFF 自由区
0x07C00 ~ 0x07DFF 引导加载区
0x07E00 ~ 0x9FFFF 自由区
0xA0000 ~ 0xBFFFF 显存映射区
0xC0000 ~ 0xFFFFF BIOS中断处理程序区
系统引导程序的主要功能就是加载一段代码并转移控制权。很多时间引导程序中还包含了一些其他信息。
为了开发操作系统方便,我们以FAT12格式来组织文件数据,但可以简化引导加载方法,由于1.44M软盘的FAT扇区与目录区相对固定,我们可以不用计算直接读取第一个文件数据,但有几个问题,一是文件的长度要控制好,二是文件不能被删除或被替换,三是要在文件数据区连续保存。这样简化就会留有后遗症,不知道什么时候就会发生加载错误。还有一个方法就是在磁盘的最后几个扇区保存操作系统加载配置程序,在FAT表中改为坏道或占用,但这样每次修改操作系统加载配置程序都要用专用的程序写入,比较麻烦。
我们来一步一步开始万里长征吧!
如果你不能一下子理解,没关系,以后回头再看看说不定就懂了。