diff --git a/.cargo/config.toml b/.cargo/config.toml index 973fadb..3b01eb5 100644 --- a/.cargo/config.toml +++ b/.cargo/config.toml @@ -8,3 +8,6 @@ build-std-features = ["compiler-builtins-mem"] [env] RUST_TARGET_PATH = { value = "kernel", relative = true } + +[target.x86_64-kernel] +runner = "scripts/run.sh" \ No newline at end of file diff --git a/Cargo.lock b/Cargo.lock index f059199..fc3b11b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,6 +2,18 @@ # It is not intended for manual editing. version = 4 +[[package]] +name = "autocfg" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" + +[[package]] +name = "bit_field" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc827186963e592360843fb5ba4b973e145841266c1357f7180c43526f2e5b61" + [[package]] name = "bitflags" version = "2.8.0" @@ -22,13 +34,47 @@ name = "kernel" version = "0.1.0" dependencies = [ "cc", - "lib_example", + "lib_ascii", + "lib_framebuffer", + "lib_serial", "limine", ] [[package]] -name = "lib_example" +name = "lazy_static" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" +dependencies = [ + "spin", +] + +[[package]] +name = "lib_ascii" version = "0.1.0" +dependencies = [ + "lazy_static", + "lib_framebuffer", + "spin", + "x86_64", +] + +[[package]] +name = "lib_framebuffer" +version = "0.1.0" +dependencies = [ + "limine", + "spin", +] + +[[package]] +name = "lib_serial" +version = "0.1.0" +dependencies = [ + "lazy_static", + "spin", + "x86_64", +] [[package]] name = "limine" @@ -39,8 +85,57 @@ dependencies = [ "bitflags", ] +[[package]] +name = "lock_api" +version = "0.4.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07af8b9cdd281b7915f413fa73f29ebd5d55d0d3f0155584dade1ff18cea1b17" +dependencies = [ + "autocfg", + "scopeguard", +] + +[[package]] +name = "rustversion" +version = "1.0.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f7c45b9784283f1b2e7fb61b42047c2fd678ef0960d4f6f1eba131594cc369d4" + +[[package]] +name = "scopeguard" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" + [[package]] name = "shlex" version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" + +[[package]] +name = "spin" +version = "0.9.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" +dependencies = [ + "lock_api", +] + +[[package]] +name = "volatile" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "442887c63f2c839b346c192d047a7c87e73d0689c9157b00b53dcc27dd5ea793" + +[[package]] +name = "x86_64" +version = "0.15.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0f042214de98141e9c8706e8192b73f56494087cc55ebec28ce10f26c5c364ae" +dependencies = [ + "bit_field", + "bitflags", + "rustversion", + "volatile", +] diff --git a/Cargo.toml b/Cargo.toml index 1d44ee7..8b3748c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,8 @@ [workspace] members = [ - "lib_example", + "lib/lib_framebuffer", + "lib/lib_serial", + "lib/lib_ascii", "kernel" ] resolver = "2" diff --git a/kernel/Cargo.toml b/kernel/Cargo.toml index 255736c..d9d4087 100644 --- a/kernel/Cargo.toml +++ b/kernel/Cargo.toml @@ -5,7 +5,9 @@ edition = "2021" [dependencies] limine = "0.3.1" -lib_example = { path = "../lib_example" } +lib_framebuffer = { path = "../lib/lib_framebuffer" } +lib_serial = { path = "../lib/lib_serial" } +lib_ascii = { path = "../lib/lib_ascii" } [build-dependencies] cc = "1.2.14" diff --git a/kernel/build.rs b/kernel/build.rs index 1ea5435..a9b7914 100644 --- a/kernel/build.rs +++ b/kernel/build.rs @@ -7,8 +7,4 @@ fn main() { println!("cargo:rerun-if-changed=src"); println!("cargo:rerun-if-changed=linker.ld"); println!("cargo:rerun-if-changed=../config/limine.conf"); - - cc::Build::new() - .file("src/main.c") - .compile("lib"); } \ No newline at end of file diff --git a/kernel/src/main.c b/kernel/src/main.c deleted file mode 100644 index af9b44a..0000000 --- a/kernel/src/main.c +++ /dev/null @@ -1,3 +0,0 @@ -int add(int x, int y) { - return x+y; -} \ No newline at end of file diff --git a/kernel/src/main.rs b/kernel/src/main.rs index d8832df..c6ae3fc 100644 --- a/kernel/src/main.rs +++ b/kernel/src/main.rs @@ -3,10 +3,13 @@ use core::arch::asm; -use limine::request::{FramebufferRequest, RequestsEndMarker, RequestsStartMarker}; +use lib_serial::{serial_println, serial_read}; +use lib_ascii::{println, WRITER}; + +use limine::request::{RequestsEndMarker, RequestsStartMarker}; use limine::BaseRevision; -use lib_example; +use lib_framebuffer; /// Sets the base revision to the latest revision supported by the crate. /// See specification for further info. @@ -16,10 +19,6 @@ use lib_example; #[link_section = ".requests"] static BASE_REVISION: BaseRevision = BaseRevision::new(); -#[used] -#[link_section = ".requests"] -static FRAMEBUFFER_REQUEST: FramebufferRequest = FramebufferRequest::new(); - /// Define the stand and end markers for Limine requests. #[used] #[link_section = ".requests_start_marker"] @@ -28,41 +27,48 @@ static _START_MARKER: RequestsStartMarker = RequestsStartMarker::new(); #[link_section = ".requests_end_marker"] static _END_MARKER: RequestsEndMarker = RequestsEndMarker::new(); - -extern "C" { - pub fn add(x: i32, y: i32) -> i32; -} - #[no_mangle] unsafe extern "C" fn kmain() -> ! { // All limine requests must also be referenced in a called function, otherwise they may be // removed by the linker. assert!(BASE_REVISION.is_supported()); - lib_example::add_nums(1, 2); - add(1, 2); - - if let Some(framebuffer_response) = FRAMEBUFFER_REQUEST.get_response() { - if let Some(framebuffer) = framebuffer_response.framebuffers().next() { - for i in 0..100_u64 { - // Calculate the pixel offset using the framebuffer information we obtained above. - // We skip `i` scanlines (pitch is provided in bytes) and add `i * 4` to skip `i` pixels forward. - let pixel_offset = i * framebuffer.pitch() + i * 4; - - // Write 0xFFFFFFFF to the provided pixel offset to fill it white. - *(framebuffer.addr().add(pixel_offset as usize) as *mut u32) = 0xFFFFFFFF; - } - } + if let Err(_) = lib_serial::init() { + loop {} } + let dimensions = lib_ascii::screensize_chars(); + let dimensions2 = lib_framebuffer::screensize_px(); + println!("Hello World!"); + println!("Dimensions: {}x{} (px)", dimensions2.0, dimensions2.1); + println!("Dimensions: {}x{} (chars)", dimensions.0, dimensions.1); + + println!(" + $$$$$$$$\\ $$\\ + $$ _____| $$ | + $$ | $$$$$$\\ $$\\ $$\\ $$$$$$$\\ $$$$$$$ | $$$$$$\\ $$\\ $$\\ + $$$$$\\ $$ __$$\\ $$ | $$ |$$ __$$\\ $$ __$$ |$$ __$$\\ $$ | $$ | + $$ __|$$ / $$ |$$ | $$ |$$ | $$ |$$ / $$ |$$ | \\__|$$ | $$ | + $$ | $$ | $$ |$$ | $$ |$$ | $$ |$$ | $$ |$$ | $$ | $$ | + $$ | \\$$$$$$ |\\$$$$$$ |$$ | $$ |\\$$$$$$$ |$$ | \\$$$$$$$ | + \\__| \\______/ \\______/ \\__| \\__| \\_______|\\__| \\____$$ | + $$$$$$\\ $$$$$$\\ $$\\ $$\\ $$\\ $$\\ $$ | + $$ __$$\\ $$ __$$\\ $$ | $$ |$$$$ | \\$$$$$$ | + $$ / $$ |$$ / \\__| $$ | $$ |\\_$$ | \\______/ + $$ | $$ |\\$$$$$$\\ \\$$\\ $$ | $$ | + $$ | $$ | \\____$$\\ \\$$\\$$ / $$ | + $$ | $$ |$$\\ $$ | \\$$$ / $$ | + $$$$$$ |\\$$$$$$ | \\$ / $$$$$$\\ + \\______/ \\______/ \\_/ \\______| + "); + hcf(); } #[panic_handler] fn rust_panic(_info: &core::panic::PanicInfo) -> ! { hcf(); - // loop {} } fn hcf() -> ! { diff --git a/lib/lib_ascii/Cargo.toml b/lib/lib_ascii/Cargo.toml new file mode 100644 index 0000000..674cb7c --- /dev/null +++ b/lib/lib_ascii/Cargo.toml @@ -0,0 +1,10 @@ +[package] +name = "lib_ascii" +version.workspace = true +edition.workspace = true + +[dependencies] +lazy_static = { version = "1.5.0", default-features = false, features = ["spin_no_std"] } +lib_framebuffer = { path = "../lib_framebuffer" } +spin = "0.9.8" +x86_64 = "0.15.2" diff --git a/lib/lib_ascii/src/font.rs b/lib/lib_ascii/src/font.rs new file mode 100644 index 0000000..0cd6ba4 --- /dev/null +++ b/lib/lib_ascii/src/font.rs @@ -0,0 +1,200 @@ +pub static FONT: [u8; 128 * 16] = [ + // ASCII 0-31 (Control Characters) - Using simple box patterns + // NUL (0) + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + // SOH (1) + 0x18, 0x3C, 0x3C, 0x3C, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, + // STX (2) + 0x18, 0x3C, 0x7E, 0x7E, 0x3C, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, + // ETX (3) + 0x18, 0x3C, 0x7E, 0xFF, 0xFF, 0x7E, 0x3C, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, + // EOT (4) + 0x18, 0x3C, 0x7E, 0xFF, 0xFF, 0xFF, 0x7E, 0x3C, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, + // ENQ (5) + 0x18, 0x3C, 0x7E, 0xFF, 0xFF, 0xFF, 0xFF, 0x7E, 0x3C, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, + // ACK (6) + 0x18, 0x3C, 0x7E, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7E, 0x3C, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, + // BEL (7) + 0x18, 0x3C, 0x7E, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7E, 0x3C, 0x18, 0x18, 0x18, 0x18, 0x18, + // BS (8) + 0x18, 0x3C, 0x7E, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7E, 0x3C, 0x18, 0x18, 0x18, 0x18, + // HT (9) + 0x18, 0x3C, 0x7E, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7E, 0x3C, 0x18, 0x18, 0x18, + // LF (10) + 0x18, 0x3C, 0x7E, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7E, 0x3C, 0x18, 0x18, + // VT (11) + 0x18, 0x3C, 0x7E, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7E, 0x3C, 0x18, + // FF (12) + 0x18, 0x3C, 0x7E, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7E, 0x3C, + // CR (13) + 0x3C, 0x7E, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7E, + // SO (14) + 0x7E, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + // SI (15) + 0xFF, 0x7E, 0x3C, 0x18, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + // DLE (16) + 0xFF, 0xFF, 0x7E, 0x3C, 0x18, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + // DC1 (17) + 0xFF, 0xFF, 0xFF, 0x7E, 0x3C, 0x18, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + // DC2 (18) + 0xFF, 0xFF, 0xFF, 0xFF, 0x7E, 0x3C, 0x18, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + // DC3 (19) + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7E, 0x3C, 0x18, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + // DC4 (20) + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7E, 0x3C, 0x18, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + // NAK (21) + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7E, 0x3C, 0x18, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + // SYN (22) + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7E, 0x3C, 0x18, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + // ETB (23) + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7E, 0x3C, 0x18, 0xFF, 0xFF, 0xFF, 0xFF, + // CAN (24) + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7E, 0x3C, 0x18, 0xFF, 0xFF, 0xFF, + // EM (25) + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7E, 0x3C, 0x18, 0xFF, 0xFF, + // SUB (26) + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7E, 0x3C, 0x18, 0xFF, + // ESC (27) + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7E, 0x3C, 0x18, + // FS (28) + 0x18, 0x3C, 0x7E, 0xFF, 0x18, 0x18, 0x18, 0x18, 0x18, 0xFF, 0x7E, 0x3C, 0x18, 0x18, 0x18, 0x18, + // GS (29) + 0x18, 0x3C, 0x7E, 0xFF, 0xFF, 0x18, 0x18, 0x18, 0xFF, 0x7E, 0x3C, 0x18, 0x18, 0x18, 0x18, 0x18, + // RS (30) + 0x18, 0x3C, 0x7E, 0xFF, 0xFF, 0xFF, 0x18, 0xFF, 0x7E, 0x3C, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, + // US (31) + 0x18, 0x3C, 0x7E, 0xFF, 0xFF, 0xFF, 0xFF, 0x7E, 0x3C, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, + // Space (32) + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + // ! (33) + 0x00, 0x00, 0x18, 0x3C, 0x3C, 0x3C, 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, + // " (34) + 0x00, 0x66, 0x66, 0x66, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + // # (35) + 0x00, 0x00, 0x00, 0x6C, 0x6C, 0xFE, 0x6C, 0x6C, 0x6C, 0xFE, 0x6C, 0x6C, 0x00, 0x00, 0x00, 0x00, + // $ (36) + 0x18, 0x18, 0x7C, 0xC6, 0xC2, 0xC0, 0x7C, 0x06, 0x86, 0xC6, 0x7C, 0x18, 0x18, 0x00, 0x00, 0x00, + // % (37) + 0x00, 0x00, 0x00, 0x00, 0xC2, 0xC6, 0x0C, 0x18, 0x30, 0x60, 0xC6, 0x86, 0x00, 0x00, 0x00, 0x00, + // & (38) + 0x00, 0x00, 0x38, 0x6C, 0x6C, 0x38, 0x76, 0xDC, 0xCC, 0xCC, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, + // ' (39) + 0x00, 0x30, 0x30, 0x30, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + // ( (40) + 0x00, 0x00, 0x0C, 0x18, 0x30, 0x30, 0x30, 0x30, 0x30, 0x18, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, + // ) (41) + 0x00, 0x00, 0x30, 0x18, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x18, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, + // * (42) + 0x00, 0x00, 0x00, 0x00, 0x66, 0x3C, 0xFF, 0x3C, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + // + (43) + 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x7E, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + // , (44) + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x30, 0x00, 0x00, 0x00, 0x00, + // - (45) + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + // . (46) + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, + // / (47) + 0x00, 0x00, 0x00, 0x00, 0x02, 0x06, 0x0C, 0x18, 0x30, 0x60, 0xC0, 0x80, 0x00, 0x00, 0x00, 0x00, + // 0-9 (48-57) + 0x00, 0x00, 0x38, 0x6C, 0xC6, 0xC6, 0xD6, 0xD6, 0xC6, 0xC6, 0x6C, 0x38, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x18, 0x38, 0x78, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x7E, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x7C, 0xC6, 0x06, 0x0C, 0x18, 0x30, 0x60, 0xC0, 0xC6, 0xFE, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x7C, 0xC6, 0x06, 0x06, 0x3C, 0x06, 0x06, 0x06, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0C, 0x1C, 0x3C, 0x6C, 0xCC, 0xFE, 0x0C, 0x0C, 0x0C, 0x1E, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xFE, 0xC0, 0xC0, 0xC0, 0xFC, 0x06, 0x06, 0x06, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x38, 0x60, 0xC0, 0xC0, 0xFC, 0xC6, 0xC6, 0xC6, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xFE, 0xC6, 0x06, 0x06, 0x0C, 0x18, 0x30, 0x30, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x7C, 0xC6, 0xC6, 0xC6, 0x7C, 0xC6, 0xC6, 0xC6, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x7C, 0xC6, 0xC6, 0xC6, 0x7E, 0x06, 0x06, 0x06, 0x0C, 0x78, 0x00, 0x00, 0x00, 0x00, + // : (58) + 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, + // ; (59) + 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x18, 0x18, 0x30, 0x00, 0x00, 0x00, 0x00, + // < (60) + 0x00, 0x00, 0x00, 0x06, 0x0C, 0x18, 0x30, 0x60, 0x30, 0x18, 0x0C, 0x06, 0x00, 0x00, 0x00, 0x00, + // = (61) + 0x00, 0x00, 0x00, 0x00, 0x00, 0x7E, 0x00, 0x00, 0x7E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + // > (62) + 0x00, 0x00, 0x00, 0x60, 0x30, 0x18, 0x0C, 0x06, 0x0C, 0x18, 0x30, 0x60, 0x00, 0x00, 0x00, 0x00, + // ? (63) + 0x00, 0x00, 0x7C, 0xC6, 0xC6, 0x0C, 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, + // @ (64) + 0x00, 0x00, 0x00, 0x7C, 0xC6, 0xC6, 0xDE, 0xDE, 0xDE, 0xDC, 0xC0, 0x7C, 0x00, 0x00, 0x00, 0x00, + // A-Z (65-90) + 0x00, 0x00, 0x10, 0x38, 0x6C, 0xC6, 0xC6, 0xFE, 0xC6, 0xC6, 0xC6, 0xC6, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xFC, 0x66, 0x66, 0x66, 0x7C, 0x66, 0x66, 0x66, 0x66, 0xFC, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x3C, 0x66, 0xC2, 0xC0, 0xC0, 0xC0, 0xC0, 0xC2, 0x66, 0x3C, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xF8, 0x6C, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x6C, 0xF8, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xFE, 0x66, 0x62, 0x68, 0x78, 0x68, 0x60, 0x62, 0x66, 0xFE, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xFE, 0x66, 0x62, 0x68, 0x78, 0x68, 0x60, 0x60, 0x60, 0xF0, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x3C, 0x66, 0xC2, 0xC0, 0xC0, 0xDE, 0xC6, 0xC6, 0x66, 0x3A, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xC6, 0xC6, 0xC6, 0xC6, 0xFE, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x3C, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3C, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x1E, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0xCC, 0xCC, 0xCC, 0x78, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xE6, 0x66, 0x6C, 0x6C, 0x78, 0x78, 0x6C, 0x66, 0x66, 0xE6, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xF0, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x62, 0x66, 0xFE, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xC6, 0xEE, 0xFE, 0xFE, 0xD6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xC6, 0xE6, 0xF6, 0xFE, 0xDE, 0xCE, 0xC6, 0xC6, 0xC6, 0xC6, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x38, 0x6C, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x6C, 0x38, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xFC, 0x66, 0x66, 0x66, 0x7C, 0x60, 0x60, 0x60, 0x60, 0xF0, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x7C, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xD6, 0xDE, 0x7C, 0x0C, 0x0E, 0x00, 0x00, + 0x00, 0x00, 0xFC, 0x66, 0x66, 0x66, 0x7C, 0x6C, 0x66, 0x66, 0x66, 0xE6, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x7C, 0xC6, 0xC6, 0x60, 0x38, 0x0C, 0x06, 0xC6, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x7E, 0x7E, 0x5A, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3C, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x6C, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xC6, 0xC6, 0xC6, 0xC6, 0xD6, 0xD6, 0xD6, 0xFE, 0xEE, 0x6C, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xC6, 0xC6, 0x6C, 0x7C, 0x38, 0x38, 0x7C, 0x6C, 0xC6, 0xC6, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x3C, 0x18, 0x18, 0x18, 0x18, 0x3C, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xFE, 0xC6, 0x86, 0x0C, 0x18, 0x30, 0x60, 0xC2, 0xC6, 0xFE, 0x00, 0x00, 0x00, 0x00, + // [ (91) + 0x00, 0x00, 0x3C, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x3C, 0x00, 0x00, 0x00, 0x00, + // \ (92) + 0x00, 0x00, 0x00, 0x80, 0xC0, 0xE0, 0x70, 0x38, 0x1C, 0x0E, 0x06, 0x02, 0x00, 0x00, 0x00, 0x00, + // ] (93) + 0x00, 0x00, 0x3C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x3C, 0x00, 0x00, 0x00, 0x00, + // ^ (94) + 0x10, 0x38, 0x6C, 0xC6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + // _ (95) + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, + // ` (96) + 0x30, 0x18, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + // a-z (97-122) - lowercase letters + 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x0C, 0x7C, 0xCC, 0xCC, 0xCC, 0x76, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xE0, 0x60, 0x60, 0x78, 0x6C, 0x66, 0x66, 0x66, 0x66, 0x7C, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x7C, 0xC6, 0xC0, 0xC0, 0xC0, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x1C, 0x0C, 0x0C, 0x3C, 0x6C, 0xCC, 0xCC, 0xCC, 0xCC, 0x76, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x7C, 0xC6, 0xFE, 0xC0, 0xC0, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x38, 0x6C, 0x64, 0x60, 0xF0, 0x60, 0x60, 0x60, 0x60, 0xF0, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xCC, 0xCC, 0xCC, 0x7C, 0x0C, 0xCC, 0x78, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xE0, 0x60, 0x60, 0x6C, 0x76, 0x66, 0x66, 0x66, 0x66, 0xE6, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x18, 0x18, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3C, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x06, 0x06, 0x00, 0x0E, 0x06, 0x06, 0x06, 0x06, 0x66, 0x66, 0x3C, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xE0, 0x60, 0x60, 0x66, 0x6C, 0x78, 0x78, 0x6C, 0x66, 0xE6, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3C, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xEC, 0xFE, 0xD6, 0xD6, 0xD6, 0xD6, 0xC6, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xDC, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x7C, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xDC, 0x66, 0x66, 0x66, 0x7C, 0x60, 0x60, 0xF0, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xCC, 0xCC, 0xCC, 0x7C, 0x0C, 0x0C, 0x1E, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xDC, 0x76, 0x66, 0x60, 0x60, 0x60, 0xF0, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x7C, 0xC6, 0x60, 0x38, 0x0C, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x10, 0x30, 0x30, 0xFC, 0x30, 0x30, 0x30, 0x30, 0x36, 0x1C, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0x76, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x66, 0x3C, 0x18, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xC6, 0xC6, 0xC6, 0xD6, 0xD6, 0xFE, 0x6C, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xC6, 0x6C, 0x38, 0x38, 0x38, 0x6C, 0xC6, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xC6, 0xC6, 0xC6, 0xC6, 0x7E, 0x06, 0xC6, 0x7C, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0xCC, 0x18, 0x30, 0x60, 0xC6, 0xFE, 0x00, 0x00, 0x00, 0x00, + // { (123) + 0x00, 0x00, 0x0E, 0x18, 0x18, 0x18, 0x70, 0x18, 0x18, 0x18, 0x18, 0x0E, 0x00, 0x00, 0x00, 0x00, + // | (124) + 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, + // } (125) + 0x00, 0x00, 0x70, 0x18, 0x18, 0x18, 0x0E, 0x18, 0x18, 0x18, 0x18, 0x70, 0x00, 0x00, 0x00, 0x00, + // ~ (126) + 0x00, 0x00, 0x76, 0xDC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + // DEL (127) + 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x6C, 0xC6, 0xC6, 0xC6, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, +]; \ No newline at end of file diff --git a/lib/lib_ascii/src/lib.rs b/lib/lib_ascii/src/lib.rs new file mode 100644 index 0000000..584ed2e --- /dev/null +++ b/lib/lib_ascii/src/lib.rs @@ -0,0 +1,199 @@ +#![no_std] + +use core::fmt; +use lazy_static::lazy_static; +use spin::{Lazy, Mutex}; +use x86_64::instructions::interrupts; + +use lib_framebuffer::FRAMEBUFFER_WRITER; + +mod font; +use font::FONT; + +static FONT_WIDTH: u32 = 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) +} + +pub struct Writer { + // these are measured in chars NOT pixels + screen_width: u32, + screen_height: u32, + + text_line: u32, // 16 pixels tall + text_col: u32, // 8 pixels wide + + fg_color: u32, + bg_color: u32 +} + +impl Writer { + + pub fn new() -> Self { + if let Some(writer) = FRAMEBUFFER_WRITER.lock().as_mut() { + Self { + screen_width: writer.width() as u32 / 8, + screen_height: writer.height() as u32 / 16, + text_line: 0, + text_col: 0, + fg_color: 0xFFFFFF, + bg_color: 0x000000 + } + } else { + panic!("Framebuffer writer not initialized"); + } + } + + pub fn write_char(&mut self, mut c: u8) { + if c == b'\n' { + self.newline(); + return; + } + + if c < 32 || c > 126 { + c = '?' as u8; + } + + // get the character data from the font array. -- each byte is a row of pixels + let data: &[u8] = &FONT[c as usize * 16..(c as usize + 1) * 16]; + + if let Some(writer) = FRAMEBUFFER_WRITER.lock().as_mut() { + for row in 0..16 { + let line: u8 = data[row]; + for col in 0..8 { + let pixel_x: u32 = self.text_col * FONT_WIDTH + col; + let pixel_y: u32 = self.text_line * FONT_HEIGHT + row as u32; + + if line & (0x80 >> col) != 0 { + // write the foreground color + writer.write_pixel(pixel_x as usize, pixel_y as usize, self.fg_color); + } else { + // write the background color + writer.write_pixel(pixel_x as usize, pixel_y as usize, self.bg_color); + } + } + } + } + + // go to next position + if self.text_col + 1 >= self.screen_width { + self.newline(); + } else { + self.text_col += 1; + } + } + + pub fn dimensions(&self) -> (u32, u32) { + (self.screen_width, self.screen_height) + } + + pub fn next_char(&mut self) { + self.text_col += 1; + } + + pub fn newline(&mut self) { + self.text_col = 0; + + if self.text_line + 1 >= self.screen_height { + self.text_line = 0; + } else { + self.text_line += 1; + } + } + + pub fn write_string(&mut self, s: &str) { + for c in s.chars() { + self.write_char(c as u8); + } + } + + pub fn set_colour(&mut self, col: (u32, u32)) { + self.fg_color = col.0; + self.bg_color = col.1; + } + + pub fn reset_colour(&mut self) { + self.fg_color = 0xFFFFFF; + self.bg_color = 0x000000; + } +} + +impl core::fmt::Write for Writer { + fn write_str(&mut self, s: &str) -> core::fmt::Result { + self.write_string(s); + Ok(()) + } +} + +fn write(args: fmt::Arguments, fg_color: u32, bg_color: u32) { + use core::fmt::Write; + + interrupts::without_interrupts(|| { + let mut writer = WRITER.lock(); + writer.set_colour((fg_color, bg_color)); + writer.write_fmt(args).unwrap(); + writer.reset_colour(); + }); +} + +pub fn _print(args: fmt::Arguments) { + write(args, 0xFFFFFF, 0x000000); +} + +pub fn _printerr(args: fmt::Arguments) { + write(args, 0xFF8080, 0x000000); +} + +pub fn _log(args: fmt::Arguments) { + write(args, 0xFFFF00, 0x000000); +} + +pub fn clear_screen() { + interrupts::without_interrupts(|| { + let mut writer = WRITER.lock(); + writer.text_line = 0; + writer.text_col = 0; + + if let Some(writer) = FRAMEBUFFER_WRITER.lock().as_mut() { + writer.clear(); + } + }); +} + +#[macro_export] +macro_rules! println_log { + () => ($crate::print_log!("\n")); + ($($arg:tt)*) => ($crate::print_log!("{}\n", format_args!($($arg)*))); +} + +#[macro_export] +macro_rules! print_log { + ($($arg:tt)*) => ($crate::_log(format_args!($($arg)*))); +} + +#[macro_export] +macro_rules! println { + () => ($crate::print!("\n")); + ($($arg:tt)*) => ($crate::print!("{}\n", format_args!($($arg)*))); +} + +#[macro_export] +macro_rules! print { + ($($arg:tt)*) => ($crate::_print(format_args!($($arg)*))); +} + +#[macro_export] +macro_rules! printlnerr { + () => ($crate::printerr!("\n")); + ($($arg:tt)*) => ($crate::printerr!("{}\n", format_args!($($arg)*))); +} + +#[macro_export] +macro_rules! printerr { + ($($arg:tt)*) => ($crate::_printerr(format_args!($($arg)*))); +} \ No newline at end of file diff --git a/lib_example/Cargo.toml b/lib/lib_framebuffer/Cargo.toml similarity index 57% rename from lib_example/Cargo.toml rename to lib/lib_framebuffer/Cargo.toml index 4ea006a..19737e4 100644 --- a/lib_example/Cargo.toml +++ b/lib/lib_framebuffer/Cargo.toml @@ -1,6 +1,8 @@ [package] -name = "lib_example" +name = "lib_framebuffer" version.workspace = true edition.workspace = true [dependencies] +limine = "0.3.1" +spin = "0.9.8" diff --git a/lib/lib_framebuffer/src/draw.rs b/lib/lib_framebuffer/src/draw.rs new file mode 100644 index 0000000..c2f0255 --- /dev/null +++ b/lib/lib_framebuffer/src/draw.rs @@ -0,0 +1,57 @@ +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/lib.rs b/lib/lib_framebuffer/src/lib.rs new file mode 100644 index 0000000..61a28a3 --- /dev/null +++ b/lib/lib_framebuffer/src/lib.rs @@ -0,0 +1,18 @@ +#![no_std] + +use limine::request::FramebufferRequest; + +#[used] +#[link_section = ".requests"] +static FRAMEBUFFER_REQUEST: FramebufferRequest = FramebufferRequest::new(); + +mod draw; +pub use draw::FRAMEBUFFER_WRITER; + +pub fn screensize_px() -> (u32, u32) { + if let Some(writer) = FRAMEBUFFER_WRITER.lock().as_mut() { + (writer.width(), writer.height()) + } else { + (0, 0) + } +} \ No newline at end of file diff --git a/lib/lib_serial/Cargo.toml b/lib/lib_serial/Cargo.toml new file mode 100644 index 0000000..fdd0427 --- /dev/null +++ b/lib/lib_serial/Cargo.toml @@ -0,0 +1,10 @@ +[package] +name = "lib_serial" +version.workspace = true +edition.workspace = true + +[dependencies] +lazy_static = { version = "1.5.0", default-features = false, features = ["spin_no_std"] } +spin = "0.9.8" +x86_64 = "0.15.2" + diff --git a/lib/lib_serial/src/io.rs b/lib/lib_serial/src/io.rs new file mode 100644 index 0000000..994cbf0 --- /dev/null +++ b/lib/lib_serial/src/io.rs @@ -0,0 +1,23 @@ +use core::arch::asm; + +#[inline] +pub unsafe fn inb(port: u16) -> u8 { + let value: u8; + asm!( + "in al, dx", + out("al") value, + in("dx") port, + options(nomem, nostack, preserves_flags) + ); + value +} + +#[inline] +pub unsafe fn outb(port: u16, value: u8) { + asm!( + "out dx, al", + in("dx") port, + in("al") value, + options(nomem, nostack, preserves_flags) + ); +} \ No newline at end of file diff --git a/lib/lib_serial/src/lib.rs b/lib/lib_serial/src/lib.rs new file mode 100644 index 0000000..59fb98c --- /dev/null +++ b/lib/lib_serial/src/lib.rs @@ -0,0 +1,157 @@ +#![no_std] + +use core::{fmt, sync::atomic::{AtomicUsize, Ordering}}; +use spin::Mutex; +use lazy_static::lazy_static; + +mod io; +use io::*; +use x86_64::instructions::interrupts; + +static PORT: u16 = 0x3f8; +static mut BUFFER: [u8; 256] = [0; 256]; +static BUFFER_LEN: AtomicUsize = AtomicUsize::new(0); + +lazy_static!{ + static ref READER: Mutex> = Mutex::new(None); + static ref WRITER: Mutex> = Mutex::new(None); +} + +struct Reader; + +struct Writer; + +impl fmt::Write for Writer { + fn write_str(&mut self, s: &str) -> fmt::Result { + for c in s.chars() { + self.write_byte(c as u8); + } + Ok(()) + } +} + +impl Writer { + unsafe fn write_success(&self) -> bool { + inb(PORT + 5) & 0x20 != 0 + } + + pub fn write_byte(&self, data: u8) { unsafe { + while !self.write_success() {}; + outb(PORT + 0, data); + }} +} + + +pub fn init() -> Result<(), &'static str> { + if let Err(e) = test() { + return Err(e); + } + + if READER.lock().is_none() { + *READER.lock() = Some(Reader); + } + + if WRITER.lock().is_none() { + *WRITER.lock() = Some(Writer); + } + + Ok(()) +} + +pub fn test() -> Result<(), &'static str> { + unsafe { + outb(PORT + 1, 0x00); // Disable all interrupts + outb(PORT + 3, 0x80); // Enable DLAB (set baud rate divisor) + outb(PORT + 0, 0x03); // Set divisor to 3 (lo byte) 38400 baud + outb(PORT + 1, 0x00); // (hi byte) + outb(PORT + 3, 0x03); // 8 bits, no parity, one stop bit + outb(PORT + 2, 0xC7); // Enable FIFO, clear them, with 14-bytethreshold + outb(PORT + 4, 0x0B); // IRQs enabled, RTS/DSR set + outb(PORT + 4, 0x1E); // Set in loopback mode, test the serial chip + outb(PORT + 0, 0xAE); // Test serial chip (send byte 0xAE and check if serial returns same byte) + + if inb(PORT + 0) != 0xAE { + return Err("serial test failed") + } + + outb(PORT + 4, 0x0F); + } + + Ok(()) +} + +impl Reader { + pub fn read_str_to_buffer(&mut self) { unsafe { + while !self.read_ready() {}; + + BUFFER_LEN.store(0, Ordering::SeqCst); + + while BUFFER_LEN.load(Ordering::SeqCst) < 256 { + let c = self.read(); + BUFFER[BUFFER_LEN.load(Ordering::SeqCst)] = c; + if c as char == '\r' { + break; + } + BUFFER_LEN.fetch_add(1, Ordering::SeqCst); + } + + serial_println!("returning") + }} + + unsafe fn read_ready(&self) -> bool { + inb(PORT + 5) & 1 != 0 + } + + pub fn read(&self) -> u8 { unsafe { + while !self.read_ready() {}; + return inb(PORT + 0); + }} +} + +pub fn _serial_write(args: fmt::Arguments) { + use core::fmt::Write; + + interrupts::without_interrupts(|| { + if let Some(writer) = WRITER.lock().as_mut() { + writer.write_fmt(args).unwrap(); + } + }) +} + +#[macro_export] +macro_rules! serial_println { + () => ($crate::serial_print!("\n")); + ($($arg:tt)*) => ($crate::serial_print!("{}\n", format_args!($($arg)*))); +} + +#[macro_export] +macro_rules! serial_print { + ($($arg:tt)*) => ($crate::_serial_write(format_args!($($arg)*))); +} + +pub fn serial_read() -> &'static str { + serial_println!("getting value!"); + + interrupts::without_interrupts(|| { + if let Some(reader) = READER.lock().as_mut() { + serial_println!("stuff happnin."); + reader.read_str_to_buffer(); + } else { + serial_println!("failed to get writer"); + } + }); + + serial_println!("eee"); + + let i = BUFFER_LEN.load(Ordering::SeqCst); + + return unsafe { + if i != 0 { + core::str::from_utf8(&BUFFER[..i - 1]).unwrap() + } else { + serial_println!("empty string"); + "" + } + } +} + diff --git a/lib_example/src/lib.rs b/lib_example/src/lib.rs deleted file mode 100644 index 1f8117c..0000000 --- a/lib_example/src/lib.rs +++ /dev/null @@ -1,5 +0,0 @@ -#![no_std] - -pub fn add_nums(x: i32, y: i32) -> i32 { - x + y -} \ No newline at end of file diff --git a/scripts/run.sh b/scripts/run.sh index 16a53c4..059a677 100755 --- a/scripts/run.sh +++ b/scripts/run.sh @@ -49,7 +49,7 @@ if [[ $1 == *"deps"* ]]; then else # Build the kernel normally cd "$project_root" - cargo build + # cargo build kernel_path="$build_dir/target/x86_64-kernel/debug/kernel" fi