源码资源:
2、【CORDIC工程源码】
本节是整个教程的起点。我们会从"嵌入式系统"的基本概念讲起,逐步引出"嵌入式 Linux",并说明本项目的核心任务——为什么要"构建"一个系统镜像。
嵌入式系统(Embedded System) 是一种以应用为中心、以计算机技术为基础、软硬件可裁剪、对功能、可靠性、成本、体积、功耗有严格要求的专用计算机系统。
IEEE 给出的定义是:嵌入式系统是用于控制、监视或辅助设备、机器或工厂运行的装置(devices used to control, monitor, or assist the operation of equipment, machinery or plants)。
通俗地说:嵌入式系统是"藏"在某个产品里、专门完成特定任务的计算机。它不是为了通用计算而设计,而是为了某个具体应用而存在。
本项目对应的是"工业示波器"这一类——一块基于 ZYNQ 的板卡,它本质上是一台"软件定义仪器"。
不是所有嵌入式系统都需要操作系统。按复杂度可以分为三档:
while(1) 主循环 + 中断处理// 典型的裸机程序结构intmain(void) { hardware_init(); // 初始化硬件while (1) { // 永远循环 read_sensor(); // 读传感器 do_something(); // 处理 delay_ms(10); // 延时 }}三者的资源需求对比(量级):
一个可启动的嵌入式 Linux 系统由 四个部分 组成。这是理解后续所有构建脚本的基础:
┌─────────────────────────────────────────────│ 1. Bootloader(引导加载器) │ 通常是 U-Boot,负责初始化硬件、加载内核 ├─────────────────────────────────────────────│ 2. Linux Kernel(内核) │ 管理硬件资源、调度进程、提供系统调用 ├─────────────────────────────────────────────│ 3. Device Tree(设备树 .dtb) │ 描述硬件信息,告诉内核"板上有什么" ├─────────────────────────────────────────────│ 4. Root Filesystem(根文件系统) │ 所有用户空间程序、库、配置文件都在这里 └─────────────────────────────────────────────① Bootloader
BootROM → FSBL → U-BootBOOT.BIN,放在 SD 卡的 boot 分区② Linux Kernel
make menuconfig),只编译需要的功能,减小体积③ Device Tree
.dts,编译后得到 .dtb(二进制),由 U-Boot 传给内核.dtb 文件放在 boot 分区,启动时由 U-Boot 加载④ Root Filesystem
/)/bin(命令)、/lib(库)、/etc(配置)、/usr(程序)、/home(用户目录)等上电 │ ▼BootROM(片内 ROM,不可改):读取启动模式引脚 → 选择从 SD 卡启动 │ ▼FSBL(在 BOOT.BIN 内) │ 初始化 PS:DDR 内存、时钟、MIO 引脚 │ 可选:加载 FPGA bitstream 到 PL ▼U-Boot(在 BOOT.BIT 内) │ 从 FAT 分区读取内核 Image 和设备树 .dtb │ 把它们加载到内存,并传参(启动参数、设备树地址) ▼Linux 内核启动 │ 解析设备树,初始化各驱动 │ 挂载根文件系统(ext4 分区) ▼systemd(PID=1) │ 按依赖关系启动各项服务(网络、SSH、nginx……) ▼用户登录 → 可使用系统很多人会问:既然都是 Linux,为什么不能直接把 PC 上的 Ubuntu 装到板子上?原因如下:
| 交叉编译+ 镜像打包 | ||
apt install 即可 |
为什么需要交叉编译?
x86 主机(开发机) ARM 目标板(运行机)
─────────────── ───────────────
源码 .c
交叉编译器 ──编译── ARM 可执行文件
arm-linux- (在这里运行)
gnueabihf-gcc
─────────────── ───────────────
生成 ARM 代码 只执行,不编译
本项目除了用交叉编译器编译内核模块外,还用了另一种巧妙方式——QEMU 用户态模拟 + chroot,这让我们能直接在 x86 主机上"运行" ARM 版的
apt-get来安装软件,相当于在 PC 里"虚拟"出一台 ARM 机器。这种方式将在第 2.4 节详细讲解。
在 PC 上安装 Ubuntu 非常简单:
下载 ISO 镜像 → 用 Rufus/balenaEtcher 刻录到 U 盘 → 从 U 盘启动 → 运行安装程序 → 完成
但嵌入式系统不能这么做,原因有三:
① 硬件架构不同
② 启动方式不同
③ 需要深度定制
──────────────────────────────────────────────────────
在 x86 主机上,制作一个 7.4GB 的 .img 镜像文件,
它包含完整的 ARM 版 Ubuntu 系统,
可以用 dd 命令直接写入 SD 卡,
插入 ZYNQ 板卡上电即可启动运行。
──────────────────────────────────────────────────────
这个 .img 文件相当于一张"虚拟 SD 卡",它的字节布局和真实 SD 卡完全一致:
.img 文件内部布局(7.4GB)
────────── ──────────────────── ────────────────────────
MBR 分区1:FAT16 (~1GB) 分区2:ext4 (~6.4GB)
512字节 boot 分区 root 分区(根文件系统)
分区表 - BOOT.BIN - Ubuntu Base 系统
- Linux 内核 Image - 应用程序、库、配置
- 设备树 .dtb - Red Pitaya 服务
- U-Boot 脚本 - 用户主目录
────────── ──────────────────── ────────────────────────
4MB 对齐 4MB ────── 1024MB ───────────── 7400MB
写入 SD 卡的命令(在 Linux 主机上):
# /dev/sdX 替换为 SD 卡的实际设备名(务必确认,别写错盘!)
sudo ddif=red_pitaya_OS_3.00.img of=/dev/sdX bs=4M conv=fsync status=progress
sync
业界有几种主流的嵌入式 Linux 构建方案,本项目采用的是其中一种"轻量定制"路线:
| Buildroot | ||||
| Yocto Project | ||||
| LFS | ||||
| 发行版 Base + chroot | apt |
apt install 即用,省去交叉编译每个库的麻烦这就是为什么本项目的脚本里有大量
apt-get install和chroot操作——它本质上是在一个"虚拟的 ARM Ubuntu"里装软件,然后把整个文件系统打包成镜像。
.img,含 Ubuntu 24.04 armhf 系统,可写 SD 卡启动 | |
下一节 1.2 ZYNQ 异构平台简介 会深入介绍本项目使用的 Xilinx Zynq-7000 SoC:为什么它要把 ARM 和 FPGA 放在一颗芯片上,PS 和 PL 如何分工协作,以及它的启动流程细节。
✨ 如果本文对你有帮助
推荐合集阅读
👇
下载资料请扫码进小程序,正在内测中.......
