diff --git a/src/arch/i686/linker.ld b/src/arch/i686/linker.ld index 44038fe..d0bd6a8 100644 --- a/src/arch/i686/linker.ld +++ b/src/arch/i686/linker.ld @@ -1,17 +1,49 @@ ENTRY(_start) -SECTIONS { - . = 1M; - - .boot : +SECTIONS +{ + .boot BLOCK(4K) : ALIGN(4K) { /* ensure that the multiboot header is at the beginning */ KEEP(*(.multiboot_header)) } - - .text : + . = 0x00100000; + .text BLOCK(4K) : ALIGN(4K) { + _kernel_start = .; *(.text) } + /* Read-only data. */ + .rodata BLOCK(4K) : ALIGN(4K) + { + *(.rodata) + } + + /* Read-write data (initialized) */ + .data BLOCK(4K) : ALIGN(4K) + { + *(.data) + } + .bss BLOCK(4K) : ALIGN(4K) + { + *(COMMON) + *(.bss) + } + .stab BLOCK(4K) : ALIGN(4K) + { + *(.stab) + } + .stabstr BLOCK(4K) : ALIGN(4K) + { + *(.stabstr) + } + .note BLOCK(4K) : ALIGN(4K) + { + *(.note) + } + .comment BLOCK(4K) : ALIGN(4K) + { + *(.comment) + } + _kernel_end = .; } - diff --git a/src/elsos.rs b/src/elsos.rs index 16172dd..a622959 100644 --- a/src/elsos.rs +++ b/src/elsos.rs @@ -5,13 +5,14 @@ #![no_std] #![no_main] -mod utilities; +mod tools; mod vga; mod keyboard; mod tty; mod multiboot; mod serial; mod gdt; +mod memory; use core::panic::PanicInfo; @@ -20,6 +21,9 @@ static PATCHLEVEL: &str = env!("PATCHLEVEL"); static SUBLEVEL: &str = env!("SUBLEVEL"); static EXTRAVERSION: &str = env!("EXTRAVERSION"); +use crate::multiboot::MULTIBOOT_MMAP; +use crate::multiboot::MULTIBOOT_MMAP_ENTRIES; + pub struct Settings { has_serial: bool, @@ -40,6 +44,8 @@ pub extern "C" fn kernel_main(magic: u32, address: u32) vga::cursor::Cursor::init(0, 15); if multiboot::check_magic(magic) && multiboot::parse(address) { + let mut alloc: memory::pageframe::Allocator = memory::pageframe::Allocator::new(); + unsafe { alloc.read_grub_mmap(MULTIBOOT_MMAP, MULTIBOOT_MMAP_ENTRIES); } init_serial(); logln!("\n"); logln!(" ::: :::::::: __ __ __ _ ____ ____ "); diff --git a/src/gdt.rs b/src/gdt.rs index 667fe73..2dc50c5 100644 --- a/src/gdt.rs +++ b/src/gdt.rs @@ -5,62 +5,62 @@ use core::mem::size_of; #[repr(C, packed)] struct gdt_ptr { - limit: u16, - base: u32 + limit: u16, + base: u32 } #[repr(C, packed)] struct gdt_entry { - limit0: u16, - base0: u16, - base1: u8, - access_byte: u8, - limit1_flags: u8, - base2: u8 + limit0: u16, + base0: u16, + base1: u8, + access_byte: u8, + limit1_flags: u8, + base2: u8 } #[repr(C, packed)] struct gdt { - null: gdt_entry, - kernel_code: gdt_entry, - kernel_data: gdt_entry, + null: gdt_entry, + kernel_code: gdt_entry, + kernel_data: gdt_entry, kernel_stack: gdt_entry, - user_code: gdt_entry, - user_data: gdt_entry, + user_code: gdt_entry, + user_data: gdt_entry, user_stack: gdt_entry, } static mut GDT_TABLE: gdt = gdt { - null: gdt_entry - { - limit0: 0, - base0: 0, - base1: 0, - access_byte: 0x00, - limit1_flags: 0x00, - base2: 0 - }, - kernel_code: gdt_entry - { - limit0: 0xffff, - base0: 0, - base1: 0, - access_byte: 0b1001_1010, - limit1_flags: 0xcf, - base2: 0 - }, - kernel_data: gdt_entry - { - limit0: 0xffff, - base0: 0, - base1: 0, - access_byte: 0b1001_0010, - limit1_flags: 0xcf, - base2: 0 - }, + null: gdt_entry + { + limit0: 0, + base0: 0, + base1: 0, + access_byte: 0x00, + limit1_flags: 0x00, + base2: 0 + }, + kernel_code: gdt_entry + { + limit0: 0xffff, + base0: 0, + base1: 0, + access_byte: 0b1001_1010, + limit1_flags: 0xcf, + base2: 0 + }, + kernel_data: gdt_entry + { + limit0: 0xffff, + base0: 0, + base1: 0, + access_byte: 0b1001_0010, + limit1_flags: 0xcf, + base2: 0 + }, kernel_stack: gdt_entry { limit0: 0xffff, @@ -70,56 +70,56 @@ static mut GDT_TABLE: gdt = gdt limit1_flags: 0xcf, base2: 0 }, - user_code: gdt_entry - { - limit0: 0xffff, - base0: 0, - base1: 0, - access_byte: 0b1111_1010, - limit1_flags: 0xcf, - base2: 0 - }, - user_data: gdt_entry - { - limit0: 0xffff, - base0: 0, - base1: 0, - access_byte: 0b1111_0010, - limit1_flags: 0xcf, - base2: 0 - }, - user_stack: gdt_entry - { - limit0: 0xffff, - base0: 0, - base1: 0, - access_byte: 0b1111_0110, - limit1_flags: 0xcf, - base2: 0 - }, + user_code: gdt_entry + { + limit0: 0xffff, + base0: 0, + base1: 0, + access_byte: 0b1111_1010, + limit1_flags: 0xcf, + base2: 0 + }, + user_data: gdt_entry + { + limit0: 0xffff, + base0: 0, + base1: 0, + access_byte: 0b1111_0010, + limit1_flags: 0xcf, + base2: 0 + }, + user_stack: gdt_entry + { + limit0: 0xffff, + base0: 0, + base1: 0, + access_byte: 0b1111_0110, + limit1_flags: 0xcf, + base2: 0 + }, }; extern "C" { - fn _gdt_flush(); - fn memcpy(dst: *const u8, src: *const u8, size: usize); + fn _gdt_flush(); + fn memcpy(dst: *const u8, src: *const u8, size: usize); } #[no_mangle] static mut _gp: gdt_ptr = gdt_ptr { - limit: 0, - base: 0x800 + limit: 0, + base: 0x800 }; pub fn init_gdt() { - let size = size_of::() - 1; - unsafe - { - memcpy(0x800 as *const u8, (&GDT_TABLE as *const _) as *const u8, size); - _gp.limit = size as u16; - _gdt_flush(); - } + let size = size_of::() - 1; + unsafe + { + memcpy(0x800 as *const u8, (&GDT_TABLE as *const _) as *const u8, size); + _gp.limit = size as u16; + _gdt_flush(); + } } diff --git a/src/keyboard/mod.rs b/src/keyboard/mod.rs index c30b97e..56d5bb2 100644 --- a/src/keyboard/mod.rs +++ b/src/keyboard/mod.rs @@ -1,5 +1,5 @@ use crate::tty; -use crate::utilities; +use crate::tools; mod azerty; mod qwerty; @@ -54,7 +54,7 @@ pub fn get_scancodes() let mut scancode: u8 = 0; loop { - let new_scancode = utilities::inb(KEYBOARD_DATA); + let new_scancode = tools::inb(KEYBOARD_DATA); if new_scancode == scancode { diff --git a/src/libc/libc.h b/src/libc/libc.h index abdba9b..995f146 100644 --- a/src/libc/libc.h +++ b/src/libc/libc.h @@ -1,9 +1,9 @@ #ifndef LIBC_H # define LIBC_H -void *memset(void *b, int c, size_t len); -void *memcpy(void *dst, const void *src, size_t n); -void *memmove(void *dst, const void *src, size_t len); -int memcmp(const void *s1, const void *s2, size_t n); +void *memset(void *b, int c, size_t len); +void *memcpy(void *dst, const void *src, size_t n); +void *memmove(void *dst, const void *src, size_t len); +int memcmp(const void *s1, const void *s2, size_t n); #endif diff --git a/src/memory/mod.rs b/src/memory/mod.rs new file mode 100644 index 0000000..3589c21 --- /dev/null +++ b/src/memory/mod.rs @@ -0,0 +1,50 @@ +pub mod pageframe; + +use core::ffi::c_void; +use crate::multiboot::MultibootTagMmap; + +extern "C" +{ + static _kernel_start: c_void; + static _kernel_end: c_void; +} + +pub fn get_mem_size(mmap: *const MultibootTagMmap, mmap_size: usize) -> usize +{ + static mut MEM_SIZE_BYTES: u64 = 0; + unsafe + { + if MEM_SIZE_BYTES > 0 + { + return MEM_SIZE_BYTES as usize; + } + crate::logln!("\x1B[33mmmap: {:#x?}\x1B[39m", (*mmap).entries(mmap_size)); + for mmap_entry in (*mmap).entries(mmap_size) + { + MEM_SIZE_BYTES += mmap_entry.len as u64; + } + if MEM_SIZE_BYTES > usize::MAX as u64 + { + panic!("This version of ElsOS is in 32 bit, it only supports {}Mo of RAM, you have {}Mo installed", (usize::MAX / 1024) / 1024, (MEM_SIZE_BYTES / 1024) / 1024); + } + return MEM_SIZE_BYTES as usize; + } +} + +pub fn get_largest_mem_seg(mmap: *const MultibootTagMmap, mmap_size: usize) -> usize +{ + let mut largest_free_mem_seg: usize = 0; + let mut largest_free_mem_seg_size: usize = 0; + unsafe + { + for entry in (*mmap).entries(mmap_size) + { + if entry.len as usize > largest_free_mem_seg_size + { + largest_free_mem_seg_size = entry.len as usize; + largest_free_mem_seg = entry.addr as usize; + } + } + } + largest_free_mem_seg +} diff --git a/src/memory/pageframe.rs b/src/memory/pageframe.rs new file mode 100644 index 0000000..772f045 --- /dev/null +++ b/src/memory/pageframe.rs @@ -0,0 +1,207 @@ +use crate::multiboot::MultibootTagMmap; +use crate::tools; +use crate::page_index; +use crate::memory::get_mem_size; + +use core::ffi::c_void; + +extern "C" +{ + static _kernel_start: c_void; + static _kernel_end: c_void; +} + +pub struct Allocator +{ + pub free_mem: usize, + pub locked_mem: usize, + pub reserved_mem: usize, + pub unusable_mem: u64, + initialized: bool, + bitmap: tools::Bitmap, +} + +impl Allocator +{ + pub fn new() -> Allocator + { + Allocator + { + free_mem: 0, + locked_mem: 0, + reserved_mem: 0, + unusable_mem: 0, + initialized: false, + bitmap: tools::Bitmap {buffer: &mut[] as &'static mut[u8], size: 0}, + } + } + + pub fn read_grub_mmap(&mut self, mmap: *const MultibootTagMmap, mmap_size: usize) + { + let kernel_start: usize; + let kernel_end: usize; + + if self.initialized + { + return ; + } + self.initialized = true; + + crate::logln!("[INFO] initializing memory map..."); + unsafe + { + kernel_start = &_kernel_start as *const _ as usize; + kernel_end = &_kernel_end as *const _ as usize; + } + self.reserved_mem = crate::memory::get_mem_size(mmap, mmap_size); + crate::logln!("[INFO] found {}KiB of memory", self.reserved_mem / 1024); + // initialise the bitmap according to mem size, and set every page as reserved + self.init_bitmap(kernel_end); + crate::logln!("[INFO] assigned {} pages to bitmap", self.bitmap.size); + unsafe + { + for entry in (*mmap).entries(mmap_size) + { + if (entry.tag_type == 1 && entry.addr < get_mem_size(mmap, mmap_size) as u32) && entry.addr != 0 + { + // unreserve grub memmap entries marked as free except lower memory + crate::logln!("unreserving {} pages", page_index!(entry.len as usize)); + self.unreserve_mem(page_index!(entry.addr as usize), page_index!(entry.len as usize)); + } + } + } + // reserve kernel space + crate::logln!("reserving {} pages for kernel", page_index!(kernel_end - kernel_start)); + self.reserve_mem(page_index!(kernel_start), page_index!(kernel_end - kernel_start)); + crate::logln!("kernel end {:#x}", kernel_end); + crate::logln!("memory start {:#x}", kernel_end + self.bitmap.size / 8); + // reserve bitmap + crate::logln!("reserving {} pages for bitmap", page_index!(self.bitmap.size / 8)); + self.reserve_mem(page_index!(kernel_end), page_index!(self.bitmap.size / 8)); + } + + pub fn request_free_page(&mut self) -> usize + { + for i in 0..self.bitmap.size + { + if self.bitmap.get(i) == false + { + crate::logln!("locking page {}", i); + self.lock_page(i); + return i * 0x1000; + } + } + 0 + } + + pub fn free_page(&mut self, address: usize) + { + let index = address / 0x1000; + if self.bitmap[index] + { + self.unlock_page(index); + } + else + { + crate::logln!("page at address {:#x} already freed", address); + } + } + + pub fn print_memusage(&self, level: usize) + { + + crate::logln!("[INFO] free mem: {}KiB", self.free_mem / 1024); + crate::logln!("[INFO] used mem: {}KiB", self.locked_mem / 1024); + if level >= 1 + { + crate::logln!("[INFO] reserved mem: {}KiB", self.reserved_mem / 1024); + } + if level >= 2 + { + crate::logln!("[INFO] reserved pages: {} pages", self.reserved_mem / 4096); + crate::logln!("[INFO] used pages: {} pages", self.locked_mem / 4096); + } + if level >= 3 + { + crate::logln!("excepted levels for print_memusage() are 0, 1 or 2."); + } + } + + fn reserve_mem(&mut self, index: usize, len: usize) + { + for i in 0..len + { + if self.bitmap[index + i] == false + { + self.bitmap.set(index + i, true); + self.reserved_mem += 4096; + self.free_mem -= 4096; + } + } + } + + fn unreserve_mem(&mut self, index: usize, len: usize) + { + for i in 0..len + { + self.bitmap.set(index + i, false); + self.reserved_mem -= 4096; + self.free_mem += 4096; + } + } + fn lock_pages(&mut self, index: usize, len: usize) + { + for i in 0..len + { + self.lock_page(index + i); + } + } + + fn lock_page(&mut self, index: usize) + { + self.bitmap.set(index, true); + self.locked_mem += 4096; + self.free_mem -= 4096; + } + + fn unlock_page(&mut self, index: usize) + { + if self.bitmap[index] == true + { + crate::logln!("unlocking page {}", index); + self.bitmap.set(index, false); + self.free_mem += 4096; + self.locked_mem -= 4096; + } + else + { + crate::logln!("page {} already unlocked", index); + } + } + + fn unlock_pages(&mut self, index: usize, len: usize) + { + for i in 0..len + { + self.unlock_page(index + i); + } + } + + fn init_bitmap(&mut self, b: usize) + { + let bitmap_size = self.reserved_mem / 4096; + crate::logln!("[INFO] bitmap location: {:#x}", b); + + unsafe + { + self.bitmap = tools::Bitmap + { + buffer: core::slice::from_raw_parts_mut (b as *mut u8, (bitmap_size / 8) + 8), + size: bitmap_size, + }; + + self.bitmap.erase(); + // self.bitmap.debug_print(256); + } + } +} diff --git a/src/multiboot.rs b/src/multiboot.rs index f28af67..c85b0bb 100644 --- a/src/multiboot.rs +++ b/src/multiboot.rs @@ -1,7 +1,12 @@ use crate::log; use crate::logln; -use crate::utilities; +use crate::tools; use crate::ok_fail; +use core::slice; +use core::mem::size_of; + +pub static mut MULTIBOOT_MMAP: *const MultibootTagMmap = core::ptr::null(); +pub static mut MULTIBOOT_MMAP_ENTRIES: usize = 0; const BOOTLOADER_MAGIC: u32 = 0x36d76289; @@ -56,7 +61,56 @@ impl MultibootTagString { unsafe { - utilities::from_c_str((&self.str_ptr as *const _) as *const u8) + tools::from_c_str((&self.str_ptr as *const _) as *const u8) + } + } +} + +struct MultibootTagBasicMeminfo +{ + tag_type: u32, + size: u32, + mem_lower: u32, + mem_upper: u32 +} + +// constants for the type inside MultiBootMmapEntry struct +const MULTIBOOT_MEMORY_AVAILABLE: u32 = 1; +const MULTIBOOT_MEMORY_RESERVED: u32 = 2; +const MULTIBOOT_MEMORY_ACPI_RECLAIMABLE: u32 = 3; +const MULTIBOOT_MEMORY_NVS: u32 = 4; +const MULTIBOOT_MEMORY_BADRAM: u32 = 5; +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct MultibootMmapEntry +{ + pub addr: u32, + addr_upper: u32, + pub len: u32, + len_upper: u32, + pub tag_type: u32, + zero: u32 +} + +#[repr(C)] +#[derive(Debug)] +pub struct MultibootTagMmap +{ + + tag_type: u32, + size: u32, + entry_size: u32, + entry_version: u32, + entries_ptr: &'static [MultibootMmapEntry]//u32, // struct *MultibootMmapEntry +} + +impl MultibootTagMmap +{ + pub fn entries(&self, number: usize) -> &'static [MultibootMmapEntry] + { + unsafe + { + slice::from_raw_parts((&self.entries_ptr as *const _) as *const MultibootMmapEntry, number) } } } @@ -186,7 +240,12 @@ pub fn parse(address: u32) -> bool logln!("[INFO] end of multiboot2 information structure"); break }, - _ => {}//println!("found tag of type {} and size {}", type_name((*tag).tag_type), (*tag).size) + MULTIBOOT_TAG_TYPE_MMAP => + { + MULTIBOOT_MMAP = tag as *const MultibootTagMmap; + MULTIBOOT_MMAP_ENTRIES = (*tag).size as usize / size_of::(); + } + _ => {}//crate::println!("found tag of type {} and size {}", type_name((*tag).tag_type), (*tag).size) }; address += ((*tag).size + 7) & !7; diff --git a/src/serial.rs b/src/serial.rs index 4cc3a17..164172c 100644 --- a/src/serial.rs +++ b/src/serial.rs @@ -1,5 +1,5 @@ use core::fmt; -use crate::utilities::{inb, outb}; +use crate::tools::{inb, outb}; #[macro_export] macro_rules! serial_print diff --git a/src/tools.rs b/src/tools.rs new file mode 100644 index 0000000..f0c0254 --- /dev/null +++ b/src/tools.rs @@ -0,0 +1,229 @@ +use core::arch::asm; +use core::slice; + +pub fn shutdown_qemu() +{ + outw(0x604, 0x2000); +} + +#[inline(always)] +pub fn outw(port: u32, value: u16) +{ + unsafe + { + asm!("out dx, ax", in("dx") port, in("ax") value, + options(nomem, nostack, preserves_flags)); + } +} + +#[inline(always)] +pub fn inb(port: u32) -> u8 +{ + let ret: u8; + unsafe + { + asm!("in al, dx", out("al") ret, in("dx") port, + options(nomem, nostack, preserves_flags)); + } + ret +} + +#[inline(always)] +pub fn outb(port: u32, value: u8) +{ + unsafe + { + asm!("out dx, al", in("dx") port, in("al") value, + options(nomem, nostack, preserves_flags)); + } +} + +pub fn get_bit_at(input: u8, n: u8) -> bool +{ + if n < 8 + { + return input & (1 << n) != 0; + } + false +} + +pub unsafe fn strlen(str: *const u8) -> usize +{ + let mut i = 0; + + while *str.add(i) != 0 + { + i += 1; + } + + i +} + +pub unsafe fn from_c_str(ptr: *const u8) -> &'static [u8] +{ + slice::from_raw_parts(ptr, strlen(ptr) + 1) +} + +pub unsafe fn print_memory(ptr: *const u8, n: usize) +{ + let mut i: usize = 0; + + while i < n + { + if i % 16 == 0 + { + crate::log!("{:08x}: ", ptr.add(i) as u32); + } + crate::log!("{:02x?} ", *ptr.add(i)); + i += 1; + if i % 16 == 0 + { + crate::log!(" |"); + for i in i - 16..i + { + let chr = *ptr.add(i); + crate::log!("{}", if chr > 0x1f && chr < 0x7f {chr as char } else { '.' }); + } + crate::log!("|"); + crate::logln!(); + } + else if i % 8 == 0 + { + crate::log!(" "); + } + } + crate::logln!(); +} + +pub unsafe fn print_memory_bin(ptr: *const u8, n: usize) +{ + let mut i: usize = 0; + + while i < n + { + if i % 4 == 0 + { + crate::log!("{:08x}: ", ptr.add(i) as u32); + } + crate::log!("{:08b} ", *ptr.add(i)); + i += 1; + if i % 4 == 0 + { + crate::logln!(); + } + } + crate::logln!(); +} + +#[macro_export] +macro_rules! get_reg +{ + ($reg:expr) => + {{ + let val: u32; + core::arch::asm!(concat!("mov {}, ", $reg), out(reg) val); + val + }} + +} + +#[macro_export] +macro_rules! page_index +{ + ($reg:expr) => + {{ + tools::divide_up($reg, 4096) + }} +} + +pub fn pow(n1: usize, n2: usize) -> usize +{ + let mut r = n1; + + for _ in 1..n2 + { + r = r * n1; + } + + r +} + +pub fn divide_up(dividend: usize, divisor: usize) -> usize +{ + (dividend + divisor - 1) / divisor +} + +pub struct Bitmap +{ + pub buffer: &'static mut[u8], + pub size: usize, // represents the number of bits, one byte = 8 bits +} + +impl core::ops::Index for Bitmap +{ + type Output = bool; + fn index<'a>(&'a self, index: usize) -> &'a bool + { + if self.get(index) + { + return &true; + } + else + { + return &false; + } + } +} + +impl Bitmap +{ + pub fn get(&self, index: usize) -> bool + { + let byte_index: usize = index / 8; + let bit_index: u8 = (index % 8) as u8; + let bit_indexer: u8 = 0b10000000 >> bit_index; + + if self.buffer[byte_index] & bit_indexer > 0 + { + return true; + } + return false; + } + + pub fn set(&mut self, index: usize, value: bool) + { + let byte_index: usize = index / 8; + let bit_index: u8 = (index % 8) as u8; + let bit_indexer: u8 = 0b10000000 >> bit_index; + + self.buffer[byte_index] &= !bit_indexer; + if value + { + self.buffer[byte_index] |= bit_indexer; + } + } + pub fn debug_print(&self, len: usize) + { + if len == 0 + { + for i in 0..self.size + { + crate::logln!("{}", self.get(i)); + } + } + else + { + for i in 0..len + { + crate::logln!("{}", self.get(i)); + } + } + } + pub fn erase(&mut self) + { + for i in 0..self.size + { + self.set(i, true); + } + } +} diff --git a/src/tty/basic_commands.rs b/src/tty/basic_commands.rs index b9a3696..c1de7a0 100644 --- a/src/tty/basic_commands.rs +++ b/src/tty/basic_commands.rs @@ -1,5 +1,5 @@ use core::arch::asm; -use crate::utilities; +use crate::tools; use crate::vga; pub fn execute(command: &str) @@ -60,7 +60,7 @@ fn clear() fn halt() { - utilities::shutdown_qemu(); + tools::shutdown_qemu(); } fn reboot() @@ -96,11 +96,11 @@ fn printmem_at(address: *const u8, binary: bool) { if binary { - utilities::print_memory_bin(address, 256); + tools::print_memory_bin(address, 256); } else { - utilities::print_memory(address, 256); + tools::print_memory(address, 256); } } } @@ -109,7 +109,7 @@ fn print_stack() { unsafe { - utilities::print_memory(crate::get_reg!("esp") as *const u8, 10 * 16); + tools::print_memory(crate::get_reg!("esp") as *const u8, 10 * 16); } } diff --git a/src/utilities.rs b/src/utilities.rs deleted file mode 100644 index b0ed081..0000000 --- a/src/utilities.rs +++ /dev/null @@ -1,127 +0,0 @@ -use core::arch::asm; -use core::slice; - -pub fn shutdown_qemu() -{ - outw(0x604, 0x2000); -} - -#[inline(always)] -pub fn outw(port: u32, value: u16) -{ - unsafe - { - asm!("out dx, ax", in("dx") port, in("ax") value, - options(nomem, nostack, preserves_flags)); - } -} - -#[inline(always)] -pub fn inb(port: u32) -> u8 -{ - let ret: u8; - unsafe - { - asm!("in al, dx", out("al") ret, in("dx") port, - options(nomem, nostack, preserves_flags)); - } - ret -} - -#[inline(always)] -pub fn outb(port: u32, value: u8) -{ - unsafe - { - asm!("out dx, al", in("dx") port, in("al") value, - options(nomem, nostack, preserves_flags)); - } -} - -pub fn get_bit_at(input: u8, n: u8) -> bool -{ - if n < 8 - { - return input & (1 << n) != 0; - } - false -} - -pub unsafe fn strlen(str: *const u8) -> usize -{ - let mut i = 0; - - while *str.add(i) != 0 - { - i += 1; - } - - i -} - -pub unsafe fn from_c_str(ptr: *const u8) -> &'static [u8] -{ - slice::from_raw_parts(ptr, strlen(ptr) + 1) -} - -pub unsafe fn print_memory(ptr: *const u8, n: usize) -{ - let mut i: usize = 0; - - while i < n - { - if i % 16 == 0 - { - crate::log!("{:08x}: ", ptr.add(i) as u32); - } - crate::log!("{:02x?} ", *ptr.add(i)); - i += 1; - if i % 16 == 0 - { - crate::log!(" |"); - for i in i - 16..i - { - let chr = *ptr.add(i); - crate::log!("{}", if chr > 0x1f && chr < 0x7f {chr as char } else { '.' }); - } - crate::log!("|"); - crate::logln!(); - } - else if i % 8 == 0 - { - crate::log!(" "); - } - } - crate::logln!(); -} - -pub unsafe fn print_memory_bin(ptr: *const u8, n: usize) -{ - let mut i: usize = 0; - - while i < n - { - if i % 4 == 0 - { - crate::log!("{:08x}: ", ptr.add(i) as u32); - } - crate::log!("{:08b} ", *ptr.add(i)); - i += 1; - if i % 4 == 0 - { - crate::logln!(); - } - } - crate::logln!(); -} - -#[macro_export] -macro_rules! get_reg -{ - ($reg:expr) => - {{ - let val: u32; - core::arch::asm!(concat!("mov {}, ", $reg), out(reg) val); - val - }} -} diff --git a/src/vga/cursor.rs b/src/vga/cursor.rs index fe7c587..14c2465 100644 --- a/src/vga/cursor.rs +++ b/src/vga/cursor.rs @@ -1,4 +1,4 @@ -use crate::utilities::{inb, outb}; +use crate::tools::{inb, outb}; use crate::vga::BUFFER_WIDTH; const CRT_ADDR_REG: u32 = 0x3D4;