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

验证方法

  1. 架构检查:执行 file baremetal.elf,输出应包含 ELF 64-bit LSB executable, ARM aarch64。
  2. 反汇编验证:执行 aarch64-linux-gnu-objdump -d baremetal.elf,应看到 _start 处的指令为 ldr x0, #0x40000000 和 mov x1, #0x5a,且地址从 0x40000000 开始。
  3. 二进制大小: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)。