一、virtio概述
virtio是一種輕量級的虛擬化I/O框架,它的核心思想是將設備的複雜功能轉移到虛擬機監控程序(VMM)上。virtio將外部設備的訪問邏輯封裝在虛擬機監控程序內部,只向虛擬機交付一組簡單而統一的介面。這些介面可以看作是一種通用的虛擬IO設備規範。
virtio規範主要包括以下幾種類型的設備:
- 塊設備(blk):提供塊級別的讀寫操作。
- 網卡設備(net):提供網路通信服務。
- 內存設備(mem):提供直接內存訪問等服務。
- 控制台設備(console):提供與虛擬機控制台的通信服務。
virtio驅動負責在虛擬機中對這些設備的操作進行處理,以及和宿主機的交互。
二、virtio驅動實現
1. virtio設備的表示
在Linux系統中,virtio設備表示為一組及其描述符。描述符中包含了virtio設備的各種信息,通過它可以實現virtio設備數據的讀寫等操作。驅動通過描述符尋找到相應的設備,並進行控制和管理。
2. 設備的初始化
虛擬機在運行時,virtio驅動會被載入到內核中,並和virtio設備進行初始化連接的過程。主要過程包括以下幾個環節:
- 讀取VM的配置信息。
- 填充設備描述符信息。
- 將設備描述符傳遞到虛擬機中,隨後虛擬機完成設備初始化的過程。
虛擬機完成設備初始化後,virtio驅動可以開始與設備進行交互。
3. 數據處理
在進行數據處理時,virtio驅動主要負責兩個過程:讀取數據和寫入數據。具體過程如下:
- 讀取數據:首先,驅動程序發送對應的讀取請求給virtio設備。虛擬機完成數據的讀取後,驅動會將數據從虛擬機中讀出並發送到應用程序中。
- 寫入數據:在寫入數據的時候,應用程序會將數據發送給virtio驅動,隨後驅動會將數據發送給虛擬機並請求寫入。
三、代碼示例
static struct virtio_driver virtio_blk_driver = { .name = "virtio_blk", .id_table = id_table, .features = features, .feature_table_size = ARRAY_SIZE(features), .probe = virtblk_probe, .remove = virtblk_remove, }; module_virtio_driver(virtio_blk_driver);
struct virtio_device *vdev; struct virtqueue *vq; int rc; char buf[512]; /* 首先初始化device */ vdev = virtio_find_device(&virtio_blk_driver, PCI_VENDOR_ID_REDHAT_QUMRANET, VIRTIO_BLK_DEVICE_ID, NULL); /* 如果沒有找到可用的virtio設備就退出 */ if (!vdev){ printk(KERN_ERR "virtio_blk: no devices found!\n"); return -ENODEV; } /* 使用模塊提供的方法進行請求隊列的初始化 */ rc = virtqueue_initialize(vdev, 0, virtblk_request); /* 如果返回值小於0,則表示初始化失敗 */ if (rc vqs ? vdev->vqs[0] : NULL; if (!vq) { printk(KERN_ERR "virtio_blk: NO vq\n"); goto error; } /* 將寫入的數據添加到隊列中去 */ struct scatterlist sg_list; sg_init_one(&sg_list, buf, sizeof(buf)); struct virtio_blk_req *req = kzalloc(sizeof(struct virtio_blk_req), GFP_KERNEL); virtblk_setup_req(req, VIRTIO_BLK_T_IN, 0, &sg_list, 0); virtqueue_push(vq, req, 0, GFP_KERNEL);
原創文章,作者:小藍,如若轉載,請註明出處:https://www.506064.com/zh-tw/n/302869.html