diff options
Diffstat (limited to 'kernel')
-rw-r--r-- | kernel/Cargo.toml | 3 | ||||
-rw-r--r-- | kernel/shell.nix | 11 | ||||
-rw-r--r-- | kernel/src/io/mod.rs | 3 | ||||
-rw-r--r-- | kernel/src/io/serial.rs | 25 | ||||
-rw-r--r-- | kernel/src/io/text_buffer.rs | 0 | ||||
-rw-r--r-- | kernel/src/io/vga_text.rs (renamed from kernel/src/vga_text.rs) | 59 | ||||
-rw-r--r-- | kernel/src/lib.rs | 25 |
7 files changed, 91 insertions, 35 deletions
diff --git a/kernel/Cargo.toml b/kernel/Cargo.toml index 2b883f4..e14865e 100644 --- a/kernel/Cargo.toml +++ b/kernel/Cargo.toml @@ -11,6 +11,9 @@ crate-type = ["staticlib"] [package.metadata.cargo-xbuild] sysroot_path = "target/sysroot" +[dependencies] +x86_64 = "0.7.5" + [dependencies.compiler_builtins] version = "0.1.19" git = "https://github.com/rust-lang/compiler-builtins" diff --git a/kernel/shell.nix b/kernel/shell.nix new file mode 100644 index 0000000..e57790f --- /dev/null +++ b/kernel/shell.nix @@ -0,0 +1,11 @@ +with import (fetchTarball { + url = https://github.com/NixOS/nixpkgs/archive/9708378251ee362a3a8861e4d0c3ffe45a21c566.tar.gz; + sha256 = "000n0vsdhii77qh5arn0lsf747xhk7y1x0mszh39psj3in0fadzl"; +}) { }; +mkShell { + name = "uff-os"; + buildInputs = [ rustup nasm grub2 cargo-xbuild gcc xorriso ]; + shellHook = '' + export GRUB_i386="${grub2}/lib/grub/i386-pc" + ''; +} diff --git a/kernel/src/io/mod.rs b/kernel/src/io/mod.rs new file mode 100644 index 0000000..8a0652e --- /dev/null +++ b/kernel/src/io/mod.rs @@ -0,0 +1,3 @@ +pub mod serial; +pub mod vga_text; + diff --git a/kernel/src/io/serial.rs b/kernel/src/io/serial.rs new file mode 100644 index 0000000..e1d4660 --- /dev/null +++ b/kernel/src/io/serial.rs @@ -0,0 +1,25 @@ +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +#[repr(u32)] +pub enum QemuExitCode { + Success = 0x10, // The actual exit code is (value << 1) | 1. + Failed = 0x11, +} + +pub fn exit_qemu(exit_code: QemuExitCode) { + use x86_64::instructions::port::Port; + + unsafe { + let mut port = Port::new(0xf4); + port.write(exit_code as u32); + } +} + +fn trivial_assertion() { + use crate::io::vga_text::OStream; + let mut stdout = OStream::new(); + stdout.clear(); + + stdout.print(b"trivial assertion... "); + assert_eq!(0, 1); + stdout.print(b"[ok]"); +} diff --git a/kernel/src/io/text_buffer.rs b/kernel/src/io/text_buffer.rs new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/kernel/src/io/text_buffer.rs diff --git a/kernel/src/vga_text.rs b/kernel/src/io/vga_text.rs index a292c8c..34f13a8 100644 --- a/kernel/src/vga_text.rs +++ b/kernel/src/io/vga_text.rs @@ -18,6 +18,9 @@ pub enum Color { White = 15, } +pub const WIDTH: usize = 80; +pub const HEIGHT: usize = 25; + #[derive(Clone, Copy)] pub struct CharState(pub u8); @@ -27,7 +30,7 @@ impl CharState { } pub fn set_fg(&mut self, fg: Color) { - self.0 = (self.0 & 240) | (fg as u8) + self.0 = (self.0 & (HEIGHT as u8) - 10) | (fg as u8) } pub fn set_bg(&mut self, bg: Color) { @@ -44,12 +47,12 @@ pub struct VgaChar { impl VgaChar { pub fn from_state_and_byte(state: CharState, byte: u8) -> Self { - Self{ state, byte } + Self { state, byte } } } pub struct OStream { - pos: (u8, u8), + pos: (usize, usize), cursor: *mut VgaChar, state: CharState, } @@ -59,7 +62,7 @@ impl OStream { Self { pos: (0, 0), cursor: Self::at(0), - state: CharState::from_colors(Color::White, Color::Black) + state: CharState::from_colors(Color::White, Color::Black), } } @@ -68,32 +71,34 @@ impl OStream { } fn compute_cursor(&mut self) { - self.cursor = Self::at(self.pos.0 as usize + self.pos.1 as usize * 80) + self.cursor = Self::at(self.pos.0 as usize + self.pos.1 as usize * WIDTH) } - pub fn set_col(&mut self, col: u8) { - self.pos.0 = core::cmp::min(col, 79); + pub fn set_col(&mut self, col: usize) { + self.pos.0 = core::cmp::min(col, WIDTH - 1); self.compute_cursor() } - - pub fn set_row(&mut self, row: u8) { - self.pos.1 = core::cmp::min(row, 24); + pub fn set_row(&mut self, row: usize) { + self.pos.1 = core::cmp::min(row, HEIGHT - 1); self.compute_cursor() } - pub fn set_cursor(&mut self, col: u8, row: u8) { - self.pos = (core::cmp::min(col, 79), core::cmp::min(row, 24)); + pub fn set_cursor(&mut self, col: usize, row: usize) { + self.pos = ( + core::cmp::min(col, WIDTH - 1), + core::cmp::min(row, HEIGHT - 1), + ); self.compute_cursor() } pub fn set_char(&mut self, c: VgaChar) { - unsafe {self.cursor.write_volatile(c)} + unsafe { self.cursor.write_volatile(c) } } pub fn put_char(&mut self, c: VgaChar) { if c.byte == b'\n' { self.new_line(); - } else if self.pos.0 >= 79 { + } else if self.pos.0 >= WIDTH - 1 { self.new_line(); self.put_char(c); } else { @@ -109,16 +114,16 @@ impl OStream { pub fn clear(&self) { let c = VgaChar::from_state_and_byte(self.state, b' '); - for i in 0..2000 { - unsafe {Self::at(i).write_volatile(c)} + for i in 0..(WIDTH * HEIGHT) { + unsafe { Self::at(i).write_volatile(c) } } } pub fn new_line(&mut self) { - if self.pos.1 >= 24 { + if self.pos.1 >= HEIGHT - 1 { self.set_col(0); for i in 0..1920 { - unsafe {Self::at(i).write_volatile(*Self::at(i + 80))} + unsafe { Self::at(i).write_volatile(*Self::at(i + WIDTH)) } } } else { self.set_cursor(0, self.pos.1 + 1); @@ -140,19 +145,23 @@ impl OStream { let mut n = 0; let slast = s.len() - 1; for (i, &b) in s.iter().enumerate() { - if n >= 80 { + if n >= WIDTH { self.set_col(0); - self.print(&line[..80]); - line = &line[80..]; + self.print(&line[..WIDTH]); + line = &line[WIDTH..]; n = 0; } if b == b'\n' || i == slast { - if b != b'\n' { n += 1 } - self.set_col(((80 - n) / 2) as u8); + if b != b'\n' { + n += 1 + } + self.set_col(((WIDTH - n) / 2) as usize); self.print(&line[..n]); self.new_line(); - if i == slast { return; } - line = &line[(n+1)..]; + if i == slast { + return; + } + line = &line[(n + 1)..]; n = 0; } n += 1; diff --git a/kernel/src/lib.rs b/kernel/src/lib.rs index 08059ea..74daa8a 100644 --- a/kernel/src/lib.rs +++ b/kernel/src/lib.rs @@ -7,10 +7,11 @@ extern crate compiler_builtins; -mod vga_text; -use vga_text::OStream; +mod io; use core::fmt::Write; +use io::vga_text; +use io::vga_text::OStream; #[cfg(test)] pub fn test_runner(tests: &[&dyn Fn(&mut OStream)]) { @@ -29,7 +30,6 @@ fn test01(stdout: &mut OStream) { #[no_mangle] pub extern "C" fn _start() -> ! { - if cfg!(test) { #[cfg(test)] test_main(); @@ -44,9 +44,7 @@ pub extern "C" fn _start() -> ! { // panic!("i has panicing"); core::iter::successors(Some(0), |n| Some(n + 1)) - .for_each(|n| - write!(&mut stdout, "hello world {}!", n).unwrap() - ); + .for_each(|n| write!(&mut stdout, "hello world {}!", n).unwrap()); loop {} } @@ -56,19 +54,26 @@ pub extern "C" fn _start() -> ! { pub extern "C" fn panic_handler(_info: &core::panic::PanicInfo) -> ! { let mut stderr = vga_text::OStream::new(); stderr.set_state(vga_text::CharState::from_colors( - vga_text::Color::LightRed, vga_text::Color::Red)); + vga_text::Color::LightRed, + vga_text::Color::Red, + )); stderr.clear(); stderr.print(b"uff-os"); stderr.set_row(10); stderr.set_state(vga_text::CharState::from_colors( - vga_text::Color::White, vga_text::Color::Red)); + vga_text::Color::White, + vga_text::Color::Red, + )); stderr.print_centered(b"<kernel panic>"); stderr.set_row(14); - let text = _info.payload() + let text = _info + .payload() .downcast_ref::<&str>() .unwrap_or(&"no panic informations are obtainable"); stderr.set_state(vga_text::CharState::from_colors( - vga_text::Color::Cyan, vga_text::Color::Red)); + vga_text::Color::Cyan, + vga_text::Color::Red, + )); stderr.print_centered(text.as_bytes()); loop {} } |