ILD

qemu emulate virtio block device
作者:Yuan Jianpeng 邮箱:yuanjp89@163.com
发布时间:2024-12-22 站点:Inside Linux Development

要给qemu启动的系统添加块设备,涉及到两个部分,一个是在qemu启动命令行添加块设备,第二个是linux内核开启相关的驱动。

qemu block device options

根据qemu document 2.2.2 Block device options。添加块设备有3种方法,


方法一:

-hda file

-hdb file

-hdc file

-hdd file

    使用file,作为hard disk 0/1/2/3。


方法二:

-blockdev

-device

前者指定backend,后者添加一个block device。


blockdev基本语法:

-blockdev driver=xxx,node-name=xxx,


driver表示类型:有file/raw/qcow2,等等。

其中file是protocol-level,raw/qcow2是image format。有2层,后image format在protocol-level之上。


file

表示底层是用文件作为后备,选项:

filename=xxx,指定文件路径


raw

表示格式是raw,选项:

file=xxx,file的node name,指定protocol-level是哪个。


例如,以文件disk.img作为后备文件的raw格式:

-blockdev driver=file,node-name=disk_file,filename=disk.img
-blockdev driver=raw,node-name=disk,file=disk_file


可以合并:

-blockdev driver=raw,node-name=disk,file.driver=file,file.filename=disk.img


-device指定要添加到模拟系统的块设备,这个没有在手册找到说明,但是有一个ok的例子:

-device virtio-blk-pci,drive=drive0,id=virtblk0,num-queues=4 -drive file=disk0,if=none,id=drive0


方法三:

-drive file=file,if=interface,index=index,bus-bus,unit=unit,media=media


这个方法相当于-blockdev + -device。


if: 接口类型,有ide, scsi, sd, mtd, floppy, pflash, virtio, none

这个是个很重要的参数,决定了块设备添加到哪个接口,常见的有ide,scsi。不同的接口有不同的限制和通用性。


media:disk or cdrom


例子:

-drive driver=raw,file.driver=file,file.filename=disk0,if=virtio,media=disk

后备文件是disk0,格式是raw,接口是virtio,media是disk。


disk0可以用dd命令生成,比如生成一个32MB的。

$ dd if=/dev/zero of=disk0 bs=4096 count=8192


linux kernel virtio block driver config option

命令行添加块设备后,还需要内核开启块设备的支持。并且开启对应的接口。


我们以

-drive driver=raw,file.driver=file,file.filename=disk0,if=virtio,media=disk

为例,


接口使用的是virtio,对应的是内核virtio_blk,virtio,是virtual IO的缩写。virtio_blk是虚拟的block接口,qemu优先使用这个接口。


要开启的内核配置如下:

CONFIG_BLOCK=y

CONFIG_PCI=y

CONFIG_PCI_HOST_GENERIC=m

CONFIG_VIRTIO_PCI=m

CONFIG_PCI_HOST_GENERIC=m

CONFIG_VIRTIO_BLK=m


之前一直以为,只要开启VIRTIO_BLK即可,但是安装virtio_blk模块后,死活没有出现块设备,

直到使用defconfig编译内核后,才发现virtio_blk是构建在PCI之上的。


编译内核后启动,加载相关的内核模块。成功发现块设备。


# modprobe pci-host-generic
[   41.375727] pci-host-generic 4010000000.pcie: host bridge /pcie@10000000 ranges:
[   41.376452] pci-host-generic 4010000000.pcie:       IO 0x003eff0000..0x003effffff -> 0x0000000000
[   41.377026] pci-host-generic 4010000000.pcie:      MEM 0x0010000000..0x003efeffff -> 0x0010000000
[   41.377227] pci-host-generic 4010000000.pcie:      MEM 0x8000000000..0xffffffffff -> 0x8000000000
[   41.377770] pci-host-generic 4010000000.pcie: Memory resource size exceeds max for 32 bits
[   41.378606] pci-host-generic 4010000000.pcie: ECAM at [mem 0x4010000000-0x401fffffff] for [bus 00-ff]
[   41.379763] pci-host-generic 4010000000.pcie: PCI host bridge to bus 0000:00
[   41.380145] pci_bus 0000:00: root bus resource [bus 00-ff]
[   41.380323] pci_bus 0000:00: root bus resource [io  0x0000-0xffff]
[   41.380470] pci_bus 0000:00: root bus resource [mem 0x10000000-0x3efeffff]
[   41.380617] pci_bus 0000:00: root bus resource [mem 0x8000000000-0xffffffffff]
[   41.381647] pci 0000:00:00.0: [1b36:0008] type 00 class 0x060000 conventional PCI endpoint
[   41.384241] pci 0000:00:01.0: [1af4:1000] type 00 class 0x020000 conventional PCI endpoint
[   41.384615] pci 0000:00:01.0: BAR 0 [io  0x0000-0x001f]
[   41.384768] pci 0000:00:01.0: BAR 1 [mem 0x00000000-0x00000fff]
[   41.384939] pci 0000:00:01.0: BAR 4 [mem 0x00000000-0x00003fff 64bit pref]
[   41.385114] pci 0000:00:01.0: ROM [mem 0x00000000-0x0003ffff pref]
[   41.385501] pci 0000:00:02.0: [1af4:1001] type 00 class 0x010000 conventional PCI endpoint
[   41.385691] pci 0000:00:02.0: BAR 0 [io  0x0000-0x007f]
[   41.385948] pci 0000:00:02.0: BAR 1 [mem 0x00000000-0x00000fff]
[   41.386098] pci 0000:00:02.0: BAR 4 [mem 0x00000000-0x00003fff 64bit pref]
[   41.388217] pci 0000:00:01.0: ROM [mem 0x10000000-0x1003ffff pref]: assigned
[   41.388533] pci 0000:00:01.0: BAR 4 [mem 0x8000000000-0x8000003fff 64bit pref]: assigned
[   41.388797] pci 0000:00:02.0: BAR 4 [mem 0x8000004000-0x8000007fff 64bit pref]: assigned
[   41.388979] pci 0000:00:01.0: BAR 1 [mem 0x10040000-0x10040fff]: assigned
[   41.389159] pci 0000:00:02.0: BAR 1 [mem 0x10041000-0x10041fff]: assigned
[   41.389314] pci 0000:00:02.0: BAR 0 [io  0x1000-0x107f]: assigned
[   41.389471] pci 0000:00:01.0: BAR 0 [io  0x1080-0x109f]: assigned
[   41.389781] pci_bus 0000:00: resource 4 [io  0x0000-0xffff]
[   41.390114] pci_bus 0000:00: resource 5 [mem 0x10000000-0x3efeffff]
[   41.390252] pci_bus 0000:00: resource 6 [mem 0x8000000000-0xffffffffff]


# modprobe virtio_pci
[   53.673580] virtio-pci 0000:00:01.0: enabling device (0000 -> 0003)
[   53.676391] virtio-pci 0000:00:02.0: enabling device (0000 -> 0003)

# modprobe virtio_blk
[   70.373227] virtio_blk virtio1: 4/0/0 default/read/poll queues
[   70.385566] virtio_blk virtio1: [vda] 65536 512-byte logical blocks (33.6 MB/32.0 MiB)


# lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINTS
vda  254:0    0  32M  0 disk

# ls /sys/block/
vda


# ls /dev/vda -l
brw-------    1 root     0         254,   0 Jan  1 08:01 /dev/vda



Copyright © linuxdev.cc 2017-2024. Some Rights Reserved.