当前位置:   article > 正文

qemu侧 块设备调试记录(一)_qemu的块设备

qemu的块设备

前言

qemu 编译版本 7.0.0

gdb --args ./build/qemu-system-x86_64  \
    -m 2G -smp 2 \
    --enable-kvm  \
    -boot order=c \
    -name plr1 \
    -drive file=/home/ostest/linux-test/run-test/ubuntu1.img,index=0,media=disk,format=qcow2  \
    -drive file=/home/ostest/new/disk.raw,index=1,media=disk,format=raw  \
    -nic none\
    -vnc :1
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

调试程序

位于 disk.raw

#define _GNU_SOURCE
#include <errno.h>
#include <fcntl.h>
#include <malloc.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/mman.h>
#include <sys/types.h>
#include <unistd.h>

int main(void)
{
    char hello_str[] = "Hello World!";
    void *write_buffer;
    void *read_buffer;
    int fd;
    int ret = 0;

    fd = open("direct_write.log", O_RDWR | O_CREAT | O_DIRECT, 0644);
    if (fd < 0) {
        perror("Failed to open file\n");
        return fd;
    }

    /* allocate a 1024 bytes buffer memalign分配指定地址对齐的资源接口 */
    write_buffer = memalign(512, 512 * 2); // align by 512
    if (!write_buffer) {
        perror("Failed to alloc write buffer\n");
        ret = -ENOMEM;
        goto bad_write_buffer;
    }

    memcpy(write_buffer, hello_str, sizeof(hello_str));

    ret = write(fd, write_buffer, 512 * 2);
    if (ret < 0) {
        perror("Failed to write file\n");
        goto bad_write;
    }
    // 文件同步
    if (fsync(fd) < 0) {
        perror("fysnc:");
        goto bad_write;
    }

    lseek(fd, 0, SEEK_SET); // read  previous write data

    read_buffer = memalign(512, 512 * 2);
    if (!read_buffer) {
        perror("Failed to alloc read buffer\n");
        ret = -ENOMEM;
        goto bad_read_buffer;
    }

    ret = read(fd, read_buffer, 512 * 2);
    if (ret < 0) {
        perror("Failed to read file\n");
        goto bad_read;
    }

    printf("read from file : %s\n", (char *)read_buffer);

bad_read:
    free(read_buffer);
bad_read_buffer:
bad_write:
    free(write_buffer);
bad_write_buffer:
    close(fd);
    return ret;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72

qemu monitor 查看

参考 QEMU(4) q35

可以在命令后面添加 -monitor stdio

(qemu) info qtree
bus: main-system-bus
  type System
  dev: hpet, id ""
    gpio-in "" 2
    gpio-out "" 1
    gpio-out "sysbus-irq" 32
    mmio 00000000fed00000/0000000000000400
  dev: kvm-ioapic, id ""
    gpio-in "" 24
    gsi_base = 0 (0x0)
    mmio 00000000fec00000/0000000000001000
  dev: i440FX-pcihost, id ""
    pci-hole64-size = 2147483648 (2 GiB)
    bypass-iommu = false
    bus: pci.0
      type PCI
      dev: PIIX4_PM, id "
        class Bridge, addr 00:01.3, pci id 8086:7113 (sub 1af4:1100)
        bus: i2c
          type i2c-bus
          dev: smbus-eeprom, id ""
            address = 87 (0x57)
      dev: piix3-ide, id ""
        addr = 01.1
        class IDE controller, addr 00:01.1, pci id 8086:7010 (sub 1af4:1100)
        bar 4: i/o at 0xc000 [0xc00f]
        bus: ide.1
          type IDE
          dev: ide-cd, id ""
            drive = "ide1-cd0"
        bus: ide.0
          type IDE
          dev: ide-hd, id ""
            drive = "ide0-hd1"
            backend_defaults = "auto"
            logical_block_size = 512 (512 B)
            physical_block_size = 512 (512 B)
            discard_granularity = 512 (512 B)
            write-cache = "auto"
            share-rw = false
            serial = "QM00002"
            model = ""
            unit = 1 (0x1)
          dev: ide-hd, id ""
            drive = "ide0-hd0"
            unit = 0 (0x0)
      dev: VGA, id ""
      dev: PIIX3, id ""
        class ISA bridge, addr 00:01.0, pci id 8086:7000 (sub 1af4:1100)
        bus: isa.0
          type ISA
          dev: port92, id ""
            gpio-out "a20" 1
          dev: vmmouse, id ""
          dev: vmport, id ""
          dev: i8042, id ""
          dev: isa-fdc, id ""
            bus: floppy-bus.0
              type floppy-bus
              dev: floppy, id ""
                unit = 0 (0x0)
                drive = "floppy0"
          dev: isa-parallel, id ""
            chardev = "parallel0"
          dev: isa-serial, id ""
          dev: i8257, id ""
          dev: i8257, id ""
          dev: isa-pcspk, id ""
          dev: kvm-pit, id ""
          dev: mc146818rtc, id ""
          dev: kvm-i8259, id ""
          dev: kvm-i8259, id ""
      dev: i440FX, id ""
        class Host bridge, addr 00:00.0, pci id 8086:1237 (sub 1af4:1100)
  dev: fw_cfg_io, id ""
  dev: kvmclock, id ""
  dev: kvmvapic, id ""
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
其他信息
(qemu) info block
ide0-hd0 (#block163): /home/ostest/new/ubuntu3.img (qcow2)
    Attached to:      /machine/unattached/device[24]
    Cache mode:       writeback

ide0-hd1 (#block307): /home/ostest/new/disk3.raw (raw)
    Attached to:      /machine/unattached/device[25]
    Cache mode:       writeback

ide1-cd0: [not inserted]
    Attached to:      /machine/unattached/device[26]
    Removable device: not locked, tray closed

floppy0: [not inserted]
    Attached to:      /machine/unattached/device[18]
    Removable device: not locked, tray closed

sd0: [not inserted]
    Removable device: not locked, tray closed

(qemu) info chardev 
parallel0: filename=vc
compat_monitor0: filename=stdio
serial0: filename=vc

info irq  -- show the interrupts statistics (if available)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26

查看大致函数调用

知道 qemu 是通过协程 异步处理io 处理函数 handle_aiocb_rw , 先通过断点这个查看函数栈,再往前进行分析

#0  handle_aiocb_rw (opaque=0x7fff51fcc4e0) at ../block/file-posix.c:1549
#1  0x00005555560fabbb in worker_thread (opaque=0x555556b16000) at ../util/thread-pool.c:104
#2  0x00005555560d297d in qemu_thread_start (args=0x555556c447f0)
    at ../util/qemu-thread-posix.c:556

// 通过qemu 源码搜索,发现
static int coroutine_fn raw_co_prw(...) {
	return raw_thread_pool_submit(bs, handle_aiocb_rw, &acb);
}

#0  raw_co_prw
    (bs=0x555556c3df60, offset=10019602432, bytes=65536, qiov=0x7fff51fcc8e0, type=1)
    at ../block/file-posix.c:2124
#1  0x0000555555f444c9 in raw_co_preadv
    (bs=0x555556c3df60, offset=10019602432, bytes=65536, qiov=0x7fff51fcc8e0, flags=0)
    at ../block/file-posix.c:2173
#2  0x0000555555ed29d0 in bdrv_driver_preadv
    (bs=0x555556c3df60, offset=10019602432, bytes=65536, qiov=0x7fff51fcc8e0, qiov_offset=0, flags=0) at ../block/io.c:1220
#3  0x0000555555ed3b55 in bdrv_aligned_preadv
    (child=0x555556bfd790, req=0x7fff51fcc720, offset=10019602432, bytes=65536, align=1, qiov=0x7fff51fcc8e0, qiov_offset=0, flags=0) at ../block/io.c:1608
#4  0x0000555555ed45aa in bdrv_co_preadv_part
    (child=0x555556bfd790, offset=10019602432, bytes=65536, qiov=0x7fff51fcc8e0, qiov_offset=0, flags=0) at ../block/io.c:1881
#5  0x0000555555ed43a1 in bdrv_co_preadv
    (child=0x555556bfd790, offset=10019602432, bytes=65536, qiov=0x7fff51fcc8e0, flags=0)
    at ../block/io.c:1830
#6  0x0000555555e9556d in bdrv_preadv
    (child=0x555556bfd790, offset=10019602432, bytes=65536, qiov=0x7fff51fcc8e0, flags=0)
    at block/block-gen.c:348
#7  0x0000555555ed26c2 in bdrv_pread
    (child=0x555556bfd790, offset=10019602432, buf=0x7ffff4a36000, bytes=65536)
    at ../block/io.c:1125
#8  0x0000555555eeb4c8 in qcow2_cache_do_get
    (bs=0x555556c368a0, c=0x555556c438f0, offset=10019602432, table=0x7fff51fcca48, read_from_disk=true) at ../block/qcow2-cache.c:382
#9  0x0000555555eeb5b0 in qcow2_cache_get
--Type <RET> for more, q to quit, c to continue without paging--
    (bs=0x555556c368a0, c=0x555556c438f0, offset=10019602432, table=0x7fff51fcca48)
    at ../block/qcow2-cache.c:406
#10 0x0000555555eecc0e in l2_load
    (bs=0x555556c368a0, offset=22488797184, l2_offset=10019602432, l2_slice=0x7fff51fcca48)
    at ../block/qcow2-cluster.c:215
#11 0x0000555555eee0ad in get_cluster_table
    (bs=0x555556c368a0, offset=22488797184, new_l2_slice=0x7fff51fccad0, new_l2_index=0x7fff51fccac4) at ../block/qcow2-cluster.c:802
#12 0x0000555555eefeab in handle_copied
    (bs=0x555556c368a0, guest_offset=22488797184, host_offset=0x7fff51fccb90, bytes=0x7fff51fccb98, m=0x7fff51fccc30) at ../block/qcow2-cluster.c:1519
#13 0x0000555555ef08db in qcow2_alloc_host_offset
    (bs=0x555556c368a0, offset=22488797184, bytes=0x7fff51fccc14, host_offset=0x7fff51fccc28, m=0x7fff51fccc30) at ../block/qcow2-cluster.c:1854
#14 0x0000555555f055d5 in qcow2_co_pwritev_part
    (bs=0x555556c368a0, offset=22488797184, bytes=4096, qiov=0x7fff586bfb80, qiov_offset=0, flags=0) at ../block/qcow2.c:2629
#15 0x0000555555ed2ca9 in bdrv_driver_pwritev
    (bs=0x555556c368a0, offset=22488797184, bytes=4096, qiov=0x7fff586bfb80, qiov_offset=0, flags=0) at ../block/io.c:1281
#16 0x0000555555ed53d6 in bdrv_aligned_pwritev
    (child=0x555556c10490, req=0x7fff51fcce00, offset=22488797184, bytes=4096, align=1, qiov=0x7fff586bfb80, qiov_offset=0, flags=0) at ../block/io.c:2157
#17 0x0000555555ed5ce5 in bdrv_co_pwritev_part
    (child=0x555556c10490, offset=22488797184, bytes=4096, qiov=0x7fff586bfb80, qiov_offset=0, flags=0) at ../block/io.c:2349
#18 0x0000555555ec2357 in blk_co_do_pwritev_part
    (blk=0x555556c36550, offset=22488797184, bytes=4096, qiov=0x7fff586bfb80, qiov_offset=0, fl--Type <RET> for more, q to quit, c to continue without paging--
ags=0) at ../block/block-backend.c:1365
#19 0x0000555555ec294c in blk_aio_write_entry (opaque=0x7fff580f40b0)
    at ../block/block-backend.c:1556
#20 0x00005555560e859a in coroutine_trampoline (i0=1477213776, i1=32767)
    at ../util/coroutine-ucontext.c:173

// 再搜索blk_aio_write_entry
BlockAIOCB *blk_aio_pwritev(BlockBackend *blk, int64_t offset,
                            QEMUIOVector *qiov, BdrvRequestFlags flags,
                            BlockCompletionFunc *cb, void *opaque)
{
    IO_CODE();
    assert((uint64_t)qiov->size <= INT64_MAX);
    return blk_aio_prwv(blk, offset, qiov->size, qiov,
                        blk_aio_write_entry, flags, cb, opaque);
}

BlockAIOCB *blk_aio_pwrite_zeroes(BlockBackend *blk, int64_t offset,
                                  int64_t bytes, BdrvRequestFlags flags,
                                  BlockCompletionFunc *cb, void *opaque)
{
    IO_CODE();
    return blk_aio_prwv(blk, offset, bytes, NULL, blk_aio_write_entry,
                        flags | BDRV_REQ_ZERO_WRITE, cb, opaque);
}

#0  blk_aio_pwritev
    (blk=0x555556c36550, offset=22488797184, qiov=0x7fff586bfb80, flags=0, cb=0x5555559f5fdf <dma_blk_cb>, opaque=0x7fff586bfb20) at ../block/block-backend.c:1640
#1  0x00005555559f6a68 in dma_blk_write_io_func
    (offset=22488797184, iov=0x7fff586bfb80, cb=0x5555559f5fdf <dma_blk_cb>, cb_opaque=0x7fff586bfb20, opaque=0x555556c36550) at ../softmmu/dma-helpers.c:379
#2  0x00005555559f64d9 in dma_blk_cb (opaque=0x7fff586bfb20, ret=0)
    at ../softmmu/dma-helpers.c:238
#3  0x00005555559f6768 in dma_blk_io
    (ctx=0x555556a06020, sg=0x5555576aa310, offset=22488797184, align=512, io_func=0x5555559f6824 <dma_blk_write_io_func>, io_func_opaque=0x555556c36550, cb=0x555555b0fb78 <ide_dma_cb>, opaque=0x5555576a9fe8, dir=DMA_DIRECTION_TO_DEVICE) at ../softmmu/dma-helpers.c:317
#4  0x00005555559f6ac9 in dma_blk_write
    (blk=0x555556c36550, sg=0x5555576aa310, offset=22488797184, align=512, cb=
    0x555555b0fb78 <ide_dma_cb>, opaque=0x5555576a9fe8) at ../softmmu/dma-helpers.c:386
#5  0x0000555555b0ff4a in ide_dma_cb (opaque=0x5555576a9fe8, ret=0) at ../hw/ide/core.c:986
#6  0x0000555555b18c2b in bmdma_cmd_writeb (bm=0x5555576ab140, val=1) at ../hw/ide/pci.c:355
#7  0x0000555555b194bf in bmdma_write (opaque=0x5555576ab140, addr=0, val=1, size=1)
    at ../hw/ide/piix.c:76
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97

piix_bmdma_ops 注册

#0  bmdma_setup_bar (d=0x5555576a9560) at ../hw/ide/piix.c:93
#1  0x0000555555b19903 in pci_piix_ide_realize (dev=0x5555576a9560, errp=0x7fffffffdae8)
    at ../hw/ide/piix.c:164
#2  0x0000555555ba0783 in pci_qdev_realize (qdev=0x5555576a9560, errp=0x7fffffffdb60) at ../hw/pci/pci.c:2192
#3  0x0000555555e5ed7e in device_set_realized (obj=0x5555576a9560, value=true, errp=0x7fffffffdc70)
    at ../hw/core/qdev.c:531
#4  0x0000555555e6789d in property_set_bool (obj=0x5555576a9560, v=
    0x5555576abcb0, name=0x55555625f251 "realized", opaque=0x555556a08870, errp=0x7fffffffdc70)
    at ../qom/object.c:2273
#5  0x0000555555e65808 in object_property_set (obj=0x5555576a9560, name=0x55555625f251 "realized", v=
    0x5555576abcb0, errp=0x7fffffffdc70) at ../qom/object.c:1408
#6  0x0000555555e69d6e in object_property_set_qobject
    (obj=0x5555576a9560, name=0x55555625f251 "realized", value=0x5555576a9510, errp=0x55555694b720 <error_fatal>) at ../qom/qom-qobject.c:28
#7  0x0000555555e65b83 in object_property_set_bool
    (obj=0x5555576a9560, name=0x55555625f251 "realized", value=true, errp=0x55555694b720 <error_fatal>)
    at ../qom/object.c:1477
#8  0x0000555555e5e612 in qdev_realize
    (dev=0x5555576a9560, bus=0x555556dafee0, errp=0x55555694b720 <error_fatal>) at ../hw/core/qdev.c:333
#9  0x0000555555e5e643 in qdev_realize_and_unref
    (dev=0x5555576a9560, bus=0x555556dafee0, errp=0x55555694b720 <error_fatal>) at ../hw/core/qdev.c:340
#10 0x0000555555ba0a72 in pci_realize_and_unref
    (dev=0x5555576a9560, bus=0x555556dafee0, errp=0x55555694b720 <error_fatal>) at ../hw/pci/pci.c:2259
#11 0x0000555555ba0ac2 in pci_create_simple_multifunction
    (bus=0x555556dafee0, devfn=9, multifunction=false, name=0x55555621c151 "piix3-ide")
    at ../hw/pci/pci.c:2267
#12 0x0000555555ba0afa in pci_create_simple (bus=0x555556dafee0, devfn=9, name=0x55555621c151 "piix3-ide")
    at ../hw/pci/pci.c:2273
#13 0x0000555555c852f0 in pc_init1
    (machine=0x555556bd50c0, host_type=0x55555621c1a4 "i440FX-pcihost", pci_type=0x55555621c19d "i440FX")
    at ../hw/i386/pc_piix.c:247
#14 0x0000555555c8592c in pc_init_v7_0 (machine=0x555556bd50c0) at ../hw/i386/pc_piix.c:427
#15 0x0000555555accf0c in machine_run_board_init (machine=0x555556bd50c0) at ../hw/core/machine.c:1189
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32

bmdma_write

#0  bmdma_write (opaque=0x5555576ab140, addr=2, val=0, size=1) at ../hw/ide/piix.c:66
#1  0x0000555555d22607 in memory_region_write_accessor
    (mr=0x5555576ab2b0, addr=2, value=0x7fff675fd688, size=1, shift=0, mask=255, attrs=...)
    at ../softmmu/memory.c:518

(gdb) p *bm
$2 = {dma = {ops = 0x5555566dfbc0 <bmdma_ops>, qiov = {iov = 0x0, niov = 0, {{nalloc = 0, local_iov = {
            iov_base = 0x0, iov_len = 0}}, {__pad = '\000' <repeats 11 times>, size = 0}}}, aiocb = 0x0}, 

hit Breakpoint 4, bmdma_cmd_writeb()  at ../hw/ide/pci.c:341
// 从这些看不是需要debug的地方
(gdb) p bm->dma_cb
$5 = (BlockCompletionFunc *) 0x555555b158f4 <ide_atapi_cmd_read_dma_cb>

hit Breakpoint 5, ide_dma_cb()
p s->blk->name
$12 = 0x555556c44850 "ide0-hd0"
(gdb) n
948         if (prep_size < n * 512) {
(gdb) p prep_size
$18 = 512
(gdb) p n
$19 = 1
(gdb) p s->bus->dma->ops->prepare_buf
$20 = (DMAInt32Func *) 0x555555b184d9 <bmdma_prepare_buf>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25

dma_blk_write

Thread 6 "qemu-system-x86" hit Breakpoint 7, dma_blk_write (blk=0xfe7c075bd59d6200, sg=0x200000, 
    offset=93825027187640, align=0, cb=0x6, opaque=0x7fff675fd4b0) at ../softmmu/dma-helpers.c:389
389     {
(gdb) n
390         return dma_blk_io(blk_get_aio_context(blk), sg, offset, align,
(gdb) p *blk
$24 = {name = 0x555556c64bd0 "ide0-hd1", refcnt = 2, root = 0x555556bf5870, ctx = 0x555556a06020, 
  legacy_dinfo = 0x555556c46570, 
  dev = 0x5555577e0c60, dev_ops = 0x5555566de5c0 <ide_hd_block_ops>, dev_opaque = 0x5555576aa3b8, 

(gdb) s
blk_get_aio_context (blk=) at ../block/block-backend.c:2164
(gdb) n
2168        if (bs) {
(gdb) p bs->filename
$31 = "/home/ostest/new/disk.raw", '\000' <repeats 4070 times>

(gdb) p *bs
$33 = {open_flags = 139266, encrypted = false, sg = false, probed = false, force_share = false, 
  implicit = false, drv = 0x5555568f40a0 <bdrv_raw>,walking_aio_notifiers = false,
 
(gdb) p *(bs->file)
$35 = {bs = 0x555556c5e550, name = 0x555556c64d50 "file", klass = 0x5555567f60c0 <child_of_bds>, role = 20, 
// 指向是不一样的
(gdb) p bs
$36 = (BlockDriverState *) 0x555556c57200

(gdb) s
dma_blk_io ()at ../softmmu/dma-helpers.c:288
 p *dbs
$43 = {common = {aiocb_info = 0x5555566cddc0 <dma_aiocb_info>, bs = 0x0, cb = 0x555555b0fb8b <ide_dma_cb>, 
    opaque = 0x5555576aa3b8, refcnt = 1}, ctx = 0x555556a06020, acb = 0x0, sg = 0x5555576aa6e0, align = 512, 
  offset = 536870912, dir = DMA_DIRECTION_TO_DEVICE, sg_cur_index = 0, sg_cur_byte = 0, iov = {
    iov = 0x7fff6017a500, niov = 0, {{nalloc = 1, local_iov = {iov_base = 0x0, iov_len = 0}}, {__pad = "", size = 0}}}, bh = 0x0, 
  io_func =  <dma_blk_write_io_func>, io_func_opaque = 0x555556c466d0}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36

dma_blk_write_io_func

函数调用关系

static void ide_dma_cb(void *opaque, int ret)
{
    IDEState *s = opaque;
    s->bus->dma->aiocb = dma_blk_write(s->blk, &s->sg, offset,
                                           BDRV_SECTOR_SIZE, ide_dma_cb, s);
}

BlockAIOCB *dma_blk_write(BlockBackend *blk,
                          QEMUSGList *sg, uint64_t offset, uint32_t align,
                          void (*cb)(void *opaque, int ret), void *opaque)
{
	// opaque -> IDEState
    return dma_blk_io(blk_get_aio_context(blk), sg, offset, align,
                      dma_blk_write_io_func, blk, cb, opaque,
                      DMA_DIRECTION_TO_DEVICE);
}

BlockAIOCB *dma_blk_io(AioContext *ctx,
    QEMUSGList *sg, uint64_t offset, uint32_t align,
    DMAIOFunc *io_func, void *io_func_opaque,
    BlockCompletionFunc *cb,
    void *opaque, DMADirection dir)
{
	// io_func_opaque->blk; opaque->IDEState
    DMAAIOCB *dbs = qemu_aio_get(&dma_aiocb_info, NULL, cb, opaque);
    dbs->acb = NULL;
    dbs->sg = sg;
    dbs->ctx = ctx;
    dbs->offset = offset;
    dbs->align = align;
    dbs->sg_cur_index = 0;
    dbs->sg_cur_byte = 0;
    dbs->dir = dir;
    dbs->io_func = io_func;
    dbs->io_func_opaque = io_func_opaque;
    dbs->bh = NULL;
    qemu_iovec_init(&dbs->iov, sg->nsg);
    dma_blk_cb(dbs, 0);
    // 即调用dma_blk_write_io_func
   		dbs->acb = dbs->io_func(dbs->offset, &dbs->iov,
                     dma_blk_cb, dbs, dbs->io_func_opaque);
    return &dbs->common;
}

static
BlockAIOCB *dma_blk_write_io_func(int64_t offset, QEMUIOVector *iov,
                                  BlockCompletionFunc *cb, void *cb_opaque,
                                  void *opaque)
{
	// cb_opaque->DMAAIOCB
    BlockBackend *blk = opaque;
    return blk_aio_pwritev(blk, offset, iov, 0, cb, cb_opaque);
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53

gdb 调试过程

Thread 6 "qemu-system-x86" hit Breakpoint 2, dma_blk_write_io_func ()
 	at ../softmmu/dma-helpers.c:269
(gdb) p blk->name
$2 = 0x555556d03cb0 "ide0-hd1"

(gdb) s
blk_aio_pwritev (blk=0x555556ce33a0, offset=138412032, qiov=0x7fff580052b0, flags=0, 
    cb=0x5555558b7f0a <dma_blk_cb>, opaque=0x7fff58005250
) at ../block/block-backend.c:1638
1638    {
(gdb) n
1640        assert((uint64_t)qiov->size <= INT64_MAX);
(gdb) n
1641        return blk_aio_prwv(blk, offset, qiov->size, qiov,
(gdb) p *qiov
$3 = {iov = 0x7fff58049bf0, niov = 1, {{nalloc = 1, local_iov = {iov_base = 0x0, iov_len = 1024}}, {, size = 1024}}}
(gdb) p *(qiov->iov)
$4 = {iov_base = 0x7fff7868f200, iov_len = 1024}
(gdb) p *(qiov->iov->iov_base)
Attempt to dereference a generic pointer.
(gdb) p (char *)(qiov->iov->iov_base)
// 此时是已经获取到数据的,猜测是在dma_blk_cb函数里
$5 = 0x7fff7868f200 "Hello World!"
(gdb) s
blk_aio_prwv (blk=0x555556ce33a0, offset=138412032, bytes=1024, iobuf=0x7fff580052b0, 
    co_entry= <blk_aio_write_entry>, flags=0, cb= <dma_blk_cb>, 
    opaque=0x7fff58005250
) at ../block/block-backend.c:1509
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Cpp五条/article/detail/217398
推荐阅读
相关标签
  

闽ICP备14008679号