vmware17安装ubuntu2204版本qemu运行armv8处理器uboot运行调试(包括windows)的一些工作

一、环境搭建

  • 首先说一下安装vmware17,官网已经不提供安装包下载了,大家自己找一下资源吧。
  • 安装好vmware17和ubuntu2204后,ubuntu桌面右键默认是没有新建文本文件这个菜单的,我们需要在 主目录 的 模板 这个文件夹里通过命令行touch创建 文本文件.txt 这个文件即可。
  • 虚拟机和主机之间没法直接复制粘贴文件和文本,我们需要命令行,sudo apt install open-vm-tools-desktop -y 即可。这个open-vm-tools-desktop是开源社区自己维护的新的vm tool工具,比vmware自己菜单栏手动安装那个tool功能还要好。但是发现,互相复制文本内容没问题,从windows复制文件到ubuntu也没问题,但是从ubuntu复制文件到windows就不行。这里不深究了,通过设置共享目录方式实现吧。
  • 关于下载uboot,安装编译器和qemu,分别给出命令行如下:
复制代码
sudo apt-get update
sudo apt-get install git build-essential qemu-system-arm libssl-dev
sudo apt-get install gcc-aarch64-linux-gnu
  • build-essentiallibssl-dev 是编译U-Boot所需的开发工具。

  • qemu-system-arm 提供了针对ARM架构的QEMU全系统模拟。

  • gcc-aarch64-linux-gnu 是针对ARMv8(AArch64)架构的交叉编译器。

复制代码
我们需要获取U-Boot源码并针对ARMv8平台进行编译
git clone https://github.com/u-boot/u-boot.git (如果网速太慢,就自己去这个网站手动下载压缩包自己解压放到主目录 的 u-boot 这个名即可)
cd u-boot
复制代码
指定我们使用ARM64的交叉编译工具链
export CROSS_COMPILE=aarch64-linux-gnu-

择配置文件:U-Boot为不同的硬件平台提供了预设的配置文件。对于在QEMU上模拟ARMv8,我们使用

复制代码
make qemu_arm64_defconfig

开始编译:这个过程可能会花费几分钟,具体取决于你的电脑性能

复制代码
make -j$(nproc)

这个过程可能会报错找不到系统一些头文件和工具啥的,我们直接安装好所有这些,执行如下:

复制代码
sudo apt install bison flex build-essential pkg-config libglib2.0-dev libpixman-1-dev

这个命令会安装:

  • flex:一个经常与 Bison 配合使用的词法分析器生成器。

  • build-essential:包含 GCC、G++、make 等基本的编译工具集合。

  • pkg-config:帮助查找库文件位置的工具。

  • libglib2.0-devlibpixman-1-dev:编译 QEMU 时可能需要的重要开发库。

再次进行编译,就能成功啦!

make -j$(nproc)

我们可以使用QEMU来加载并运行刚刚编译好的U-Boot了:

二、qemu和gdb-multiarch启动调试

复制代码
qemu-system-aarch64 -machine virt -cpu cortex-a57 -m 512M -nographic -bios u-boot.bin

参数解释:

  • -machine virt:指定模拟的机器类型为QEMU的通用ARM虚拟平台("virt")。

  • -cpu cortex-a57:指定模拟的CPU为ARMv8架构的Cortex-A57。你也可以尝试其他ARMv8 CPU如 cortex-a53cortex-a72

  • -m 512M:为虚拟机分配512MB的内存。

  • -nographic:这个选项会以无图形界面模式启动,并将串口输出直接打印到当前终端。这对于在终端中直接与U-Boot交互非常方便。

  • -bios u-boot.bin:指定U-Boot镜像文件作为BIOS加载。

如果一切顺利,你将在终端看到U-Boot的启动日志,并最终进入U-Boot的命令行提示符(通常是 =>)。

在U-Boot命令行中,你可以尝试一些基础命令来验证环境:

  • help:查看所有可用的命令。

  • bdinfo:显示开发板信息。

  • printenv:打印环境变量。

  • version:显示U-Boot版本。

输入 reset 命令可以重新启动系统。

要退出QEMU,通常可以先按下 Ctrl+A,然后释放再按 X 键。

进行gdb单步调试u-boot,如下:

# 终端1:启动 QEMU

qemu-system-aarch64 -machine virt -cpu cortex-a57 -m 512M -nographic \

-bios u-boot.bin -S -s

  • -S:在启动时暂停 CPU,等待 GDB 的 continue 命令

  • -s:在端口 1234 开启 GDB 调试服务器

# 终端2:启动 GDB 调试

gdb-multiarch u-boot

在 GDB 中执行:

(gdb) target remote :1234

(gdb) break _start

(gdb) continue

(gdb) stepi # 单步执行汇编指令

(gdb) info registers

(gdb) break board_init_f

(gdb) continue

(gdb) next # 在 C 代码中单步执行

三、采用gcc工具链中自带的gdb进行调试

/home/lhb/arm-gnu-toolchain-13_3_rel1-x86_64-aarch64-none-linux-gnu/bin/aarch64-none-linux-gnu-gdb u-boot 进行调试,会报错:

  • /home/lhb/arm-gnu-toolchain-13_3_rel1-x86_64-aarch64-none-linux-gnu/bin/aarch64-none-linux-gnu-gdb: error while loading shared libraries: libncursesw.so.5: cannot open shared object file: No such file or directory
  • /home/lhb/arm-gnu-toolchain-13_3_rel1-x86_64-aarch64-none-linux-gnu/bin/aarch64-none-linux-gnu-gdb: error while loading shared libraries: libtinfo.so.5: cannot open shared object file: No such file or directory

上面两个共享库,在当前ubuntu系统(我这个是ubuntu22版本,自带的是libncursesw.so.6、libtinfo.so.6)里没有找到,说明该gdb构建时候依赖的是这两个库(估计是ubuntu18版本才是这两个库名),所以我们要给当前系统下载这两个库,但是会下载失败(E: 无法定位软件包 libncursesw5),所以我们直接用命令找到我们系统里的新版本库复制为那个名就可以了,如下:

lhb@lhb-VMware-Virtual-Platform:~/u-boot$ ldd /home/lhb/arm-gnu-toolchain-13_3_rel1-x86_64-aarch64-none-linux-gnu/bin/aarch64-none-linux-gnu-gdb (该命令可以看该gdb依赖动态库的情况)

linux-vdso.so.1 (0x0000730ac358e000)
libncursesw.so.5 => not found
libtinfo.so.5 => not found

libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x0000730ac3570000)

libstdc++.so.6 => /lib/x86_64-linux-gnu/libstdc++.so.6 (0x0000730ac3200000)

libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x0000730ac3487000)

libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x0000730ac31d2000)

libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x0000730ac3480000)

libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x0000730ac2e00000)

/lib64/ld-linux-x86-64.so.2 (0x0000730ac3590000)

lhb@lhb-VMware-Virtual-Platform:~/u-boot$ find /usr -name "libncursesw.so.*" 2>/dev/null

/usr/lib/x86_64-linux-gnu/libncursesw.so.6.4 (可以查找目标库在哪儿存放)

/usr/lib/x86_64-linux-gnu/libncursesw.so.6

lhb@lhb-VMware-Virtual-Platform:~/u-boot$ sudo ln -s /usr/lib/x86_64-linux-gnu/libncursesw.so.6 /usr/lib/x86_64-linux-gnu/libncursesw.so.5 (进行重新复制且给gdb指定链接即可)

libtinfo.so库也同理操作即可。

再执行最上面的gdb启动调试命令,就成功了!!!

四、windows系统里同样进行qemu和gdb调试uboot

  • 把u-boot工程通过共享目录方式复制到windows系统里;
  • windows系统里安装和ubuntu里同样版本的编译器 ,这样就能把ubuntu里的gcc编译得到的u-boot文件(本质上是个elf文件)放到widnows上同版本工具链中的gdb进行调试了(否则不同编译工具链版本可能调试符号解析有问题)。(注意:有些厂商发行的编译器只有linux版没有对应的windows版的情况。例如gcc-linaro-7.5.0-2019.12-x86_64_aarch64-linux-gnu

arm官方下载页面:https://developer.arm.com/downloads/-/arm-gnu-toolchain-downloads

windows下载如下版本:

ubuntu里下如下版本:注意:那么ubuntu里编译uboot时候,需要通过命令指定使用该版本编译器,命令为:

make distclean

make qemu_arm64_defconfig

make CROSS_COMPILE=/home/lhb/arm-gnu-toolchain-13_3_rel1-x86_64-aarch64-none-linux-gnu/bin/aarch64-none-linux-gnu--j$(nproc)

如果想生成编译数据库文件 compile_commands.json,那么上面一条命令改为:

bear -- make CROSS_COMPILE=/home/lhb/arm-gnu-toolchain-13_3_rel1-x86_64-aarch64-none-linux-gnu/bin/aarch64-none-linux-gnu- -j$(nproc)

  • windows里下载qemu,这个版本下载最新的就行,网页:https://qemu.weilnetz.de/w64/2025/,然后安装到一个没有空格和中文的路径即可,例如我安装到了D:\qemu
  • 在u-boot根目录里,按住shift右键打开两个powershell命令行终端

与ubuntu中qemu和gdb调试同理,终端1,输入命令

D:\qemu\qemu-system-aarch64.exe -machine virt -cpu cortex-a57 -m 512M -nographic -bios u-boot.bin -S -s

终端2输入命令

D:/desktop_old/file/qtProject/build_lightning_dir/debug/RedPandaIDE/debug/kit/arm-gnu-toolchain-13_3_rel1-mingw-w64-i686-aarch64-none-linux-gnu/bin/aarch64-none-linux-gnu-gdb.exe u-bbot

进入gdb后,输入 target remote :1234 即可连接上终端1启动的qemu,然后即可进行单步调试了。

五、调试说明

u-boot运行流程:

复制代码
start (加载地址) → board_init_f函数早期初始化 → relocate_code函数 (重定位) → 运行地址继续执行(board_init_r函数后期初始化)> 进入main_loop进行命令行交互

u-boot在中间阶段会把自己进行重定位,此时gdb解析的u-boot文件里的符号地址和实际运行的地址有偏移了,导致gdb下断点,以及单步调试等动作就不能正常工作了,一般gdb会报错 Cannot find bounds of current function

关于解决该问题,大模型搜一下就能给出多种解决方法,这里简单说几个:

  1. 在重定位函数处设置断点,

    复制代码
    print gd->reloc_off #获取重定位的偏移地址
    add-symbol-file u-boot 0x40000000  # 使用实际的重定位地址重新加载u-boot符号文件
  2. 重定位后的入口地址打个断点,例如

    复制代码
    break *0x40000000     # 使用实际的重定位地址
    continue
    symbol-file #替换已有的符号文件u-boot
    add-symbol-file u-boot #重新加载符号文件
  3. 修改u-boot源码,不让其进行重定位

在 .config 文件中添加

CONFIG_SYS_TEXT_BASE=0x0

CONFIG_POSITION_INDEPENDENT is not set

六、总结

总的来说,windows里调试u-boot还是比较方便的,也方便与自己做一个gdb调试器前端相结合,先直接调试到重定位那里,后面熟悉了再把重定位后面的内容进行调试学习吧。

相关推荐
DeBuggggggg4 小时前
linux 安装Python3.9 且支持SSL
linux·运维·ssl
杨云龙UP4 小时前
【MySQL迁移】MySQL数据库迁移实战(利用mysqldump从Windows 5.7迁至Linux 8.0)
linux·运维·数据库·mysql·mssql
Wang's Blog4 小时前
Nestjs框架: 微服务断路器实现原理与OPOSSUM库实践
运维·微服务·nestjs
威桑4 小时前
C++ Linux 环境下内存泄露检测方式
linux·c++
深思慎考4 小时前
微服务即时通讯系统(服务端)——文件存储模块全链路设计与实现(3)
linux·微服务·架构·c++项目·聊天系统
mm-q29152227295 小时前
高并发-负载均衡
运维·负载均衡
就叫飞六吧5 小时前
Nginx 主要的几种负载均衡模式
运维·nginx·负载均衡
wdfk_prog6 小时前
[Linux]学习笔记系列 -- [kernel][time]tick
linux·笔记·学习
凯歌的博客6 小时前
python虚拟环境应用
linux·开发语言·python