要给qemu启动的系统添加块设备,涉及到两个部分,一个是在qemu启动命令行添加块设备,第二个是linux内核开启相关的驱动。
根据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
命令行添加块设备后,还需要内核开启块设备的支持。并且开启对应的接口。
我们以
-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