From 092784c552b0b8aa4d9903db09c15e862c99124a Mon Sep 17 00:00:00 2001 From: Red Bear OS Date: Thu, 16 Jul 2026 22:04:18 +0900 Subject: [PATCH] bootloader: restore color boot output (lost on 1.0.0 rebase) Re-adds the TextColor enum + Os::set_text_color (no-op default, VGA fg override for BIOS, EFI SetAttribute for UEFI) and colors the default-resolution message green + the autoboot countdown yellow. The countdown + default 1280x720 were already present; only the color mechanism was lost when the bootloader was rebased to upstream 1.0.0 (the color commits stayed on bootloader-detached-pending). --- src/main.rs | 6 +++++- src/os/bios/mod.rs | 14 +++++++++++++- src/os/mod.rs | 13 +++++++++++++ src/os/uefi/mod.rs | 14 +++++++++++++- 4 files changed, 44 insertions(+), 3 deletions(-) diff --git a/src/main.rs b/src/main.rs index 78dabb0377..4429d49701 100644 --- a/src/main.rs +++ b/src/main.rs @@ -17,7 +17,7 @@ use core::{ use redoxfs::{Disk, Node, TreeData}; use self::arch::{paging_create, paging_framebuffer}; -use self::os::{Os, OsHwDesc, OsKey, OsMemoryEntry, OsMemoryKind, OsVideoMode}; +use self::os::{Os, OsHwDesc, OsKey, OsMemoryEntry, OsMemoryKind, OsVideoMode, TextColor}; #[macro_use] mod os; @@ -154,7 +154,9 @@ fn select_mode( if mode.width == DEFAULT_WIDTH && mode.height == DEFAULT_HEIGHT { selected = mode.id; selected_from_default = true; + os.set_text_color(TextColor::Green); print!(", default resolution: {}x{}", DEFAULT_WIDTH, DEFAULT_HEIGHT); + os.set_text_color(TextColor::Default); break; } } @@ -212,10 +214,12 @@ fn select_mode( os.set_text_position(0, countdown_y); os.set_text_highlight(false); if countdown_active { + os.set_text_color(TextColor::Yellow); println!( "Autobooting default mode in {} seconds (press any key to cancel countdown)", countdown ); + os.set_text_color(TextColor::Default); } else { println!("Manual mode selection active. Press Enter to boot selected mode. "); } diff --git a/src/os/bios/mod.rs b/src/os/bios/mod.rs index d4549fe0bf..1cd0b5575c 100644 --- a/src/os/bios/mod.rs +++ b/src/os/bios/mod.rs @@ -4,7 +4,7 @@ use linked_list_allocator::LockedHeap; use spin::Mutex; use crate::logger::LOGGER; -use crate::os::{Os, OsHwDesc, OsKey, OsVideoMode}; +use crate::os::{Os, OsHwDesc, OsKey, OsVideoMode, TextColor}; use crate::KernelArgs; use self::disk::DiskBios; @@ -284,6 +284,18 @@ impl Os for OsBios { vga.y = y; } + fn set_text_color(&self, color: TextColor) { + let mut vga = VGA.lock(); + vga.bg = VgaTextColor::Black; + vga.fg = match color { + TextColor::Default | TextColor::White => VgaTextColor::White, + TextColor::Red => VgaTextColor::LightRed, + TextColor::Green => VgaTextColor::LightGreen, + TextColor::Yellow => VgaTextColor::Yellow, + TextColor::Cyan => VgaTextColor::LightCyan, + }; + } + fn set_text_highlight(&self, highlight: bool) { let mut vga = VGA.lock(); if highlight { diff --git a/src/os/mod.rs b/src/os/mod.rs index f01c222aec..368492a3e6 100644 --- a/src/os/mod.rs +++ b/src/os/mod.rs @@ -36,6 +36,17 @@ pub enum OsKey { Other, } +/// Text colors for bootloader console output (restored Red Bear feature). +#[derive(Clone, Copy, Debug)] +pub enum TextColor { + Default, + Red, + Green, + Yellow, + Cyan, + White, +} + // Keep synced with BootloaderMemoryKind in kernel #[derive(Clone, Copy, Debug, Eq, PartialEq)] #[repr(u64)] @@ -96,4 +107,6 @@ pub trait Os { fn get_text_position(&self) -> (usize, usize); fn set_text_position(&self, x: usize, y: usize); fn set_text_highlight(&self, highlight: bool); + /// Set the console foreground color. Default is a no-op; backends override. + fn set_text_color(&self, _color: TextColor) {} } diff --git a/src/os/uefi/mod.rs b/src/os/uefi/mod.rs index 28882bcb29..670767b75b 100644 --- a/src/os/uefi/mod.rs +++ b/src/os/uefi/mod.rs @@ -11,7 +11,7 @@ use uefi::{ Handle, }; -use crate::os::{Os, OsHwDesc, OsKey, OsVideoMode}; +use crate::os::{Os, OsHwDesc, OsKey, OsVideoMode, TextColor}; use self::{ device::{device_path_to_string, disk_device_priority}, @@ -393,6 +393,18 @@ impl Os for OsEfi { )); } + fn set_text_color(&self, color: TextColor) { + let attr = match color { + TextColor::Default => 0x07, + TextColor::White => 0x0F, + TextColor::Red => 0x0C, + TextColor::Green => 0x0A, + TextColor::Yellow => 0x0E, + TextColor::Cyan => 0x0B, + }; + status_to_result((self.st.ConsoleOut.SetAttribute)(self.st.ConsoleOut, attr)).unwrap(); + } + fn set_text_highlight(&self, highlight: bool) { let attr = if highlight { 0x70 } else { 0x07 }; status_to_result((self.st.ConsoleOut.SetAttribute)(self.st.ConsoleOut, attr)).unwrap();