使用脚本, 运行 就搭建好了内核编译环境和文件系统,还有vscode的环境和调试方法

#!/bin/bash
# ============================================================
# Linux 内核阅读 + QEMU 调试环境 一键搭建
# 目标:x86_64,最小化,够用就行
# ============================================================
set -e

WORKDIR="$HOME/kernel-lab"
KERNEL_VERSION="6.6"   # LTS 版本,稳定
BUSYBOX_VERSION="1.36.1"
JOBS=$(nproc)

echo "==> 工作目录: $WORKDIR"
mkdir -p "$WORKDIR"
cd "$WORKDIR"

# ============================================================
# 1. 安装依赖
# ============================================================
echo "==> [1/5] 安装依赖..."
sudo apt-get update -qq
sudo apt-get install -y \
    clang llvm lld \
    qemu-system-x86 \
    wget curl git \
    bc bison flex libssl-dev libelf-dev \
    cpio gzip \
    python3 \
    bear \
    --no-install-recommends

# ============================================================
# 2. 下载内核源码
# ============================================================
echo "==> [2/5] 下载内核 $KERNEL_VERSION..."
if [ ! -d "linux" ]; then
    wget -q --show-progress \
        "https://cdn.kernel.org/pub/linux/kernel/v6.x/linux-${KERNEL_VERSION}.tar.xz"
    tar xf "linux-${KERNEL_VERSION}.tar.xz"
    mv "linux-${KERNEL_VERSION}" linux
    rm "linux-${KERNEL_VERSION}.tar.xz"
else
    echo "    已存在,跳过下载"
fi
cd linux

# ============================================================
# 3. 配置 + 用 clang 编译,生成 compile_commands.json
# ============================================================
echo "==> [3/5] 配置内核(最小配置 + 调试选项)..."

# 从 x86_64 defconfig 开始
make ARCH=x86_64 CC=clang defconfig

# 追加调试/QEMU 必要选项
cat >> .config << 'EOF'
# 调试支持
CONFIG_DEBUG_INFO=y
CONFIG_DEBUG_INFO_DWARF4=y
CONFIG_GDB_SCRIPTS=y
CONFIG_KALLSYMS=y
CONFIG_KALLSYMS_ALL=y

# QEMU 串口
CONFIG_SERIAL_8250=y
CONFIG_SERIAL_8250_CONSOLE=y

# 文件系统(rootfs 用)
CONFIG_DEVTMPFS=y
CONFIG_DEVTMPFS_MOUNT=y
CONFIG_TMPFS=y
CONFIG_EXT4_FS=y
CONFIG_VIRTIO=y
CONFIG_VIRTIO_PCI=y
CONFIG_VIRTIO_BLK=y
CONFIG_VIRTIO_NET=y
EOF

make ARCH=x86_64 CC=clang olddefconfig

echo "==> 编译内核(这需要几分钟)..."
make ARCH=x86_64 CC=clang -j"$JOBS"

echo "==> 生成 compile_commands.json..."
python3 scripts/clang-tools/gen_compile_commands.py
echo "    生成完成:$(pwd)/compile_commands.json"

cd "$WORKDIR"

# ============================================================
# 4. 制作最小 rootfs(busybox)
# ============================================================
echo "==> [4/5] 编译 BusyBox rootfs..."
if [ ! -d "busybox" ]; then
    wget -q --show-progress \
        "https://busybox.net/downloads/busybox-${BUSYBOX_VERSION}.tar.bz2"
    tar xf "busybox-${BUSYBOX_VERSION}.tar.bz2"
    mv "busybox-${BUSYBOX_VERSION}" busybox
    rm "busybox-${BUSYBOX_VERSION}.tar.bz2"
fi

cd busybox
make defconfig
# 静态编译,不依赖 libc
sed -i 's/# CONFIG_STATIC is not set/CONFIG_STATIC=y/' .config
make -j"$JOBS"
make install   # 安装到 busybox/_install/
cd "$WORKDIR"

# 制作 initramfs
echo "==> 打包 initramfs..."
mkdir -p initramfs/{bin,sbin,etc,proc,sys,dev,tmp}
cp -a busybox/_install/* initramfs/

# init 脚本
cat > initramfs/init << 'EOF'
#!/bin/sh
mount -t proc  none /proc
mount -t sysfs none /sys
mount -t devtmpfs none /dev 2>/dev/null || mdev -s

echo ""
echo "=============================="
echo "  Mini Linux on QEMU - ready "
echo "=============================="
echo ""

exec /bin/sh
EOF
chmod +x initramfs/init

# 打包成 cpio
cd initramfs
find . | cpio -o -H newc | gzip > ../initramfs.cpio.gz
cd "$WORKDIR"
echo "    initramfs.cpio.gz 制作完成"

# ============================================================
# 5. 生成启动脚本 + VSCode 配置
# ============================================================
echo "==> [5/5] 生成配置文件..."

# 启动脚本
cat > run_qemu.sh << EOF
#!/bin/bash
# 普通启动
qemu-system-x86_64 \\
    -kernel $WORKDIR/linux/arch/x86_64/boot/bzImage \\
    -initrd $WORKDIR/initramfs.cpio.gz \\
    -append "console=ttyS0 nokaslr" \\
    -nographic \\
    -m 512M \\
    -no-reboot

# 退出:Ctrl+A 然后按 X
EOF
chmod +x run_qemu.sh

# GDB 调试启动脚本
cat > run_qemu_debug.sh << EOF
#!/bin/bash
# 调试模式:QEMU 等待 GDB 连接(端口 1234)
qemu-system-x86_64 \\
    -kernel $WORKDIR/linux/arch/x86_64/boot/bzImage \\
    -initrd $WORKDIR/initramfs.cpio.gz \\
    -append "console=ttyS0 nokaslr" \\
    -nographic \\
    -m 512M \\
    -no-reboot \\
    -s -S

# 然后在另一个终端运行:
# gdb $WORKDIR/linux/vmlinux
# (gdb) target remote :1234
# (gdb) c
EOF
chmod +x run_qemu_debug.sh

# VSCode 配置
mkdir -p linux/.vscode
cat > linux/.vscode/settings.json << EOF
{
    "clangd.arguments": [
        "--compile-commands-dir=\${workspaceFolder}",
        "--background-index",
        "--clang-tidy=false",
        "--header-insertion=never",
        "--completion-style=detailed",
        "--log=error"
    ],
    "C_Cpp.intelliSenseEngine": "disabled",
    "c-cpp-flylint.enable": false
}
EOF

# VSCode 调试配置 launch.json
cat > linux/.vscode/launch.json << EOF
{
    "version": "0.2.0",
    "configurations": [
        {
            "name": "Kernel Debug (QEMU)",
            "type": "cppdbg",
            "request": "launch",
            "program": "$WORKDIR/linux/vmlinux",
            "args": [],
            "stopAtEntry": false,
            "cwd": "$WORKDIR/linux",
            "miDebuggerPath": "/usr/bin/gdb",
            "miDebuggerServerAddress": "localhost:1234",
            "setupCommands": [
                {
                    "description": "设置架构",
                    "text": "set architecture i386:x86-64",
                    "ignoreFailures": false
                },
                {
                    "description": "允许加载内核 GDB 脚本",
                    "text": "add-auto-load-safe-path $WORKDIR/linux",
                    "ignoreFailures": false
                }
            ]
        }
    ]
}
EOF

# GDB 配置
cat > linux/.gdbinit << EOF
# 加载内核 GDB 脚本(符号、辅助命令)
add-auto-load-safe-path $WORKDIR/linux/scripts/gdb/vmlinux-gdb.py
source $WORKDIR/linux/scripts/gdb/vmlinux-gdb.py
set architecture i386:x86-64
EOF

echo ""
echo "=========================================="
echo "  环境搭建完成!"
echo "=========================================="
echo ""
echo "目录结构:"
echo "  $WORKDIR/"
echo "  ├── linux/                  内核源码(用 VSCode 打开这个目录)"
echo "  │   ├── compile_commands.json   clangd 索引文件"
echo "  │   ├── .vscode/settings.json  clangd 配置(已关闭 flylint)"
echo "  │   └── .vscode/launch.json   F5 直接调试"
echo "  ├── initramfs.cpio.gz       最小根文件系统"
echo "  ├── run_qemu.sh             普通启动"
echo "  └── run_qemu_debug.sh       GDB 调试启动"
echo ""
echo "启动 QEMU:"
echo "  cd $WORKDIR && ./run_qemu.sh"
echo ""
echo "GDB 调试:"
echo "  终端1: ./run_qemu_debug.sh"
echo "  终端2: gdb linux/vmlinux"
echo "         (gdb) target remote :1234"
echo "         (gdb) b start_kernel"
echo "         (gdb) c"
echo ""
echo "VSCode:"
echo "  用 Remote SSH 打开 $WORKDIR/linux"
echo "  clangd 会自动加载 compile_commands.json"

标签: none

添加新评论