summaryrefslogtreecommitdiff
path: root/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'kernel')
-rw-r--r--kernel/Cargo.toml3
-rw-r--r--kernel/shell.nix11
-rw-r--r--kernel/src/io/mod.rs3
-rw-r--r--kernel/src/io/serial.rs25
-rw-r--r--kernel/src/io/text_buffer.rs0
-rw-r--r--kernel/src/io/vga_text.rs (renamed from kernel/src/vga_text.rs)59
-rw-r--r--kernel/src/lib.rs25
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 {}
}