zoukankan      html  css  js  c++  java
  • 追踪QEMU中PCI设备的初始化过程


    首先需要知道的一些背景知识:PCI是总线的名称,同时也可以是一个PCI bridge,这个bridge就是一个设备了。在这个bridge上可以挂多种PCI设备,例如virtio-block,virtio-net等设备,这些block或者net设备逻辑上挂载到PCI总线上,物理上连接到PCI bridge上。

    pci_qdev_realize这个函数位置设置断点。
    bt栈如下:

    Thread 1 "qemu-system-x86" hit Breakpoint 1, pci_qdev_realize (qdev=0x555556cb67f0, errp=0x7fffffffda40) at hw/pci/pci.c:2070
    2070	{
    (gdb) bt
    #0  pci_qdev_realize (qdev=0x555556cb67f0, errp=0x7fffffffda40) at hw/pci/pci.c:2070
    #1  0x0000555555a68aae in device_set_realized (obj=0x555556cb67f0, value=true, errp=0x7fffffffdc00) at hw/core/qdev.c:834
    #2  0x0000555555c4ba4f in property_set_bool (obj=0x555556cb67f0, v=0x555556cbb020, name=0x555555f6aa11 "realized", opaque=0x555556c7fdb0,
        errp=0x7fffffffdc00) at qom/object.c:2079
    #3  0x0000555555c49cb9 in object_property_set (obj=0x555556cb67f0, v=0x555556cbb020, name=0x555555f6aa11 "realized", errp=0x7fffffffdc00)
        at qom/object.c:1271
    #4  0x0000555555c4cdc4 in object_property_set_qobject (obj=0x555556cb67f0, value=0x555556cbaf70, name=0x555555f6aa11 "realized", errp=0x7fffffffdc00)
        at qom/qom-qobject.c:26
    #5  0x0000555555c49f97 in object_property_set_bool (obj=0x555556cb67f0, value=true, name=0x555555f6aa11 "realized", errp=0x7fffffffdc00)
        at qom/object.c:1337
    #6  0x0000555555a67790 in qdev_init_nofail (dev=0x555556cb67f0) at hw/core/qdev.c:321
    #7  0x0000555555b224c2 in pci_create_simple_multifunction (bus=0x555556c7f270, devfn=0, multifunction=false, name=0x555555f35b65 "i440FX")
        at hw/pci/pci.c:2131
    #8  0x0000555555b22526 in pci_create_simple (bus=0x555556c7f270, devfn=0, name=0x555555f35b65 "i440FX") at hw/pci/pci.c:2142
    #9  0x0000555555b199fe in i440fx_init (host_type=0x555555f35b6c "i440FX-pcihost", pci_type=0x555555f35b65 "i440FX", pi440fx_state=0x7fffffffdda8,
        piix3_devfn=0x7fffffffdd98, isa_bus=0x7fffffffdda0, pic=0x555556c7b5a0, address_space_mem=0x5555569b1a90, address_space_io=0x5555569b2510,
        ram_size=4294967296, below_4g_mem_size=3221225472, above_4g_mem_size=1073741824, pci_address_space=0x555556a60be0, ram_memory=0x555556a612d0)
        at hw/pci-host/piix.c:384
    #10 0x0000555555937e59 in pc_init1 (machine=0x5555569ad800, host_type=0x555555f35b6c "i440FX-pcihost", pci_type=0x555555f35b65 "i440FX")
        at /root/code/qemu-4.1.0/hw/i386/pc_piix.c:201
    #11 0x00005555559387e3 in pc_init_v4_1 (machine=0x5555569ad800) at /root/code/qemu-4.1.0/hw/i386/pc_piix.c:445
    #12 0x0000555555a71a49 in machine_run_board_init (machine=0x5555569ad800) at hw/core/machine.c:1132
    #13 0x00005555559fe083 in main (argc=25, argv=0x7fffffffe208, envp=0x7fffffffe2d8) at vl.c:4348
    

    其中需要注意的是相关的realized函数是在xxx_xxx_class_init()函数中设定的。例如,

    static void pci_device_class_init(ObjectClass *klass, void *data)
    {
        DeviceClass *k = DEVICE_CLASS(klass);
    
        k->realize = pci_qdev_realize;
        k->unrealize = pci_qdev_unrealize;
        k->bus_type = TYPE_PCI_BUS;
        k->props = pci_props;
    }
    
    1. 初始化i440FX
    Thread 1 "qemu-system-x86" hit Breakpoint 1, pci_create_simple (bus=0x555556c7f270, devfn=0, name=0x555555f35b65 "i440FX") at hw/pci/pci.c:2142
    #0  pci_create_simple (bus=0x555556c7f270, devfn=0, name=0x555555f35b65 "i440FX") at hw/pci/pci.c:2142
    #1  0x0000555555b199fe in i440fx_init (host_type=0x555555f35b6c "i440FX-pcihost", pci_type=0x555555f35b65 "i440FX", pi440fx_state=0x7fffffffdda8,
        piix3_devfn=0x7fffffffdd98, isa_bus=0x7fffffffdda0, pic=0x555556c7b5a0, address_space_mem=0x5555569b1a90, address_space_io=0x5555569b2510,
        ram_size=4294967296, below_4g_mem_size=3221225472, above_4g_mem_size=1073741824, pci_address_space=0x555556a60be0, ram_memory=0x555556a612d0)
        at hw/pci-host/piix.c:384
    #2  0x0000555555937e59 in pc_init1 (machine=0x5555569ad800, host_type=0x555555f35b6c "i440FX-pcihost", pci_type=0x555555f35b65 "i440FX")
        at /root/code/qemu-4.1.0/hw/i386/pc_piix.c:201
    #3  0x00005555559387e3 in pc_init_v4_1 (machine=0x5555569ad800) at /root/code/qemu-4.1.0/hw/i386/pc_piix.c:445
    #4  0x0000555555a71a49 in machine_run_board_init (machine=0x5555569ad800) at hw/core/machine.c:1132
    #5  0x00005555559fe083 in main (argc=25, argv=0x7fffffffe208, envp=0x7fffffffe2d8) at vl.c:4348
    
    2. 初始化VGA PCI设备
    Thread 1 "qemu-system-x86" hit Breakpoint 1, pci_create_simple (bus=0x555556c7f270, devfn=-1, name=0x555555fab6df "VGA") at hw/pci/pci.c:2142
    2142        return pci_create_simple_multifunction(bus, devfn, false, name);
    (gdb) bt
    #0  pci_create_simple (bus=0x555556c7f270, devfn=-1, name=0x555555fab6df "VGA") at hw/pci/pci.c:2142
    #1  0x0000555555b21e97 in pci_vga_init (bus=0x555556c7f270) at hw/pci/pci.c:1951
    #2  0x0000555555934085 in pc_vga_init (isa_bus=0x555556ffea70, pci_bus=0x555556c7f270) at /root/code/qemu-4.1.0/hw/i386/pc.c:1975
    #3  0x000055555593801a in pc_init1 (machine=0x5555569ad800, host_type=0x555555f35b6c "i440FX-pcihost", pci_type=0x555555f35b65 "i440FX")
        at /root/code/qemu-4.1.0/hw/i386/pc_piix.c:236
    #4  0x00005555559387e3 in pc_init_v4_1 (machine=0x5555569ad800) at /root/code/qemu-4.1.0/hw/i386/pc_piix.c:445
    #5  0x0000555555a71a49 in machine_run_board_init (machine=0x5555569ad800) at hw/core/machine.c:1132
    #6  0x00005555559fe083 in main (argc=25, argv=0x7fffffffe208, envp=0x7fffffffe2d8) at vl.c:4348
    
    3. 初始化芯片组PIIX3(控制IO)
    Thread 1 "qemu-system-x86" hit Breakpoint 1, pci_create_simple (bus=0x555556c7f270, devfn=9, name=0x555555f7240c "piix3-ide") at hw/pci/pci.c:2142
    2142        return pci_create_simple_multifunction(bus, devfn, false, name);
    (gdb) bt
    #0  pci_create_simple (bus=0x555556c7f270, devfn=9, name=0x555555f7240c "piix3-ide") at hw/pci/pci.c:2142
    #1  0x0000555555ab8dc3 in pci_piix3_ide_init (bus=0x555556c7f270, hd_table=0x7fffffffde50, devfn=9) at hw/ide/piix.c:229
    #2  0x0000555555938172 in pc_init1 (machine=0x5555569ad800, host_type=0x555555f35b6c "i440FX-pcihost", pci_type=0x555555f35b65 "i440FX")
        at /root/code/qemu-4.1.0/hw/i386/pc_piix.c:256
    #3  0x00005555559387e3 in pc_init_v4_1 (machine=0x5555569ad800) at /root/code/qemu-4.1.0/hw/i386/pc_piix.c:445
    #4  0x0000555555a71a49 in machine_run_board_init (machine=0x5555569ad800) at hw/core/machine.c:1132
    #5  0x00005555559fe083 in main (argc=25, argv=0x7fffffffe208, envp=0x7fffffffe2d8) at vl.c:4348
    

     命令行参数:
    -device virtio-blk-pci,iothread=iothreadxxx1,scsi=off,bus=pci.0,addr=0x6,drive=drive-virtio-disk1,id=virtio-disk0,disable-modern=off,disable-legacy=on 
    -drive format=raw,if=none,id=drive-virtio-disk1,cache=directsync,file=/data/rootfs.img,aio=native 
    

    对应的流程如下:

    1. 初始化virtio-pci的流程
    
    #0  pci_qdev_realize (qdev=0x55555789a4c0, errp=0x7fffffffdc30) at hw/pci/pci.c:2073
    #1  0x0000555555bae9e5 in virtio_pci_dc_realize (qdev=0x55555789a4c0, errp=0x7fffffffdc30) at hw/virtio/virtio-pci.c:1859
    #2  0x0000555555a68aae in device_set_realized (obj=0x55555789a4c0, value=true, errp=0x7fffffffde10) at hw/core/qdev.c:834
    #3  0x0000555555c4ba4f in property_set_bool (obj=0x55555789a4c0, v=0x5555578a7be0, name=0x555555f500f2 "realized", opaque=0x55555789a030,
        errp=0x7fffffffde10) at qom/object.c:2079
    #4  0x0000555555c49cb9 in object_property_set (obj=0x55555789a4c0, v=0x5555578a7be0, name=0x555555f500f2 "realized", errp=0x7fffffffde10)
        at qom/object.c:1271
    #5  0x0000555555c4cdc4 in object_property_set_qobject (obj=0x55555789a4c0, value=0x5555578a7840, name=0x555555f500f2 "realized", errp=0x7fffffffde10)
        at qom/qom-qobject.c:26
    #6  0x0000555555c49f97 in object_property_set_bool (obj=0x55555789a4c0, value=true, name=0x555555f500f2 "realized", errp=0x7fffffffde10)
        at qom/object.c:1337
    #7  0x00005555559f146b in qdev_device_add (opts=0x5555568fae30, errp=0x555556859010 <error_fatal>) at qdev-monitor.c:634
    #8  0x00005555559f916b in device_init_func (opaque=0x0, opts=0x5555568fae30, errp=0x555556859010 <error_fatal>) at vl.c:2191
    #9  0x0000555555d9b5bb in qemu_opts_foreach (list=0x555556676040 <qemu_device_opts>, func=0x5555559f9144 <device_init_func>, opaque=0x0,
        errp=0x555556859010 <error_fatal>) at util/qemu-option.c:1170
    #10 0x00005555559fe128 in main (argc=25, argv=0x7fffffffe208, envp=0x7fffffffe2d8) at vl.c:4372
    

    继续追踪到virtio-blk设备的realize,如下:

    Thread 1 "qemu-system-x86" hit Breakpoint 1, virtio_blk_pci_realize (vpci_dev=0x55555789a4c0, errp=0x7fffffffdb78)
        at /root/code/qemu-4.1.0/hw/virtio/virtio-blk-pci.c:50
    50          VirtIOBlkPCI *dev = VIRTIO_BLK_PCI(vpci_dev);
    (gdb) bt
    #0  virtio_blk_pci_realize (vpci_dev=0x55555789a4c0, errp=0x7fffffffdb78) at /root/code/qemu-4.1.0/hw/virtio/virtio-blk-pci.c:50
    #1  0x0000555555bae634 in virtio_pci_realize (pci_dev=0x55555789a4c0, errp=0x7fffffffdb78) at hw/virtio/virtio-pci.c:1788
    #2  0x0000555555b22308 in pci_qdev_realize (qdev=0x55555789a4c0, errp=0x7fffffffdc30) at hw/pci/pci.c:2092
    #3  0x0000555555bae9e5 in virtio_pci_dc_realize (qdev=0x55555789a4c0, errp=0x7fffffffdc30) at hw/virtio/virtio-pci.c:1859
    #4  0x0000555555a68aae in device_set_realized (obj=0x55555789a4c0, value=true, errp=0x7fffffffde10) at hw/core/qdev.c:834
    #5  0x0000555555c4ba4f in property_set_bool (obj=0x55555789a4c0, v=0x5555578a7be0, name=0x555555f500f2 "realized", opaque=0x55555789a030,
        errp=0x7fffffffde10) at qom/object.c:2079
    #6  0x0000555555c49cb9 in object_property_set (obj=0x55555789a4c0, v=0x5555578a7be0, name=0x555555f500f2 "realized", errp=0x7fffffffde10)
        at qom/object.c:1271
    #7  0x0000555555c4cdc4 in object_property_set_qobject (obj=0x55555789a4c0, value=0x5555578a7840, name=0x555555f500f2 "realized", errp=0x7fffffffde10)
        at qom/qom-qobject.c:26
    #8  0x0000555555c49f97 in object_property_set_bool (obj=0x55555789a4c0, value=true, name=0x555555f500f2 "realized", errp=0x7fffffffde10)
        at qom/object.c:1337
    #9  0x00005555559f146b in qdev_device_add (opts=0x5555568fae30, errp=0x555556859010 <error_fatal>) at qdev-monitor.c:634
    #10 0x00005555559f916b in device_init_func (opaque=0x0, opts=0x5555568fae30, errp=0x555556859010 <error_fatal>) at vl.c:2191
    --Type <RET> for more, q to quit, c to continue without paging--
    #11 0x0000555555d9b5bb in qemu_opts_foreach (list=0x555556676040 <qemu_device_opts>, func=0x5555559f9144 <device_init_func>, opaque=0x0,
        errp=0x555556859010 <error_fatal>) at util/qemu-option.c:1170
    #12 0x00005555559fe128 in main (argc=25, argv=0x7fffffffe208, envp=0x7fffffffe2d8) at vl.c:4372
    
    
    --------------------------------------------
    
    Thread 1 "qemu-system-x86" hit Breakpoint 1, virtio_blk_device_realize (dev=0x5555578a2630, errp=0x7fffffffd8e0)
        at /root/code/qemu-4.1.0/hw/block/virtio-blk.c:1097
    1097    {
    (gdb) bt
    #0  virtio_blk_device_realize (dev=0x5555578a2630, errp=0x7fffffffd8e0) at /root/code/qemu-4.1.0/hw/block/virtio-blk.c:1097
    #1  0x000055555591a452 in virtio_device_realize (dev=0x5555578a2630, errp=0x7fffffffd940) at /root/code/qemu-4.1.0/hw/virtio/virtio.c:2613
    #2  0x0000555555a68aae in device_set_realized (obj=0x5555578a2630, value=true, errp=0x7fffffffdb78) at hw/core/qdev.c:834
    #3  0x0000555555c4ba4f in property_set_bool (obj=0x5555578a2630, v=0x5555578a5fc0, name=0x555555f32f98 "realized", opaque=0x5555578a3cf0,
        errp=0x7fffffffdb78) at qom/object.c:2079
    #4  0x0000555555c49cb9 in object_property_set (obj=0x5555578a2630, v=0x5555578a5fc0, name=0x555555f32f98 "realized", errp=0x7fffffffdb78)
        at qom/object.c:1271
    #5  0x0000555555c4cdc4 in object_property_set_qobject (obj=0x5555578a2630, value=0x5555578a5f10, name=0x555555f32f98 "realized", errp=0x7fffffffdb78)
        at qom/qom-qobject.c:26
    #6  0x0000555555c49f97 in object_property_set_bool (obj=0x5555578a2630, value=true, name=0x555555f32f98 "realized", errp=0x7fffffffdb78)
        at qom/object.c:1337
    #7  0x000055555592dbc4 in virtio_blk_pci_realize (vpci_dev=0x55555789a4c0, errp=0x7fffffffdb78) at /root/code/qemu-4.1.0/hw/virtio/virtio-blk-pci.c:58
    #8  0x0000555555bae634 in virtio_pci_realize (pci_dev=0x55555789a4c0, errp=0x7fffffffdb78) at hw/virtio/virtio-pci.c:1788
    #9  0x0000555555b22308 in pci_qdev_realize (qdev=0x55555789a4c0, errp=0x7fffffffdc30) at hw/pci/pci.c:2092
    #10 0x0000555555bae9e5 in virtio_pci_dc_realize (qdev=0x55555789a4c0, errp=0x7fffffffdc30) at hw/virtio/virtio-pci.c:1859
    #11 0x0000555555a68aae in device_set_realized (obj=0x55555789a4c0, value=true, errp=0x7fffffffde10) at hw/core/qdev.c:834
    #12 0x0000555555c4ba4f in property_set_bool (obj=0x55555789a4c0, v=0x5555578a7be0, name=0x555555f500f2 "realized", opaque=0x55555789a030,
        errp=0x7fffffffde10) at qom/object.c:2079
    --Type <RET> for more, q to quit, c to continue without paging--
    #13 0x0000555555c49cb9 in object_property_set (obj=0x55555789a4c0, v=0x5555578a7be0, name=0x555555f500f2 "realized", errp=0x7fffffffde10)
        at qom/object.c:1271
    #14 0x0000555555c4cdc4 in object_property_set_qobject (obj=0x55555789a4c0, value=0x5555578a7840, name=0x555555f500f2 "realized", errp=0x7fffffffde10)
        at qom/qom-qobject.c:26
    #15 0x0000555555c49f97 in object_property_set_bool (obj=0x55555789a4c0, value=true, name=0x555555f500f2 "realized", errp=0x7fffffffde10)
        at qom/object.c:1337
    #16 0x00005555559f146b in qdev_device_add (opts=0x5555568fae30, errp=0x555556859010 <error_fatal>) at qdev-monitor.c:634
    #17 0x00005555559f916b in device_init_func (opaque=0x0, opts=0x5555568fae30, errp=0x555556859010 <error_fatal>) at vl.c:2191
    #18 0x0000555555d9b5bb in qemu_opts_foreach (list=0x555556676040 <qemu_device_opts>, func=0x5555559f9144 <device_init_func>, opaque=0x0,
        errp=0x555556859010 <error_fatal>) at util/qemu-option.c:1170
    #19 0x00005555559fe128 in main (argc=25, argv=0x7fffffffe208, envp=0x7fffffffe2d8) at vl.c:4372
    (gdb)
    

    参考文献:
    https://github.com/GiantVM/doc/blob/master/pci.md
    https://dangokyo.me/2018/03/28/qemu-internal-pci-device/

  • 相关阅读:
    SequenceInputStream
    BufferedReader
    FileWriter
    FileReader
    BufferedOutputStream
    javascript/html 禁止图片缓存
    localStorage util
    FormData上传文件 带进度条
    javascript 一些函数的实现 Function.prototype.bind, Array.prototype.map
    替代jquery中的几个函数
  • 原文地址:https://www.cnblogs.com/powerrailgun/p/12653864.html
Copyright © 2011-2022 走看看