目的:

学习嵌入式,特别是Linux/Uboot的源码,硬啃不如跟着跑一遍,不懂的就多打印,从而学习提炼最基本的公共知识体系。另外,与其雄心勃勃始于购买开发板,终于”点灯“,”hello world“,不如使用QEMU模拟不同架构的CPU,仿真真实的硬件环境。工欲善其事,必先利其器,有个趁手的环境,是一切好的开端。

一、开发环境

1.1 搭建虚拟机环境

以前一直使用VMware或VirtualBox之类的客户端,现在WIN11也有自带的虚拟机组件,个人感觉挺好用的,至少不用安装增强型特性用于支持拖曳,对于宿主机主windows来说,都是可以随便访问的文件夹。

以管理员身份登入Windows PowerShell,安装WSL2后重启,可以查看版本号,以及查看可用的WSL发行版列表。

PS C:\WINDOWS\system32> wsl --install
PS C:\WINDOWS\system32> wsl --version
PS C:\WINDOWS\system32> wsl --list --online
以下是可安装的有效分发的列表。
使用“wsl.exe --install <Distro>”安装。

NAME                            FRIENDLY NAME
Ubuntu                          Ubuntu
Ubuntu-26.04                    Ubuntu 26.04 LTS
Ubuntu-24.04                    Ubuntu 24.04 LTS
Ubuntu-22.04                    Ubuntu 22.04 LTS
openSUSE-Tumbleweed             openSUSE Tumbleweed
openSUSE-Leap-16.0              openSUSE Leap 16.0
SUSE-Linux-Enterprise-15-SP7    SUSE Linux Enterprise 15 SP7
SUSE-Linux-Enterprise-16.0      SUSE Linux Enterprise 16.0
kali-linux                      Kali Linux Rolling
Debian                          Debian GNU/Linux
AlmaLinux-8                     AlmaLinux OS 8
AlmaLinux-9                     AlmaLinux OS 9
AlmaLinux-Kitten-10             AlmaLinux OS Kitten 10
AlmaLinux-10                    AlmaLinux OS 10
archlinux                       Arch Linux
FedoraLinux-44                  Fedora Linux 44
FedoraLinux-43                  Fedora Linux 43
eLxr                            eLxr 12.12.0.0 GNU/Linux
OracleLinux_7_9                 Oracle Linux 7.9
OracleLinux_8_10                Oracle Linux 8.10
OracleLinux_9_5                 Oracle Linux 9.5
SUSE-Linux-Enterprise-15-SP6    SUSE Linux Enterprise 15 SP6

1.2 安装Ubuntu

自然是安装最新的就完事了,或者上一个版本,一般而言配套软件可能比较稳定。以及一些常用命令。

PS C:\WINDOWS\system32> wsl --install Ubuntu-26.04   安装系统
PS C:\WINDOWS\system32> wsl --install Ubuntu-24.04
PS C:\WINDOWS\system32> wsl -l -v                    查看已安装的系统
PS C:\WINDOWS\system32> wsl -d Ubuntu-26.04          启动指定系统  
PS C:\WINDOWS\system32> wsl -t Ubuntu-26.04          关闭指定系统
PS C:\WINDOWS\system32> wsl --shutdown               全部关闭

1.3 安装工具

安装linux内核编译工具链,调试模拟工具,交叉编译工具链,以及linux,uboot源码,按需即可

安装内核编译工具,调试模拟工具
sudo apt update
sudo apt install build-essential flex bison libssl-dev libelf-dev dwarves git
sudo apt install -y gcc make gdb python3-dev clangd gdb-multiarch
sudo apt install qemu-system-x86
sudo apt install qemu-system-arm
sudo apt install qemu-system-arm64
sudo apt install qemu-system-misc

安装交叉编译工具链
sudo apt install gcc-aarch64-linux-gnu gcc-arm-linux-gnueabihf
sudo apt install gcc-riscv64-unknown-elf

克隆内核源码
git clone git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
cd linux && git tag

二、嵌入式环境

2.1 选择kernel

查看并选择自己需要的版本,选用比较主流的版本,或厂家SDK版本

git tag -l "v6.6*"                            查看所有 6.6 开头的版本
git branch -r                                 查看当前正在维护的稳定版分支

git checkout -b kernel_5.15.167 v5.15.167     创建并切换到所需副本
git checkout -b kernel_6.6.86 v6.6.86
git branch
git checkout kernel_5.15.167

2.2 编译kernel

编译生成的镜像文件在arch/arm64/boot/Image,dtb文件在arch/arm64/boot/dts/arm/vexpress-v2f-1xv7-ca53x2.dtb

make ARCH=arm64 defconfig                              生成标准的 ARM64 默认配置文件
./scripts/config --enable DEBUG_INFO \                 开启相关的内核调试参数
                 --enable DEBUG_KERNEL \
                 --enable GDB_SCRIPTS \
                 --enable KALLSYMS_ALL \
                 --enable FRAME_POINTER
make ARCH=arm64 olddefconfig                           根据新开启的参数,自动调整并刷新配置文件
make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- -j8   交叉编译内核镜像
make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- dtbs  交叉编译设备树文件

2.3 启动kernel

使用qemu启动镜像文件。因无根文件系统,暂无法进入bash测试

qemu-system-aarch64 \
    -machine virt,virtualization=on \
    -cpu cortex-a57 \
    -kernel arch/arm64/boot/Image \
    -append "console=ttyAMA0 nokaslr" \
    -nographic

三、调试环境

3.1 配置vscode

搜索并安装WSL,以及SSH插件后。注意 VS Code 窗口的左下角,会多出一个远程连接图标(>< 符号)。点击这个图标,顶部会弹出一个命令菜单,选择点击 Connect to WSL using Distro... 选择你具体的 Linux 发行版,我选择的Ubuntu-26.04。

在左侧Explorer的任务栏中选择“Open Folder”打开需要的文件路径。终端窗口可以用vscode中的Terminal,也可以用PowerShell进入的WSL窗口,按个人喜好即可。

3.2 安装插件

同上,安装必要的插件,方便检索,高亮代码等。因为C/C++和clangd冲突,需要打开 VS Code 的设置(Ctrl + ,),搜索 intelli Sense Engine,将其从 default 改为 disabled。这样微软插件就只负责调试,代码解析全权交给 clangd

3.3 配置检索文件

生成compile_commands.json编译数据库

./scripts/clang-tools/gen_compile_commands.py

在.vscode文件下,创建settings.json,设置过滤规则。重启vscode,或按下 Ctrl + Shift + P 唤出命令面板,输入 Clangd: Restart language server(重启语言服务器)。

{
    // ==================== 文件与搜索过滤 ====================
    "search.exclude": {
        "**/*.o": true, "**/*.py": true, "**/*.sh": true, "**/*.mod": true,
        "**/*.mod.c": true, "**/*.d": true, "**/*.su": true, "**/*.cmd": true,
        "**/.git": true, "**/.gitignore": true, "**/*.MODULE": true,
        "**/*.ko": true, "**/*.symvers": true, "**/*.order": true
    },
    "files.exclude": {
        "**/*.o": true, "**/*.py": true, "**/*.sh": true, "**/*.mod": true,
        "**/*.mod.c": true, "**/*.d": true, "**/*.su": true, "**/*.cmd": true,
        "**/.git": true, "**/.gitignore": true, "**/*.MODULE": true,
        "**/*.ko": true, "**/*.symvers": true, "**/*.order": true
    },

    // ==================== Clangd 深度配置 ====================
    "clangd.path": "/usr/bin/clangd",
    "clangd.arguments": [
        // 让 clangd 在后台默默建立索引,不卡顿界面
        "--background-index",
        // 允许并发建立索引的线程数(根据你的 CPU 核心数调整,4-8 比较合适)
        "-j=4",
        // 代码补全时显示详细的函数签名
        "--completion-style=detailed",
        // 自动头文件补全(iwyu = Include What You Use),写驱动时极为方便
        "--header-insertion=iwyu",
        // 告诉 clangd 到哪里去找 compile_commands.json(默认根目录即可)
        "--compile-commands-dir=${workspaceFolder}/linux",
        // 开启全索引模式,增强跳转精准度
        "--all-scopes-completion",
        "-log=info",
        // 允许 clangd 调用你的交叉编译器来辅助解析内核头文件(请根据你实际的交叉编译器名字匹配,这里用通配符 *gdb 或 *gcc)
        "--query-driver=/usr/bin/aarch64-linux-gnu-*"
    ]
}

解决一些检索报错问题,不认部分gcc的特定选项。在.vscode同级目录下,创建.clangd,指定架构,过滤不认识的特性,再重启服务。

CompileFlags: { Add: [-target, aarch64-linux-gnu], Remove: [-fno-allow-store-data-races, -femit-struct-debug-baseonly, -fconserve-stack, -mno-fp-ret-in-387, -mskip-rax-setup, -maccumulator-profile, -falign-jumps=0, -mstack-protector-guard-reg=*, -mstack-protector-guard=*, -fmacro-prefix-map=*, -mabi=lp64] }

记一些常用的vscode命令

Ctrl+P                               查找文件
Ctrl+G                               定位行号
Ctrl+T                               全局符号搜索
Ctrl+Shift+F                         整个工作区搜索
右键选择 Rename Symbol 或按 F2        符号重命名
右键选择 Show Call Hierarchy          查看调用层次
右键选择 Find All References          查找引用
Ctrl+Click                           跳转到定义

3.4 配置调试文件

在.vscode文件下,创建launch.json,指定内核符号表,跨架构调试器 GDB,监听端口

{
    // 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": "Debug Kernel",
            "type": "cppdbg",
            "request": "launch",
            "program": "${workspaceFolder}/linux/vmlinux",
            "args": [],
            "stopAtEntry": false,
            "cwd": "${fileDirname}",
            "environment": [],
            "miDebuggerPath": "/usr/bin/gdb-multiarch",
            "miDebuggerServerAddress": "localhost:1234",   
            "externalConsole": false,
            "MIMode": "gdb",
            "setupCommands": [
                {
                    "description": "为 gdb 启用整齐打印",
                    "text": "-enable-pretty-printing",
                    "ignoreFailures": true
                },
                {
                    "description": "将反汇编风格设置为 Intel",
                    "text": "-gdb-set disassembly-flavor intel",
                    "ignoreFailures": true
                }
            ]
        }
    ]
}

3.5 开启调试

使用qemu启动镜像,增加-s -S参数。

-s (小写):它是 -gdb tcp::1234 的缩写。作用是在后台启动一个 GDB 服务器,监听本地的 1234 端口。后续你可以在另一个终端通过 gdb 命令连接这个端口来调试内核

-S (大写):作用是让 CPU 在启动的瞬间立刻冻结(Freeze)。此时内核不会真正运行,它会死死停在第一行汇编代码前,静静等待你在 GDB 里输入 c (continue) 才会开始流转。这是抓取内核刚初始化时断点的绝佳时机。

qemu-system-aarch64 -machine virt,virtualization=on -cpu cortex-a57 -kernel arch/arm64/boot/Image -append "console=ttyAMA0 nokaslr" -nographic -s -S

在vscode中的代码处打断点,按F5启动,可运行至断点处,以此可完成可视化的调试手段。如此,可以检索代码,运行代码,跟着学习执行流程。

Logo

智能硬件社区聚焦AI智能硬件技术生态,汇聚嵌入式AI、物联网硬件开发者,打造交流分享平台,同步全国赛事资讯、开展 OPC 核心人才招募,助力技术落地与开发者成长。

更多推荐