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}