0x01 前言
文件系统是依托于硬盘之上的,所以如果我们想要搞清楚 linux 内核中,文件系统的实现,就先要理解内核是如何对硬盘进行读写的。
而在研究内核对硬盘的读写时,又经常需要做一些测试,所以我们必须要有一个灵活可配置的虚拟测试环境,来模拟各种硬盘。
因为现在常用的硬盘,基本上都是 nvme ssd,即 nvme 固态硬盘,所以我们就选择 nvme ssd,做我们的测试硬盘。
下面我们就来演示下,如何在 qemu 虚拟机中,模拟 nvme ssd。
0x02 在 qemu 中模拟 nvme ssd
先做如下准备工作:

上图中,先使用 qemu-img 命令创建一个大小为 1g,名为 nvme.img 的文件,然后再使用 mkfs.ext4 命令,把该文件格式化成 ext4 文件系统。
接着执行以下命令,启动一个 qemu 虚拟机,并把 nvme.img 文件作为一个 nvme ssd,挂载到这个虚拟机里:
qemu-system-x86_64 \ -machine q35,accel=kvm \ -smp 4 \ -m 4G \ -device virtio-blk-pci,drive=vda \ -blockdev driver=file,filename=./root.img,node-name=vda \ -kernel ~/linux/arch/x86/boot/bzImage \ -append "root=/dev/vda rw console=ttyS0" \ -nographic \ -device nvme,serial=deadbeef,drive=nvme0n1 \ -blockdev driver=file,filename=./nvme.img,node-name=nvme0n1
在上面的命令中,最后两个参数就是用来把 nvme.img 文件,模拟成一个 nvme ssd 设备,并挂载到虚拟中的,而其它参数是用来辅助启动虚拟机的,这些参数可以根据需要自己调整。
注意,-device 参数中的 drive 子参数,和 -blockdev 参数中的 node-name 子参数,它们的值要相同。
有关各参数的意义,请参考 qemu 官方文档。
如果对 qemu 完全不了解的,也可以看我之前写的一篇文章 在 qemu 中运行和调试 linux 内核 。
如果还是对某些地方有疑问,可以扫描右侧的二维码,加我微信。
下面我们进入到刚刚启动的 qemu 虚拟机中,实际使用下这个 nvme ssd:

上图中,先用 lsblk 命令列出所有的块设备文件,注意 nvme0n1 就是我们模拟的 nvme ssd。
接着,图中又使用 mount 命令,把 nvme ssd 挂载到 /mnt 目录,这样我们就可以通过这个目录,来访问 nvme ssd 了。
最后,上图中又执行了各种命令,来验证 nvme ssd 是可以使用的,没有任何问题。
0x03 总结
以上就是在 qemu 中 模拟 nvme ssd 的全部过程,有了这个 nvme ssd 设备,我们就可以在研究内核源码的过程中,方便的做各种测试了。
qemu 不仅可以用来模拟 nvme ssd,还可以用来模拟各种设备。
在我的 linux 内核课程中,我就写了个 qemu 脚本,来启动一个包含各种硬件的 qemu 虚拟机,我的内核课程中的很多实验,都是在里面完成的,大家感兴趣的话,可以关注下。
0x04 其他
我开设了很多 linux 内核课程,这些课程会分篇章、系统性的讲解 linux 内核源码,有对内核源码感兴趣的,可以扫描右侧的二维码,加我微信,报名课程。