资源描述:
《QEMU中挂载vTPM 笔记》由会员上传分享,免费在线阅读,更多相关内容在教育资源-天天文库。
1、QEMU中挂载vTPM步骤在Qemu的/hw目录下添加vTPM.c文件,步骤如下:首先定义vTPM的设备管理结构体,其中包含设备名称、设备描述、初始化函数和读写配置文件函数。增加了保存新PCI设备的状态数据结构vTPMStatestaticPCIDeviceInfovTPM_info={.qdev.name=“vTPM”,//定义设备名称.qdev.desc=“vTPMforQEMU”,//设备描述.qdev.size=sizeof(vTPMState),//vTPM状态结构大小,用于保存其状态数据.init=vTPM_init,//定义PCI设备
2、初始化函数,初始化PCI各种属性.config_write=pci_hardware_manager_write_config,.config_read=pci_hardware_manager_read_config,};typedefstructvTPMState_t{//PCI设备信息PCIDevice*pci_dev;//TPM状态,可用/不可用,激活/未激活,占有/未占有的状态组合Unsignedcharstatus;//传输包Unsignedcharbuf[TPM_MAX_DATA];uint32_taddr;uint8_tindex;
3、uint8_tstatus;uint32_toffset;uint8_tbuf[TPM_MAX_PKT];}vTPMState;vTPM_init函数会在QEMU开启的时候统一调用。vTPM_init用于初始化vTPM属性,包括设置PCI的厂商ID号(vendor_id)和设备ID号(device_id),PCIbar空间的大小以及端口映射函数vTPM_map等,在vTPM_map函数中注册对vTPMState的读写函数。在QEMU中,在初始化我们的硬件设备的时候需要注册我们的IO空间,对于PCI设备来说,IO地址注册就要多一步,因为要进行PCIb
4、ar地址与IO的映射,所以必须先调用下面函数来给bar注册PCI地址(给bar分配IO地址)。原函数:voidpci_register_bar(PCIDevice*pci_dev,intregion_num, pcibus_tsize,inttype, PCIMapIORegionFunc*map_func);第一个参数是PCI设备指针;第二个参数是bar的编号,每个PCI设备有6个bar,对应0-5,也就是6个region;第三个是分配的IO地
5、址空间范围;第四个参数表示IO类型是PIO还是MMIO;最后一个参数是我们要进行IO读写映射函数指针。我们可以发现这里并没有给设备分配IO空间的基地址,只有一个空间长度而已,这也进一步说明PCI设备在QEMU中一般是随机动态分配空间的,通过不断的updatemapping来不断更新IO空间的映射。staticvoidmap_func(PCIDevice*pci_dev,intregion_num, pcibus_taddr,pcibus_tsize,inttype);第一个依然是PCI设备指针,第三个是PCI地址映射的PIO起始地址,这个起始地址是
6、在我们注册PCI地址的时候,PCI总线通过计算比较PIO地址空间得到的一个PIO地址起始空间,所以这里不能够随便的改变,因为PCI地址空间需要和PIO空间进行映射。所以在我们注册设备PIO空间的时候必须将这个地址作为注册IO空间的起始地址。这个函数是在更新bar映射的时候被调用的,实际上它的作用就是给PCI设备安装IO读写函数,能够操作IO调用QEMU的pci_regiser_bar注册PCI地址pci_regiser_bar(pci_dev,0,SIZE,PCI_BAR_ADDRESS_SPACE_IO,vTPM_map);PCI_BASE_AD
7、DRESS_SPACE_IO(别人)实现映射函数,PCIbar地址初始化以后会将映射IO的起始地址作为start_addr参数传到映射函数,然后通过之前的register函数注册IO地址空间,在这个操作以后,一旦这些位的IO发生读写,虚拟机就会产生VM-exit,进而我们的ioread和iowrite就能够被调用。//在vTPM_map函数中调用QEMU的register_ioport_write注册对vTPMState的写函数,调用QEMU的register_ioport_read注册对vTPMState的读函数staticvoidvTPM_ma
8、p(PCIDevice*pci_dev,intregion_num,pcibus_tstart_addr,pcibus_t