diff --git a/blog/content/edition-3/posts/03-screen-output/index.md b/blog/content/edition-3/posts/03-screen-output/index.md index 67b17469..9c970ba1 100644 --- a/blog/content/edition-3/posts/03-screen-output/index.md +++ b/blog/content/edition-3/posts/03-screen-output/index.md @@ -12,14 +12,110 @@ icon = ''' = OnceCell::uninit(); +``` + +By setting the logger up as a static `OnceCell` it becomes much easier to initialize. We use `pub(crate)` to ensure that the kernel can see it but nothing else can. + +After this, it's time to actually initialize it. To do that, we use a function: + +```rust +// in src/main.rs +use bootloader_api::info::FrameBufferInfo; +// ... +pub(crate) fn init_logger(buffer: &'static mut [u8], info: FrameBufferInfo) { + let logger = LOGGER.get_or_init(move || LockedLogger::new(buffer, info, true, false)); + log::set_logger(logger).expect("Logger already set"); + log::set_max_level(log::LevelFilter::Trace); + log::info!("Hello, Kernel Mode!"); +} +``` + +This function takes two parameters: a byte slice representing a raw framebuffer and a `FrameBufferInfo` structure containing information about the first parameter. Getting those parameters, however, requires jumping through some hoops to satisfy the borrow checker: + +```rust +// in src/main.rs +fn kernel_main(boot_info: &'static mut bootloader_api::BootInfo) -> ! { + // ... + // free the doubly wrapped framebuffer from the boot info struct + let frame_buffer_optional = &mut boot_info.framebuffer; + + // free the wrapped framebuffer from the FFI-safe abstraction provided by bootloader_api + let frame_buffer_option = frame_buffer_optional.as_mut(); + + // unwrap the framebuffer + let frame_buffer_struct = frame_buffer_option.unwrap(); + + // extract the framebuffer info and, to satisfy the borrow checker, clone it + let frame_buffer_info = frame_buffer.info().clone(); + + // get the framebuffer's mutable raw byte slice + let raw_frame_buffer = frame_buffer_struct.buffer_mut(); + + // finally, initialize the logger using the last two variables + init_logger(raw_frame_buffer, frame_buffer_info); + // ... +} +``` + +Any one of these steps, if skipped, will cause the borrow checker to throw a hissy fit due to the use of the `move ||` closure by the initializer function. With this, however, you're done, and you'll know the logger has been initialized when you see "Hello, Kernel Mode!" printed on the screen. - -Molestiae quidem ipsa nihil laboriosam sapiente laudantium quia. Praesentium et repudiandae minima voluptas et. Repellendus voluptatem distinctio enim et alias distinctio recusandae quos. Dolores ex eum culpa quo sunt sint voluptate voluptates. Facere unde sequi quo ea vel nihil. Rem deleniti repellat rem molestias - -Molestiae quidem ipsa nihil laboriosam sapiente laudantium quia. Praesentium et repudiandae minima voluptas et. Repellendus voluptatem distinctio enim et alias distinctio recusandae quos. Dolores ex eum culpa quo sunt sint voluptate voluptates. Facere unde sequi quo ea vel nihil. Rem deleniti repellat rem molestias -