Display Drivers

Relevant source files

This document covers the display driver subsystem within the axdriver_crates framework. The display drivers provide a unified interface for graphics devices and framebuffer management in ArceOS. This subsystem handles graphics device initialization, framebuffer access, and display output operations.

For network device drivers, see Network Drivers. For block storage drivers, see Block Storage Drivers. For VirtIO display device integration, see VirtIO Integration.

Display Driver Architecture

The display driver subsystem follows the same architectural pattern as other device types in the framework, extending the base driver operations with display-specific functionality.

Display Driver Interface Overview

flowchart TD
subgraph subGraph3["Integration Points"]
    VirtIOGpu["VirtIO GPU Device"]
    PCIGraphics["PCI Graphics Device"]
    MMIODisplay["MMIO Display Device"]
end
subgraph subGraph2["Core Operations"]
    info_op["info() -> DisplayInfo"]
    fb_op["fb() -> FrameBuffer"]
    need_flush_op["need_flush() -> bool"]
    flush_op["flush() -> DevResult"]
end
subgraph subGraph1["Display Interface"]
    DisplayDriverOps["DisplayDriverOps trait"]
    DisplayInfo["DisplayInfo struct"]
    FrameBuffer["FrameBuffer struct"]
end
subgraph Foundation["Foundation"]
    BaseDriverOps["BaseDriverOps"]
    DevResult["DevResult / DevError"]
    DeviceType["DeviceType::Display"]
end

BaseDriverOps --> DisplayDriverOps
DevResult --> flush_op
DisplayDriverOps --> MMIODisplay
DisplayDriverOps --> PCIGraphics
DisplayDriverOps --> VirtIOGpu
DisplayDriverOps --> fb_op
DisplayDriverOps --> flush_op
DisplayDriverOps --> info_op
DisplayDriverOps --> need_flush_op
DisplayInfo --> info_op
FrameBuffer --> fb_op

Sources: axdriver_display/src/lib.rs(L1 - L60) 

The DisplayDriverOps trait extends BaseDriverOps and defines the core interface that all display drivers must implement. This trait provides four essential operations for display management.

Core Data Structures

The display subsystem defines two primary data structures for managing graphics device state and framebuffer access.

DisplayInfo Structure

flowchart TD
subgraph Usage["Usage"]
    info_method["DisplayDriverOps::info()"]
    display_config["Display Configuration"]
    memory_mapping["Memory Mapping Setup"]
end
subgraph subGraph0["DisplayInfo Fields"]
    width["width: u32Visible display width"]
    height["height: u32Visible display height"]
    fb_base_vaddr["fb_base_vaddr: usizeFramebuffer virtual address"]
    fb_size["fb_size: usizeFramebuffer size in bytes"]
end

fb_base_vaddr --> memory_mapping
fb_size --> memory_mapping
height --> display_config
info_method --> fb_base_vaddr
info_method --> fb_size
info_method --> height
info_method --> width
width --> display_config

Sources: axdriver_display/src/lib.rs(L8 - L19) 

The DisplayInfo struct contains essential metadata about the graphics device, including display dimensions and framebuffer memory layout. This information is used by higher-level graphics systems to configure rendering operations.

FrameBuffer Management

flowchart TD
subgraph Integration["Integration"]
    fb_method["DisplayDriverOps::fb()"]
    graphics_rendering["Graphics Rendering"]
    pixel_operations["Pixel Operations"]
end
subgraph subGraph1["Safety Considerations"]
    unsafe_creation["Unsafe raw pointer access"]
    memory_validity["Memory region validity"]
    exclusive_access["Exclusive mutable access"]
end
subgraph subGraph0["FrameBuffer Construction"]
    from_raw_parts_mut["from_raw_parts_mut(ptr: *mut u8, len: usize)"]
    from_slice["from_slice(slice: &mut [u8])"]
    raw_field["_raw: &mut [u8]"]
end

exclusive_access --> raw_field
fb_method --> graphics_rendering
fb_method --> pixel_operations
from_raw_parts_mut --> raw_field
from_slice --> raw_field
memory_validity --> from_raw_parts_mut
raw_field --> fb_method
unsafe_creation --> from_raw_parts_mut

Sources: axdriver_display/src/lib.rs(L21 - L44) 

The FrameBuffer struct provides safe access to the device framebuffer memory. It offers both safe construction from existing slices and unsafe construction from raw pointers for device driver implementations.

DisplayDriverOps Trait Implementation

Required Methods

MethodReturn TypePurpose
info()DisplayInfoRetrieve display configuration and framebuffer metadata
fb()FrameBufferGet access to the framebuffer for rendering operations
need_flush()boolDetermine if explicit flush operations are required
flush()DevResultSynchronize framebuffer contents to the display

Sources: axdriver_display/src/lib.rs(L46 - L59) 

Display Driver Operation Flow

sequenceDiagram
    participant Application as "Application"
    participant DisplayDriverOpsImplementation as "DisplayDriverOps Implementation"
    participant GraphicsHardware as "Graphics Hardware"

    Application ->> DisplayDriverOpsImplementation: info()
    DisplayDriverOpsImplementation ->> GraphicsHardware: Query display configuration
    GraphicsHardware -->> DisplayDriverOpsImplementation: Display dimensions & framebuffer info
    DisplayDriverOpsImplementation -->> Application: DisplayInfo struct
    Application ->> DisplayDriverOpsImplementation: fb()
    DisplayDriverOpsImplementation -->> Application: FrameBuffer reference
    Note over Application: Render graphics to framebuffer
    Application ->> DisplayDriverOpsImplementation: need_flush()
    DisplayDriverOpsImplementation -->> Application: bool (hardware-dependent)
    opt If flush needed
        Application ->> DisplayDriverOpsImplementation: flush()
        DisplayDriverOpsImplementation ->> GraphicsHardware: Synchronize framebuffer
        GraphicsHardware -->> DisplayDriverOpsImplementation: Completion status
        DisplayDriverOpsImplementation -->> Application: DevResult
    end

Sources: axdriver_display/src/lib.rs(L46 - L59) 

The need_flush() method allows drivers to indicate whether they require explicit flush operations. Some hardware configurations automatically update the display when framebuffer memory is modified, while others require explicit synchronization commands.

Integration with Driver Framework

Base Driver Integration

The display driver system inherits core functionality from the axdriver_base foundation layer:

flowchart TD
subgraph subGraph2["Error Handling"]
    DevResult["DevResult"]
    DevError["DevError enum"]
end
subgraph subGraph1["Display-Specific Extensions"]
    info["info() -> DisplayInfo"]
    fb["fb() -> FrameBuffer"]
    need_flush["need_flush() -> bool"]
    flush["flush() -> DevResult"]
end
subgraph subGraph0["Inherited from BaseDriverOps"]
    device_name["device_name() -> &str"]
    device_type["device_type() -> DeviceType"]
end
DisplayDriverOps["DisplayDriverOps"]

DevResult --> DevError
DisplayDriverOps --> fb
DisplayDriverOps --> flush
DisplayDriverOps --> info
DisplayDriverOps --> need_flush
device_name --> DisplayDriverOps
device_type --> DisplayDriverOps
flush --> DevResult

Sources: axdriver_display/src/lib.rs(L5 - L6)  axdriver_display/src/lib.rs(L46 - L59) 

Device Type Classification

Display drivers return DeviceType::Display from their device_type() method, enabling the driver framework to properly categorize and route display devices during system initialization.

Hardware Implementation Considerations

Memory Safety

The FrameBuffer implementation provides both safe and unsafe construction methods to accommodate different hardware access patterns:

  • from_slice() for pre-validated memory regions
  • from_raw_parts_mut() for direct hardware memory mapping with explicit safety requirements

Flush Requirements

The need_flush() method accommodates different hardware architectures:

  • Immediate update hardware: Returns false, display updates automatically
  • Buffered hardware: Returns true, requires explicit flush() calls
  • Memory-mapped displays: May return false for direct framebuffer access

Sources: axdriver_display/src/lib.rs(L54 - L58) 

Dependencies and Build Configuration

The display driver crate has minimal dependencies, relying only on axdriver_base for core driver infrastructure:

[dependencies]
axdriver_base = { workspace = true }

This lightweight dependency structure ensures that display drivers can be compiled efficiently and integrated into embedded systems with minimal overhead.

Sources: axdriver_display/Cargo.toml(L14 - L15)