This commit is contained in:
Jack Halford 2018-02-09 14:50:07 +01:00
parent 4c12c768dc
commit 56c937e620
3 changed files with 111 additions and 91 deletions

View file

@ -21,18 +21,9 @@ rustup component add rust-src
cargo install xargo cargo install xargo
``` ```
### docker
a standard development environment can be invoked:
```
docker run jzck/arch-kernel -it /usr/bin/zsh
```
clone the repo and `make iso`
# running # running
`make run` in your host operating system to launch qemu gtk window `make run` runs the OS + a tmux split for the qemu terminal
# References # References

View file

@ -12,11 +12,28 @@ mod vga_buffer;
#[no_mangle] #[no_mangle]
pub extern fn kmain() -> ! { pub extern fn kmain() -> ! {
vga_buffer::clear_screen(); use vga_buffer::WRITER;
println!("Kernel startup..."); use vga_buffer::Color;
use vga_buffer::ColorCode;
WRITER.lock().reset_screen();
println!(">> Kernel startup...");
println!(">> Kernel startup...");
WRITER.lock().color_code = ColorCode::new(Color::Blue, Color::Yellow);
println!(">> Kernel startup...");
println!(">> Kernel startup...");
println!(">> Kernel startup...");
WRITER.lock().color_code = ColorCode::new(Color::Red, Color::Green);
println!(">> Kernel startup...");
println!(">> Kernel startup...");
println!(">> Kernel startup...");
WRITER.lock().color_code = ColorCode::new(Color::White, Color::Black);
loop { loop {
} }
} }

View file

@ -12,26 +12,27 @@ use core::fmt;
use spin::Mutex; use spin::Mutex;
use volatile::Volatile; use volatile::Volatile;
struct Buffer {
chars: [[Volatile<ScreenChar>; BUFFER_WIDTH]; BUFFER_HEIGHT],
}
const BUFFER_HEIGHT: usize = 25; const BUFFER_HEIGHT: usize = 25;
const BUFFER_WIDTH: usize = 80; const BUFFER_WIDTH: usize = 80;
static mut VGA_BUFFER: Unique<Buffer> = unsafe {
Unique::new_unchecked(0xb8000 as *mut _)
};
fn vga_buffer() -> &'static mut Buffer {
unsafe { VGA_BUFFER.as_mut() }
}
pub static WRITER: Mutex<Writer> = Mutex::new(Writer { pub static WRITER: Mutex<Writer> = Mutex::new(Writer {
column_position: 0, column_position: 0,
color_code: ColorCode::new(Color::LightGreen, Color::Black), color_code: ColorCode::new(Color::White, Color::Black),
vgabuffer: unsafe { Unique::new_unchecked(0xb8000 as *mut _) },
}); });
pub struct Writer {
column_position: usize,
pub color_code: ColorCode,
vgabuffer: Unique<Buffer>,
}
struct VScreen {
column_position: usize,
pub color_code: ColorCode,
buffer: Buffer,
}
macro_rules! println { macro_rules! println {
($fmt:expr) => (print!(concat!($fmt, "\n"))); ($fmt:expr) => (print!(concat!($fmt, "\n")));
($fmt:expr, $($arg:tt)*) => (print!(concat!($fmt, "\n"), $($arg)*)); ($fmt:expr, $($arg:tt)*) => (print!(concat!($fmt, "\n"), $($arg)*));
@ -39,7 +40,7 @@ macro_rules! println {
macro_rules! print { macro_rules! print {
($($arg:tt)*) => ({ ($($arg:tt)*) => ({
$crate::vga_buffer::print(format_args!($($arg)*)); $crate::vga_buffer::print(format_args!($($arg)*));
}); });
} }
@ -48,9 +49,75 @@ pub fn print(args: fmt::Arguments) {
WRITER.lock().write_fmt(args).unwrap(); WRITER.lock().write_fmt(args).unwrap();
} }
pub fn clear_screen() { impl Writer {
for _ in 0..BUFFER_HEIGHT { pub fn reset_screen(&mut self)
println!(""); {
let color_code = self.color_code;
for row in 1..BUFFER_HEIGHT {
for col in 0..BUFFER_WIDTH {
self.buffer().chars[row][col].write(ScreenChar {
ascii_character: b' ',
color_code,
});
}
}
self.column_position = 0;
}
pub fn write_byte(&mut self, byte: u8) {
match byte {
b'\n' => self.new_line(),
byte => {
if self.column_position >= BUFFER_WIDTH {
self.new_line();
}
let row = BUFFER_HEIGHT - 1;
let col = self.column_position;
let color_code = self.color_code;
self.buffer().chars[row][col].write(ScreenChar {
ascii_character: byte,
color_code: color_code,
});
self.column_position += 1;
}
}
}
fn buffer(&mut self) -> &mut Buffer {
unsafe { self.vgabuffer.as_mut() }
}
fn new_line(&mut self) {
for row in 1..BUFFER_HEIGHT {
for col in 0..BUFFER_WIDTH {
let buffer = self.buffer();
let character = buffer.chars[row][col].read();
buffer.chars[row - 1][col].write(character);
}
}
self.clear_row(BUFFER_HEIGHT - 1);
self.column_position = 0;
}
fn clear_row(&mut self, row: usize) {
let blank = ScreenChar {
ascii_character: b' ',
color_code: ColorCode::new(Color::White, Color::Black),
};
for col in 0..BUFFER_WIDTH {
self.buffer().chars[row][col].write(blank);
}
}
}
impl fmt::Write for Writer {
fn write_str(&mut self, s: &str) -> ::core::fmt::Result {
for byte in s.bytes() {
self.write_byte(byte)
}
Ok(())
} }
} }
@ -76,70 +143,11 @@ pub enum Color {
White = 15, White = 15,
} }
pub struct Writer {
column_position: usize,
color_code: ColorCode,
}
impl Writer {
pub fn write_byte(&mut self, byte: u8) {
match byte {
b'\n' => self.new_line(),
byte => {
if self.column_position >= BUFFER_WIDTH {
self.new_line();
}
let row = BUFFER_HEIGHT - 1;
let col = self.column_position;
let color_code = self.color_code;
vga_buffer().chars[row][col].write(ScreenChar {
ascii_character: byte,
color_code: color_code,
});
self.column_position += 1;
}
}
}
fn new_line(&mut self) {
for row in 1..BUFFER_HEIGHT {
for col in 0..BUFFER_WIDTH {
let buffer = vga_buffer();
let character = buffer.chars[row][col].read();
buffer.chars[row - 1][col].write(character);
}
}
self.clear_row(BUFFER_HEIGHT - 1);
self.column_position = 0;
}
fn clear_row(&mut self, row: usize) {
let blank = ScreenChar {
ascii_character: b' ',
color_code: self.color_code,
};
for col in 0..BUFFER_WIDTH {
vga_buffer().chars[row][col].write(blank);
}
}
}
impl fmt::Write for Writer {
fn write_str(&mut self, s: &str) -> ::core::fmt::Result {
for byte in s.bytes() {
self.write_byte(byte)
}
Ok(())
}
}
#[derive(Debug, Clone, Copy)] #[derive(Debug, Clone, Copy)]
struct ColorCode(u8); pub struct ColorCode(u8);
impl ColorCode { impl ColorCode {
const fn new(foreground: Color, background: Color) -> ColorCode { pub const fn new(foreground: Color, background: Color) -> ColorCode {
ColorCode((background as u8) << 4 | (foreground as u8)) ColorCode((background as u8) << 4 | (foreground as u8))
} }
} }
@ -150,3 +158,7 @@ struct ScreenChar {
ascii_character: u8, ascii_character: u8,
color_code: ColorCode, color_code: ColorCode,
} }
struct Buffer {
chars: [[Volatile<ScreenChar>; BUFFER_WIDTH]; BUFFER_HEIGHT],
}