device probe - virtio
device の probe
virtio-console は PCI のデバイスとして export されているので普通に見つかる。
PciInf pciInf; Pci pci; pci.CheckPciExist(PCI_VENDOR_ID_REDHAT_QUMRANET, PCI_DEVICE_ID_VIRTIO_CONSOLE, &pciInf); if (pciInf.isExist) { _printf("device found\n"); _printf("base=%x\n", pciInf.baseAdress & ~1); _printf("irqLine=%x\n", pciInf.irqLine); } else { _printf("device not found\n"); } }
このベースアドレスを基準に各 virtio device に対して read/write できる。
_printf("%x", inp32((pciInf.baseAdress & ~1) + VIRTIO_PCI_HOST_FEATURES));
利用可能なのは
VIRTIO_PCI_HOST_FEATURES VIRTIO_PCI_GUEST_FEATURES VIRTIO_PCI_QUEUE_PFN VIRTIO_PCI_QUEUE_NUM VIRTIO_PCI_QUEUE_SEL VIRTIO_PCI_STATUS VIRTIO_PCI_ISR
config
virtio-net では PCI config で mac address / status が取り出せる。
struct virtio_net_config { /* The config defining mac address (6 bytes) */ uint8_t mac[6]; /* See VIRTIO_NET_F_STATUS and VIRTIO_NET_S_* above */ uint16_t status; } __attribute__((packed)); int main(int argc, char* argv[]) { PciInf pciInf; Pci pci; pci.CheckPciExist(PCI_VENDOR_ID_REDHAT_QUMRANET, PCI_DEVICE_ID_VIRTIO_NET, &pciInf); if (pciInf.isExist) { _printf("device found\n"); _printf("base=%x\n", pciInf.baseAdress); _printf("base=%x\n", pciInf.baseAdress & ~1); _printf("irqLine=%x\n", pciInf.irqLine); struct virtio_net_config config; for (int i = 0; i < sizeof(config); i += 4) { (((uint32_t*)&config)[i / 4]) = inp32((pciInf.baseAdress & ~1) + VIRTIO_PCI_CONFIG + i); } printf("config.mac= %x:%x:%x:%x:%x:%x\n", config.mac[0], config.mac[1], config.mac[2], config.mac[3], config.mac[4], config.mac[5]); } else { _printf("device not found\n"); } return 0; }
qemu 起動オプション
% qemu -virtioconsole stdio -net nic,model=virtio -cdrom /home/taro/mona/tool/mkimg/mona.iso -fda /home/taro/mona/tool/mkimg/mona.img -boot d
思い出せない
取り出した baseAdress & ~1 するのはなぜだっけか?思い出せない。
id:Yamami さんならご存じかな。
これか。
BARs are used to hold memory addresses used by the device, for example the DMA address. It can also hold I/O ports. To distinguish between them, you can check if the lowest bit is 1. If it is, the lower word represents the I/O port. Also don't forget to zero the lowest bit.
todo
- virtio queue の利用方法が分からない
- pfn って何?これが鍵か?