linux mailbox 学习

一、引言

在多核 SoC、异构处理器以及 AMP(Asymmetric Multi-Processing)系统中,处理器之间需要一种低延迟、低开销、硬件强相关 的通信机制。Linux Mailbox 子系统正是为此类场景而设计的一套内核级 IPC 基础框架

从源码角度看,Mailbox 子系统的定位非常克制:

  • 不定义通信协议

  • 不管理大块数据

  • 不关心消息语义

而是专注于一件事:

在硬件 Mailbox 控制器与上层通信框架之间,建立一个统一、可复用的软件抽象层。

本文将严格围绕 Linux Mailbox 子系统的核心结构体与 源码 组织方式展开,帮助读者在阅读内核代码,能够快速建立整体认知框架。


二、源码组织结构总览

Mailbox 子系统相关代码主要分布在以下目录中:

  • include/linux/mailbox_client.h 定义 Mailbox 对外接口与核心数据结构

  • drivers/mailbox/mailbox.c Mailbox 框架核心实现(资源管理、调度、状态机)

  • 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 承担了三类责任:

  1. 资源绑定

    1. 绑定到某个 mailbox_controller

    2. 绑定到某个 mbox_client

  2. 状态管理

    1. 是否忙

    2. 是否有待发送数据

    3. 是否处于 shutdown 状态

  3. 并发与同步控制

    1. 串行化发送请求

    2. 配合中断完成状态切换


关键字段拆解

常见关键字段包括:

  • 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 的灵魂:

  1. mbox_client:我是谁,我想怎么用

  2. mailbox_chan:资源 + 状态 + 并发控制

  3. mailbox_controller:我能驱动什么硬件

相关推荐
NAGNIP13 小时前
轻松搞懂全连接神经网络结构!
人工智能·算法·面试
NAGNIP14 小时前
一文搞懂激活函数!
算法·面试
董董灿是个攻城狮14 小时前
AI 视觉连载7:传统 CV 之高斯滤波实战
算法
爱理财的程序媛20 小时前
openclaw 盯盘实践
算法
MobotStone1 天前
Google发布Nano Banana 2:更快更便宜,图片生成能力全面升级
算法
崔小汤呀1 天前
最全的docker安装笔记,包含CentOS和Ubuntu
linux·后端
颜酱1 天前
队列练习系列:从基础到进阶的完整实现
javascript·后端·算法
用户5757303346241 天前
两数之和:从 JSON 对象到 Map,大厂面试官到底在考察什么?
算法
何中应1 天前
vi编辑器使用
linux·后端·操作系统