
一、引言
在多核 SoC、异构处理器以及 AMP(Asymmetric Multi-Processing)系统中,处理器之间需要一种低延迟、低开销、硬件强相关 的通信机制。Linux Mailbox 子系统正是为此类场景而设计的一套内核级 IPC 基础框架。
从源码角度看,Mailbox 子系统的定位非常克制:
-
它 不定义通信协议
-
不管理大块数据
-
不关心消息语义
而是专注于一件事:
在硬件 Mailbox 控制器与上层通信框架之间,建立一个统一、可复用的软件抽象层。
本文将严格围绕 Linux Mailbox 子系统的核心结构体与 源码 组织方式展开,帮助读者在阅读内核代码,能够快速建立整体认知框架。
二、源码组织结构总览
Mailbox 子系统相关代码主要分布在以下目录中:
-
include/linux/mailbox_client.h定义 Mailbox 对外接口与核心数据结构 -
drivers/mailbox/mailbox.cMailbox 框架核心实现(资源管理、调度、状态机) -
drivers/mailbox/各类硬件 Mailbox 控制器驱动实现
从架构上看:
mbox_client <------> mailbox framework <------> mailbox_controller
(使用者) (通用层) (硬件驱动)
这一分层是理解所有结构体设计的前提。
三、mbox_client:客户端视角的抽象
设计定位
struct mbox_client 是 上层使用者看到的唯一 Mailbox 接口抽象。
任何希望使用 Mailbox 的模块(rpmsg、remoteproc、SCMI、平台驱动),都需要先定义并注册一个 mbox_client。
它的设计目标是:
-
描述客户端的通信能力需求
-
声明客户端希望采用的通信语义(同步 / 异步)
-
提供回调 入口,用于框架向客户端反向通知事件
核心字段拆解

在源码中,mbox_client 通常包含以下关键字段:
-
dev 指向所属的
struct device,用于设备模型与电源管理绑定。 -
rx_callback 接收回调函数指针,当 Mailbox 框架收到新消息时调用。
-
tx_done 发送完成回调,用于通知客户端消息已成功送达或被硬件确认。
-
tx_block / tx_tout 描述发送路径是否允许阻塞,以及阻塞的最大超时时间。
-
knows_txdone 告知框架:客户端是否理解并期望 tx_done 回调语义。
这些字段共同决定了:
Mailbox 框架该如何"服务"这个客户端。
四、mailbox_chan:最核心的逻辑实体
为什么需要 mailbox_chan
mailbox_chan 是 Mailbox 子系统中最容易被忽视,但最关键的结构体。
它代表的是:
一个可以被独占、调度、管理状态的"逻辑 Mailbox 通道"。
注意:
-
一个 channel 不等同于 一个 client
-
一个 controller 可以提供多个 channel
mailbox_chan 的核心职责
从设计角度看,mailbox_chan 承担了三类责任:
-
资源绑定:
-
绑定到某个
mailbox_controller -
绑定到某个
mbox_client
-
-
状态管理:
-
是否忙
-
是否有待发送数据
-
是否处于 shutdown 状态
-
-
并发与同步控制:
-
串行化发送请求
-
配合中断完成状态切换
-
关键字段拆解

常见关键字段包括:
-
cl 指向当前绑定的
mbox_client。 -
mbox 指向所属的
mailbox_controller。 -
tx_done 表示当前发送是否完成,用于同步语义支持。
-
lock / spinlock 保护 channel 状态的并发访问。
可以认为:
mailbox_chan 是 Mailbox 子系统内部真正"跑状态机"的对象。
五、mailbox_controller:硬件抽象层
控制器抽象的设计原则
mailbox_controller 是对具体 Mailbox 硬件控制器能力的抽象描述。
它的设计目标非常明确:
-
不参与策略
-
不感知客户端
-
只提供"我能做什么"和"我怎么做"
核心字段拆解(源码阅读主线)

在源码中,mailbox_controller 通常包含:
-
dev 对应控制器的设备节点。
-
num_chans 控制器支持的 channel 数量。
-
chans 指向
mailbox_chan数组,由框架统一管理。 -
ops 一组函数指针,描述控制器支持的底层操作。

Tx done 的方式
mailbox_controller_ops

这是 Mailbox 框架与硬件驱动之间最关键的接口边界。
常见回调包括:
-
send_data 向硬件 Mailbox 写入一条消息。
-
startup / shutdown channel 启停钩子,用于打开/关闭中断、电源等资源。
-
peek_data / last_tx_done(可选) 用于轮询模式或特殊硬件能力。
这些回调函数构成了:
硬件 Mailbox 驱动向通用框架暴露的"最小能力集合"。
六、Mailbox 框架的通道生命周期
注册阶段
-
硬件驱动分配并初始化
mailbox_controller -
设置 ops、num_chans
-
调用框架注册接口
此时,channel 尚未与任何 client 绑定。

申请阶段(Client Bind)
-
client 调用请求接口
-
框架为其分配空闲 channel
-
执行 controller 的 startup 回调
从这一刻起:
channel 成为 client 的"专属通信资源"。


运行阶段
- client 通过 channel 发送消息


-
controller 驱动触发硬件动作
-
msg_free就是ringbuf的写指针

-
中断或轮询路径完成接收
-
框架回调 client

释放阶段
-
client 释放 channel
-
框架调用 shutdown

- channel 回到空闲池
七、发送与接收路径(结合结构体理解)
发送路径
mbox_client
↓
mailbox_chan(状态检查 / 加锁)
↓
mailbox_controller_ops.send_data
↓
硬件 Mailbox
整个过程中:
-
mbox_client提供语义 -
mailbox_chan管理状态 -
mailbox_controller操作硬件
接收路径
硬件中断
↓
mailbox_controller 驱动
↓
mailbox framework
↓
mbox_client.rx_callback
这条路径体现了 Mailbox 设计中非常重要的一点:
硬件相关逻辑止步于 controller ,协议与业务止步于 client。
八、Mailbox 的设计边界与取舍
Mailbox 子系统刻意保持"能力最小化":
-
不缓存大规模数据
-
不处理复杂队列
-
不定义消息生命周期
正因如此,它才能被:
-
rpmsg 作为 kick / notify
-
remoteproc 作为核间事件
-
SCMI 作为固件通信基础
九、总结
从源码角度看,Linux Mailbox 子系统是一套以结构体为中心、以 回调 为边界、以 channel 为核心状态机的软件框架。
理解以下三点,基本就抓住了 Mailbox 的灵魂:
-
mbox_client:我是谁,我想怎么用 -
mailbox_chan:资源 + 状态 + 并发控制 -
mailbox_controller:我能驱动什么硬件