参考nvme驱动相关的博客,可以使用qemu + buildroot进行nvme驱动的流程debug。
一、QEMU编译
首先需要编译qemu,可以参考QEMU编译。wget下载最新版本的QEMU,编译之前,最好检查下依赖包是否安装,避免安装过程出现各种错误。
sudo apt-get install ninja-build
sudo apt-get install build-essential zlib1g-dev pkg-config libglib2.0-dev
sudo apt-get install binutils-dev libboost-all-dev autoconf libtool libssl-dev
sudo apt-get install libpixman-1-dev libpython-dev python-pip python-capstone virtualenv
wget https://download.qemu.org/qemu-9.0.0.tar.xz
tar xvJf qemu-9.0.0.tar.xz
cd qemu-9.0.0
./configure --target-list=x86_64-softmmu
如果不去指定target-list,那么会全部编译,导致时间更长。进行配置时候出现如下错误:
根据产生的log信息,这里是python3-venv和ninja未找到,安装对应的包即可。
sudo apt-get install python3-venv
sudo apt-get install ninja-build
接着进行make编译。
二、buildboot编译
另外,builidroot可以下载最新的版本,进入网站下载,进行解压。
进入目录xxx/buildroot-2024.02.1,然后执行:
make qemu_x86_64_defconfig
make
这里可能出现的问题:
参考了某些博文,使用udo apt-get install -y ca-certificates,也依然报错。后面继续查找资料,使用命令:
echo "check_certificate = off" >> ~/.wgetrc
问题得以解决,接着等待编译结束(执行时间比较长),直接执行以下命令启动qemu,在buildboot路径里面:
//路径如下:
cat board/qemu/x86_64/readme.txt
//执行如下命令:(注意:这个和参考博客上不一样,不用执行改终端的操作,run起来是可以敲命令的)
qemu-system-x86_64 -M pc -kernel output/images/bzImage -drive file=output/images/rootfs.ext2,if=virtio,format=raw -append "rootwait root=/dev/vda console=tty1 console=ttyS0" -serial stdio -net nic,model=virtio -net user # qemu_x86_64_defconfig
运行到这里,可以正常进入编译的系统,退出系统。
使用qemu-img创建虚拟磁盘,参考如下命令:
qemu-img create -f raw nvme.img 1G
接着使用如下命令运行qemu:
sudo qemu-system-x86_64 -M pc -kernel output/images/bzImage -drive file=output/images/rootfs.ext2,if=virtio,format=raw -append "rootwait root=/dev/vda console=tty1 console=ttyS0" -serial stdio -net nic,model=virtio -net user -drive file=nvme.img,if=none,format=raw,id=drv0 -device nvme,drive=drv0,serial=foo
但是这里遇到参考博客评论区遇到的问题,使用ls-l /dev/n*命令找nvme设备,没有找到任何设备。
三、编译liunx内核
于是想了一个办法,新拉了一个Linux内核版本,目前我使用的是linux-6.8.8版本,于是编译Linux。
//step1:先默认配置
sudo make x86_64_defconfig
//step2: 配置nvme驱动 找到device driver->NVME support->全选
sudo make menuconfig
//step3: 编译
sudo make -j8
//step4
sudo make install
注意:qemu版本和Linux版本发布日期最好接近,不然可能出现兼容性等异常问题 。
编译完成后,将image拷贝到buildboot的output目录下(根据自己保存的目录 最终的output目录应该都一样)。
cp ./arch/x86_64/boot/bzImage ../../buildroot-2024.02.1/output/images/
然后执行上面的qemu命令运行qemu,可以正常看到nvme设备,此时就可以调试nvme驱动代码。
修改内核nvme driver上面的code,增加打印信息:
重新编译,把image文件拷入到buildboot指定目录(参考上面),然后运行qemu:
最后根据增加打印信息来追踪nvme驱动过程,探究nvme驱动。
四、遇到的问题
1 在使用过程中,重启后遇到Ubuntu开机进入initramfs,可参考博客,进入启动界面后,选择advanced选项,换一个低版本内核。
2 运行qemu时候,报错如下:
qemu-system-x86_64: -net user: network backend 'user' is not compiled into this binary
解决方式:./configure --target-list=x86_64-softmmu --enable-slirp(加上一个--enable-slirp)
./configure --target-list=x86_64-softmmu --enable-slirp
重新编译make make instal后,可以正常执行。
3 配置qemu过程中发现:
--target-list=x86_64-softmmu,x86_64-linux-user
--prefix 表示要交 qemu 安装到那个目录下, 也就是执行完 make install 之后会把东西 isntall 到这个目录中 --target-list 表示要构建的目标平台, 比如 --target-list=arm-softmmu 的话就会只编译 arm 平台。
上面的命令中要编译 x86_64 平台的 system 和 user,user 选项编译出来的 qemu 可以直接执行用户态的程序,比如 ls 等等,而 system 编译出来的 qemu 是模拟一台真的物理机,包括像 rootfs 之类的东西都需要自己在手动进行加载或挂载。