android virtio-input驱动加载过程分析

目录

virtinput_probe调用的完整backtrace

kernel_init到do_one_initcall

virtio_input_driver_init通过bus匹配device和driver的过程

register_virtio_driver

driver_register

__driver_attach

小结

device配置信息失踪之谜

在virtio-mmio中添加debug log

在bus_for_each_dev添加debug log

转译fdt文件

是谁修改了dts数据?

 register_for_ssr_events函数

virtinput_probe调用的完整backtrace

下面是virtinput_probe被调用过程完整的backtrace(你可以通过在virtinput_probe函数中加入WARN_ON()把这些信息输出到内核日志中).

virtinput_probe+0xfc/0xaec
virtio_dev_probe+0x1a8/0x474
really_probe+0x1cc/0x78c
driver_probe_device+0xb4/0x13c
device_driver_attach+0x6c/0xac
__driver_attach+0xd4/0x22c
bus_for_each_dev+0x9c/0x108
driver_attach+0x24/0x30
bus_add_driver+0x124/0x204
driver_register+0x78/0x114
register_virtio_driver+0x2c/0x3c
virtio_input_driver_init+0x18/0x24
do_one_initcall+0x198/0x368
do_initcall_level+0x188/0x1b0
do_basic_setup+0x30/0x4c
kernel_init_freeable+0xc0/0x140
kernel_init+0x18/0x2b4

这个backtrace大致分为了三个部分:

1,kernel_init到do_one_initcall

2,virtio_input_driver_init通过bus去匹配device和driver的过程

3,virtinput_probe

kernel_init到do_one_initcall

这个过程相对清晰,简单来说就是,kernel_init内核线程会调用do_initcall_level依次去加载各个level的驱动模块,这些驱动模块被分为了很多个level,每个level加载的优先并不同。 这些驱动模块在内核编译的时候已经按照对应的level存在于内核镜像中,最终由do_one_initcall通过不同的offset调用到函数的入口.

virtio_input_driver_init通过bus匹配device和driver的过程

前面提到do_one_initcall会调用各个fn来完成驱动加载,而这些fn是已经编译在内核镜像中,在链接的过程中,放在了对应的section.内核在编译的时候通过kernel config知道那些module是需要编译的。

以当前virtio-input这个驱动函数为例,do_one_initcall函数中的fn函数即为virtio_input_driver_init

int __init_or_module do_one_initcall(initcall_t fn)
{
    int count = preempt_count();
    char msgbuf[64];
    int ret;
 
    if (initcall_blacklisted(fn))
        return -EPERM;
 
    do_trace_initcall_start(fn);
    ret = fn();
    do_trace_initcall_finish(fn, ret);

需要注意的是我们并不能在内核源码中直接搜索到这个函数,这个函数通常是一个宏定义函数。分析源码文件:drivers/virtio/virtio_input.c

module_virtio_driver(virtio_input_driver);
MODULE_DEVICE_TABLE(virtio, id_table);
 
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("Virtio input device driver");
MODULE_AUTHOR("Gerd Hoffmann <[email protected]>")

module_virtio_driver定义在文件include/linux/virtio.h


/* module_virtio_driver() - Helper macro for drivers that don't do
 * anything special in module init/exit.  This eliminates a lot of
 * boilerplate.  Each module may only use this macro once, and
 * calling it replaces module_init() and module_exit()
 */
#define module_virtio_driver(__virtio_driver) \
    module_driver(__virtio_driver, register_virtio_driver, \
            unregister_virtio_driver)
#endif /* _LINUX_VIRTIO_H */

而module_driver的定义在文件:include/linux/device.h

#define module_driver(__driver, __register, __unregister, ...) \
static int __init __driver##_init(void) \
{ \
    return __register(&(__driver) , ##__VA_ARGS__); \
} \
module_init(__driver##_init); \
static void __exit __driver##_exit(void) \
{ \
    __unregister(&(__driver) , ##__VA_ARGS__); \
} \
module_exit(__driver##_exit);

看到这里就清晰了virtio_input_driver_init函数定义,他是由virtio_input_driver + _init构成的. 最终由内核的module_init宏定义注册到内核中. 在内核调用do_one_initcall挨个调用对应的init函数时,最终会调用到上面宏定义中的__register函数,这个函数其实就是register_virtio_driver(module_driver宏定义中第二个宏参数).

register_virtio_driver会调用driver_register走标准的linux设备驱动模型流程,最终调用了virtinput_probe.

really_probe+0x1cc/0x78c
driver_probe_device+0xb4/0x13c
device_driver_attach+0x6c/0xac
__driver_attach+0xd4/0x22c
bus_for_each_dev+0x9c/0x108
driver_attach+0x24/0x30
bus_add_driver+0x124/0x204
driver_register+0x78/0x114

我们知道,标准的linux设备驱动模型涉及到三个概念:bus、driver、device,这里:

bus:virtio, 是core level的驱动,是一种bus驱动。源码文件为:drivers/virtio/virtio.c, 其他virtio设备也是基于这个bus,例如virtio-i2c/virtio-blk等.

static struct bus_type virtio_bus = {
    .name  = "virtio",
    .match = virtio_dev_match,
    .dev_groups = virtio_dev_groups,
    .uevent = virtio_uevent,
    .probe = virtio_dev_probe,
    .remove = virtio_dev_remove,
};
...skip...
static void __exit virtio_exit(void)
{
    bus_unregister(&virtio_bus);
    ida_destroy(&virtio_index_ida);
}
core_initcall(virtio_init);
module_exit(virtio_exit);

driver:这里是virtio_input_driver

device: 暂时还没找着,通常device node信息一般是由dts解析后得到,但是我们搜索了使用的dts文件,并没有发现和virtio-input相关的节点.

不过没关系,我们从virtio_input_driver_init函数开始分析,看看他是如何真正调用到probe函数的.

register_virtio_driver

前面我们提到virtio_input_driver_init在注册的时候实际调用的是register_virtio_driver函数:

int register_virtio_driver(struct virtio_driver *driver)
{
    /* Catch this early. */
    BUG_ON(driver->feature_table_size && !driver->feature_table);
    driver->driver.bus = &virtio_bus;
    return driver_register(&driver->driver);
}

这个函数实现很简单,先判断了驱动中的feature_table_size 和feature_table是否已经被正常赋值.,然后将驱动与bus挂钩.

driver_register

...skip....
    other = driver_find(drv->name, drv->bus);
    if (other) {
        printk(KERN_ERR "Error: Driver '%s' is already registered, "
            "aborting...\n", drv->name);
        return -EBUSY;
    }  
    ret = bus_add_driver(drv);
    if (ret)
        return ret;
    ret = driver_add_groups(drv, drv->groups);
    if (ret) {
        bus_remove_driver(drv);
        return ret;
    }  
    kobject_uevent(&drv->p->kobj, KOBJ_ADD);

这个函数开始会做一些判断,比如判断这个driver是不是已经加载到bus过,其中最重要的是bus_add_driver函数。

__driver_attach

这个函数经过一些列的调用之后,最后调用到了__driver_attach函数,这个函数中最重要的是调用是:ret = driver_match_device(drv, dev);

这行代码是真正将driver和device匹配起来的地方.

这个函数代码实现也很简单,如果bus有自己的match函数,则调用bus自己的match接口,否则直接返回1.

static inline int driver_match_device(struct device_driver *drv,
                      struct device *dev)
{
    return drv->bus->match ? drv->bus->match(dev, drv) : 1;
}

而virtio bus的match函数实现如下

static inline int virtio_id_match(const struct virtio_device *dev,
                  const struct virtio_device_id *id)
{
    if (id->device != dev->id.device && id->device != VIRTIO_DEV_ANY_ID)
        return 0;
 
    return id->vendor == VIRTIO_DEV_ANY_ID || id->vendor == dev->id.vendor;
}
 
/* This looks through all the IDs a driver claims to support.  If any of them
 * match, we return 1 and the kernel will call virtio_dev_probe(). */
static int virtio_dev_match(struct device *_dv, struct device_driver *_dr)
{
    unsigned int i;
    struct virtio_device *dev = dev_to_virtio(_dv);
    const struct virtio_device_id *ids;
 
    ids = drv_to_virtio(_dr)->id_table;
    for (i = 0; ids[i].device; i++)
        if (virtio_id_match(dev, &ids[i]))
            return 1;
    return 0;
}

可以看到,driver和device是否会match是通过条件id->vendor == VIRTIO_DEV_ANY_ID || id->vendor == dev→id.vendor来判定的.而在驱动drivers/virtio/virtio_input.c中:

static struct virtio_device_id id_table[] = {
    { VIRTIO_ID_INPUT, VIRTIO_DEV_ANY_ID },
    { 0 },
};

小结

整个virtio-input加载的过程大致分为了三个部分

1,kernel_init到do_one_initcall

这个过程比较清晰

2,virtio_input_driver_init通过bus去匹配device和driver的过程

这个过程遵循了标准的linux设备驱动模型,在device-driver匹配的过程中,调用了bus定义的match函数去匹配driver和device。在virtio-input驱动中,通过id_table去匹配驱动和设备.

3,virtinput_probe

我们知道一般来说,device负责提供硬件资源信息,比如gpio/寄存器地址等等,但是目前为止,我们还没发现virtio-input设备有提供任何硬件资源信息。

device配置信息失踪之谜

前面我们提到我们在kernel的dts和驱动源码中是找不到任何virtio-touch的配置信息的,但是实际上,virtio-touch驱动加载和工作没有问题,这个就很奇怪了。

因为理论上,不管怎样virtio-touch都应该应该遵循linux平台设备驱动模型,bus driver device 三者缺一不可。

在virtio-mmio中添加debug log

virtio-mmio是内核中virtio起的最早的virtio模块,在这个模块的probe函数中,添加log:

printk("for debug virtio_mmio_probe pdev->name:%s\n", pdev→name);

发现即使在这个时候打印log,发现pdev->name也已经被赋值了,而且查看整个mmio的驱动,好像没有那些地方存在于qnx通信的接口。

这就更奇怪了,因为这个实验说明,我们上面的猜想可能是不成立的,我们需要找到最早内核把dtb转译成device node的地方,在那个地方添加log。

在bus_for_each_dev添加debug log

在这个函数中添加log,会把内核中所有的device node的名字都打印出来,添加log后发现,即使在内核最开始的时候,virtio-touch的节点就已经存在。

 怀疑是不是内核拿到的dtb数据就是已经添加了dts node的数据?

转译fdt文件

我们知道内核中的msmnile_gvmq:/sys/firmware/fdt 文件就是内核dtb文件,我们可以把这个文件转换成dts,确认里面是否包含virtio-input的节点。

使用指令:dtc  -I dtb -o sa8295p-vm.dts fdt 转换得到dts文件,在里面我们能找到:

 说明内核拿到的dtb数据中的确是添加了virtio-input节点的.

是谁修改了dts数据?

观察每次la启动的日志文件la_gvm.txt,可以看到有几行log

怀疑这几行log是添加修改dts的地方,尝试修改linux-la.config之后发现,删除vdev vdev-virtio-input.so节点的同时,下面几行log的输出也会变少.比如下面的log删除了两个vdev vdev-virtio-input.so节点(原本有三个)

我们尝试从这里面入手.

 register_for_ssr_events函数

在QNX中搜索register_for_ssr_events,可以发现文件 AMSS/platform/vm/vdev/vdev-glink-ssr/vdev.c +683 存在函数register_for_ssr_events,其中就有对dts的操作


static int register_for_ssr_events(glink_ssr_virt_dev_t *dev)
{
    uint64_t client_magic = 0;
    uint32_t event_mask = 0;
    char * client_name = "vdev_glink_ssr";
    void *handle;
    const void *fdt;
    int offset;
    int ret = EOK;
        QVM_LOG(GLINK_SSRVIRTLOG_ERROR, "%s ++", __func__);
        printf("%s ++\r\n", __func__);
 
    fdt = fdt_get_root();
    if (!fdt) {
        QVM_LOG(GLINK_SSRVIRTLOG_ERROR, "/glink-ssr fdt_get_root failed");
        return -1;
    }

不过深入去研究之后发现,真正virtio的register_for_ssr_events函数并不是在这个模块中调用的,只是上面的模块展示了virtio-input库中可能的用法(这个库并不开源)

不过我们可以用objdump看看内部函数:

root@ubuntu$ ~/SDP/./host/linux/x86_64/usr/bin/ntoaarch64-objdump -x ./qnx_bins/prebuilt_QNX700/target/qnx7/x86_64/lib/dll/vdev-virtio-input.so
 
./qnx_bins/prebuilt_QNX700/target/qnx7/x86_64/lib/dll/vdev-virtio-input.so:     file format elf64-little
./qnx_bins/prebuilt_QNX700/target/qnx7/x86_64/lib/dll/vdev-virtio-input.so
architecture: UNKNOWN!, flags 0x00000150:
HAS_SYMS, DYNAMIC, D_PAGED
start address 0x0000000000001dc0
 
Program Header:
    LOAD off    0x0000000000000000 vaddr 0x0000000000000000 paddr 0x0000000000000000 align 2**21
         filesz 0x0000000000024a34 memsz 0x0000000000024a34 flags r-x
    LOAD off    0x0000000000024b20 vaddr 0x0000000000224b20 paddr 0x0000000000224b20 align 2**21
         filesz 0x0000000000000558 memsz 0x00000000000005b0 flags rw-
 DYNAMIC off    0x0000000000024b88 vaddr 0x0000000000224b88 paddr 0x0000000000224b88 align 2**3
         filesz 0x00000000000001e0 memsz 0x00000000000001e0 flags rw-
    NOTE off    0x00000000000001c8 vaddr 0x00000000000001c8 paddr 0x00000000000001c8 align 2**2
         filesz 0x0000000000000020 memsz 0x0000000000000020 flags r--
    NOTE off    0x0000000000024a1c vaddr 0x0000000000024a1c paddr 0x0000000000024a1c align 2**2
         filesz 0x0000000000000018 memsz 0x0000000000000018 flags r--
EH_FRAME off    0x0000000000024408 vaddr 0x0000000000024408 paddr 0x0000000000024408 align 2**2
         filesz 0x00000000000000bc memsz 0x00000000000000bc flags r--
   RELRO off    0x0000000000024b20 vaddr 0x0000000000224b20 paddr 0x0000000000224b20 align 2**0
         filesz 0x00000000000004e0 memsz 0x00000000000004e0 flags r--
 
Dynamic Section:
  NEEDED               libscreen.so.1
  NEEDED               libc.so.4
  SONAME               vdev-virtio-input.so
  SYMBOLIC             0x0000000000000000
  INIT                 0x0000000000001930
  FINI                 0x000000000000585a
  INIT_ARRAY           0x0000000000224b20
  INIT_ARRAYSZ         0x0000000000000010
  FINI_ARRAY           0x0000000000224b30
  FINI_ARRAYSZ         0x0000000000000008
  GNU_HASH             0x00000000000001e8
  STRTAB               0x0000000000000a40
  SYMTAB               0x0000000000000230
  STRSZ                0x0000000000000607
  SYMENT               0x0000000000000018
  PLTGOT               0x0000000000224d68
  PLTRELSZ             0x00000000000006a8
  PLTREL               0x0000000000000007
  JMPREL               0x0000000000001288
  RELA                 0x0000000000001048
  RELASZ               0x0000000000000240
  RELAENT              0x0000000000000018
  BIND_NOW             0x0000000000000000
  FLAGS_1              0x0000000000000001
  RELACOUNT            0x0000000000000011
 
Sections:
Idx Name          Size      VMA               LMA               File off  Algn
  0 .note.gnu.build-id 00000020  00000000000001c8  00000000000001c8  000001c8  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  1 .gnu.hash     00000048  00000000000001e8  00000000000001e8  000001e8  2**3
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  2 .dynsym       00000810  0000000000000230  0000000000000230  00000230  2**3
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  3 .dynstr       00000607  0000000000000a40  0000000000000a40  00000a40  2**0
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  4 .rela.dyn     00000240  0000000000001048  0000000000001048  00001048  2**3
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  5 .rela.plt     000006a8  0000000000001288  0000000000001288  00001288  2**3
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  6 .init         00000009  0000000000001930  0000000000001930  00001930  2**0
                  CONTENTS, ALLOC, LOAD, READONLY, CODE
  7 .plt          00000480  0000000000001940  0000000000001940  00001940  2**4
                  CONTENTS, ALLOC, LOAD, READONLY, CODE
  8 .text         00003a9a  0000000000001dc0  0000000000001dc0  00001dc0  2**4
                  CONTENTS, ALLOC, LOAD, READONLY, CODE
  9 .fini         00000009  000000000000585a  000000000000585a  0000585a  2**0
                  CONTENTS, ALLOC, LOAD, READONLY, CODE
 10 .rodata       0001eb88  0000000000005880  0000000000005880  00005880  2**5
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
 11 .eh_frame_hdr 000000bc  0000000000024408  0000000000024408  00024408  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
 12 .eh_frame     00000554  00000000000244c8  00000000000244c8  000244c8  2**3
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
 13 .note         00000018  0000000000024a1c  0000000000024a1c  00024a1c  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
 14 .init_array   00000010  0000000000224b20  0000000000224b20  00024b20  2**3
                  CONTENTS, ALLOC, LOAD, DATA
 15 .fini_array   00000008  0000000000224b30  0000000000224b30  00024b30  2**3
                  CONTENTS, ALLOC, LOAD, DATA
 16 .jcr          00000008  0000000000224b38  0000000000224b38  00024b38  2**3
                  CONTENTS, ALLOC, LOAD, DATA
 17 .data.rel.ro  00000048  0000000000224b40  0000000000224b40  00024b40  2**5
                  CONTENTS, ALLOC, LOAD, DATA
 18 .dynamic      000001e0  0000000000224b88  0000000000224b88  00024b88  2**3
                  CONTENTS, ALLOC, LOAD, DATA
 19 .got          00000288  0000000000224d68  0000000000224d68  00024d68  2**3
                  CONTENTS, ALLOC, LOAD, DATA
 20 .data         00000078  0000000000225000  0000000000225000  00025000  2**5
                  CONTENTS, ALLOC, LOAD, DATA
 21 .bss          00000050  0000000000225080  0000000000225080  00025078  2**5
                  ALLOC
 22 .comment      0000003e  0000000000000000  0000000000000000  00025078  2**0
                  CONTENTS, READONLY
 23 QNX_usage     00000cc4  0000000000000000  0000000000000000  000250b6  2**0
                  CONTENTS, READONLY
 24 .gnu_debuglink 00000020  0000000000000000  0000000000000000  00025d7a  2**0
                  CONTENTS, READONLY
 25 QNX_info      000000ed  0000000000000000  0000000000000000  00025d9a  2**0
                  CONTENTS, READONLY
SYMBOL TABLE:
0000000000000001 l       *ABS*  0000000000000000 __pic__
0000000000000001 l       *ABS*  0000000000000000 __PIC__
0000000000000001 l       *ABS*  0000000000000000 __pic__
0000000000000001 l       *ABS*  0000000000000000 __PIC__
0000000000024508 l     O .eh_frame  0000000000000000 __EH_FRAME_BEGIN__
0000000000224b38 l     O .jcr   0000000000000000 __JCR_LIST__
0000000000001de0 l     F .text  0000000000000000 deregister_tm_clones
0000000000001e20 l     F .text  0000000000000000 register_tm_clones
0000000000001e70 l     F .text  0000000000000000 __do_global_dtors_aux
0000000000225080 l     O .bss   0000000000000001 completed.6154
0000000000224b30 l     O .fini_array    0000000000000000 __do_global_dtors_aux_fini_array_entry
0000000000001ec0 l     F .text  0000000000000000 frame_dummy
00000000002250a0 l     O .bss   0000000000000030 object.6159
0000000000224b20 l     O .init_array    0000000000000000 __frame_dummy_init_array_entry
0000000000000001 l       *ABS*  0000000000000000 __pic__
0000000000000001 l       *ABS*  0000000000000000 __PIC__
0000000000001f10 l     F .text  0000000000000033 vdinput_pulse
0000000000001f50 l     F .text  000000000000022b vi_event_transfer
0000000000002180 l     F .text  00000000000000a9 vdinput_vread
0000000000002230 l     F .text  0000000000000132 vi_device_lookup
0000000000002370 l     F .text  000000000000004c vi_device_touches
00000000000023c0 l     F .text  0000000000000081 vi_device_coords
0000000000002450 l     F .text  000000000000008c vi_device_moved
00000000000024e0 l     F .text  0000000000000077 vi_config_insert.isra.9
0000000000002560 l     F .text  00000000000002f3 abs_dimensions
0000000000002860 l     F .text  000000000000007d vi_config_merge
00000000000028e0 l     F .text  000000000000069b screen_device_insertion
0000000000005d80 l     O .rodata    000000000001e4ce keyboard_map_keys
0000000000005d68 l     O .rodata    000000000000000a touch_map_taps
0000000000005d78 l     O .rodata    0000000000000008 pointer_map_buttons
0000000000002f80 l     F .text  0000000000001559 event_via_screen
0000000000005d50 l     O .rodata    0000000000000011 __func__.10353
0000000000005d20 l     O .rodata    0000000000000008 overflow.10144
0000000000005d30 l     O .rodata    0000000000000017 __func__.10307
00000000000044e0 l     F .text  00000000000000a3 vi_state_reset
0000000000004590 l     F .text  00000000000002b3 vdinput_vwrite
0000000000004850 l     F .text  000000000000007a vdinput_pulse_thread
0000000000004a20 l     F .text  00000000000005cf vi_screen_setup
0000000000004ff0 l     F .text  000000000000077b vdinput_control
0000000000024260 l     O .rodata    0000000000000020 input_description
0000000000001dc0 l     F .text  0000000000000011 vdinput_register
0000000000225020 l     O .data  0000000000000058 vdinput_factory.10591
0000000000224b40 l     O .data.rel.ro   0000000000000048 vdinput_options.10590
0000000000000001 l       *ABS*  0000000000000000 __pic__
0000000000000001 l       *ABS*  0000000000000000 __PIC__
0000000000000001 l       *ABS*  0000000000000000 __pic__
0000000000000001 l       *ABS*  0000000000000000 __PIC__
0000000000024a18 l     O .eh_frame  0000000000000000 __FRAME_END__
0000000000224b38 l     O .jcr   0000000000000000 __JCR_END__
0000000000224b88 l     O .dynamic   0000000000000000 _DYNAMIC
0000000000225078 l     O .data  0000000000000000 __TMC_END__
0000000000225000 l     O .data  0000000000000000 __dso_handle
0000000000224d68 l     O .got   0000000000000000 _GLOBAL_OFFSET_TABLE_
00000000000001c8 l    d  .note.gnu.build-id 0000000000000000 .note.gnu.build-id
00000000000001e8 l    d  .gnu.hash  0000000000000000 .gnu.hash
0000000000000230 l    d  .dynsym    0000000000000000 .dynsym
0000000000000a40 l    d  .dynstr    0000000000000000 .dynstr
0000000000001048 l    d  .rela.dyn  0000000000000000 .rela.dyn
0000000000001288 l    d  .rela.plt  0000000000000000 .rela.plt
0000000000001930 l    d  .init  0000000000000000 .init
0000000000001940 l    d  .plt   0000000000000000 .plt
0000000000001dc0 l    d  .text  0000000000000000 .text
000000000000585a l    d  .fini  0000000000000000 .fini
0000000000005880 l    d  .rodata    0000000000000000 .rodata
0000000000024408 l    d  .eh_frame_hdr  0000000000000000 .eh_frame_hdr
00000000000244c8 l    d  .eh_frame  0000000000000000 .eh_frame
0000000000024a1c l    d  .note  0000000000000000 .note
0000000000224b20 l    d  .init_array    0000000000000000 .init_array
0000000000224b30 l    d  .fini_array    0000000000000000 .fini_array
0000000000224b38 l    d  .jcr   0000000000000000 .jcr
0000000000224b40 l    d  .data.rel.ro   0000000000000000 .data.rel.ro
0000000000224b88 l    d  .dynamic   0000000000000000 .dynamic
0000000000224d68 l    d  .got   0000000000000000 .got
0000000000225000 l    d  .data  0000000000000000 .data
0000000000225080 l    d  .bss   0000000000000000 .bss
0000000000000000 l    d  .comment   0000000000000000 .comment
0000000000000000 l    d  QNX_usage  0000000000000000 QNX_usage
0000000000000000 l    d  .gnu_debuglink 0000000000000000 .gnu_debuglink
0000000000000000 l    d  QNX_info   0000000000000000 QNX_info
0000000000000000         *UND*  0000000000000000 vio_setup_queues
0000000000005770 g     F .text  0000000000000033 virtq_avail_get
0000000000000000         *UND*  0000000000000000 guest_cpu_read
0000000000000000       F *UND*  0000000000000000 pthread_cond_signal
0000000000000000       F *UND*  0000000000000000 screen_get_window_property_pv
0000000000000000       F *UND*  0000000000000000 strerror
0000000000000000         *UND*  0000000000000000 gfdt_update_prop_string
00000000000057b0 g     F .text  00000000000000aa virtq_used_put_notify
0000000000000000       F *UND*  0000000000000000 screen_set_window_property_pv
0000000000000000       F *UND*  0000000000000000 snprintf
0000000000000000       F *UND*  0000000000000000 screen_get_device_property_iv
00000000000048d0 g     F .text  0000000000000141 set_display
0000000000000000         *UND*  0000000000000000 vio_ctrl_pci_bars
0000000000000000       O *UND*  0000000000000000 __stack_chk_guard
0000000000000000         *UND*  0000000000000000 qvm_outf
0000000000000000       F *UND*  0000000000000000 screen_create_window_buffers
0000000000000000       F *UND*  0000000000000000 getpid
0000000000000000       F *UND*  0000000000000000 screen_destroy_event
0000000000000000       F *UND*  0000000000000000 screen_flush_context
0000000000000000       F *UND*  0000000000000000 pthread_cancel
0000000000000000       F *UND*  0000000000000000 screen_create_window_type
0000000000000000         *UND*  0000000000000000 gasp_unmap
0000000000000000  w    F *UND*  0000000000000000 __cxa_finalize
0000000000000000       F *UND*  0000000000000000 screen_set_session_property_pv
0000000000000000       F *UND*  0000000000000000 malloc
0000000000000000       F *UND*  0000000000000000 screen_destroy_session
0000000000000000         *UND*  0000000000000000 vio_init_queue
0000000000000000       F *UND*  0000000000000000 screen_destroy_window
0000000000000000       F *UND*  0000000000000000 screen_set_session_property_iv
0000000000000000         *UND*  0000000000000000 qvm_outff
0000000000000000       F *UND*  0000000000000000 __stack_chk_fail
0000000000001930 g     F .init  0000000000000000 _init
0000000000000000       F *UND*  0000000000000000 screen_create_event
0000000000000000       F *UND*  0000000000000000 screen_set_window_property_iv
0000000000000000       F *UND*  0000000000000000 screen_get_event
0000000000000000       F *UND*  0000000000000000 calloc
0000000000000000       F *UND*  0000000000000000 screen_get_event_property_pv
0000000000000000       F *UND*  0000000000000000 screen_notify
0000000000000000  w      *UND*  0000000000000000 __deregister_frame_info
0000000000000000         *UND*  0000000000000000 vio_read
0000000000000000  w      *UND*  0000000000000000 _ITM_registerTMCloneTable
0000000000000000         *UND*  0000000000000000 guest_cpu_write
0000000000000000       F *UND*  0000000000000000 __get_errno_ptr
0000000000000000         *UND*  0000000000000000 gfdt_update_reg
0000000000000000         *UND*  0000000000000000 gfdt_update_node
0000000000000000         *UND*  0000000000000000 vdev_register_factory
0000000000000000       F *UND*  0000000000000000 screen_create_session_type
0000000000000000       F *UND*  0000000000000000 strlcpy
0000000000000000       F *UND*  0000000000000000 strncmp
0000000000000000       F *UND*  0000000000000000 pthread_cond_init
0000000000000000       F *UND*  0000000000000000 sscanf
0000000000001dc0 g       .text  0000000000000000 _btext
0000000000000000       F *UND*  0000000000000000 screen_set_window_property_cv
0000000000000000  w      *UND*  0000000000000000 _ITM_deregisterTMCloneTable
0000000000225078 g       .bss   0000000000000000 __bss_start
0000000000000000       F *UND*  0000000000000000 memset
0000000000000000         *UND*  0000000000000000 qvm_parse_num
0000000000000000       F *UND*  0000000000000000 screen_get_window_property_cv
0000000000000000       F *UND*  0000000000000000 strcmp
0000000000000000       F *UND*  0000000000000000 pthread_mutex_unlock
0000000000000000         *UND*  0000000000000000 vio_write
000000000000585a g     F .fini  0000000000000000 _fini
0000000000000000       F *UND*  0000000000000000 screen_get_window_property_iv
0000000000000000       F *UND*  0000000000000000 screen_get_event_property_iv
0000000000000000         *UND*  0000000000000000 vio_init
0000000000000000       F *UND*  0000000000000000 screen_create_context
0000000000225078 g       .data  0000000000000000 _edata
00000000002250d0 g       .bss   0000000000000000 _end
0000000000000000       F *UND*  0000000000000000 pthread_mutex_lock
0000000000000000       F *UND*  0000000000000000 pthread_cond_wait
0000000000000000         *UND*  0000000000000000 vio_reset
0000000000000000       F *UND*  0000000000000000 pthread_cond_destroy
0000000000000000         *UND*  0000000000000000 gfdt_update_interrupts
0000000000000000       F *UND*  0000000000000000 screen_get_context_property_pv
0000000000000000       F *UND*  0000000000000000 screen_get_display_property_iv
0000000000000000         *UND*  0000000000000000 vdev_pulse
0000000000000000       F *UND*  0000000000000000 screen_destroy_context
0000000000000000         *UND*  0000000000000000 gasp_map_vdma
0000000000000000  w      *UND*  0000000000000000 _Jv_RegisterClasses
0000000000000000       F *UND*  0000000000000000 pthread_join
0000000000000000  w      *UND*  0000000000000000 __register_frame_info
0000000000000000         *UND*  0000000000000000 vdev_thread_create
0000000000000000       F *UND*  0000000000000000 screen_get_context_property_iv
0000000000000000       F *UND*  0000000000000000 free

virtio与具体设备对应关系:

msmnile_gvmq:/ # cat /proc/interrupts  | grep virt
  5:     206598          0          0          0          0          0          0     GICv3  80 Level     virtio0-1c200000.virtio_clock
  6:          6          0          0          0          0          0          0     GICv3  81 Level     virtio1-1c300000.virtio_clock
  7:        139          0          0          0          0          0          0     GICv3  74 Level     virtio2-1c700000.virtio_regulator
  8:          0          0          0          0          0          0          0     GICv3  77 Level     virtio3-1c800000.virtio-spmi
159:          8          0          0          0          0          0          0     GICv3  40 Level     virtio4-1c450000.virtio_blk, virtio8-1c0b0000.virtio_blk
160:          5          0          0          0          0          0          0     GICv3  43 Level     virtio5-1c460000.virtio_blk
161:          5          0          0          0          0          0          0     GICv3  44 Level     virtio6-1c470000.virtio_blk
162:     115140          0          0          0          0          0          0     GICv3  45 Level     virtio7-1c480000.virtio_blk
163:          2          0          0          0          0          0          0     GICv3  48 Level     virtio9-1c140000.virtio_blk
164:          1          0          0          0          0          0          0     GICv3  49 Level     virtio10-1c0f0000.virtio_blk
165:          0          0          0          0          0          0          0     GICv3  46 Level     virtio11-1c380000.virtio_input_mtouch
166:          0          0          0          0          0          0          0     GICv3  42 Level     virtio12-1c0d0000.virtio_input_mtouch
167:          0          0          0          0          0          0          0     GICv3  82 Level     virtio13-1c900000.virtio_fastrpc
168:      33871          0          0          0          0          0          0     GICv3  76 Level     virtio14-1c1c0000.virtio_net
169:      19030          0          0          0          0          0          0     GICv3  41 Level     virtio15-1c0c0000.virtio_net
195:        643          0          0          0          0          0          0     GICv3  37 Level     virtio16-1c090000.virtio_console
197:          0          0          0          0          0          0          0     GICv3  47 Level     virtio17-1c150000.virtio_input_keyboard

猜你喜欢

转载自blog.csdn.net/kill150/article/details/130237978