目标
制作一个光盘实现qemu下操作系统的引导
储备知识
df命令
:列出文件系统的整体磁盘使用量
du命令
:常用于计算目录所占容量
-h :以(G/M)方式显示容量
-k:以KB方式显示
-m:以MB方式显示
mkfs命令
:使用指定的文件系统格式化磁盘
-t :接文件系统格式,如ext3,ext2,vfat等
mount命令
:将文件系统挂载到指定的目录下
losetup命令
:连接文件与循环设备(/dev/loop)
详解
-d 卸除设备。
-e<加密方式> 启动加密编码。
-o<平移数目> 设置数据平移的数目。
循环设备可把文件虚拟成区块设备,籍以模拟整个文件系统,让用户得以将其视为硬盘驱动器,光驱或软驱等设备,并挂入当作目录来使用。
/dev/loop
设备
/dev/loop(或称vnd (vnode disk)、lofi(循环文件接口))是一种伪设备,这种设备使得文件可以如同块设备一般被访问。
在使用之前,循环设备必须与现存文件系统上的文件相关联。这种关联将提供给用户一个应用程序接口,接口将允许文件视为块特殊文件(参见设备文件系统)使用。因此,如果文件中包含一个完整的文件系统,那么这个文件就能如同磁盘设备一般被挂载。
这种设备文件经常被用于光盘或是磁盘镜像(IOS、IMG)。通过循环挂载来挂载包含文件系统的文件,便使处在这个文件系统中的文件得以被访问。这些文件将出现在挂载点目录。
在一个目录上挂载包含包含文件系统的文件的步骤:
使用一个循环设备(/dev/loop)连接文件(使用命令losetup
)
在目录上挂载该循环设备(使用命令 mount)
其他/dev
虚拟设备
/dev/null: “空”设备,也有人称它为黑洞。任何输入到这个“设备”的数据都将被直接丢弃最常用的用法是把不需要的输出重定向到这个文件。/dev/zero:零”设备,可以无限的提供空字符(0x00,ASCII代码NUL)。常用来生成一个特定大小的文件。/dev/random和/dev/urandom:随机数设备,提供不间断的随机字节流。二者的区别是/dev/random产生随机数据依赖系统中断,当系统中断不足时,/dev/random设备会“挂起”,因而产生数据速度较慢,但随机性好;/dev/urandom不依赖系统中断,数据产生速度快,但随机性较低。
生成一个大小为1.44mb软盘,并且将其挂载到指定目录下
实现过程
先生成一个空的大小为1.44MB的磁盘mkdosfs
命令
详解
-F 指定 FAT 表的大小,通常是 12 或是 16 个位元组。12 位元组通常用于磁碟片,16 位元组用于一般硬盘的分割区,也就是所谓的 FAT16 格式。这个值通常系统会自己选定适当的值。在磁碟片上用 FAT16 通常不会发生作用,反之在硬盘上用 FAT12 亦然。
xxd
命令查看其内容
xxd -u -a -g l -c 16 floopy
其前512字节是一个引导扇区(Boot Sector),前62字节是BPB的结构,BPB数据结构的字段是windows文件系统和操作系统约定好的,用于描述磁盘的物理布局,可以适用于FAT系列文件系统和NTFS文件系统。这里我们看到最后的文件系统类型为FAT12
FAT引导扇区结构
详细介绍链接
引导代码
boot.asm程序:
jmp init; BS_jmpBoot短跳转指令(加上nop填充后为3个字节)nopBs_OEMName db "Jiaxgong";Bs_OEMName 厂商名称 8字节BPB_BytsPerSec dw 512;每扇区字节数BPB_SecPerClus db 1;每簇扇区数BPB_RsvdSecCnt dw 1;保留区中的保留扇区数FAT12必须为1,(引导记录占用的扇区数)BPB_NumFATs db 2;此卷中FAT表的份数,建议为2BPB_RootEntCnt dw 512;根目录中的目录项数 FAT12中建议取值512BPB_TotSec16 dw 2880;扇区总数BPB_Media db 0xf0;BPB_Media 存储介质f0表示可移动介质,f8表示固定介质BPB_FATSz16 dw 9;一个FAT表所占的扇区数BPB_SecPerTrk dw 18;每磁道扇区数BPB_NumHeaders dw 2;磁头数BPB_HiddSec dd 0;FAT分区之前的隐藏扇区数,对于未分区介质必须为0BPB_TotSec32 dd 0BS_drveNum db 0;int13得到的驱动器号BS_Reserved1 db 0;保留(供NT使用)BS_BootSig db 0x29;扩展引导标记,指明此后的3个域可用BS_VolID dd 0;卷标序列号BS_VolLab db "VirtualBoot";磁盘卷标,此域必须与根目录中11字节长的卷标一致BS_FilSysType db "FAT12 ";文件系统类型init:mov ax, 7c00hmov ds, axmov es, axmov ss, axmov sp, 180hcall DispStrloop:jmploopDispStr:mov ax, BootMsgmov bp, axmov cx, 16mov ax, 01301hmov bx, 000chmov dl, 0int10hretBootMsg: db "Hello, OS World!"times 510-($-$$) db 0dw 0xaa55
以上程序写好后,使用nasm
命令汇编成二进制文件
nasm boot.asm -o boot.bin
汇编完成后,可以使用以下命令查看boot.bin的大小,刚好为512字节
wc -c boot.bin
plus:反汇编指令ndisasm boot.bin -o 0x7c00>> disboot.asm
可以查看处理过后的汇编代码
将引导代码写入floopy软盘中
dd if=boot.bin ibs=512 of=floopy obs=512 count=1 seek=0 conv=notrunc
notrunc意味着不缩减输出文件,也就是说,如果输出文件已经存在,只改变指定的字节,然后退出,并保留输出文件的剩余部分。没有这个选项,dd将创建一个512字节长的文件。
写入完成后,使用qemu启动软盘(a.img就是上面的floppy软盘,为了和命令区分,改为了a.img)
qemu-system-x86_64 -drive file=a.img,of=floppy