linux启动过程

系统上电—>bootrom—>uboot—>kernel加载—>init—>应用程序

bootrom

电子设备芯片(SoC)内部的一小块固态只读存储器。
在设备开机时,内存(RAM)里是一片空白的,CPU 根本不知道去哪里读系统镜像。这时 CPU 会强制将指针指向 BootROM 的固定地址。
BootROM 的工作流程通常如下:
硬件基本初始化: 设置最基础的时钟、关闭看门狗、初始化芯片内部的微量内存(SRAM)。
检查启动介质(Boot Modes): 检查芯片引脚(如拨码开关、GPIO 电平),判断当前应该从哪里加载下一阶段的代码。常见的启动介质包括:
eMMC / SD 卡
NAND / NOR Flash
USB 接口(用于生产线烧录或救砖)
加载并验证二级引导程序: 将下一阶段的引导程序(如 U-Boot 的 SPL 阶段、或者移动端的 Bootloader)从外部存储介质拷贝到芯片内部的 SRAM 中。
交出控制权: 跳转到该程序运行,BootROM 的使命宣告结束。

U-Boot

常见的 开源引导加载程序,用于嵌入式系统。它支持多种架构,包括 ARM、x86、PowerPC、RISC-V 等。U-Boot 提供了启动嵌入式系统的关键功能,如加载操作系统内核、引导文件系统、硬件初始化和系统调试。

b: Byte 8bit
w: Word 字 16bit(嵌入式)
I: 整型 interge 32bit

BSP

板级支持包(BSP):BSP 是嵌入式系统开发中的一个重要概念,指的是为特定的硬件平台或开发板提供的软件支持包。BSP 包含了针对特定硬件平台的驱动程序、操作系统适配层、外设控制库以及其他必要的软件组件。它的目的是为嵌入式开发人员提供一个统一的接口和工具集,简化针对特定硬件平台的软件开发过程。BSP 可以包括针对处理器、内存、外设(如串口、GPIO、SPI、I2C 等)、中断控制等的底层驱动程序和库。

PS and PL

PS : Processing System

PS端通常指的是处理系统部分,即嵌入式处理器或CPU。这个部分通常运行软件,执行高层次的应用程序代码和控制任务。
在Xilinx的Zynq系列FPGA中,PS端通常指的是内嵌的ARM Cortex-A9处理器。

FATFS文件系统库

f_mount函数

将逻辑驱动器(如 SD 卡、USB 闪存等)挂载到文件系统,通过它可以访问存储设备上的文件。
一般步骤是先将驱动器(sd等)初始化,再将驱动器挂载到文件系统

f_mkfs函数

对物理存储设备(如 SD 卡、eMMC、USB 闪存等)进行格式化操作。
它会在存储设备上创建一个新的 FAT 文件系统(如 FAT12、FAT16 或 FAT32),从而使该设备可以被文件系统管理,并用于读写文件操作。

emmc (embedded multiMediaCard)

通常焊接在主板上

一个嵌入式 Linux 系统可能会将 eMMC 分为多个分区:

Boot 分区:存储启动加载器和内核映像。
RootFS 分区:存储根文件系统。
Data 分区:用于用户数据存储。

lwip

在 lwIP 中,TCP 协议使用两种定时器来处理 TCP 连接的维护:

  1. 快速定时器 (tcp_fasttmr):
  • 触发频率:通常每 250 毫秒触发一次(在默认配置下)。
  • 主要职责:用于处理 TCP 的快速任务,比如:
  • ACK 确认包的发送。
  • 保持活动的连接管理。
  • 处理 TCP 重传计时器(当重传定时器超时时会触发重传操作)。
  • 调整滑动窗口,处理延迟确认(delayed ACK)。
  1. 慢速定时器 (tcp_slowtmr):
  • 触发频率:通常每 500 毫秒触发一次。
  • 主要职责:处理超时重传、连接超时检测和断开连接等操作。

tcp_recv(struct tcp_pcb *pcb, tcp_recv_fn recv)

提供了一种在应用程序中注册接收数据回调函数的机制。当 TCP 连接上有新数据到达时,系统会调用这个回调函数,以便用户代码可以处理接收到的数据。

  • pcb 代表 Protocol Control Block (协议控制块),是 lwIP 中用来维护一个 TCP 连接状态的数据结构。
  • tcp_recv_fn 指向接收回调函数的指针

struct tcp_pcb

  • struct tcp_pcb 是 lwIP(Lightweight IP)协议栈中的一个数据结构,用于表示一个 TCP 协议控制块(PCB,Protocol Control Block)。
    它是 lwIP 中管理 TCP 连接的核心数据结构,包含了 TCP 连接的状态、控制信息、缓冲区和回调函数等。
  • 每个 TCP 连接都有一个对应的 tcp_pcb 结构,用来存储连接的相关信息。这些信息包括连接的本地和远程地址、端口号、连接状态
    (如 LISTEN、ESTABLISHED、CLOSED 等),以及与 TCP 协议相关的控制参数(如滑动窗口、超时时间、重传计数等)。

xemacif_input

Xilinx 的以太网接口驱动程序中的一个函数,用于处理接收到的以太网数据包。该函数通常在基于 lwIP(Lightweight IP)协议栈的嵌入式系统中使用,
特别是在 Xilinx Zynq 和 Zynq Ultrascale+ 平台上,它负责将接收到的以太网数据包传递给上层协议栈进行处理。
该函数主要用于与 AXI Ethernet 或 Ethernet Lite 这样的硬件接口进行通信,通过 DMA 或中断的方式获取数据包,并将其交给 lwIP 处理。

nagle算法

一个lwip中的优化算法,用于减少网络传输中小包的数量,将小包数据包缓冲起来,等到一定数量后一起发送。关闭后可以让每个数据包尽快发送而不是等待。

tcp_arg(newpcb, (void *)(UINTPTR)conn)

为指定的 TCP 连接设置用户自定义的数据指针。
tcp_err() 注册错误处理回调函数,用于处理连接中的异常情况。

flash type

-flash-type
QSPI-X8 Dual Parallel 是一种 Quad-SPI(QSPI) 闪存模式,在嵌入式系统中经常用于提高存储器的读写速度和带宽.

QSPI-X8 Dual Parallel 模式结合了 Quad-SPI 和 Dual Parallel 的优点:

  1. Quad-SPI (X4):每个 QSPI 闪存使用 4 条数据线,并通过 I/O 线传输 4 位数据。
  2. Dual Parallel:两个 QSPI 闪存并行工作,组合成 8 位数据宽度(X8 模式)。
    所以每个时钟周期传输 8 位数据。

AXI (Advanced eXtensible Interface)

总线接口协议,广泛用于嵌入式系统和片上系统(SoC)中,特别是在FPGA设计中。AXI作为数据传输协议,负责处理不同设备间的通信,比如处理器、外设、存储器等硬件模块之间的数据传输。

DMA (Direct Memory Access)

  • 直接存储访问, 一种在嵌入式系统、计算机系统中用于提高数据传输效率的技术。它允许设备直接访问内存,而不需要经过 CPU 的参与,从而大幅减少 CPU 的工作负荷,特别是在数据传输任务频繁的系统中。

外设协议

总线特性、速率范围、驱动实现要点和常见问题定位方法。

常用外设协议对比

协议 典型信号线 通信方式 典型速率范围 常见应用 软件侧关键词
UART(串口) TX/RX(可选 RTS/CTS) 异步、点对点 9.6 kbps ~ 4 Mbps+ 调试口、模块控制、日志输出 中断接收、DMA、帧解析
Ethernet(网口) TX/RX 差分对(经 PHY) 全双工、分层协议栈 10/100/1000 Mbps 联网、远程升级、工业通信 MAC/PHY、Socket、零拷贝
I2S BCLK/LRCK/SD(可选 MCLK) 同步串行(音频) 与采样率和位宽相关 音频编解码器、麦克风、功放 DMA 双缓冲、时钟主从
I2C SCL/SDA 同步串行、多主多从 100k/400k/1M/3.4M 传感器、PMIC、EEPROM 起止条件、ACK、总线恢复
SPI SCLK/MOSI/MISO/CS 同步串行、主从 数百 kbps ~ 数十 Mbps Flash、ADC、LCD、高速传感器 CPOL/CPHA、片选时序、DMA
SDIO CLK/CMD/D0~D3 同步串行(命令+数据) 25/50 MHz(常见) SD 卡、Wi-Fi 模块 枚举流程、块传输、缓存一致性

串口(UART)

基本原理

UART 是异步通信,不传输时钟线,通信双方通过约定波特率来采样数据。典型帧格式是 1 个起始位 + 8 位数据 + 可选校验位 + 1/2 个停止位(常见配置为 8N1)。

软件开发关注点

  • 接收路径建议使用“中断 + 环形缓冲区”或“DMA + 空闲中断”以降低 CPU 占用。
  • 协议解析通常需要定义帧边界(长度字段、分隔符、超时)避免粘包/拆包问题。
  • RS-485 半双工场景要控制 DE/RE 方向脚,发送完成后再切回接收。

常见问题

  • 波特率、数据位、停止位不一致会直接导致乱码。
  • 高速日志输出阻塞主线程,建议用 DMA 或异步日志缓冲。
  • 接地不良、线缆过长会引入误码。

网口(Ethernet)

基本原理

嵌入式系统里网口通常由 MAC + PHY 组成:

  • MAC 在 SoC 内部,负责二层帧收发、DMA 描述符管理。
  • PHY 负责电信号编解码和链路协商(速率/双工)。

软件开发关注点

  • 驱动初始化顺序通常是:时钟/复位 -> MDIO 读写 PHY -> 配置 MAC -> 建立 RX/TX 描述符环。
  • lwIP/Socket 场景要关注 pbuf 生命周期、缓存对齐和零拷贝策略。
  • 大流量下优先用 DMA + 中断合并/轮询机制,避免频繁中断。

常见问题

  • PHY 地址配置错误会导致链路始终 down。
  • RMII/RGMII 引脚复用或时钟方向配置错误会导致收发异常。
  • Cache 未做 clean/invalidate,常见表现是“偶发丢包或包内容错乱”。

I2S

基本原理

I2S 主要用于音频数据传输,不传输寄存器命令,通常配合 I2C/SPI 去配置音频 codec。常见信号:

  • BCLK:位时钟
  • LRCK(WS):左右声道选择时钟
  • SD:串行音频数据
  • MCLK(可选):主时钟

软件开发关注点

  • 音频场景建议使用 DMA 双缓冲(ping-pong)保证连续流。
  • 需要统一采样率、位宽、通道数,例如 48 kHz/16 bit/2 ch。
  • 主从模式要在时钟树层面先确定,避免多个主时钟冲突。

常见问题

  • 声音断续通常是 DMA 缓冲过小或任务调度不及时。
  • 声道错位常由数据对齐模式(I2S/Left-Justified)配置不一致引起。

I2C(集成电路总线)

基本原理

I2C 是双线开漏总线,SCL(穿行时钟线) 和 SDA(串行数据线) 都需要上拉电阻。通过 7 位或 10 位地址区分从设备,标准通信序列为:

Start -> Address + R/W -> ACK -> Data(多字节) -> ACK/NACK -> Stop

寻址方式:

  • 7位地址:0x00~0x7F,其中0x00为广播地址。
  • 10位地址:扩展寻址,用于特殊设备。
    多主竞争解决:
  • 通过SDA线的电平检测实现总线仲裁,先检测到SDA线被拉低的主设备退出竞争。

软件开发关注点

  • 驱动中必须处理 ACK 失败、超时和仲裁丢失。
  • 很多器件读寄存器需要 Repeated Start(重复起始),不是 Stop 后再 Start。
  • 出现总线卡死(SDA 被拉低)时,需要做总线恢复(手动打时钟释放)。

常见问题

  • 上拉电阻过大导致上升沿慢,高速模式不稳定。
  • 地址 7bit/8bit 传参混淆导致访问失败(常见左移一位问题)。

SPI(串行外设接口)

基本原理

SPI 是主从同步全双工总线,常见四线:SCLK、MOSI、MISO、CS。核心参数是模式(CPOL/CPHA),共 4 种。

模式配置:

  • 时钟极性(CPOL):0(空闲时SCLK为低)或1(空闲时SCLK为高)。
  • 时钟相位(CPHA):0(第一个边沿采样)或1(第二个边沿采样)。
    数据位宽:8位或16位。
    主从模式区别:
  • 主模式:控制SCK时钟,负责发起通信。
  • 从模式:接收SCK时钟,响应主设备请求。

软件开发关注点

  • 同一 SPI 总线挂多个从设备时,每个设备可能有不同 mode 和最大时钟,需要按设备切换配置。
  • 大块数据传输建议走 DMA;小控制命令可用轮询提高实时性。
  • 片选时序很关键:不少器件要求“CS 拉低后延时再发首字节”。

常见问题

  • CPOL/CPHA 配置错会导致读回全 0x00/0xFF 或数据错位。
  • 时钟过高超过从设备能力会出现随机位翻转。

SDIO

基本原理

SDIO 用于与 SD 卡或 SDIO 外设(如 Wi-Fi 模块)通信,包含命令线 CMD 和 1-bit/4-bit 数据线。相比 SPI 模式,SDIO 吞吐更高。

软件开发关注点

  • 初始化通常包含:CMD0、CMD8、ACMD41、CMD2、CMD3、CMD7 等标准流程。
  • 数据传输以块为单位(通常 512B),要关注块大小、块数量和超时设置。
  • 带 Cache 的系统中,DMA 缓冲区要做对齐和 cache 维护。

常见问题

  • 时钟切换过快(初始化阶段直接高速)会导致枚举失败。
  • 文件系统层报错(如 FAT 挂载失败)往往根因在底层读写时序或 CRC 错误。

ADC(模拟-to-数字转换器)

采样时间配置:

  • 采样时间越长,转换结果越精确,但转换速度越慢。
  • 示例:STM32F4的ADC采样时间可配置为3、15、28、56、84、112、144、480周期。
    多通道扫描模式:
    // 配置ADC1扫描模式,采样通道0、1、2
    hadc1.Instance = ADC1;
    hadc1.Init.ScanConvMode = ENABLE;
    hadc1.Init.ContinuousConvMode = DISABLE;
    hadc1.Init.NbrOfConversion = 3; // 3个转换通道

    sConfig.Channel = ADC_CHANNEL_0;
    sConfig.Rank = 1;
    HAL_ADC_ConfigChannel(&hadc1, &sConfig);

    sConfig.Channel = ADC_CHANNEL_1;
    sConfig.Rank = 2;
    HAL_ADC_ConfigChannel(&hadc1, &sConfig);

    sConfig.Channel = ADC_CHANNEL_2;
    sConfig.Rank = 3;
    HAL_ADC_ConfigChannel(&hadc1, &sConfig);

协议选型建议(软件视角)

  • 低速控制类(寄存器配置、传感器):优先 I2C。
  • 中高速短距离外设(Flash、屏、ADC):优先 SPI。
  • 音频流:优先 I2S(控制面配 I2C)。
  • 大容量存储/无线模块:优先 SDIO。
  • 调试、日志、简单控制链路:优先 UART。
  • 联网和远程维护:优先 Ethernet。

tcp/ip 协议栈

tcpip模型

OSI模型层级 Linux TCP/IP模型 常用协议示例 典型网络设备/功能
7. 应用层 应用层 HTTP, FTP, SSH, DNS, SMTP 网页服务器、邮件服务器
6. 表示层 TLS, SSL, JPEG, GIF 加密/解密、编码/解码
5. 会话层 RPC, NetBIOS, SMB 会话管理
4. 传输层 传输层 TCP, UDP 路由器、交换机(L4功能)
3. 网络层 网络层 IP, ICMP, ARP, IGMP 路由器
2. 数据链路层 链路层 Ethernet, PPP, VLAN, MAC 交换机、网卡
1. 物理层 物理层 RJ45, 光纤, 电缆, 无线信号 集线器、网线、无线模块

以太网协议

以太网(Ethernet)是最常用的局域网通信协议,主要工作在 OSI 模型的数据链路层和物理层。它定义了数据帧的格式、寻址方式、介质访问控制等内容。

1. 以太网帧结构

字段 长度(字节) 说明
前导码 7 用于同步
帧开始定界符 1 标记帧的开始
目的MAC地址 6 接收方网卡的物理地址
源MAC地址 6 发送方网卡的物理地址
类型/长度 2 上层协议类型或帧长度
数据 46-1500 负载数据
FCS校验序列 4 帧校验序列(CRC)
  • 最小帧长64字节,最大帧长1518字节(不含VLAN标签时)。

2. MAC地址

  • 每个以太网设备有唯一的48位MAC地址(如 00-1A-2B-3C-4D-5E)。
  • 用于局域网内设备寻址。

3. 介质访问控制(CSMA/CD)

  • 以太网采用载波监听多路访问/冲突检测(CSMA/CD)机制,避免数据冲突。
  • 现代以太网多为全双工模式,已基本不再使用CSMA/CD。

4. 以太网类型

  • 10BASE-T:10Mbps,双绞线
  • 100BASE-TX:100Mbps,双绞线
  • 1000BASE-T:1Gbps,千兆以太网
  • 10GBASE-T:10Gbps,万兆以太网

5. 以太网类型字段

  • 0x0800:IPv4
  • 0x0806:ARP
  • 0x86DD:IPv6

6. VLAN(虚拟局域网)

  • IEEE 802.1Q 标准为以太网帧增加4字节VLAN标签,实现逻辑分组。

TCP 与 UDP 的区别

特性 TCP(传输控制协议) UDP(用户数据报协议)
连接方式 面向连接(三次握手) 无连接
可靠性 可靠,保证数据顺序和完整性 不可靠,可能丢包、乱序
传输方式 字节流,面向流 数据报,面向报文
流量控制 有(滑动窗口、拥塞控制等)
速度 较慢(因需保证可靠性) 较快
适用场景 文件传输、网页、邮件等 视频、语音、DNS、广播等
首部开销 20字节(不含选项) 8字节
是否有顺序保证
是否有重传机制

TCP 三次握手(Three-way Handshake)

TCP 连接的建立需要经过三次握手,确保客户端和服务器双方都具备发送和接收数据的能力。过程如下:

  1. 第一次握手:客户端发送 SYN

    • 客户端向服务器发送一个带 SYN 标志位的数据包(SYN=1,Seq=x),表示请求建立连接。
    • 此时客户端进入 SYN_SEND 状态。
  2. 第二次握手:服务器应答 SYN+ACK

    • 服务器收到 SYN 包后,确认客户端的 SYN(ACK=1,Ack=x+1),同时自己也发送一个 SYN 包(SYN=1,Seq=y)。
    • 服务器将 SYN 和 ACK 一起发送(SYN=1,ACK=1,Seq=y,Ack=x+1)。
    • 服务器进入 SYN_RCVD 状态。
  3. 第三次握手:客户端确认 ACK

    • 客户端收到服务器的 SYN+ACK 包后,发送一个确认包(ACK=1,Seq=x+1,Ack=y+1)给服务器。
    • 客户端进入 ESTABLISHED 状态,服务器收到后也进入 ESTABLISHED 状态,连接建立完成。

说明

  • 三次握手的目的是同步双方的初始序列号(Seq),并确认双方的接收能力。
  • 若握手过程中某一步失败,连接不会建立,需重新发起。
  • 握手完成后,双方可以开始可靠的数据传输。

TCP 四次挥手(Four-way Handshake)

TCP 连接的断开需要经过四次挥手,确保双方都能完成数据传输并正常释放资源。过程如下:

  1. 第一次挥手:客户端发送 FIN

    • 客户端向服务器发送一个带 FIN 标志位的数据包(FIN=1,Seq=u),表示客户端没有数据要发送了,请求关闭连接。
    • 客户端进入 FIN_WAIT_1 状态。
  2. 第二次挥手:服务器应答 ACK

    • 服务器收到 FIN 包后,发送一个确认包(ACK=1,Ack=u+1,Seq=v)给客户端,表示已收到关闭请求。
    • 服务器进入 CLOSE_WAIT 状态,客户端收到 ACK 后进入 FIN_WAIT_2 状态。
  3. 第三次挥手:服务器发送 FIN

    • 服务器处理完剩余数据后,向客户端发送一个带 FIN 标志位的数据包(FIN=1,Seq=w),请求关闭连接。
    • 服务器进入 LAST_ACK 状态。
  4. 第四次挥手:客户端应答 ACK

    • 客户端收到服务器的 FIN 包后,发送一个确认包(ACK=1,Ack=w+1)给服务器。
    • 客户端进入 TIME_WAIT 状态,等待一段时间后彻底关闭连接;服务器收到 ACK 后立即关闭连接,进入 CLOSED 状态。

tcp