WSL2 + Qemu模拟嵌入式,VSCode + GDB + Linux/Uboot远程开发
目的:
学习嵌入式,特别是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启动,可运行至断点处,以此可完成可视化的调试手段。如此,可以检索代码,运行代码,跟着学习执行流程。

更多推荐

所有评论(0)