久久精品人人爽,华人av在线,亚洲性视频网站,欧美专区一二三

virtio驅動是如何同設備交互

156次閱讀
沒有評論

共計 2569 個字符,預計需要花費 7 分鐘才能閱讀完成。

這篇文章將為大家詳細講解有關 virtio 驅動是如何同設備交互,文章內(nèi)容質(zhì)量較高,因此丸趣 TV 小編分享給大家做個參考,希望大家閱讀完這篇文章后對相關知識有一定的了解。

irtio 是對虛擬化環(huán)境下 guest kernel 中 io 操作的一種優(yōu)化。
首先需要說明的是,在內(nèi)核的角度來看,virtio 設備及其 driver,和其他設備及驅動一樣,都是普通的設備,并沒有什么特殊性。也就是說,內(nèi)核并不知道這種 io 優(yōu)化的存在。
virtio 設備,在系統(tǒng)層面看,就是 pci 設備。但是,為了提高 io 效率,對 io 操作做出了優(yōu)化。
主要方案是:
1) 當 virtio 設備輸出數(shù)據(jù)時,driver 將數(shù)據(jù)送到 buffer 隊列中(從 virtio 網(wǎng)卡驅動的代碼來看,此操作無內(nèi)存拷貝,直接將數(shù)據(jù)所占的內(nèi)存 作為 buffer 添加到隊列中就完成了),然后通過 io 指令寫設備寄存器(vp_dev- ioaddr + VIRTIO_PCI_QUEUE_NOTIFY),以通知虛擬機系統(tǒng)(kvm+qemu)。虛擬機系統(tǒng)捕獲了 io 指令,就得到了通知,從 buffer 隊 列中獲取設備輸出的數(shù)據(jù)。

2) 當需要向 virtio 設備輸入數(shù)據(jù)時,虛擬機系統(tǒng)將數(shù)據(jù)送到 buffer 隊列中,然后觸發(fā)設備中斷。driver 收到中斷后,直接從隊列中取出數(shù)據(jù)即可 (從 virtio 網(wǎng)卡驅動的代碼來看,隊列中的數(shù)據(jù)已經(jīng)不需要再進行內(nèi)存拷貝,隊列中的數(shù)據(jù)已經(jīng)是 sk_buff 結構了)。

從上面的機制來看,virtio 并不是完全沒有了 io 操作。例如,設備輸出數(shù)據(jù)時,在將數(shù)據(jù)送入 buffer 隊列后,還是執(zhí)行了 io 操作,以通知虛擬機系統(tǒng)。但是,這個 io 操作,并不是將輸出數(shù)據(jù)寫入設備,而是將數(shù)據(jù)已入隊這件事,寫入設備。

以上是 virtio 的大體原理。下面來看看 virtio 的設計思路。
大體分如下 4 個層次。

一、buffer 隊列

既然 virtio 通過 buffer 隊列實現(xiàn)設備輸入輸出。那么,如果每一種設備都來實現(xiàn)一下 buffer 隊列,不是浪費么?沒錯,virtio 考慮到這個 共性需求,因此就實現(xiàn)一個共同的 buffer 隊列模塊——virtio_ring(一個環(huán)型隊列)。但是,如果哪天 buffer 隊列的實現(xiàn),需要重新設計 怎么辦?考慮到這一點,再對 buffer 隊列的操作包裝出一個抽象層——struct virtqueue_ops。每一種 buffer 隊列的實現(xiàn),只要提供一個 virtqueue_ops 結構變量給用戶使用即可。這就實現(xiàn)了隊列操作與隊列 實現(xiàn)的解耦。
struct virtqueue_ops 
{
int (*add_buf)(struct virtqueue *vq,
      struct scatterlist sg[],
      unsigned int out_num,
      unsigned int in_num,
      void *data);

void (*kick)(struct virtqueue *vq);

void *(*get_buf)(struct virtqueue *vq, unsigned int *len);

void (*disable_cb)(struct virtqueue *vq);
bool (*enable_cb)(struct virtqueue *vq);
};

二、pci 層
每一個 virtio 設備(例如:塊設備或網(wǎng)卡),在系統(tǒng)層面看來,都是一個 pci 設備。這些設備之間,有共性部分,也有差異部分。
1) 共性部分:這些設備都需要掛接相應的 buffer 隊列操作 virtqueue_ops,都需要申請若干個 buffer 隊列,當執(zhí)行 io 輸出時,需要向 隊列寫入數(shù)據(jù);都需要執(zhí)行 pci_iomap 將設備配置寄存器區(qū)間映射到內(nèi)存區(qū)間;都需要設置中斷處理;等中斷來了,都需要從隊列讀出數(shù)據(jù),并通知虛擬機 系統(tǒng),數(shù)據(jù)已入隊。
2) 差異部分:設備中系統(tǒng)中,如何與業(yè)務關聯(lián)起來。各個設備不相同。例如,網(wǎng)卡在內(nèi)核中是一個 net_device,與協(xié)議棧系統(tǒng)關聯(lián)起來。同時,向隊列中寫入什么數(shù)據(jù),數(shù)據(jù)的含義如何,各個設備不相同。隊列中來了數(shù)據(jù),是什么含義,如何處理,各個設備不相同。

如果每個 virtio 設備都完整實現(xiàn)自己的功能,又會形成浪費。
針對這個現(xiàn)象,virtio 又設計了 virtio_pci 模塊,以處理所有 virtio 設備的共性部分。這樣一來,所有的 virtio 設備,在系統(tǒng)層面看來,都是一個 pci 設備,其設備驅動都是 virtio_pci。
但是,virtio_pci 并不能完整的驅動任何一個設備。因此,virtio_pci 在 probe(接管)每一個設備時,根據(jù)每個 pci 設備的 subsystem vendor/device id 來識別出這具體是哪一種 virtio 設備,然后相應的向內(nèi)核注冊一個 virtio 設備。當然,在注冊 virtio 設備之前,virtio_pci 驅動 已經(jīng)為此設備做了諸多共性的操作。同時,還為設備提供了各種操作的適配接口,例如,一些常用的 pci 設備操作,還有申請 buffer 隊列的操作。這些操 作,都通過 virtio_config_ops 結構變量來適配。

三、virtio 驅動
這里講 virtio 驅動,指的是具體的各個設備的驅動了。例如,網(wǎng)卡或塊設備。有了前面所述的各模塊的工作,virtio 各個設備的驅動實現(xiàn),就相對簡單了。大體來說,除了完成本設備特有的功能以外,剩下的基本就是 buffer 隊列相關操作了。
那就是申請幾個隊列,并提供相應的回調(diào)函數(shù)。有數(shù)據(jù)要輸出,往隊列中送就行了。隊列來數(shù)據(jù)了,自然會有中斷產(chǎn)生,中斷處理中,自然會觸發(fā)回調(diào)來處理。

四、virtio_bus
內(nèi)核中的各種對象,總是有秩序的。為了管理每種具體的 virtio 驅動及每個具體的 virtio 設備,干脆搞了一個 virtio_bus 出來。當然,這個 bus 并不存在實際的硬件電路,純粹起個管理與適配作用。就這個管理與適配功能而言,他和 pci 總線是相似的。全部的 virtio driver 與 virtio device,在 virtio_bus 中都能夠找到。每當有新的 virtio driver 或者 virtio device 注冊到系統(tǒng)中時,系統(tǒng)都會執(zhí)行一次設備與驅動的匹配操作。

關于 virtio 驅動是如何同設備交互 就分享到這里了,希望以上內(nèi)容可以對大家有一定的幫助,可以學到更多知識。如果覺得文章不錯,可以把它分享出去讓更多的人看到。

正文完
 
丸趣
版權聲明:本站原創(chuàng)文章,由 丸趣 2023-08-16發(fā)表,共計2569字。
轉載說明:除特殊說明外本站除技術相關以外文章皆由網(wǎng)絡搜集發(fā)布,轉載請注明出處。
評論(沒有評論)
主站蜘蛛池模板: 永顺县| 长宁县| 富锦市| 九龙城区| 保康县| 黄梅县| 正镶白旗| 门头沟区| 北宁市| 宜兰县| 霍山县| 永福县| 科尔| 黔南| 长治市| 杭州市| 富裕县| 正镶白旗| 延津县| 呼和浩特市| 和政县| 名山县| 武乡县| 南部县| 太谷县| 龙南县| 聂荣县| 灌阳县| 全南县| 杨浦区| 平安县| 绍兴市| 霍邱县| 广东省| 梅州市| 延寿县| 五台县| 三河市| 安丘市| 陕西省| 饶平县|