04 主引导程序的扩展-上

参考

https://www.cnblogs.com/wanmeishenghuo/tag/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F/

https://blog.51cto.com/13475106/category6.html

及狄泰软件相关课程

一.主引导程序上

从之前的几章可以知道,主引导程序的代码量不能超过512字节,但是在实际中我们需要突破512字节的限制
突破限制的思路-主引导程序
1.完成最基本的初始化工作
2.从存储介质中加载程序到内存中
3.将控制权交由新加载的程序执行

操作系统--主引导程序的扩展

但是在这会出现问题-主引导程序如何加载存储介质中的其它程序?
文件系统--存储介质上组织文件数据的方法-主要包含数据区、根目录、FAT2、FAT1、引导扇区如图所示
操作系统--主引导程序的扩展
A.文件系统示例(用到的虚拟网盘时F12)
1.FAT12是DOS时代的早期文件系统
2.FAT12结构非常简单,一直沿用于软盘
3.FAT12的基本组织单位-字节:基本数据单位、扇区:磁盘中的最小数据单元、簇:一个或者多个扇区
通过之前的介绍,可以得出解决方案
1.使用FAT12对软盘(data..img自定义的)进行格式化
2.编写可执行程序(Loader),并将其拷贝到软盘中
3.主引导程序(Boot)在文件系统中查找Loader
4.将Loader复制到内存中,并跳转到入口处执行
实验-往虚拟软盘中写入文件,在这里我们需要一些准备的基本bochs、FreeDos、bximage,主要步骤是创建虚拟软盘然后在FreeDos中进行格式化,最后将data.img挂载Linux中,并写入文件

通过bximage命令生成data.img(参考之前博文),并在配置中将其并入到freeDos.img上

操作系统--主引导程序的扩展
操作系统--主引导程序的扩展

通过运行之后生成,然后通过format B命令对B盘进行格式化,B盘就是虚拟软驱,将其格式化虚拟软盘data.img就有了文件系统就是Fata12文件系统,然后通过终端以及命令生成之前提到的原材料并将其拷贝至软盘中
操作系统--主引导程序的扩展

最后通过命令进行查看虚拟软盘下的文件,以及文件内的内容
操作系统--主引导程序的扩展
操作系统--主引导程序的扩展
操作系统--主引导程序的扩展
B.对FAT12进行深入的理解
FAT12文件系统由引导区,FAT表,根目录项表和文件数据区组成
操作系统--主引导程序的扩展

FAT12的主引导区--主引导区存储的比较重要的信息是文件系统的类型,文件系统逻辑扇区总数,每簇包含的扇区数,等。主引导区最后以0x55AA两个字节作为结束,共占用一个扇区
操作系统--主引导程序的扩展

怎么来验证一下我们格式化后的a.img虚拟软盘中就是这些信息呢?我们可以将a.img当成一个普通的文件,然后写一个程序进行读取,读取程序使用Qt creater来写,因为Qt中提供了很多好用的工具类,方便我们来验证程序如下

#include <QtCore/QCoreApplication>
#include <QFile>
#include <QDataStream>
#include <QDebug>

#pragma pack(push)
#pragma pack(1)

struct Fat12Header
{
    char BS_OEMName[8];
    ushort BPB_BytsPerSec;
    uchar BPB_SecPerClus;
    ushort BPB_RsvdSecCnt;
    uchar BPB_NumFATs;
    ushort BPB_RootEntCnt;
    ushort BPB_TotSec16;
    uchar BPB_Media;
    ushort BPB_FATSz16;
    ushort BPB_SecPerTrk;
    ushort BPB_NumHeads;
    uint BPB_HiddSec;
    uint BPB_TotSec32;
    uchar BS_DrvNum;
    uchar BS_Reserved1;
    uchar BS_BootSig;
    uint BS_VolID;
    char BS_VolLab[11];
    char BS_FileSysType[8];
};

#pragma pack(pop)

void PrintHeader(Fat12Header& rf, QString p)
{
    QFile file(p);

    if( file.open(QIODevice::ReadOnly) )
    {
        QDataStream in(&file);

        file.seek(3);

        in.readRawData(reinterpret_cast<char*>(&rf), sizeof(rf));

        rf.BS_OEMName[7] = 0;
        rf.BS_VolLab[10] = 0;
        rf.BS_FileSysType[7] = 0;

        qDebug() << "BS_OEMName: " << rf.BS_OEMName;
        qDebug() << "BPB_BytsPerSec: " << hex << rf.BPB_BytsPerSec;
        qDebug() << "BPB_SecPerClus: " << hex << rf.BPB_SecPerClus;
        qDebug() << "BPB_RsvdSecCnt: " << hex << rf.BPB_RsvdSecCnt;
        qDebug() << "BPB_NumFATs: " << hex << rf.BPB_NumFATs;
        qDebug() << "BPB_RootEntCnt: " << hex << rf.BPB_RootEntCnt;
        qDebug() << "BPB_TotSec16: " << hex << rf.BPB_TotSec16;
        qDebug() << "BPB_Media: " << hex << rf.BPB_Media;
        qDebug() << "BPB_FATSz16: " << hex << rf.BPB_FATSz16;
        qDebug() << "BPB_SecPerTrk: " << hex << rf.BPB_SecPerTrk;
        qDebug() << "BPB_NumHeads: " << hex << rf.BPB_NumHeads;
        qDebug() << "BPB_HiddSec: " << hex << rf.BPB_HiddSec;
        qDebug() << "BPB_TotSec32: " << hex << rf.BPB_TotSec32;
        qDebug() << "BS_DrvNum: " << hex << rf.BS_DrvNum;
        qDebug() << "BS_Reserved1: " << hex << rf.BS_Reserved1;
        qDebug() << "BS_BootSig: " << hex << rf.BS_BootSig;
        qDebug() << "BS_VolID: " << hex << rf.BS_VolID;
        qDebug() << "BS_VolLab: " << rf.BS_VolLab;
        qDebug() << "BS_FileSysType: " << rf.BS_FileSysType;

        file.seek(510);

        uchar b510 = 0;
        uchar b511 = 0;

        in.readRawData(reinterpret_cast<char*>(&b510), sizeof(b510));
        in.readRawData(reinterpret_cast<char*>(&b511), sizeof(b511));

        qDebug() << "Byte 510: " << hex << b510;
        qDebug() << "Byte 511: " << hex << b511;
    }
    else
    {
        qDebug() << "file not found";
    }

    file.close();
}

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    Fat12Header f12;

    PrintHeader(f12, "data.img");
    
    return a.exec();
}

我们定义的Fat12Header结构体是和主引导程序一一对应的,执行以上代码,输出如下所示:

  可以看到,我们读出的信息和FAT文件系统引导区的详细信息完全对应了。

修改bochrc文件,从data.img启动

###############################################################
# Configuration file for Bochs
###############################################################

# how much memory the emulated machine will have
megs: 32

# filename of ROM images
romimage: file=/usr/local/share/bochs/BIOS-bochs-latest
vgaromimage: file=/usr/share/vgabios/vgabios.bin

# what disk images will be used
#floppya: 1_44=freedos.img, status=inserted
floppya: 1_44=data.img, status=inserted
# choose the boot disk.
boot: a

# where do we send log messages?
# log: bochsout.txt

# disable the mouse
mouse: enabled=0

# enable key mapping, using US layout as default.
keyboard_mapping: enabled=1, map=/usr/local/share/bochs/keymaps/x11-pc-us.map  

结果如下:

 总结:

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值