Skip to main content

kernel/screen/basic/
framebuffer.rs

1// SPDX-License-Identifier: GPL-3.0-only
2//! Linear framebuffer wrapper for early-boot screen output.
3//!
4//! Authors: MarioS271
5
6// Safe: kernel is single-threaded during early boot; raw pointer access is guarded by Once
7unsafe impl Send for BasicFramebuffer {}
8unsafe impl Sync for BasicFramebuffer {}
9
10/// A thin wrapper around the Limine-provided linear framebuffer.
11pub struct BasicFramebuffer {
12    /// Pointer to the first pixel; pixels are row-major, `bytes_per_row` per row.
13    pub fb_pointer: *mut u32,
14    /// Number of 32-bit pixels per row (Limine pitch / 4).
15    pub bytes_per_row: u32,
16    pub width: u64,
17    pub height: u64,
18}
19
20impl BasicFramebuffer {
21    /// Construct a `BasicFramebuffer` from the Limine framebuffer descriptor.
22    pub fn new(limine_fb: &limine::framebuffer::Framebuffer) -> Self {
23        Self {
24            fb_pointer: limine_fb.address() as *mut u32,
25            bytes_per_row: (limine_fb.pitch / 4) as u32,
26            width: limine_fb.width,
27            height: limine_fb.height,
28        }
29    }
30
31    /// Write zero (black) to every pixel in the framebuffer.
32    pub fn clear(&self) {
33        for y in 0..self.height {
34            for x in 0..self.width {
35                // Safe because we're iterating inside the given fb bounds and only
36                // changing memory there
37                unsafe {
38                    self.fb_pointer
39                        .add(y as usize * self.bytes_per_row as usize + x as usize)
40                        .write_volatile(0u32);
41                }
42            }
43        }
44    }
45}