跳转到内容
新建笔记

嵌入式 Linux:寄存器、启动链与学习入口

嵌入式 Linux 的学习可以沿两条线推进:一条是启动链、内核与根文件系统如何组成可运行的系统;另一条是应用和驱动如何使用硬件。本文保留早期学习资料入口,并用 TWI 控制寄存器说明最容易混淆的「地址、内容、访问方式」。

寄存器地址不会随数值变化

跳转到“寄存器地址不会随数值变化”

以 Allwinner F1C200s 用户手册 Rev.1.2 的 TWI0 为例,模块基地址为 0x01C27000,控制寄存器 TWI_CNTR_REG 的偏移是 0x0C,所以它的物理地址为:

0x01C27000+0x0C=0x01C2700C.0x01C27000+0x0C=0x01C2700C.

INT_EN 是该寄存器的 bit 7。把这一位设为 1 改变的是寄存器内容;地址仍为 0x01C2700C。对一个普通 32 位变量,value | 0x80u 表示保留原值的其他位并置位 bit 7。例如 0x00 → 0x80、0x40 → 0xC0。这组地址是特定芯片的实例,不能直接移用到 i.MX8MP 或 STM32。

按位或不能保证硬件「其他状态不变」

跳转到“按位或不能保证硬件「其他状态不变」”

原笔记使用裸指针和 |= 0x80。|= 实际包含一次读、一次修改、一次写;硬件寄存器不一定具有普通 RAM 的读写语义。该 TWI 控制寄存器还含有 START、STOP 和中断状态字段;手册描述 START/STOP 位可由硬件自动清除,INT_FLAG 则通过写 0 清除。软件必须按控制器状态机组织整次写入。更一般地,其他设备还可能存在读清除、写 1 清除、只写寄存器和保留位。

因此,上述数值例子只解释位运算,不能作为完整 TWI 初始化或中断使能驱动。时钟、复位、引脚、总线使能、中断控制器,以及当前传输状态都需要另外配置。volatile 也不提供并发互斥、原子更新或完整的设备访问排序保证。

在 Linux 驱动中,通常先取得设备资源并映射为 __iomem 地址,再按设备要求使用 readl()、writel() 等访问器。用户程序中的指针是进程地址,不能把物理地址强转后当作普通内存访问。Linux 6.8 设备 I/O 文档 解释了映射、访问器与排序的关系。

从 TF 卡启动需要哪些内容

跳转到“从 TF 卡启动需要哪些内容”

下面是工作流程,不是通用磁盘写入命令:

  1. 确认板卡、SoC、存储介质、启动模式与对应 BSP。
  2. 按启动方案规划分区表、引导程序保留区域和文件系统。
  3. 用分区工具写分区边界,再用文件系统工具格式化各分区;两步作用不同。
  4. 在 ROM 要求的位置放置引导镜像,在启动分区放置内核和设备树,在根分区部署 rootfs。
  5. 核对 U-Boot 加载路径、内核启动参数和 rootfs 所需驱动,完成写入并正常卸载介质。

Allwinner 某些 SD 启动方案把 SPL/U-Boot 放在 8 KiB 偏移,这由 ROM 启动规则决定。它不适用于所有 SoC,也不能据此推断 GPT 的元数据不会被覆盖。分区尺寸、文件名和介质写入偏移应来自所用板卡的启动资料。

工具或接口能做什么使用前提
i2c-tools查询 I²C 适配器,按已知协议访问设备寄存器已有 I²C 控制器和 i2c-dev 支持、正确总线号与访问权限
spi-tools、内核 spidev_test通过 SPI 用户接口进行传输或回环检查已为该设备提供合适的用户接口,确认片选、模式、位宽与最高时钟

I²C 的总线扫描会发出实际事务,SPI 读写也会影响设备状态;不要把它们当成完全被动的识别工具。已有内核驱动占用的设备,应优先使用该驱动公开的接口。I²C 用户接口 和 SPI 用户接口 分别说明了设备节点和传输方式。

资料用途
Lichee Zero 文档原笔记的板卡入门资料,使用前核对 Zero 与 Nano 的芯片差异
野火 Linux I²C 应用教程I²C 应用开发实例,板卡条件以该教程为准
NanoPi M1 文档另一块板卡的硬件与系统资料
Linux 驱动实现者指南按自己内核版本查阅驱动 API
Buildroot 发布目录查询发布包与对应版本资料

原实验还记录了 Linaro GCC 7.2.1 / 2017.11、U-Boot 2018.01、Linux 5.7.1 和 Lichee-Pi U-Boot 仓库。这些链接用于追溯旧实验,不代表今天应把四者任意组合。复现实验需要同时记录源代码提交、配置、工具链和板卡版本。