主引导程序的扩展(上)

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
将主引导程序加载到内存中执行,然后在存储介质中寻找目标程序,加载到内存中执行,将控制权交给此程序(跳转到目标程序第一条指令执行)

在这里插入图片描述
在C/C++中可以直接搜寻文件名读取加载,但这是基于操作系统的,现在没有操作系统,不能这么做。
那咋办?引入文件系统
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
挂载到Linux:方便写入文件
在这里插入图片描述
创建1.44大小的虚拟软盘,命名为data.img
在这里插入图片描述
增加14行,意思是:将虚拟软盘data.img增加到freedos里面去,盘符是B盘
进入bochs,敲入c命令,进入freedos系统
在这里插入图片描述
敲入format B:
意思是格式化B盘,data.img便拥有FAT12文件系统:
在这里插入图片描述
发现B盘没有文件,所以需要挂载到Linux传入文件
在这里插入图片描述
以上命令意思为:
将虚拟软盘data.img挂载到Linux,编写两个文件(文件里写点字符串)
将文件拷贝到data.img
关闭挂载

此时去freedos查看B盘文件,发现有两个文件:
在这里插入图片描述
查看文件具体内容,发现确实是刚才编写的内容
在这里插入图片描述
因此,到目前为止,data.img这张虚拟软盘拥有文件系统FAT12和两个文件
data.img内部拥有一定的格式,其实就是FAT12文件系统,内部数据拥有一定的组织格式
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
以下是0扇区存放的信息:
在这里插入图片描述
为了加深文件系统理解,进行以下实验:
在这里插入图片描述
在Linux中打开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);//定位到偏移3个单位的地方,因为与文件系统相关的信息从偏移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;
    }

    file.close();
}

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

    Fat12Header f12;

    PrintHeader(f12, "/home/delphi/data.img");	//当前目录下的data.img为之前上文所述的带文件系统和两个文件的虚拟软盘

    return a.exec();
}

上述结构体中的成员按照0扇区中的内容来定义,通过program来规定字节对齐方式为1个字节对齐,也就是说结构体中不存在浪费的空间

编译运行:
在这里插入图片描述
可以发现最后两个字节确实为0x55 0xaa
猜测:freedos在格式化软盘时,塞了一个主引导程序进去
实验:
在这里插入图片描述
将data.img作为启动盘
启动bochs:
在这里插入图片描述
说明freedos在初始化时悄悄地写入了主引导程序,作用是打印提示信息的字符串
在这里插入图片描述
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值