阿呆实战NVMe之三

原创内容,转载请注明:  [http://www.ssdfans.com]  谢谢!

 

有人说阿呆你搞个虚拟的东西来玩NVMe,看起来是很爽,代码随便写,然并卵有个什么鸟用呢?其实在实际产品研发中还是有点用的,QEMU最大的好处是可以用GDB Debug。一般实体机如果发生了Panic,只能通过Linux Kernel Panic Dump的方式查看堆栈,找原因,有些藏得比较深的问题比较难发现。而QEMU虚拟机在出错的时候会停下来,就能直接查看出错时各个变量的现场值,找到Root Cause。你如果开发了Linux NVMe驱动,可以用QEMU Debug,也能做一些简单的测试。

 

我们上回说到,蛋蛋定义了QEMU的一套顶层架构,这样后来的人加新的硬件进来,就可以直接套用。本文就通过NVMe设备的追根溯源来看看QEMU使用了何种巧妙的架构来驾驭那么多复杂的硬件。

 

怎样在QEMU注册一个NVMe设备?

 

上回说nvme.c里面定义了一个PCIDeviceInfo对象nvme_info,如下图,包含了构造和析构函数,还有其他配置与接口赋值。那这个对象是怎样在QEMU之中被使用的呢?

 

 

如下面代码,nvme_register_devices注册了一个PCI设备nvme_info。然后,用一个宏device_init来声明这个注册函数。看得出来,奥秘就在这个宏里面。

 

 

如下,可以看到device_init宏变成了module_init,而这个module_init宏是个有constructor attribute的函数,起什么作用呢?在GCC中,这两个编译的attribute用于修饰某个函数, 经过constructor属性修饰过的函数, 可以在main函数运行前就先运行完毕, 同理destructor在进程exit之前执行。相当于构造和析构函数。要知道Linux分为内核态和用户态,内核态的程序都是通过modprobe .ko文件形式加载,没有main函数一说。而用户态都是从main函数进来的,而虚拟机本身是跑在用户态的,所以也是从main函数进来。不过,module_init宏声明的函数在main函数之前就执行了,就是为main函数做一些配置工作。

 

我们说QEMU把硬件分成了Block,Device和Machine三种,最终三种硬件的注册函数都汇总到了一个函数:register_module_init(void (*fn)(void), module_init_type type).

 

于是,我们又来一探这个通用的注册函数干了些什么。如下面的代码,功能非常简单,就是每种硬件类型,在QEMU中都有一个设备链表,链表中每个节点的内容就是这个设备的注册函数。所以,在QEMU中注册一个设备就是把这个设备的ModuleEntry挂到链表的尾巴上。

 

 

QEMU初始化

 

NVMe设备的注册是完成了,非常的简单。那么QEMU又怎么来使用这个注册的设备呢?请你回过头看看,其实折腾了半天,只是在main函数调用之前把nvme_register_devices这个函数注册到了device设备的链表里面,真正的NVMe初始化还没弄呢。不过别着急,NVMe设备初始化肯定是和nvme_register_devices函数内容分不开了。那我们就来看看这个函数做了什么。

看起来是给继承的DeviceInfo qdev赋初值。下面是PCIDeviceInfo的定义,包含了构造和析构函数,PCI设备的config读写接口,还有vendor id等参数。

拿这些注册的DeviceInfo的init函数到底什么时候调用?要找到答案,我们就得去看看main函数做了些什么,毕竟注册PCIDeviceInfo对象是在main之前完成,那main肯定不会不用注册的结果。QEMU包含了很多main函数,因为有很多工具,但是真正的main函数位于Vl.c。

首先初始化最核心的Machine设备,CPU之类的。

中间有1000多行代码不知道在干嘛,反正还没轮到Device设备。直到1000多行以后,Device设备才被初始化。

但是当我们看到module_call_init函数的内容,还是很失望,它只是调用了e->init()。

e->init()是什么,请翻到本文开头,nvme_register_devices函数就是e->init()!!是不是觉得搞了半天,又回来了。悲哀啊,怎么这么麻烦啊,那本文开头的nvme_info的那些init函数到底什么时候调用?等下回阿呆搞明白了再告诉你。

 

引用

 

https://github.com/nvmeqemu

 

分类目录 SSD, 技术文章.
扫一扫二维码或者微信搜索公众号ssdfans关注(添加朋友->点最下面的公众号->搜索ssdfans),可以经常看到SSD技术和产业的文章(SSD Fans只推送干货)。
ssdfans微信群介绍
技术讨论群 覆盖2000多位中国和世界华人圈SSD以及存储技术精英
固件、软件、测试群 固件、软件和测试技术讨论
异构计算群 讨论人工智能和GPU、FPGA、CPU异构计算
ASIC-FPGA群 芯片和FPGA硬件技术讨论群
闪存器件群 NAND、3D XPoint等固态存储介质技术讨论
企业级 企业级SSD、企业级存储
销售群 全国SSD供应商都在这里,砍砍价,会比某东便宜20%
工作求职群 存储行业换工作,发招聘,要关注各大公司招聘信息,赶快来
高管群 各大SSD相关存储公司高管和创始人、投资人

想加入这些群,请微信扫描下面二维码,或搜索nanoarchplus,加阿呆为微信好友,介绍你的昵称-单位-职务,注明群名,拉你进群。SSD业界需要什么帮助,也可以找阿呆聊。