1. 程式人生 > >QEMU虛擬網絡卡裝置的建立流程

QEMU虛擬網絡卡裝置的建立流程

基於qemu-kvm-0.12.1.2-2.160.el6_1.8.src.rpm 虛擬網絡卡型別為virtio-net-pci virtio網絡卡裝置對應的命令列引數為  -device virtio-net-pci,netdev=hostnet0,id=net0,mac=00:16:36:01:c4:86,bus=pci.0,addr=0x3 1. 在parse命令列的時候,qemu把所有的-device選項parse後儲存到qemu_device_opts中 2. 呼叫module_call_init(MODULE_INIT_DEVICE); 往系統中新增所有支援的裝置型別    virtio-net-pci的裝置型別資訊如下(virtio-pci.c): static PCIDeviceInfo virtio_info[] = {     {         .qdev.name  = "virtio-net-pci",         .qdev.size  = sizeof(VirtIOPCIProxy),         .init       = virtio_net_init_pci,         .exit       = virtio_net_exit_pci,         .romfile    = "pxe-virtio.bin",         .qdev.props = (Property[]) {             DEFINE_PROP_BIT("ioeventfd", VirtIOPCIProxy, flags,                             VIRTIO_PCI_FLAG_USE_IOEVENTFD_BIT, false),             DEFINE_PROP_UINT32("vectors", VirtIOPCIProxy, nvectors, 3),             DEFINE_VIRTIO_NET_FEATURES(VirtIOPCIProxy, host_features),             DEFINE_NIC_PROPERTIES(VirtIOPCIProxy, nic),             DEFINE_PROP_UINT32("x-txtimer", VirtIOPCIProxy,                                net.txtimer, TX_TIMER_INTERVAL),             DEFINE_PROP_INT32("x-txburst", VirtIOPCIProxy,                               net.txburst, TX_BURST),             DEFINE_PROP_STRING("tx", VirtIOPCIProxy, net.tx),             DEFINE_PROP_END_OF_LIST(),         },         .qdev.reset = virtio_pci_reset,     }    }; 3. 呼叫qemu_opts_foreach(&qemu_device_opts, device_init_func, NULL, 1) 建立命令列上指定的裝置 4. device_init_func呼叫qdev_device_add(opts) 5. qdev_device_add函式的流程如下:    a) 呼叫qemu_opt_get(opts, "driver")獲取driver選項,這裡應該是virtio-net-pci    b) 呼叫qdev_find_info(NULL, driver)來獲取註冊的DeviceInfo,這裡應該是上面virtio_info裡面關於       virtio-net-pci的結構    c) 呼叫qemu_opt_get(opts, "bus")獲取bus路徑,以/分隔各元件。這裡是pci.0    d) 如果bus路徑不為空,則呼叫qbus_find(path)來獲取bus例項(BusState結構)       qbus_find函式的流程如下:       d.1) 先找到路徑中的根bus,如果路徑以/開頭,則根bus為main_system_bus,否則,使用            qbus_find_recursive(main_system_bus, elem, NULL)來查詢。這裡的elem = "pci.0"       d.2) 如果整個路徑已經完成,則返回當前bus       d.2) parse出下一個元件,呼叫qbus_find_dev查詢對應的裝置       d.3) parse出下一個元件,呼叫qbus_find_bus查詢屬於上層裝置的子bus       d.4) 返回步驟2       由於這裡的值是pci.0,因此其實只進行了一次qbus_find_recursive呼叫    e) 如果bus路徑為空,則呼叫qbus_find_recursive(main_system_bus, NULL, info->bus_info)來獲取bus       例項。這裡的info是driver("virtio-net-pci")所對應的DeviceInfo,即最上面的結構       virtio-pci的初始化步驟是virtio_pci_register_devices -> pci_qdev_register_many ->        pci_qdev_register,在該函式中,會設定info->bus_info = &pci_bus_info,這樣就把PCIDeviceInfo       和pci的BusInfo聯絡起來了       qbus_find_recursive是一個遞迴函式,其流程如下:       e.1) 如果當前bus的名稱和指定的名稱相同(指定名稱不為空的情況下),並且當前bus指向的bus info和            指定的bus info相同(指定bus info不為空的情況下),則返回當前bus       e.2) 這裡是一個兩重迴圈:            對於當前bus所有附屬的裝置(bus->children為連結串列頭)                對於當前裝置所有的附屬bus(dev->child_bus為連結串列頭)                    呼叫qbus_find_recursive函式    f) 呼叫qdev_create_from_info(bus, info)來建立裝置,返回的是DeviceState結構。這裡其實返回的是       一個VirtIOPCIProxy例項,因為create的時候是根據qdev.size來分配記憶體大小的。    g) 如果qemu_opts_id(opts)不為空,則設定qdev->id    h) 呼叫qemu_opt_foreach(opts, set_property, qdev, 1)來設定裝置的各種屬性    i) 呼叫qdev_init來初始化裝置。    j) qdev_init會呼叫dev->info->init函式。這裡實際呼叫的函式是virtio_net_init_pci 在這裡也大致描述一下bus pci.0是如何生成的 1. 在main函式裡面很前面的地方會呼叫module_call_init(MODULE_INIT_MACHINE); 2. module_call_init會呼叫所有已註冊QEMUMachine的init函式。該版本的qemu是註冊了    pc_machine_rhel610, pc_machine_rhel600, pc_machine_rhel550, pc_machine_rhel544,    pc_machine_rhel540這幾個 (pc.c) 3. 這些Machine的init函式(pc_init_rhel600, ...)都會呼叫到pc_init_pci函式 4. pc_init_pci回撥用pc_init1,pc_init1在pci_enabled情況下會呼叫i440fx_init (piix_pci.c) 5. i440fx_init首先會呼叫qdev_create(NULL, "i440FX-pcihost")建立一個host device 6. 然後呼叫pci_bus_new在該裝置下面建立一個附屬的pci bus。在呼叫該函式時,傳遞的name為NULL。    下面再看看這個bus的名稱怎麼會變成pci.0的 7. pci_bus_new呼叫pci_bus_new_inplace(bus, parent, name, devfn_min),其中bus指向剛分配的    記憶體,parent是前面建立的host device,name為NULL,devfn_min為0 8. pci_bus_new_inplace會呼叫qbus_create_inplace(&bus->qbus, &pci_bus_info, parent, name),    注意這裡的第二個引數是&pci_bus_info 9. qbus_create_inplace在開始的地方會為該bus生成一個名稱。因為傳遞進來的name為NULL,並且    parent(那個host device)的id也為NULL,因此分支會跳到下面的程式碼         len = strlen(info->name) + 16;         buf = qemu_malloc(len);         len = snprintf(buf, len, "%s.%d", info->name,                        parent ? parent->num_child_bus : 0);         for (i = 0; i < len; i++)             buf[i] = qemu_tolower(buf[i]);         bus->name = buf; 10. 在該段程式碼中,info就是之前pci_bus_new_inplace呼叫時傳進來的&pci_bus_info,info->name是     字串"PCI"。並且,因為這是在host device上建立的第一個bus,因此parent->num_child_bus = 0,     最後經過小寫處理之後,該bus的名稱就成為了"pci.0"     這一段分析所對應的bus/device layout如下     main-system-bus ---->  i440FX-pcihost ----> pci.0

相關推薦

QEMU虛擬裝置建立流程

基於qemu-kvm-0.12.1.2-2.160.el6_1.8.src.rpm 虛擬網絡卡型別為virtio-net-pci virtio網絡卡裝置對應的命令列引數為  -device virtio-net-pci,netdev=hostnet0,id=net0,

qemu+kvm 建立虛擬機器並虛擬

Linux目前流行的開源虛擬化技術解決方案:                 主機虛擬化:xen, kvm, virtualbox                 容器級:lxc, libcontainer, runC, openvz                 模擬器

虛擬TUN/TAP裝置使用例項

文章出處:http://blog.csdn.net/solstice/article/details/6579232 轉載淵源:這篇文章源自陳碩老師的部落格,原文討論的主題是在繞開作業系統協議棧的情況下,對tcp併發連線數的支援情況;因為其中對TUN / TAP裝置的使用

20. ubuntu 16.04 LTS 建立虛擬

     在使用ubuntu 搭建一些測試環境的時候,有時一個ip地址是不能實現的,那麼就需要用到虛擬網絡卡的技術,虛擬多個ip地址. 在ubuntu 中虛擬網絡卡比較容易,可以在命令列中設定,也可以寫入配置檔案.在ubuntu 系統中新增虛擬網絡卡有兩步:       1

Linux下建立虛擬

方法一: 在eth0網絡卡上建立一個叫eth0:0的虛擬網絡卡並指定ip地址。 建立虛擬網絡卡:Sudo ifconfig eth0:0 192.168.1.5 up 刪除虛擬網絡卡:Sudo ifconfig eth0:0 down 重啟電腦或網路後,虛擬網絡卡消失,且

為openvpn建立tap虛擬

openvpn配置: 1、openvpn會使用tap虛擬網絡卡,安裝openvpn後會自動建立一個tap裝置。 2、需要建立兩個vpn連線時,就需要手動增加一個tap虛擬裝置。增加的方法為: "C:\Program Files\TAP-Windows\bin\tapinstall.exe" install

圖解幾個與Linux網路虛擬化相關的虛擬-VETH/MACVLAN/MACVTAP/IPVLAN

分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!http://blog.csdn.net/jiangjunshow 也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!        

Linux移除虛擬

今天上大資料實踐課時,使用學校提供的雲主機平臺建立了幾臺vps,但是安全組配置好之後發現無法用ssh無法登入,ping也不通,提示網路無法到達。 但是拿別人的電腦試了下能順利使用ssh連線。 有人說是我電腦防火牆的問題,對於這個說法我是萬萬不信的。 反覆觀察後發現: vps的地址是172.19.241.45

已解決 vmware 虛擬機器安裝後沒有虛擬問題

        我用的方法是重灌vmware ,使用的是win10的系統 。之前安裝網ubuntu以後,發現主機並沒有虛擬網絡卡,也百度了各種方法,然而並沒有什麼用,也問了很多人,他們也提供了各種方法,但是試過之後也都沒有什麼用,下面我就介紹一下我成功的操作步

新增橋,新增一對虛擬

新增網橋 新增網橋,名稱為br0 brctl addbr br0 將網橋關聯到網絡卡ens33 brctl addif br0 ens33 這裡如果你是ssh連線,執行完了你可能就會斷開連線了,所以最好吧這一步和下面幾步連在一起執行這樣就不會斷開了 brctl addif

安裝過VMware後,沒有虛擬vmnet1、vmnet8

原文地址:https://blog.csdn.net/qq_36769100/article/details/78802756 問題簡述: win8、win10系統,安裝過VMware後,在本地的網路介面卡中找不到相關的虛擬網絡卡VMnet。 解決步驟: 1.開

Linux Namespace Veth虛擬

Linux Namespace Network Namespace 建立networ

混合多系統虛擬核間中斷實現

APIC介紹APIC的全稱是Advanced Programmable Interrupt Controller,是8259控制器的升級版本。APIC包括了Local APIC和I/O APIC兩部分內容,Local APIC是總的控制器,位於CPU內部;I/O APIC主要用於處理外部裝置的中斷。引入

centos7 增加虛擬

確認核心是否有tun模組 # modinfo tun yum install tunctl -y 如果找不到 vim /etc/yum.repos.d/nux-misc.repo [nux-misc]name=Nux Miscbaseurl=http://li.nux.ro/download/nux

安裝VMware後,本機網路介面卡中沒有虛擬VMnet1、VMnet8

1、開啟本機服務,開啟相關的服務。   2、重置虛擬網路編輯器 1>開啟VMware,點選下圖左上角標註的"編輯",然後選中並進入"虛擬網路編輯器"。 2>還原預設設定   如果 "還原預設設定" 如上圖一

VMWare克隆CentOS後虛擬無法啟動

大家在學習linux時,會建立linux虛擬模板,然後我們會建立克隆,但克隆會檢視啟動過程會發現網絡卡無法啟動,此時我們需要如下操作。 vi /etc/sysconfig/network-scripts/ifcfg-eth0 #vi編輯器編輯這個檔案。 #按i進入編輯模式,刪除HWAD

VMware安裝後沒有虛擬VMnet1和VMnet8

筆者是大資料初學者,(同時也是第一次寫部落格,本著互相交流、互相學習的心態。不喜勿噴.....哈哈 )這兩天剛剛接觸到lunix的學習,昨天安裝好了VMware,今天進行了虛擬機器通訊的配置,對於建立好的虛擬機器,可以ping通網路,包括(主機的IP,閘道器,外

在win10環境下安裝vmware軟體後沒有vmnet1、vmnet8虛擬

在win10環境下安裝vmware軟體後沒有虛擬網絡卡!    此問題困擾已經半年之久,差點重灌系統,更甚至更換筆記本,網上的方法幾乎全部用過了,最後一波自己嘗試終於解決了!!!   解決辦法:  環境確認win10,                      

OpenVPN效能-多OpenVPN共享一個虛擬

                OpenVPN是一個很難評價的東西,我可以說出超過10個它的好處,併發出一些感慨。然而針對每一個優點,它卻又有些美中不足,然而這又有什麼大不了的呢,夠用就可以了吧!不過,如果你遇到了一些場合,它真的就不夠用了怎麼辦?答案只有一個,改掉它!     OpenVPN架設方便,配置簡

windows系統禁用多餘禁用看不到的虛擬(多個ip出現情況下)

轉載地址:https://jingyan.baidu.com/article/17bd8e522662b485ab2bb8eb.html 1.在計算機(我的電腦或此電腦)上點選滑鼠右鍵,選擇【管理】,開啟計算機管理控制器。 2.在計算機管理中,開啟【裝置管理器】,在右側可以看到本計算機的