使用vscode和qemu调试linux内核(包含汇编)

vscode调试kernel的汇编部分有两个麻烦点

  • linux加载地址和链接地址不同
  • vscode的默认setupCommands无法正常使用

通过一段时间的摸索我找到了调试这部分代码的方法

  • 对于加载地址问题,可以通过gdb的add-symbol-file的-o参数来解决(这要求gdb的版本较新才可以)
  • 对于vscode的配置,后面我会列出目前摸索出的配置文件供参考

调试步骤

  • 编译linux内核,目前我使用的是linux-5.17.4内核

    为了能更好的支持c的调试,我这边尽可能的将C代码通过O0编译,对kernel做了如下修改, 并且编译去掉了CONFIG_JUMP_LABEL:

    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
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    diff --git a/arch/arm64/Makefile b/arch/arm64/Makefile
    index 2f1de8865..27ecec930 100644
    --- a/arch/arm64/Makefile
    +++ b/arch/arm64/Makefile
    @@ -213,3 +213,5 @@ define archhelp
    echo ' (distribution) /sbin/installkernel or'
    echo ' install to $$(INSTALL_PATH) and run lilo'
    endef
    +
    +subdir-ccflags-y = -O0
    diff --git a/drivers/Makefile b/drivers/Makefile
    index a110338c8..da99b36a1 100644
    --- a/drivers/Makefile
    +++ b/drivers/Makefile
    @@ -187,3 +187,5 @@ obj-$(CONFIG_GNSS) += gnss/
    obj-$(CONFIG_INTERCONNECT) += interconnect/
    obj-$(CONFIG_COUNTER) += counter/
    obj-$(CONFIG_MOST) += most/
    +
    +subdir-ccflags-y = -O0
    diff --git a/drivers/char/tpm/Makefile b/drivers/char/tpm/Makefile
    index 66d39ea6b..252f4d9d2 100644
    --- a/drivers/char/tpm/Makefile
    +++ b/drivers/char/tpm/Makefile
    @@ -41,3 +41,5 @@ obj-$(CONFIG_TCG_XEN) += xen-tpmfront.o
    obj-$(CONFIG_TCG_CRB) += tpm_crb.o
    obj-$(CONFIG_TCG_VTPM_PROXY) += tpm_vtpm_proxy.o
    obj-$(CONFIG_TCG_FTPM_TEE) += tpm_ftpm_tee.o
    +
    +subdir-ccflags-y = -O1
    diff --git a/drivers/net/phy/Makefile b/drivers/net/phy/Makefile
    index b2728d00f..f369abb70 100644
    --- a/drivers/net/phy/Makefile
    +++ b/drivers/net/phy/Makefile
    @@ -85,3 +85,5 @@ obj-$(CONFIG_STE10XP) += ste10Xp.o
    obj-$(CONFIG_TERANETICS_PHY) += teranetics.o
    obj-$(CONFIG_VITESSE_PHY) += vitesse.o
    obj-$(CONFIG_XILINX_GMII2RGMII) += xilinx_gmii2rgmii.o
    +
    +CFLAGS_phylink.o = -O1
    diff --git a/include/net/sch_generic.h b/include/net/sch_generic.h
    index 472843eed..06d6edcdf 100644
    --- a/include/net/sch_generic.h
    +++ b/include/net/sch_generic.h
    @@ -512,7 +512,7 @@ static inline bool lockdep_tcf_proto_is_locked(struct tcf_proto *tp)

    static inline void qdisc_cb_private_validate(const struct sk_buff *skb, int sz)
    {
    - struct qdisc_skb_cb *qcb;
    + struct qdisc_skb_cb *qcb __attribute__((unused));

    BUILD_BUG_ON(sizeof(skb->cb) < sizeof(*qcb));
    BUILD_BUG_ON(sizeof(qcb->data) < sz);
    diff --git a/init/Makefile b/init/Makefile
    index 06326e304..9a0b7f269 100644
    --- a/init/Makefile
    +++ b/init/Makefile
    @@ -35,3 +35,5 @@ quiet_cmd_compile.h = CHK $@

    include/generated/compile.h: FORCE
    $(call cmd,compile.h)
    +
    +subdir-ccflags-y = -O0
    diff --git a/kernel/Makefile b/kernel/Makefile
    index a18d16973..aeaa9d6d8 100644
    --- a/kernel/Makefile
    +++ b/kernel/Makefile
    @@ -160,3 +160,5 @@ $(obj)/kheaders_data.tar.xz: FORCE
    $(call cmd,genikh)

    clean-files := kheaders_data.tar.xz kheaders.md5
    +
    +subdir-ccflags-y = -O0
    diff --git a/kernel/bpf/Makefile b/kernel/bpf/Makefile
    index c1a9be6a4..d4713f4e3 100644
    --- a/kernel/bpf/Makefile
    +++ b/kernel/bpf/Makefile
    @@ -40,3 +40,5 @@ obj-$(CONFIG_BPF_PRELOAD) += preload/
    obj-$(CONFIG_BPF_SYSCALL) += relo_core.o
    $(obj)/relo_core.o: $(srctree)/tools/lib/bpf/relo_core.c FORCE
    $(call if_changed_rule,cc_o_c)
    +
    +CFLAGS_core.o = -O1
    diff --git a/kernel/dma/Makefile b/kernel/dma/Makefile
    index 0dd65ec1d..a09453711 100644
    --- a/kernel/dma/Makefile
    +++ b/kernel/dma/Makefile
    @@ -10,3 +10,5 @@ obj-$(CONFIG_SWIOTLB) += swiotlb.o
    obj-$(CONFIG_DMA_COHERENT_POOL) += pool.o
    obj-$(CONFIG_DMA_REMAP) += remap.o
    obj-$(CONFIG_DMA_MAP_BENCHMARK) += map_benchmark.o
    +
    +CFLAGS_direct.o = -O1
    diff --git a/lib/Makefile b/lib/Makefile
    index 300f569c6..98aa9a698 100644
    --- a/lib/Makefile
    +++ b/lib/Makefile
    @@ -398,3 +398,5 @@ $(obj)/$(TEST_FORTIFY_LOG): $(addprefix $(obj)/, $(TEST_FORTIFY_LOGS)) FORCE
    ifeq ($(CONFIG_FORTIFY_SOURCE),y)
    $(obj)/string.o: $(obj)/$(TEST_FORTIFY_LOG)
    endif
    +
    +subdir-ccflags-y = -O0
    diff --git a/lib/zstd/Makefile b/lib/zstd/Makefile
    index fc45339fc..96cb0ce27 100644
    --- a/lib/zstd/Makefile
    +++ b/lib/zstd/Makefile
    @@ -42,3 +42,5 @@ zstd_decompress-y := \
    decompress/zstd_ddict.o \
    decompress/zstd_decompress.o \
    decompress/zstd_decompress_block.o \
    +
    +subdir-ccflags-y = -O1
    diff --git a/mm/Makefile b/mm/Makefile
    index 70d4309c9..c225b254c 100644
    --- a/mm/Makefile
    +++ b/mm/Makefile
    @@ -132,3 +132,12 @@ obj-$(CONFIG_PAGE_REPORTING) += page_reporting.o
    obj-$(CONFIG_IO_MAPPING) += io-mapping.o
    obj-$(CONFIG_HAVE_BOOTMEM_INFO_NODE) += bootmem_info.o
    obj-$(CONFIG_GENERIC_IOREMAP) += ioremap.o
    +
    +subdir-ccflags-y = -O0
    +CFLAGS_truncate.o = -O1
    +CFLAGS_gup.o = -O1
    +CFLAGS_memory.o = -O1
    +CFLAGS_pagewalk.o = -O1
    +CFLAGS_page_io.o = -O1
    +CFLAGS_vmalloc.o = -O1
    +CFLAGS_swapfile.o = -O1
  • 将vscode的launch按如下方式进行配置

    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
    {
    "version": "0.2.0",
    "configurations": [
    {
    "name": "linux",
    "type": "cppdbg",
    "request": "launch",
    "program": "${workspaceFolder}/vmlinux",
    "args": [],
    "stopAtEntry": false,
    "cwd": "${workspaceFolder}",
    "environment": [],
    "externalConsole": false,
    "MIMode": "gdb",
    "miDebuggerPath": "/home/gngshn/.local/opt/aarch64-buildroot-linux-gnu/bin/aarch64-linux-gdb",
    "targetArchitecture": "arm64",
    "customLaunchSetupCommands": [
    {
    "text": "add-symbol-file vmlinux"
    },
    {
    "text": "add-symbol-file vmlinux -o -0xffff7fffc7e00000"
    },
    {
    "text": "b _text"
    },
    {
    "text": "target remote :1234"
    },
    ],
    }
    ]
    }
  • 使用qemu打开linux

    1
    qemu-system-aarch64 -M virt -cpu cortex-a53 -smp 4 -m 4G -nographic -append "console=ttyAMA0" -kernel arch/arm64/boot/Image -initrd ../rootfs.cpio.uboot -S -s
  • 直接再vscode中按F5开始调试即可