axdriver_display 技术文档
路径:
components/axdriver_crates/axdriver_display类型:库 crate 分层:组件层 / 显示设备类别接口层 版本:0.1.4-preview.3文档依据:Cargo.toml、README.md、src/lib.rs、components/axdriver_crates/axdriver_virtio/src/gpu.rs、os/arceos/modules/axdisplay/src/lib.rs、os/StarryOS/kernel/src/pseudofs/dev/fb.rs
axdriver_display 的职责是为显示设备定义统一的驱动接口。它不负责探测设备,也不负责把帧缓冲暴露成 /dev/fb0,更不提供窗口系统或图形合成能力;它只定义显示驱动最小需要暴露的信息和操作,让 virtio-gpu 之类的具体实现可以被 ax-driver 聚合层和 ax-display 上层模块统一消费。
1. 架构设计分析
1.1 设计定位
这个 crate 只处理“显示设备驱动应该向上暴露什么”:
DisplayInfo描述显示分辨率和帧缓冲位置。FrameBuffer封装设备映射出来的帧缓冲内存。DisplayDriverOps定义查询信息、获取帧缓冲、判断是否需要刷新以及执行刷新这四类操作。
它在分层上位于:
ax-driver-base之上:继承统一的BaseDriverOps。- 具体显示驱动之下:例如
ax_driver_virtio::VirtIoGpuDev会实现它。 ax-display之下:上层模块通过AxDisplayDevice使用它,而不是直接接触具体 GPU 驱动类型。
1.2 关键类型
| 符号 | 作用 | 备注 |
|---|---|---|
DisplayInfo | 描述宽、高、帧缓冲虚拟地址和大小 | 是上层显示能力的元信息入口 |
FrameBuffer<'a> | 对帧缓冲内存的薄包装 | 不拥有显存,只包装已映射内存 |
DisplayDriverOps | 显示设备统一 trait | 继承 BaseDriverOps |
1.3 帧缓冲对象模型
FrameBuffer 的设计非常克制:
from_raw_parts_mut()允许驱动把一段已经映射好的设备内存包装成帧缓冲。from_slice()允许直接用切片构造。- 它本身不做像素格式协商、双缓冲管理或显存映射建立。
因此,FrameBuffer 只是“对一段可写图像内存的访问句柄”,不是图形 API。
1.4 与上下层的接线关系
在当前仓库中,最典型的实现来自 ax_driver_virtio::VirtIoGpuDev:
try_new()内部调用virtio_drivers::device::gpu::VirtIOGpu。- 通过
setup_framebuffer()建立帧缓冲。 - 用
resolution()生成DisplayInfo。 flush()最终转发给底层 VirtIO GPU 刷新。
再往上一层:
ax-driver把具体实例包装为AxDisplayDevice放入AllDevices.display。ax-runtime调用ax_display::init_display(all_devices.display)。ax-display提供framebuffer_info()/framebuffer_flush()。- StarryOS 的
pseudofs/dev/fb.rs再把这组能力包装成伪文件系统的 framebuffer 设备。
1.5 边界澄清
最 重要的边界是:axdriver_display 只定义“显示驱动该如何向上暴露帧缓冲能力”,它不是图形子系统,也不是用户可见显示服务本身。
2. 核心功能说明
2.1 主要能力
- 为显示设备统一定义
DisplayDriverOps。 - 用
DisplayInfo传递最关键的屏幕和帧缓冲信息。 - 用
FrameBuffer表达设备映射显存的可写视图。 - 让不同显示驱动能被
ax-driver和ax-display统一消费。
2.2 关键 API 与语义
info():返回显示元信息。fb():返回帧缓冲视图。need_flush():说明写入显存后是否还需要显式提交。flush():把帧缓冲内容真正推到设备侧。
need_flush() 的存在很关键,因为它把“直写显存即可见”和“还需要显式提交”这两类设备统一在一套接口里。