嵌入式工具介绍

交叉编译

参与编译和运行的机器根据其角色可以分成以下三类

  • 构建(build)系统:生成编译器可执行程序的计算机系统。(生成编译器的电脑)
  • 主机(host)系统:运行编译器可执行程序,编译链接应用程序的计算机系统。(生成应用程序的电脑)
  • 目标(target)系统:运行应用程序的计算机系统。(执行应用程序的电脑)

根据 build/host/target 的不同组合我们可以得到如下的编译方式分类

  • 本地(native)编译:build == host == target
  • 交叉(cross)编译: build == host != target

调试器 GDB

  • https://ww.gnu.org/software/gdb
  • GDB(The GNU Project Debugger),GNU 项目调试器,用于查看另一个程序在执行过程中正在执行的操作,或该程序崩溃时正在执行的操作。
  • 被调试的程序可能与 GDB 在同一台计算机上执行,也可能在另一台计算机(远程)上或者在模拟器上执行。
  • GDB 支持调试多种语言:如 Rust 等。

GDB

当执行gdb a.out后发生了什么

本地调试时

gdb运行起来之后他会在本地先 fork 一个子进程去运行 a.out,然后 gdb 本身也会运行在一个子进程中,二者通过 ptrace 这个系统调用建立连接;当你在 gdb 中运行至a.out 中的断点时,他就会把 a.out 这个所在的进程挂起来进入阻塞状态。

远程调试时

首先会在目标机器上启动一个名叫 gdbServer 的远程服务,本地的 gdb 会与 gdbServer 建立连接,由 gdbServer 来代理我们的调试过程; a.outgdbServer 运行在目标机器上。

调试机器和目标机器通过网络进行连接。

GDB基本调试流程

模拟器 QEMU

  • https://www.qemu.org/
  • QEMU是一套由(Fabrice Bellard)编写的以 GPL 许可证分发源代码的计算机系统模拟软件,在 GNU/Linux 平台上被广泛使用。
  • 支持多种体系架构。譬如:RISC-V、X86等。
  • QEMU 有两种主要运行模式
    • User mode:直接运行应用程序。
    • System mode:模拟整个计算机系统,包括中央处理器及其他周边设变。

项目构造工具 Make

  • https://ww.gnu.org/software/make/
  • Make 是什么
    • make 是一种自动化工程管理工具。
  • Makefile 是什么
    • 配合 make,用于描述构建过程中所管理的对象以及如何构造工程的过程。
  • Make 如何找到 Makefile
    • 隐士查找:当前目录下按顺序查找名为”GNUmakefule”、”makefile”、”Makefile”的文件。
    • 显示查找:-f

Makefile 的构成

  • Makefile 由一条或者多条规则(fule)构成。

  • 每条规则由三要素构成

    • target:目标,可以是 obj 文件也可以是可执行文件。
    • prerequisites:生成 target 所需要的依赖。
    • command:为了生成 target 需要执行的命令,可以有多条。
  • 一个简单的 Makefile 如下

  • # 定义 Makefile 中的一些变量名
    # = 为简单赋值 := 为赋值展开,即如果后续更改了用于赋值的变量的值,那么这个改变不会影响已经赋值的变量。
    TARGET := riscv64gc-unknown-none-elf
    MODE := release
    APP_DIR := src/bin
    TARGET_DIR := target/$(TARGET)/$(MODE)
    APPS := $(wildcard $(APP_DIR)/*.rs)
    ELFS := $(patsubst $(APP_DIR)/%.rs, $(TARGET_DIR)/%, $(APPS))
    BINS := $(patsubst $(APP_DIR)/%.rs, $(TARGET_DIR)/%.bin, $(APPS))
    
    OBJDUMP := rust-objdump --arch-name=riscv64
    OBJCOPY := rust-objcopy --binary-architecture=riscv64
    
    elf:
        @cargo build --release --target $(TARGET)
    
    binary: elf
        @$(foreach elf, $(ELFS), $(OBJCOPY) $(elf) --strip-all -O binary $(patsubst $(TARGET_DIR)/%, $(TARGET_DIR)/%.bin, $(elf));)
    
    build: binary
    
  • 行注释以 # 开头