diff --git a/docs/Usage/Building The Kernel.md b/docs/Usage/Building The Kernel.md index 8de145e..154f9f4 100644 --- a/docs/Usage/Building The Kernel.md +++ b/docs/Usage/Building The Kernel.md @@ -6,7 +6,6 @@ - Specific rustup components that can be installed with the following commands: > rustup component add rust-src > rustup component add llvm-tools-preview - ### Building run the following command (in the root directory of the project) > ./run.sh diff --git a/lib/lib_ascii/src/lib.rs b/lib/lib_ascii/src/lib.rs index 584ed2e..45cf5e3 100644 --- a/lib/lib_ascii/src/lib.rs +++ b/lib/lib_ascii/src/lib.rs @@ -5,7 +5,7 @@ use lazy_static::lazy_static; use spin::{Lazy, Mutex}; use x86_64::instructions::interrupts; -use lib_framebuffer::FRAMEBUFFER_WRITER; +use lib_framebuffer::{FRAMEBUFFER_WRITER, Color}; mod font; use font::FONT; @@ -15,6 +15,8 @@ static FONT_HEIGHT: u32 = 16; pub static WRITER: Lazy> = Lazy::new(|| Mutex::new(Writer::new())); + + pub fn screensize_chars() -> (u32, u32) { let writer = WRITER.lock(); (writer.screen_width, writer.screen_height) @@ -71,10 +73,10 @@ impl Writer { if line & (0x80 >> col) != 0 { // write the foreground color - writer.write_pixel(pixel_x as usize, pixel_y as usize, self.fg_color); + writer.write_pixel(pixel_x as usize, pixel_y as usize, Color::RGB(255, 0, 0)); } else { // write the background color - writer.write_pixel(pixel_x as usize, pixel_y as usize, self.bg_color); + writer.write_pixel(pixel_x as usize, pixel_y as usize, Color::HexARGB(self.bg_color)); } } } diff --git a/lib/lib_framebuffer/src/colour.rs b/lib/lib_framebuffer/src/colour.rs new file mode 100644 index 0000000..7477864 --- /dev/null +++ b/lib/lib_framebuffer/src/colour.rs @@ -0,0 +1,51 @@ +#[repr(u32)] +#[derive(Copy, Clone, PartialEq, Eq, Debug)] +pub enum Color { + ARGB(u8, u8, u8, u8), + RGB(u8, u8, u8), + HexARGB(u32), + Black = 0x000000FF, + Blue = 0x0000FFFF, + Green = 0x00FF00FF, + Cyan = 0x00FFFFFF, + Red = 0xFF0000FF, + Magenta = 0xFF00FFFF, + Yellow = 0xFFFF00FF, + White = 0xFFFFFFFF, +} + +impl Into for Color { + fn into(self) -> u32 { + match self { + Color::ARGB(a, r, g, b) => (a as u32) << 24 | (r as u32) << 16 | (g as u32) << 8 | (b as u32), + Color::RGB(r, g, b) => (0u32) << 24 | (r as u32) << 16 | (g as u32) << 8 | (b as u32), + Color::HexARGB(hex) => hex, + Color::Black => 0xFF000000, + Color::Blue => 0xFF0000FF, + Color::Green => 0xFF00FF00, + Color::Cyan => 0xFF00FFFF, + Color::Red => 0xFFFF0000, + Color::Magenta => 0xFFFF00FF, + Color::Yellow => 0xFFFFFF00, + Color::White => 0xFFFFFFFF, + } + } +} + +impl core::fmt::Display for Color { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + match self { + Color::ARGB(r, g, b, a) => write!(f, "RGBA(#{:x}{:x}{:x}{:x})", r, g, b, a), + Color::RGB(r, g, b) => write!(f, "RGB(#{:x}{:x}{:x})", r, g, b), + Color::HexARGB(hex) => write!(f, "Hex(#{:x})", hex), + Color::Black => write!(f, "Black"), + Color::Blue => write!(f, "Blue"), + Color::Green => write!(f, "Green"), + Color::Cyan => write!(f, "Cyan"), + Color::Red => write!(f, "Red"), + Color::Magenta => write!(f, "Magenta"), + Color::Yellow => write!(f, "Yellow"), + Color::White => write!(f, "White"), + } + } +} \ No newline at end of file diff --git a/lib/lib_framebuffer/src/draw.rs b/lib/lib_framebuffer/src/draw.rs index c2f0255..e69de29 100644 --- a/lib/lib_framebuffer/src/draw.rs +++ b/lib/lib_framebuffer/src/draw.rs @@ -1,57 +0,0 @@ -use core::panic; -use limine::framebuffer::Framebuffer; -use spin::{Mutex, Lazy}; - -use crate::FRAMEBUFFER_REQUEST; - -pub static FRAMEBUFFER_WRITER: Lazy>> = Lazy::new(|| Mutex::new( - if let Some(framebuffer_response) = FRAMEBUFFER_REQUEST.get_response() { - let framebuffer = framebuffer_response.framebuffers().next().unwrap(); - Some(FramebufferWriter::new(framebuffer)) - } else { - panic!("Framebuffer request failed"); - } -)); - -pub struct FramebufferWriter<'a> { - framebuffer: Framebuffer<'a>, -} - -unsafe impl<'a> Send for FramebufferWriter<'a> {} -unsafe impl<'a> Sync for FramebufferWriter<'a> {} -impl<'a> FramebufferWriter<'a> { - pub fn new(framebuffer: Framebuffer<'a>) -> Self { - Self { - framebuffer, - } - } - - pub fn write_pixel(&self, x: usize, y: usize, color: u32) { - let pitch = self.framebuffer.pitch() as usize; - let bpp = (self.framebuffer.bpp() / 8) as usize; - let pixel_offset = y * pitch + x * bpp; - - unsafe { - *(self.framebuffer.addr().add(pixel_offset) as *mut u32) = color; - } - } - - pub fn width(&self) -> u32 { - self.framebuffer.width() as u32 - } - - pub fn height(&self) -> u32 { - self.framebuffer.height() as u32 - } - - pub fn clear(&self) { - let width = self.framebuffer.width() as usize; - let height = self.framebuffer.height() as usize; - - for y in 0..height { - for x in 0..width { - self.write_pixel(x, y, 0x000000); - } - } - } -} \ No newline at end of file diff --git a/lib/lib_framebuffer/src/framebuffer.rs b/lib/lib_framebuffer/src/framebuffer.rs new file mode 100644 index 0000000..0d91287 --- /dev/null +++ b/lib/lib_framebuffer/src/framebuffer.rs @@ -0,0 +1,67 @@ +use core::panic; +use limine::framebuffer::Framebuffer; +use spin::{Mutex, Lazy}; + +use crate::{colour::Color, FRAMEBUFFER_REQUEST}; + +pub static FRAMEBUFFER_WRITER: Lazy>> = Lazy::new(|| Mutex::new( + if let Some(framebuffer_response) = FRAMEBUFFER_REQUEST.get_response() { + let framebuffer = framebuffer_response.framebuffers().next().unwrap(); + Some(FramebufferWriter::new(framebuffer)) + } else { + panic!("Framebuffer request failed"); + } +)); + + + +pub struct FramebufferWriter<'a> { + framebuffer: Framebuffer<'a>, +} + +unsafe impl<'a> Send for FramebufferWriter<'a> {} +unsafe impl<'a> Sync for FramebufferWriter<'a> {} +impl<'a> FramebufferWriter<'a> { + pub fn new(framebuffer: Framebuffer<'a>) -> Self { + Self { + framebuffer, + } + } + + pub fn write_pixel(&self, x: usize, y: usize, color: Color) { + let pitch = self.framebuffer.pitch() as usize; + let bpp = (self.framebuffer.bpp() / 8) as usize; + let pixel_offset = y * pitch + x * bpp; + + unsafe { + *(self.framebuffer.addr().add(pixel_offset) as *mut u32) = color.into(); + } + } + + pub fn render_frame(&self, buffer: &[Color; 1280 * 800]) { + for (y, row) in buffer.chunks(1280).enumerate() { + for (x, pixel) in row.iter().enumerate() { + self.write_pixel(x, y, *pixel); + } + } + } + + pub fn width(&self) -> u32 { + self.framebuffer.width() as u32 + } + + pub fn height(&self) -> u32 { + self.framebuffer.height() as u32 + } + + pub fn clear(&self) { + let width = self.framebuffer.width() as usize; + let height = self.framebuffer.height() as usize; + + for y in 0..height { + for x in 0..width { + self.write_pixel(x, y, Color::Black); + } + } + } +} \ No newline at end of file diff --git a/lib/lib_framebuffer/src/lib.rs b/lib/lib_framebuffer/src/lib.rs index 61a28a3..5b16a7c 100644 --- a/lib/lib_framebuffer/src/lib.rs +++ b/lib/lib_framebuffer/src/lib.rs @@ -6,8 +6,10 @@ use limine::request::FramebufferRequest; #[link_section = ".requests"] static FRAMEBUFFER_REQUEST: FramebufferRequest = FramebufferRequest::new(); -mod draw; -pub use draw::FRAMEBUFFER_WRITER; +mod framebuffer; +mod colour; +pub use framebuffer::FRAMEBUFFER_WRITER; +pub use colour::Color; pub fn screensize_px() -> (u32, u32) { if let Some(writer) = FRAMEBUFFER_WRITER.lock().as_mut() { diff --git a/scripts/run.sh b/scripts/run.sh index 059a677..2cf05ad 100755 --- a/scripts/run.sh +++ b/scripts/run.sh @@ -22,7 +22,7 @@ info() { } compiling() { - echo -e "${GREEN}${BOLD}Compiling${NC} $1" + echo -e "${GREEN}${BOLD}Compiling${NC}: $1" } warning() { @@ -30,7 +30,11 @@ warning() { } building() { - echo -e "${GREEN}${BOLD}Building${NC} $1" + echo -e "${GREEN}${BOLD}Building${NC}: $1" +} + +copying() { + echo -e "${GREEN}${BOLD} Copying${NC}: $1 to $2" } error() { @@ -38,6 +42,11 @@ error() { exit 1 } +copy_file() { + copying $1 $2 + cp "$1" "$2" || error $3 +} + build_dir="$project_root/build" iso_root="$build_dir/iso_root" @@ -83,12 +92,13 @@ fi # Copy files info "Copying files to ISO root" -cp -v "$kernel_path" "$iso_root/boot/kernel" || error "failed to copy kernel" -cp -v "$project_root/config/limine.conf" "$iso_root/boot/limine/limine.conf" || error "failed to copy limine config" -cp -v "$build_dir/limine/limine-bios.sys" "$build_dir/limine/limine-bios-cd.bin" \ - "$build_dir/limine/limine-uefi-cd.bin" "$iso_root/boot/limine/" || error "failed to copy limine files" -cp -v "$build_dir/limine/BOOTX64.EFI" "$iso_root/EFI/BOOT/" || error "failed to copy BOOTX64.EFI" -cp -v "$build_dir/limine/BOOTIA32.EFI" "$iso_root/EFI/BOOT/" || error "failed to copy BOOTIA32.EFI" +copy_file "$kernel_path" "$iso_root/boot/kernel" "failed to copy kernel" +copy_file "$project_root/config/limine.conf" "$iso_root/boot/limine/limine.conf" "failed to copy limine config" +copy_file "$build_dir/limine/limine-bios-cd.bin" "$iso_root/boot/limine/" "failed to copy limine-bios-cd.bin" +copy_file "$build_dir/limine/limine-uefi-cd.bin" "$iso_root/boot/limine/" "failed to copy limine-uefi-cd.bin" +copy_file "$build_dir/limine/limine-bios.sys" "$iso_root/boot/limine/" "failed to copy limine-bios.sys" +copy_file "$build_dir/limine/BOOTX64.EFI" "$iso_root/EFI/BOOT/" "failed to copy BOOTX64.EFI" +copy_file "$build_dir/limine/BOOTIA32.EFI" "$iso_root/EFI/BOOT/" "failed to copy BOOTIA32.EFI" # Create ISO building "bootable ISO image"