Teach you how to debug Linux kernel with VS Code+Qemu+GDB

background

All along, the understanding of Linux system is at the application level. After reading advanced programming in UNIX environment, I still lack a deep understanding of the implementation methods of some modules in the system, so I want to study the Linux kernel mechanism.

Simply reading the source code is not as good as debugging the kernel step by step. There are many methods to debug the kernel on the Internet, mainly using Qemu+GDB to debug the kernel, but most of the online materials are scattered and the step records are not detailed enough. The author has taken many detours in the implementation process, and it is not convenient to directly use GDB to debug and view the code, Therefore, VS Code+Qemu+GDB is used for Linux kernel debugging, and the main steps in the process are recorded.

environment

Since the personal host is MacOS 10.14.5, use Ubuntu 14.04 amd64 to build the kernel debugging environment on the Parrales Desktop virtual machine.

If the host itself is a Linux system, there is no need to install a virtual machine, and the kernel debugging environment can be built directly, with better performance.

Main steps

summary

  1. Install Ubuntu in the virtual machine (parales desktop, vmware, etc.) (if the host itself is a Linux system, this step can be omitted)
  2. Download linux kernel, compile and generate bzImage
  3. Update GCC, G + +, GDB
  4. Installing Qemu
  5. Install VS Code and configure it

Virtual machine Ubuntu installation

Install Ubuntu 14.04 in the virtual machine (Parrales Desktop, vmware, etc.), where the Ubuntu version can be selected freely, as long as Parrales tools can be installed normally.

In addition, the x64 version is the best choice, and the performance will be better. The specific installation process is omitted. Due to the slow update speed of the original apt, the domestic source needs to be updated. Tsinghua apt source is used here

vim /etc/apt/sources.list

Kernel compilation

#Installation and compilation related dependencies
apt-get install libncurses5-dev libssl-dev bison flex libelf-dev gcc make openssl libc6-dev

#If you choose Tsinghua source here, the domestic speed will be much faster
wget https://mirrors.tuna.tsinghua.edu.cn/kernel/v4.x/linux-4.5.tar.gz

#decompression
tar -xvf linux-4.5.tar.gz

cd  linux-4.5
#Configure compilation options. Various configurations for kernel compilation can be performed here. Since debugging related configurations have been checked by default, you can exit and save directly from esc
make menuconfig
#Start multi-threaded compilation. This step will take a long time for the first time. Later, the speed will become faster because intermediate files have been generated
make -j8

After compilation, the following will be generated in the directory

./vmLinux

./arch/x86/boot/bzImage

vmLinux is the debugging Map file required by GDB, and bzImage is the large kernel file

If you need to install the kernel, you can perform the following steps (this step is not necessary)

#If you need to install the kernel,
make modules_install
make install

After installation, restart the host and select a new kernel in Grub.

Update GCC,G++,GDB

Because the default GDB of the system will have the error of "Remote 'g' packet reply is too long" when debugging the kernel, we need to modify the source code of GDB instead of Buy a mobile game account Compiling the new version of GDB source code requires a new version of GCC and G + +, so the following needs to be updated:

#Install GCC-9,G++-9
sudo apt install software-properties-common
sudo apt-get update
sudo apt install gcc-9 g++-9
#Execute after installation
gcc -v
#If it is a new version of GCC, it is completed. If it is not a new version, you need to link GCC to gcc-9

Compile and install GDB

#Download GDB. The gnu source of Beijing Jiaotong is used here. The domestic speed will be much faster
wget https://mirror.bjtu.edu.cn/gnu/gdb/gdb-8.3.tar.xz
tar -xvf gdb-8.3.tar.xz

#Make the following changes under gdb/remote.c file
    /* Further sanity checks, with knowledge of the architecture.  */
    // if (buf_len > 2 * rsa->sizeof_g_packet)
    //   error (_("Remote 'g' packet reply is too long (expected %ld bytes, got %d "
    //      "bytes): %s"),
    //    rsa->sizeof_g_packet, buf_len / 2,
    //    rs->buf.data ());
  if (buf_len > 2 * rsa->sizeof_g_packet) {
    rsa->sizeof_g_packet = buf_len;
    for (i = 0; i < gdbarch_num_regs (gdbarch); i++){
            if (rsa->regs[i].pnum == -1)
                continue;
            if (rsa->regs[i].offset >= rsa->sizeof_g_packet)
                rsa->regs[i].in_g_packet = 0;
            else
                rsa->regs[i].in_g_packet = 1;
        }
    }

#Compile GDB
./configure
./make -j8
sudo ./make install
#Open GDB to see if it is a new version
gdb

Qemu configuration

#Installing qemu
apt-get install qemu

Make rootfs of helloworld for testing

touch main.c

Type the following code

#include <stdio>
int main()
{
    printf("hello world!");
    printf("hello world!");
    printf("hello world!");
    printf("hello world!");
    fflush(stdout);
    while(1);
    return 0;
}

compile

gcc --static -o helloworld main.c
echo helloworld | cpio -o --format=newc > rootfs

Qemu direct run test (not required)

qemu-system-x86_64 \
    -kernel ./arch/x86/boot/bzImage \
    -initrd ./rootfs \
    -append "root=/dev/ram rdinit=/helloworld"

Qemu starts GDB debugging

qemu-system-x86_64  \
 -kernel ./arch/x86/boot/bzImage  \
 -initrd ./rootfs  \
 -append "root=/dev/ram rdinit=/helloworld" \
 -smp 2  \
 -s -S

The above will open Qemu and enter the state of waiting for debugging. At this time, you can directly gdb debug, as follows (not required)

gdb ./vmLinux
#Debug the following
target remote:1234
b start_kernel
c

It can be found that the kernel is broken at start_ On kernel function

VS code configuration

1. vscode opens the kernel source folder

2. Install the gdb debug plug-in

3. Debug - > open configurations, do the following configuration

{
    // Use IntelliSense to learn about possible attributes.
    // Hover to view descriptions of existing attributes.
    // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
    "version": "0.2.0",
    "configurations": [
        {
            "name": "kernel-debug",
            "type": "cppdbg",
            "request": "launch",
            "miDebuggerServerAddress": "127.0.0.1:1234",
            "program": "${workspaceFolder}/vmlinux",
            "args": [],
            "stopAtEntry": false,
            "cwd": "${workspaceFolder}",
            "environment": [],
            "externalConsole": false,
            "logging": {
                "engineLogging": false
            },
            "MIMode": "gdb",
        }
    ]
    }

Set the breakpoint to start in init/main.c_ In the kernel function, Qemu starts GDB debugging, and vscode start debug starts debugging the kernel.

Keywords: C# xml https

Added by pixelfish on Thu, 28 Oct 2021 08:54:46 +0300