commit 99b87d5163e7b7b6a1a65cec784d8edb1292130e Author: faulty Date: Thu Dec 22 13:23:08 2022 +0100 Initial Commit diff --git a/.cargo/config.toml b/.cargo/config.toml new file mode 100644 index 0000000..06b024b --- /dev/null +++ b/.cargo/config.toml @@ -0,0 +1,6 @@ +[unstable] +build-std-features = ["compiler-builtins-mem"] +build-std = ["core", "compiler_builtins"] + +[build] +target = "x86_64-none-generic.json" \ No newline at end of file diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..bba7b53 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +/target/ +/.idea/ diff --git a/Cargo.lock b/Cargo.lock new file mode 100644 index 0000000..8894932 --- /dev/null +++ b/Cargo.lock @@ -0,0 +1,23 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "bootloader" +version = "0.9.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6e02311b16c9819e7c72866d379cdd3026c3b7b25c1edf161f548f8e887e7ff" + +[[package]] +name = "kernel" +version = "0.1.0" +dependencies = [ + "bootloader", + "volatile", +] + +[[package]] +name = "volatile" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3ca98349dda8a60ae74e04fd90c7fb4d6a4fbe01e6d3be095478aa0b76f6c0c" diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000..8587d9e --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,14 @@ +[package] +name = "kernel" +version = "0.1.0" +edition = "2018" + +[profile.dev] +panic = "abort" + +[profile.release] +panic = "abort" + +[dependencies] +bootloader = "0.9.23" +volatile = "0.4.5" \ No newline at end of file diff --git a/run.sh b/run.sh new file mode 100755 index 0000000..ec8ead5 --- /dev/null +++ b/run.sh @@ -0,0 +1,6 @@ +#!/bin/sh + +cargo +nightly build --release +cargo +nightly bootimage + +qemu-system-x86_64 -drive format=raw,file=target/x86_64-none-generic/debug/bootimage-kernel.bin \ No newline at end of file diff --git a/src/io/mod.rs b/src/io/mod.rs new file mode 100644 index 0000000..5826a79 --- /dev/null +++ b/src/io/mod.rs @@ -0,0 +1 @@ +pub mod vga; diff --git a/src/io/vga/buffer.rs b/src/io/vga/buffer.rs new file mode 100644 index 0000000..2554d52 --- /dev/null +++ b/src/io/vga/buffer.rs @@ -0,0 +1,64 @@ +use crate::io::vga::colors::ColorCode; + +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +#[repr(C)] +struct ScreenChar { + ascii_character: u8, + color_code: ColorCode, +} + +const BUFFER_HEIGHT: usize = 25; +const BUFFER_WIDTH: usize = 80; + +#[repr(transparent)] +pub struct Buffer { + chars: [[ScreenChar; BUFFER_WIDTH]; BUFFER_HEIGHT], +} + +pub struct Writer { + pub(crate) column_position: usize, + pub(crate) color_code: ColorCode, + pub(crate) buffer: &'static mut Buffer, +} + +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; + self.buffer.chars[row][col] = ScreenChar { + ascii_character: byte, + color_code, + }; + self.column_position += 1; + } + } + } + + fn new_line(&mut self) { + unimplemented!(); + } +} + + +impl Writer { + pub fn write_string(&mut self, s: &str) { + for byte in s.bytes() { + match byte { + // printable ASCII byte or newline + 0x20..=0x7e | b'\n' => self.write_byte(byte), + // not part of printable ASCII range + _ => self.write_byte(0xfe), + } + + } + } +} \ No newline at end of file diff --git a/src/io/vga/colors.rs b/src/io/vga/colors.rs new file mode 100644 index 0000000..5f29709 --- /dev/null +++ b/src/io/vga/colors.rs @@ -0,0 +1,31 @@ +#[allow(dead_code)] +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +#[repr(u8)] +pub enum Color { + Black = 0, + Blue = 1, + Green = 2, + Cyan = 3, + Red = 4, + Magenta = 5, + Brown = 6, + LightGray = 7, + DarkGray = 8, + LightBlue = 9, + LightGreen = 10, + LightCyan = 11, + LightRed = 12, + Pink = 13, + Yellow = 14, + White = 15, +} + +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +#[repr(transparent)] +pub struct ColorCode(u8); + +impl ColorCode { + pub(crate) fn new(foreground: Color, background: Color) -> ColorCode { + ColorCode((background as u8) << 4 | (foreground as u8)) + } +} \ No newline at end of file diff --git a/src/io/vga/mod.rs b/src/io/vga/mod.rs new file mode 100644 index 0000000..144d4b5 --- /dev/null +++ b/src/io/vga/mod.rs @@ -0,0 +1,2 @@ +pub mod colors; +pub mod buffer; \ No newline at end of file diff --git a/src/main.rs b/src/main.rs new file mode 100644 index 0000000..5abb595 --- /dev/null +++ b/src/main.rs @@ -0,0 +1,27 @@ +#![no_std] +#![no_main] + +use core::panic::PanicInfo; +use crate::io::vga::buffer::{Buffer, Writer}; +use crate::io::vga::colors::{Color, ColorCode}; + +mod io; + +#[no_mangle] +#[panic_handler] +pub extern "C" fn panic_handler(_info: &PanicInfo) -> ! { + loop {} +} + +#[no_mangle] +pub extern "C" fn _start() -> ! { + let mut writer = Writer { + column_position: 0, + color_code: ColorCode::new(Color::Yellow, Color::Black), + buffer: unsafe { &mut *(0xb8000 as *mut Buffer) } + }; + + writer.write_string("Hello World\n"); + + loop {} +} \ No newline at end of file diff --git a/x86_64-none-generic.json b/x86_64-none-generic.json new file mode 100644 index 0000000..7d2110d --- /dev/null +++ b/x86_64-none-generic.json @@ -0,0 +1,15 @@ +{ + "llvm-target": "x86_64-unknown-none", + "data-layout": "e-m:e-i64:64-f80:128-n8:16:32:64-S128", + "arch": "x86_64", + "target-endian": "little", + "target-pointer-width": "64", + "target-c-int-width": "32", + "os": "none", + "executables": true, + "linker-flavor": "ld.lld", + "linker": "rust-lld", + "panic-strategy": "abort", + "disable-redzone": true, + "features": "-mmx,-sse,+soft-float" +}