自制能使用U盘引导的程序(一)

一直想写一段程序能把它放在U盘里面,然后开机的时候可以运行它,下面就开始做吧。

一 、基础知识

1. pc的启动过程

pc启动后首先执行bios里面的程序,bios完成一些硬件检测之类的工作。然后就把pc的启动磁盘上的第一个扇区(MBR,master boot record)加载到内存0x7c00处,如果这段数据的最后两个字节分别是0x55和0xAA,那么就跳转到0x7c00处执行。也就是说只要我们能将自己写的代码放到U盘MBR中,然后在开机时选择U盘启动,那么我们的代码也就能得以执行了。但是,这仅仅只有510个字节可用(最后面两个字节要是0x55和0xAA),甚至,如果U盘要在写入我们的代码后还要保证能正常使用,那我们可用的空间还不足510个字节。这一点,接下来再说。

2. FAT32文件系统简介

由上面的说明我们知道我们的程序不能完全放到MBR中,毕竟空间太小了,让人很不尽兴。所以我们要想办法使我们的程序能像其他的文件一样很方便的放到U盘去,然后还能够加载到内存运行。要想达到这个目标,我们就必须了解下磁盘(准确说是文件系统)是怎样组织文件的。

对于纯粹的物理磁盘我们完全可以把它看作是从0开始编号一个个扇区排列而组成的,这也是磁盘能读写的最小单位了。磁盘要能被操作系统使用都得经过分区和格式化。分区能使得磁盘的使用更加的灵活,比如我们可以把硬盘分成多个区,分别格式化成不同的文件系统,在这些不同的文件系统上安装不同的操作系统。我们平时对U盘分区的情况不多(一般U盘只有一个分区),仅仅把它格式化一下,比如格式化成FAT32格式的。

接下来我们探索一下FAT32是怎么存放文件的。

首先,将U盘格式化一下(避免不必要的干扰),例如使用 HP U盘格式化工具。


格式化后,在u盘中新建一个文本文件,内容输入一些容易辨识的英文句子,如HelloWorld,文件名kernel.bin(这个文件以后就是我们的程序名了)。接下来我们的任务就是就要在茫茫扇区海洋里把文件的内容给找出来,这也就是我们熟悉FAT32文件系统格式的过程了。这里,我们就要用到一个工具WinHex,这个软件可以查看物理磁盘里面的原始数据。

使用WinHex打开U盘(按F9然后选择物理设备里面的U盘)。


首先我们知道数据肯定是在分区上,有关分区的信息就存放在MBR里,所以我们定位(Ctrl+G)到第0号扇区也就是MBR处。这一个扇区的数据是怎么组织的,它又提供了哪些信息呢(至少我们知道里面有引导代码)。WinHex可以按照MBR格式规范帮我们把这个扇区的内容整理成易于阅读的形式。按Alt+F12弹出模板管理对话框,选择其中的Master Boot Record模板。整理好的形式如下图:


首先在偏移地址0处是440个字节的引导代码,然后第一个红线框处是第一个分区表,偏移地址0x1c2处的一个字节代表这是FAT32类型的分区,下面的三个分区表没有用上,我没有把它们截出来。第二个红线框是我们第一个需要注意的量,代表的是这一个分区的起始扇区号。关于MBR结构的详细内容可以搜索下,网上有很多讲解。接下来我们还是Ctrl+G跳转到63号扇区,我们猜想,这个扇区应该会包含关于这个FAT32分区的一些信息。继续Alt+F12弹出模板管理对话框,选择Boot Sector FAT32,弹出的对话框如下所示:




FAT32分区分为三个部分,第一是包括Boot Sector在内的保留区,第二是FAT(File Allocate Table)区(一般两个FAT组成),第三是数据区。数据区是按一簇一簇来划分的,那么什么是簇(cluster),简单的说就是文件系统分配的最小单元(一般由8扇区组成)。上图中,第一个红线框中分别表示每簇所占的扇区数8,保留区的扇区数38,FAT的个数2。第二个红线框中的是一个FAT的包含的扇区数。我们要找的文件都放在数据区,那数据区在几号扇区呢。通过以上几个标记出的参数我相信你就能计算出来吧。那就是分区的起始扇区号加上保留区的扇区数再加上FAT区的扇区数。然后我们Ctrl+G跳到那个扇区,是不是眼前一亮,我相信你肯定看到了我们放进去那个文件的文件名。其实我们现在看到的区域(占用一簇)是专门用来存放文件的一些基本信息(文件名,属性等)的区域,叫根目录项区(一个短目录项占用32个字节),该区所占用簇的簇号是2,没有0号和1号簇。在这些关于文件的信息中,现在我们唯一关心的就是文件的内容开始于数据区的哪个簇。照旧按Alt+F12打开模板管理,选择普通的短FAT Directory Entry。第一个目录项是U盘格式化时指定的卷标,不用管,如果现在U盘中惟一的是文件就是kernel.bin,那么第二个目录项就是它的的了。模板解析如下:



为了简单起见,这里仅仅标出了kernel.bin起始簇号的低16位(如果u盘里面的文件不是很多这个号就够用了)。有了文件的簇号,我们就可以计算出文件的具体扇区了吧,把这个簇号减去2然后乘上每簇的扇区数就得到了文件内容相对于数据区开始处偏移扇区数,这个偏移值加上前面计算的数据区起始扇区号,就得到了文件内容的总扇区号。Ctrl+G跳到这个扇区,相信你肯定看到了你写入的英文句子。如果文件的大小超过了一簇的大小,那么下一簇内容怎样寻找。这个就要使用到FAT区了,FAT区也是由所谓的FAT项组成,一个项占用4个字节,32位,这就是我们的FAT32中32的来由了。每一个FAT项对应一簇,如果文件还有下一簇就在这里指出,否则就标记结束。为了与簇号保持一致,第0第1项不用。具体内容可以自行搜索。

有了这些基础知识,就可以开始写程序了。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值