异架构相关

sky123

环境搭建

qemu 仿真

QEMU(Quick Emulator) 是一个开源的通用虚拟化和仿真框架,该框架主要有如下分类:

  • qemu-user:提供用户态的简单仿真。适用于对一些相对简单程序的进行仿真。

  • qemu-system:提供完整的系统级仿真。例如有些固件的运行需要一整套复杂的环境,单纯使用 qemu-user 仿真比较麻烦并且容易出问题,因此一个比较简单的方法是把整个 IOT 设备的文件系统扔到对应架构的一个完整虚拟机中然后 chroot 切换到 IOT 设备的文件系统的根目录进行仿真,此时需要使用 qemu-system 运行整个虚拟机。

  • qemu-utils:qemu 的一些配套工具,比如制作磁盘镜像的 qemu-img

安装命令:

1
2
3
4
sudo apt install qemu -y
sudo apt install qemu-user qemu-user-static -y
sudo apt install qemu-system -y
sudo apt install qemu-utils -y

qemu-user

qemu-user 是 QEMU 的用户态仿真组件,用于在宿主机(例如 x86_64 Linux)上直接运行其他架构(如 ARM/MIPS/RISC-V)的用户态二进制程序。该组件只仿真用户空间指令,不包括系统级仿真,因而被仿真的二进制程序的系统调用由宿主机内核负责。

安装与使用

qemu-user 组件可以单独安装,安装命令如下:

1
sudo apt install qemu-user qemu-user-static -y

qemu-user 的基本命令格式如下:

1
qemu-<arch> [options] <target_program> [args...]

例如:

  • 在 x86_64 上运行 ARM 二进制

    1
    qemu-arm ./hello-arm
  • 在 x86_64 上运行 RISC-V 二进制并传递参数

    1
    qemu-riscv64 ./hello-riscv arg1 arg2

常用参数

qemu-user 支持一些特定参数:

  • -L <path>:指定目标程序依赖的根文件系统(sysroot)。适合动态链接二进制。
    例如:

    1
    qemu-arm -L /path/to/armfs ./hello-arm

    注意

    有些依赖特定动态库和特定路径的固件程序需要通过 chroot 将根目录切换到解压出的文件系统根目录然后再用 qemu-user 仿真程序,如果使用动态链接的 qemu-user 仿真会因根目录切换而无法找到 qemu-user 本身所依赖的动态库进而导致仿真失败,因此需要使用静态编译的 qemu-user-static

  • -strace:输出系统调用日志,调试用:

    1
    qemu-arm -strace ./hello-arm
  • -g <port>: 开启 gdbserver,进行远程调试:

    1
    qemu-arm -g 1234 ./hello-arm
  • -cpu <model>:指定仿真 CPU 型号:

    1
    qemu-arm -cpu cortex-a9 ./hello-arm
  • -E VAR=value:向目标程序注入环境变量。

binfmt

在 Linux 内核中,binfmt(binary format)机制负责决定“某个可执行文件被执行时应由谁来解释 / 运行”。通过配置 binfmt,我们可以“透明”地执行异架构的二进制程序,而不用显式的通过 qemu-user 执行。

这一能力的核心子系统是 **binfmt_misc**。加载 binfmt_misc 模块后,内核会在 /proc/sys/fs/binfmt_misc/ 目录下暴露一组伪文件,用户空间通过向这些文件写入配置即可把“文件格式 → 解释器”映射关系注册给内核。

qemu-user 在安装时会在 /proc/sys/fs/binfmt_misc/ 路径下添加 binfmt_misc 相应的配置文件。因此我们直接运行异架构程序 Linux 会选择正确的 qemu-user-static 程序运行。

1
2
3
4
5
6
7
➜  ~ cat /proc/sys/fs/binfmt_misc/qemu-arm  
enabled
interpreter /usr/bin/qemu-arm-static
flags: OCF
offset 0
magic 7f454c4601010100000000000000000002002800
mask ffffffffffffff00fffffffffffffffffeffffff

然而对于动态链接的程序,qemu 可以正常加载程序,但是动态库却会默认使用本机的动态库导致程序崩溃,因此需要 -L 参数指定 ld 的前缀径。另外如果将交叉编译工具链添加到对应的 qemu-binfmt,则 qemu-user 在运行程序时能加载正确的动态链接库,不需要指定路径。

1
2
3
4
5
6
7
8
sudo mkdir /etc/qemu-binfmt
sudo ln -s /usr/arm-linux-gnueabi /etc/qemu-binfmt/arm
sudo ln -s /usr/mipsel-linux-gnu/ /etc/qemu-binfmt/mipsel
sudo ln -s /usr/aarch64-linux-gnu /etc/qemu-binfmt/aarch64
sudo ln -s /usr/powerpc-linux-gnu /etc/qemu-binfmt/ppc
sudo ln -s /usr/mips64-linux-gnuabi64 /etc/qemu-binfmt/mips64
sudo ln -s /usr/mips64el-linux-gnuabi64 /etc/qemu-binfmt/mips64el
sudo ln -s /usr/mips-linux-gnu /etc/qemu-binfmt/mips

qemu-system

qemu-system 仿真需要提供系统内核和文件系统,我们可以在这个网站下载所需结构的内核和文件系统。

qemu-system 启动命令如下,具体启动参数还要参考镜像对应的 README 作相应的调整。

1
2
3
4
5
6
7
8
9
qemu-system-arm \
-M versatilepb \
-kernel vmlinuz-3.2.0-4-versatile \
-hda debian_wheezy_armel_standard.qcow2 \
-initrd initrd.img-3.2.0-4-versatile \
-append "root=/dev/sda1 console=tty0" \
-net nic \
-net tap,ifname=tap0,script=no,downscript=no \
-nographic
  • -M malta:主板类型,参考内核镜像后缀。
  • -kernel vmlinux-3.2.0-4-4kc-malta:内核镜像。
  • -hda debian_wheezy_mipsel_standard.qcow2:虚拟磁盘镜像。
  • -initrd initrd.img-3.2.0-4-versatile:一个临时的文件系统映像,用于在Linux系统引导过程中提供必要的文件和工具,它通常用于初始化和准备真正的根文件系统之前。
  • -append root=/dev/sda1 console=tty0: 内核启动参数。
  • -net nic:添加一个网络接口卡(NIC)到模拟器中,以实现网络功能。
  • -net tap,ifname=tap0,script=no,downscript=no:添加一个 TAP 设备,并将其与模拟器中的网络接口卡关联起来,用于与主机的网络进行通信。
  • -nographic:禁用图形界面输出,只使用命令行界面进行连接和操作。

为了能够与 qemu 虚拟机通信,需要再 qemu 虚拟机启动先在外部主机创建并配置网卡 tap0

1
2
3
4
5
6
sudo apt install uml-utilities

if ! ip link show tap0 &>/dev/null; then
tunctl -t tap0 -u $(whoami)
fi
ifconfig tap0 192.168.2.1/24

qemu 虚拟机启动后需要再虚拟机中分配 ip 。

1
ifconfig eth0 192.168.2.2/24

之后就可以通过 scp 向虚拟机传文件或者 ssh 登录虚拟机。

1
2
3
sudo apt install sshpass
sshpass -p root scp squashfs-root.tar.xz root@192.168.2.2:~
sshpass -p root ssh root@192.168.2.2

交叉编译

交叉编译工具链

对于一些简单情形的交叉编译,直接下载对应的交叉编译工具链即可。

1
2
3
4
5
6
7
8
9
10
11
12
sudo apt install gcc-arm-linux-gnueabi g++-arm-linux-gnueabi -y
sudo apt install gcc-aarch64-linux-gnu g++-aarch64-linux-gnu -y
sudo apt install gcc-mips64el-linux-gnuabi64 g++-mips64el-linux-gnuabi64 -y
sudo apt install gcc-mips-linux-gnu g++-mips-linux-gnu -y
sudo apt install gcc-mipsel-linux-gnu g++-mipsel-linux-gnu -y
sudo apt install gcc-mips64-linux-gnuabi64 g++-mips64-linux-gnuabi64 -y
sudo apt install gcc-powerpc-linux-gnu g++-powerpc-linux-gnu -y
sudo apt install gcc-powerpc64-linux-gnu g++-powerpc64-linux-gnu -y
sudo apt install gcc-riscv64-linux-gnu g++-riscv64-linux-gnu -y
sudo apt install gcc-alpha-linux-gnu g++-alpha-linux-gnu -y
sudo apt install gcc-s390x-linux-gnu g++-s390x-linux-gnu -y
sudo apt install gcc-sparc64-linux-gnu g++-sparc64-linux-gnu -y

crosstool-ng

crosstool-ng 是一个 跨平台交叉编译工具链自动生成器。它通过一套脚本 + Kconfig 菜单界面,自动下载、打补丁、配置并编译 Binutils、GCC、C 库及调试工具,最终生成可重复使用的交叉编译环境(<triplet>-gcc<triplet>-gdb 等)。

crosstool-ng 安装

在安装 crosstool-NG 之前,可能需要在宿主操作系统上额外安装若干软件包。这里我们可以参考项目中对应系统的 Dockerfile,例如 Ubuntu 22.04 需要安装如下依赖:

1
2
3
4
sudo apt-get update
sudo apt-get install -y gcc g++ gperf bison flex texinfo help2man make libncurses5-dev \
python3-dev autoconf automake libtool libtool-bin gawk wget bzip2 xz-utils unzip \
patch libstdc++6 rsync git meson ninja-build

之后将 crosstool-ng 项目克隆下来:

1
git clone https://github.com/crosstool-ng/crosstool-ng

克隆后须先执行 bootstrap 生成 configure

1
cd crosstool-ng && ./bootstrap

之后编译安装即可:

1
2
3
./configure --prefix=/usr
make -j$(nproc)
sudo make install

构建交叉编译工具链

这里以 x86-32 架构为例。

提示

由于构建整个工具链的过程受众多依赖种类、版本等影响,因此只能通过排列组合探索出一种可行的方式,并不能保证这个配置方式是最简的。

ARM

ARM 版本体系

ARM的版本体系可以分为三个层次

  • 架构版本(ISA) :这是 ARM 处理器的核心指令集架构,决定了处理器如何执行指令、如何与内存交互。
  • 核心版本(Core) :基于架构,ARM 会设计具体的处理器核心,比如 Cortex 系列、Neoverse 等。
  • 平台和产品系列 :ARM 设计的不同平台解决方案,比如面向移动设备的平台,面向服务器的 Neoverse 平台等。

ARM 架构版本(ISA)

ARM的架构版本是ARM处理器指令集的基础,从 ARMv4 开始,到现在的 ARMv9 ,ARM经历了几个大的变革:

架构版本 发布年份 特点 代表性产品
ARMv4 1994 初代架构,支持32位指令集,主打低功耗嵌入式应用。 ARM7TDMI
ARMv5 1999 加入了增强指令集,优化了性能,支持更高效的指令执行。 ARM9
ARMv6 2001 引入了Thumb指令集(16位指令,减小代码体积),支持更复杂的缓存系统。 ARM11
ARMv7 2005 分为A/R/M三种子架构,支持硬件虚拟化、浮点运算、SIMD等功能,支持Thumb-2(16/32位混合)。 Cortex-A8, Cortex-A9
ARMv8 2011 支持64位架构(AArch64),引入了64位寄存器和指令,提升了性能和寻址能力,同时保持向下兼容32位。 Cortex-A53, Cortex-A57
ARMv9 2021 强化了AI加速、安全(TrustZone增强)和虚拟化功能,同时优化了指令集。 Cortex-A510, Cortex-A710, Neoverse V1

其中 ARMv8 架构在引入 64 位计算时,增加了 AArch 作为区分不同指令集架构模式的标识,提出了 AArch32AArch64 两个明确的模式:

  • AArch32:保持与 ARMv7 及之前架构兼容,支持 32 位程序执行,且继续支持 Thumb模式(16位指令)和 ARM模式(32位指令)。
  • AArch64:是 ARMv8 引入的 64 位指令集,处理器支持 64 位寄存器(X0-X30),支持更大的寻址空间,且指令集被简化为统一的 32 位宽度指令(没有 Thumb 模式)。

ARM核心版本(Core)

ARM 设计了多个处理器核心系列,用于满足不同的应用需求。每个核心基于一个架构版本,提供了不同的性能、功耗、特性。

核心系列 说明 代表核心
Cortex-A系列 高性能,面向应用处理器,支持运行操作系统(Linux/Android等),适用于手机、平板、笔记本等设备。 Cortex-A7, Cortex-A9, Cortex-A53, Cortex-A72, Cortex-A76, Cortex-A78
Cortex-R系列 实时处理器,强调低延迟和高可靠性,广泛用于汽车、工业控制、实时系统等领域。 Cortex-R4, Cortex-R5, Cortex-R7
Cortex-M系列 超低功耗微控制器,适用于嵌入式系统、物联网、传感器控制等。 Cortex-M0, Cortex-M0+, Cortex-M3, Cortex-M4, Cortex-M7, Cortex-M33
Neoverse系列 针对数据中心、云计算、服务器市场设计,优化了AI和高吞吐量任务。 Neoverse N1, Neoverse V1

ARM 平台和产品系列

ARM 不仅设计了核心,还根据市场需求推出了各种完整的系统平台解决方案。这些平台集成了 ARM 处理器、GPU、内存、I/O 等组件,形成一个完整的 SoC(System-on-Chip)方案。

平台 说明 代表平台/产品
ARMv7-A/ARMv8-A平台 移动和消费电子产品,支持高性能处理器、图形、音视频处理等。 Apple A系列,Qualcomm Snapdragon
Neoverse平台 针对数据中心、云计算、边缘计算等市场设计,提供高性能的ARM处理器,优化了AI计算、并行处理和高吞吐量。 AWS Graviton,Ampere Altra
Automotive平台 针对汽车电子、自动驾驶提供优化的处理器和系统方案。 ARM Cortex-A系列在车载系统中的应用
Arm Total Compute平台 针对智能终端设备(手机、平板、嵌入式设备)提供的完整系统平台,集成CPU、GPU、AI加速器等。 Arm’s solution for mobile devices

ARM32

寄存器

ARM64

MIPS

  • Title: 异架构相关
  • Author: sky123
  • Created at : 2022-09-28 11:45:14
  • Updated at : 2025-06-02 23:46:35
  • Link: https://skyi23.github.io/2022/09/28/异架构相关/
  • License: This work is licensed under CC BY-NC-SA 4.0.
Comments