1. 搭建ARMv8交叉编译环境
任务目标
在x86_64主机上搭建ARMv8(AArch64)交叉编译环境,使用aarch64-linux-gnu-gcc工具链编译一个不依赖操作系统的裸机程序,并通过file命令和反汇编验证生成的可执行文件确为AArch64架构。
环境准备
Ubuntu 20.04/22.04 主机,安装工具链:
sudo apt update
sudo apt install gcc-aarch64-linux-gnu binutils-aarch64-linux-gnu
验证安装:
aarch64-linux-gnu-gcc --version
裸机程序源码
创建 startup.s(汇编启动代码)和 main.c(C入口函数)。由于裸机程序无操作系统加载器,需通过链接脚本将代码定位到固定地址,并用汇编提供入口点。
startup.s:
.section .text._start
.global _start
_start:
ldr x0, =0x40000000 // 向内存地址写一个测试值
mov x1, #0x5A
str x1, [x0]
b . // 死循环,模拟程序驻留
main.c:
void main(void) {
// 空函数:演示C代码与汇编链接
// 实际功能由_start中的汇编完成
}
linker.ld:
SECTIONS
{
. = 0x40000000;
.text : {
*(.text._start)
*(.text*)
}
.data : { *(.data*) }
.bss : { *(.bss*) }
}
编译与链接
aarch64-linux-gnu-as -o startup.o startup.s
aarch64-linux-gnu-gcc -c -o main.o main.c -ffreestanding
aarch64-linux-gnu-ld -T linker.ld -o baremetal.elf startup.o main.o
aarch64-linux-gnu-objcopy -O binary baremetal.elf baremetal.bin
验证方法
- 架构检查:执行
file baremetal.elf,输出应包含ELF 64-bit LSB executable, ARM aarch64。 - 反汇编验证:执行
aarch64-linux-gnu-objdump -d baremetal.elf,应看到_start处的指令为ldr x0, #0x40000000和mov x1, #0x5a,且地址从0x40000000开始。 - 二进制大小:
ls -l baremetal.bin应存在且非空(预期约几十字节)。
若上述检查均通过,说明交叉编译工具链工作正常,已成功生成AArch64裸机程序。
常见问题
- 链接地址错误:若反汇编地址不是从
0x40000000开始,检查链接脚本是否被正确加载(-T参数)。 - 缺少
-ffreestanding:编译C文件时不加此选项,编译器可能假设存在宿主环境,导致链接时引用未定义的库函数。 - 运行方式:本程序为裸机镜像,不能直接在Linux下运行。如需执行验证,可使用QEMU模拟:
qemu-system-aarch64 -machine virt -cpu cortex-a57 -kernel baremetal.elf -nographic(需安装qemu-system-arm)。