diff --git a/src/arch/i686/paging.asm b/src/arch/i686/paging.asm new file mode 100644 index 0000000..a7c18de --- /dev/null +++ b/src/arch/i686/paging.asm @@ -0,0 +1,24 @@ +global load_page_directory +load_page_directory: + push ebp + mov ebp, esp + + mov eax, [8+esp] + mov cr3, eax + + mov esp, ebp + pop ebp + ret + +global enable_paging +enable_paging: + push ebp + mov ebp, esp + + mov eax, cr0 + or eax, 0x80000000 + mov cr0, eax + + mov esp, ebp + pop ebp + ret diff --git a/src/elsos.rs b/src/elsos.rs index a622959..82e28ee 100644 --- a/src/elsos.rs +++ b/src/elsos.rs @@ -5,7 +5,7 @@ #![no_std] #![no_main] -mod tools; +mod ferramenta; mod vga; mod keyboard; mod tty; @@ -13,6 +13,7 @@ mod multiboot; mod serial; mod gdt; mod memory; +mod libc; use core::panic::PanicInfo; @@ -44,8 +45,7 @@ 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); } + unsafe { crate::memory::init(MULTIBOOT_MMAP, MULTIBOOT_MMAP_ENTRIES); } init_serial(); logln!("\n"); logln!(" ::: :::::::: __ __ __ _ ____ ____ "); diff --git a/src/tools.rs b/src/ferramenta.rs similarity index 90% rename from src/tools.rs rename to src/ferramenta.rs index f0c0254..031ef4d 100644 --- a/src/tools.rs +++ b/src/ferramenta.rs @@ -38,9 +38,9 @@ pub fn outb(port: u32, value: u8) } } -pub fn get_bit_at(input: u8, n: u8) -> bool +pub fn get_bit_at(input: u32, n: u8) -> bool { - if n < 8 + if n < 32 { return input & (1 << n) != 0; } @@ -132,7 +132,7 @@ macro_rules! page_index { ($reg:expr) => {{ - tools::divide_up($reg, 4096) + ferramenta::divide_up($reg, 4096) }} } @@ -227,3 +227,20 @@ impl Bitmap } } } + +pub fn set_bit(var: &mut u32, value: bool, bit: u8) +{ + if value + { + *var |= (value as u32) << bit; + } + else + { + *var &= !(!value as u32) << bit; + } +} + +pub fn align(val: usize, bound: usize) -> usize +{ + val + bound - 1 & !(bound - 1) +} diff --git a/src/gdt.rs b/src/gdt.rs index 2dc50c5..3392b7c 100644 --- a/src/gdt.rs +++ b/src/gdt.rs @@ -1,6 +1,8 @@ // using https://wiki.osdev.org/Global_Descriptor_Table#Segment_Descriptor to fill the values use core::mem::size_of; +use core::ffi::c_void; +use crate::libc; #[repr(C, packed)] struct gdt_ptr @@ -102,7 +104,6 @@ static mut GDT_TABLE: gdt = gdt extern "C" { fn _gdt_flush(); - fn memcpy(dst: *const u8, src: *const u8, size: usize); } #[no_mangle] @@ -117,7 +118,7 @@ pub fn init_gdt() let size = size_of::() - 1; unsafe { - memcpy(0x800 as *const u8, (&GDT_TABLE as *const _) as *const u8, size); + libc::memcpy(0x800 as *mut c_void, (&GDT_TABLE as *const _) as *const c_void, size); _gp.limit = size as u16; _gdt_flush(); } diff --git a/src/keyboard/mod.rs b/src/keyboard/mod.rs index 56d5bb2..0778487 100644 --- a/src/keyboard/mod.rs +++ b/src/keyboard/mod.rs @@ -1,5 +1,5 @@ use crate::tty; -use crate::tools; +use crate::ferramenta; mod azerty; mod qwerty; @@ -54,7 +54,7 @@ pub fn get_scancodes() let mut scancode: u8 = 0; loop { - let new_scancode = tools::inb(KEYBOARD_DATA); + let new_scancode = ferramenta::inb(KEYBOARD_DATA); if new_scancode == scancode { diff --git a/src/libc/libc.h b/src/libc/libc.h index 995f146..b07b659 100644 --- a/src/libc/libc.h +++ b/src/libc/libc.h @@ -4,6 +4,6 @@ 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); +int memcmp(const void *s1, const void *s2, size_t n); #endif diff --git a/src/libc/mod.rs b/src/libc/mod.rs index 5cff0ba..708a828 100644 --- a/src/libc/mod.rs +++ b/src/libc/mod.rs @@ -4,4 +4,5 @@ extern "C" { pub fn memcpy(dest: *mut c_void, src: *const c_void, n: usize) -> *mut c_void; pub fn memmove(dest: *mut c_void, src: *const c_void, n: usize) -> *mut c_void; + pub fn memset(dest: *mut c_void, val: usize, len: usize) -> *mut c_void; } diff --git a/src/memory/mod.rs b/src/memory/mod.rs index 3589c21..8129775 100644 --- a/src/memory/mod.rs +++ b/src/memory/mod.rs @@ -1,13 +1,10 @@ -pub mod pageframe; +mod pageframe; +mod pagetable; +mod page; -use core::ffi::c_void; use crate::multiboot::MultibootTagMmap; -extern "C" -{ - static _kernel_start: c_void; - static _kernel_end: c_void; -} +static PAGE_SIZE: usize = 4096; pub fn get_mem_size(mmap: *const MultibootTagMmap, mmap_size: usize) -> usize { @@ -25,26 +22,47 @@ pub fn get_mem_size(mmap: *const MultibootTagMmap, mmap_size: usize) -> usize } 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); + panic!("This version of elsOS is in 32 bit, it only supports {}MiB of RAM, you have {}MiB 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 +pub fn init(mmap: *const MultibootTagMmap, mmap_size: usize) { - let mut largest_free_mem_seg: usize = 0; - let mut largest_free_mem_seg_size: usize = 0; + let alloc: &mut pageframe::Allocator = pageframe::Allocator::shared(); + alloc.read_grub_mmap(mmap, mmap_size); + + let page_directory_addr = alloc.request_free_page(); + let mut pt_manager = pagetable::Manager::new(page_directory_addr); + + id_map(&mut pt_manager); 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; - } - } + load_page_directory(page_directory_addr as *const page::DirectoryEntry); + enable_paging(); + } +} + +fn id_map(pt_manager: &mut pagetable::Manager) +{ + for i in 0..1024 + { + pt_manager.memory_map(i * PAGE_SIZE, i * PAGE_SIZE); + pageframe::Allocator::shared().lock_page(i); } - largest_free_mem_seg +} + +extern "C" +{ + fn load_page_directory(address: *const page::DirectoryEntry); + fn enable_paging(); +} + +pub fn page_map_indexer(v_addr: usize) -> (usize, usize) +{ + let pdindex = v_addr >> 22; + let ptindex = v_addr >> 12 & 0x03FF; + + return (pdindex, ptindex); } diff --git a/src/memory/page.rs b/src/memory/page.rs new file mode 100644 index 0000000..ca852d4 --- /dev/null +++ b/src/memory/page.rs @@ -0,0 +1,339 @@ +use crate::ferramenta; + +#[repr(C)] +pub struct DirectoryEntry +{ + pub value: u32 +} + +impl core::fmt::Debug for DirectoryEntry +{ + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result + { + f.debug_struct("PageDirectoryEntry") + .field("value", &self.value) + .field("addr", &self.get_addr()) + .field("flags", &self.get_flags()) + .field("ps", &self.get_ps()) + .field("flag2", &self.get_flag2()) + .field("accessed", &self.get_accessed()) + .field("pcd", &self.get_pcd()) + .field("pwt", &self.get_pwt()) + .field("us", &self.get_us()) + .field("rw", &self.get_rw()) + .field("present", &self.get_present()) + .finish() + } +} + +impl DirectoryEntry +{ + // Bits 31-12 represents the address to the PageTableDirectory. + pub fn get_addr(&self) -> u32 + { + self.value & 0xfffff000 + } + pub fn set_addr(&mut self, addr: u32) + { + self.value &= 0xfff; + self.value |= addr; + } + + // Bits 11-8 are available for us to do whatever we want. + pub fn get_flags(&self) -> u8 + { + ((self.value << 20) >> 28) as u8 + } + pub fn set_flags(&mut self, flags: u8) + { + self.value &= 0xffff_f0ff; + self.value |= (flags as u32) << 8; + } + + // Bit 7 + // PS, or 'Page Size' stores t-he page size for that specific entry. + // If the bit is set, then the PDE maps to a page that is 4 MiB in size. + // Otherwise, it maps to a 4 KiB page table. Please note that 4-MiB pages + // require PSE to be enabled. In our case, it will be 0. + pub fn get_ps(&self) -> bool + { + ferramenta::get_bit_at(self.value, 7) + } + pub fn set_ps(&mut self, value: bool) + { + ferramenta::set_bit(&mut self.value, value, 7); + } + + + // Bit 6 is available for us to do whatever we want. + pub fn get_flag2(&self) -> bool + { + ferramenta::get_bit_at(self.value, 6) + } + pub fn set_flag2(&mut self, value: bool) + { + ferramenta::set_bit(&mut self.value, value, 6); + } + + // Bit 5 + // 'Accessed' is used to discover whether a PDE or PTE was read during + // virtual address translation. If it has, then the bit is set, otherwise, + // it is not. Note that, this bit will not be cleared by the CPU, + // so that burden falls on the OS (if it needs this bit at all). + pub fn get_accessed(&self) -> bool + { + ferramenta::get_bit_at(self.value, 5) + } + pub fn set_accessed(&mut self, value: bool) + { + ferramenta::set_bit(&mut self.value, value, 5); + } + + // Bit 4 + // PCD, is the 'Cache Disable' bit. If the bit is set, the page will not be + // cached. Otherwise, it will be. + pub fn get_pcd(&self) -> bool + { + ferramenta::get_bit_at(self.value, 4) + } + pub fn set_pcd(&mut self, value: bool) + { + ferramenta::set_bit(&mut self.value, value, 4); + } + + // Bit 3 + // PWT, controls Write-Through' abilities of the page. If the bit is set, + // write-through caching is enabled. If not, then write-back is enabled + // instead. + pub fn get_pwt(&self) -> bool + { + ferramenta::get_bit_at(self.value, 3) + } + pub fn set_pwt(&mut self, value: bool) + { + ferramenta::set_bit(&mut self.value, value, 3); + } + + // Bit 2 + // The 'User/Supervisor' bit, controls access to the page based on privilege + // level. If the bit is set, then the page may be accessed by all; + // if the bit is not set, however, only the supervisor can access it. + // For a page directory entry, the user bit controls access to all the pages + // referenced by the page directory entry. T + // herefore if you wish to make a page a user page, you must set the user + // bit in the relevant page directory entry as well as the page table entry + pub fn get_us(&self) -> bool + { + ferramenta::get_bit_at(self.value, 2) + } + pub fn set_us(&mut self, value: bool) + { + ferramenta::set_bit(&mut self.value, value, 2); + } + + // Bit 1 + // The 'Read/Write' permissions flag. If the bit is set, the page is + // read/write. Otherwise when it is not set, the page is read-only. + // The WP bit in CR0 determines if this is only applied to userland, + // always giving the kernel write access (the default) or both userland and + // the kernel (see Intel Manuals 3A 2-20). + pub fn get_rw(&self) -> bool + { + ferramenta::get_bit_at(self.value, 1) + } + pub fn set_rw(&mut self, value: bool) + { + ferramenta::set_bit(&mut self.value, value, 1); + } + + // Bit 0 + // If the bit is set, the page is actually in physical memory at the moment. + // For example, when a page is swapped out, it is not in physical memory and + // therefore not 'Present'. + // If a page is called, but not present, a page fault will occur, + // and the OS should handle it. + pub fn get_present(&self) -> bool + { + ferramenta::get_bit_at(self.value, 0) + } + pub fn set_present(&mut self, value: bool) + { + ferramenta::set_bit(&mut self.value, value, 0); + } +} + +#[repr(C)] +pub struct TableEntry +{ + pub value: u32 +} + +impl core::fmt::Debug for TableEntry +{ + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result + { + f.debug_struct("PageDirectoryEntry") + .field("value", &self.value) + .field("addr", &self.get_addr()) + .field("flags", &self.get_flags()) + .field("global", &self.get_global()) + .field("pat", &self.get_pat()) + .field("dirty", &self.get_dirty()) + .field("accessed", &self.get_accessed()) + .field("pcd", &self.get_pcd()) + .field("pwt", &self.get_pwt()) + .field("us", &self.get_us()) + .field("rw", &self.get_rw()) + .field("present", &self.get_present()) + .finish() + } +} + +impl TableEntry +{ + // Bits 31-12 represents the address to the PageTableEntry. + pub fn get_addr(&self) -> u32 + { + self.value & 0xfffff000 + } + + pub fn set_addr(&mut self, addr: u32) + { + self.value &= 0xfff; + self.value |= addr; + } + + // Bits 11-9 are available for us to do whatever we want. + pub fn get_flags(&self) -> u8 + { + ((self.value << 20) >> 29) as u8 + } + pub fn set_flags(&mut self, flags: u8) + { + self.value &= 0b1111_1111_1111_1111_1111_1000_1111_1111; + self.value |= (flags as u32) << 8; + } + + // Bit 8 + // Global tells the processor not to invalidate the TLB entry corresponding + // to the page upon a MOV to CR3 instruction. Bit 7 (PGE) in CR4 must be set + // to enable global pages. + pub fn get_global(&self) -> bool + { + ferramenta::get_bit_at(self.value, 8) + } + pub fn set_global(&mut self, value: bool) + { + ferramenta::set_bit(&mut self.value, value, 8); + } + + // Bit 7 + // PAT, or Page Attribute Table. If PAT is supported, then PAT along with + // PCD and PWT shall indicate the memory caching type. Otherwise, + // it is reserved and must be set to 0. + pub fn get_pat(&self) -> bool + { + ferramenta::get_bit_at(self.value, 7) + } + pub fn set_pat(&mut self, value: bool) + { + ferramenta::set_bit(&mut self.value, value, 7); + } + + // Bit 6 + // 'Dirty' is used to determine whether a page has been written to. + pub fn get_dirty(&self) -> bool + { + ferramenta::get_bit_at(self.value, 6) + } + pub fn set_dirty(&mut self, value: bool) + { + ferramenta::set_bit(&mut self.value, value, 6); + } + + // Bit 5 + // 'Accessed' is used to discover whether a PDE or PTE was read during + // virtual address translation. If it has, then the bit is set, otherwise, + // it is not. Note that, this bit will not be cleared by the CPU, + // so that burden falls on the OS (if it needs this bit at all). + pub fn get_accessed(&self) -> bool + { + ferramenta::get_bit_at(self.value, 5) + } + pub fn set_accessed(&mut self, value: bool) + { + ferramenta::set_bit(&mut self.value, value, 5); + } + + // Bit 4 + // PCD, is the 'Cache Disable' bit. If the bit is set, the page will not be + // cached. Otherwise, it will be. + pub fn get_pcd(&self) -> bool + { + ferramenta::get_bit_at(self.value, 4) + } + pub fn set_pcd(&mut self, value: bool) + { + ferramenta::set_bit(&mut self.value, value, 4); + } + + // Bit 3 + // PWT, controls Write-Through' abilities of the page. If the bit is set, + // write-through caching is enabled. If not, then write-back is enabled + // instead. + pub fn get_pwt(&self) -> bool + { + ferramenta::get_bit_at(self.value, 3) + } + pub fn set_pwt(&mut self, value: bool) + { + ferramenta::set_bit(&mut self.value, value, 3); + } + + // Bit 2 + // The 'User/Supervisor' bit, controls access to the page based on privilege + // level. If the bit is set, then the page may be accessed by all; + // if the bit is not set, however, only the supervisor can access it. + // For a page directory entry, the user bit controls access to all the pages + // referenced by the page directory entry. T + // herefore if you wish to make a page a user page, you must set the user + // bit in the relevant page directory entry as well as the page table entry + pub fn get_us(&self) -> bool + { + ferramenta::get_bit_at(self.value, 2) + } + pub fn set_us(&mut self, value: bool) + { + ferramenta::set_bit(&mut self.value, value, 2); + } + + // Bit 1 + // The 'Read/Write' permissions flag. If the bit is set, the page is + // read/write. Otherwise when it is not set, the page is read-only. + // The WP bit in CR0 determines if this is only applied to userland, + // always giving the kernel write access (the default) or both userland and + // the kernel (see Intel Manuals 3A 2-20). + pub fn get_rw(&self) -> bool + { + ferramenta::get_bit_at(self.value, 1) + } + pub fn set_rw(&mut self, value: bool) + { + ferramenta::set_bit(&mut self.value, value, 1); + } + + // Bit 0 + // If the bit is set, the page is actually in physical memory at the moment. + // For example, when a page is swapped out, it is not in physical memory and + // therefore not 'Present'. + // If a page is called, but not present, a page fault will occur, + // and the OS should handle it. + pub fn get_present(&self) -> bool + { + ferramenta::get_bit_at(self.value, 0) + } + pub fn set_present(&mut self, value: bool) + { + ferramenta::set_bit(&mut self.value, value, 0); + } +} diff --git a/src/memory/pageframe.rs b/src/memory/pageframe.rs index 772f045..f9d9bae 100644 --- a/src/memory/pageframe.rs +++ b/src/memory/pageframe.rs @@ -1,7 +1,8 @@ use crate::multiboot::MultibootTagMmap; -use crate::tools; +use crate::ferramenta; use crate::page_index; use crate::memory::get_mem_size; +use super::PAGE_SIZE; use core::ffi::c_void; @@ -18,21 +19,25 @@ pub struct Allocator pub reserved_mem: usize, pub unusable_mem: u64, initialized: bool, - bitmap: tools::Bitmap, + bitmap: ferramenta::Bitmap, } impl Allocator { - pub fn new() -> Allocator + pub fn shared() -> &'static mut Allocator { - Allocator + static mut ALLOC: 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}, + bitmap: ferramenta::Bitmap {buffer: &mut[] as &'static mut[u8], size: 0}, + }; + unsafe + { + &mut ALLOC } } @@ -56,7 +61,7 @@ impl Allocator 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); + self.init_bitmap(ferramenta::align(kernel_end, 0x1000)); crate::logln!("[INFO] assigned {} pages to bitmap", self.bitmap.size); unsafe { @@ -74,10 +79,11 @@ impl Allocator 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); + crate::logln!("memory start {:#x}", (self.bitmap.buffer as *const _ as *const usize as usize) + self.bitmap.buffer.len()); // 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)); + crate::logln!("free {}KiB used {}KiB reserved {}KiB", self.free_mem / 1024, self.locked_mem / 1024, self.reserved_mem / 1024); } pub fn request_free_page(&mut self) -> usize @@ -118,8 +124,8 @@ impl Allocator } if level >= 2 { - crate::logln!("[INFO] reserved pages: {} pages", self.reserved_mem / 4096); - crate::logln!("[INFO] used pages: {} pages", self.locked_mem / 4096); + crate::logln!("[INFO] reserved pages: {} pages", self.reserved_mem / PAGE_SIZE); + crate::logln!("[INFO] used pages: {} pages", self.locked_mem / PAGE_SIZE); } if level >= 3 { @@ -134,8 +140,8 @@ impl Allocator if self.bitmap[index + i] == false { self.bitmap.set(index + i, true); - self.reserved_mem += 4096; - self.free_mem -= 4096; + self.reserved_mem += PAGE_SIZE; + self.free_mem -= PAGE_SIZE; } } } @@ -145,8 +151,8 @@ impl Allocator for i in 0..len { self.bitmap.set(index + i, false); - self.reserved_mem -= 4096; - self.free_mem += 4096; + self.reserved_mem -= PAGE_SIZE; + self.free_mem += PAGE_SIZE; } } fn lock_pages(&mut self, index: usize, len: usize) @@ -157,11 +163,14 @@ impl Allocator } } - fn lock_page(&mut self, index: usize) + pub fn lock_page(&mut self, index: usize) { - self.bitmap.set(index, true); - self.locked_mem += 4096; - self.free_mem -= 4096; + if self.bitmap[index] == false + { + self.bitmap.set(index, true); + self.locked_mem += PAGE_SIZE; + self.free_mem -= PAGE_SIZE; + } } fn unlock_page(&mut self, index: usize) @@ -170,8 +179,8 @@ impl Allocator { crate::logln!("unlocking page {}", index); self.bitmap.set(index, false); - self.free_mem += 4096; - self.locked_mem -= 4096; + self.free_mem += PAGE_SIZE; + self.locked_mem -= PAGE_SIZE; } else { @@ -189,12 +198,12 @@ impl Allocator fn init_bitmap(&mut self, b: usize) { - let bitmap_size = self.reserved_mem / 4096; + let bitmap_size = self.reserved_mem / PAGE_SIZE; crate::logln!("[INFO] bitmap location: {:#x}", b); unsafe { - self.bitmap = tools::Bitmap + self.bitmap = ferramenta::Bitmap { buffer: core::slice::from_raw_parts_mut (b as *mut u8, (bitmap_size / 8) + 8), size: bitmap_size, diff --git a/src/memory/pagetable.rs b/src/memory/pagetable.rs new file mode 100644 index 0000000..756d566 --- /dev/null +++ b/src/memory/pagetable.rs @@ -0,0 +1,69 @@ +use crate::libc; +use crate::memory::PAGE_SIZE; +use crate::memory::page; +use crate::memory::pageframe; +use crate::memory::page_map_indexer; +use core::ffi::c_void; + +pub struct Manager +{ + pub page_directory: &'static mut [page::DirectoryEntry], +} + +impl Manager +{ + pub fn new(addr: usize) -> Manager + { + unsafe + { + libc::memset(addr as *mut c_void, 0, PAGE_SIZE); + Manager + { + page_directory: core::slice::from_raw_parts_mut(addr as *mut page::DirectoryEntry, 1024) + } + } + } + + fn create_page_directory_entry(&mut self, index: usize) + { + let page_directory_entry = &mut self.page_directory[index]; + + if !page_directory_entry.get_present() + { + let alloc = pageframe::Allocator::shared(); + let page_table_addr = alloc.request_free_page(); + unsafe + { + libc::memset(page_table_addr as *mut c_void, 0, PAGE_SIZE); + } + page_directory_entry.set_addr(page_table_addr as u32); + page_directory_entry.set_rw(true); + page_directory_entry.set_present(true); + } + } + + fn create_page_table_entry(&mut self, page_directory_index: usize, page_table_index: usize, physical_address: usize) + { + let page_directory_entry = &mut self.page_directory[page_directory_index]; + let page_table = unsafe + { + core::slice::from_raw_parts_mut(page_directory_entry.get_addr() as *mut page::TableEntry, 1024) + }; + let page_table_entry = &mut page_table[page_table_index]; + + if !page_table_entry.get_present() + { + page_table_entry.set_addr(physical_address as u32); + page_table_entry.set_rw(true); + page_table_entry.set_present(true); + } + } + + pub fn memory_map(&mut self, v_addr: usize, phys_addr: usize) + { + let (pdi, pti): (usize, usize) = page_map_indexer(v_addr); + + self.create_page_directory_entry(pdi); + self.create_page_table_entry(pdi, pti, phys_addr); + } +} diff --git a/src/multiboot.rs b/src/multiboot.rs index c85b0bb..07d1c62 100644 --- a/src/multiboot.rs +++ b/src/multiboot.rs @@ -1,6 +1,6 @@ use crate::log; use crate::logln; -use crate::tools; +use crate::ferramenta; use crate::ok_fail; use core::slice; use core::mem::size_of; @@ -61,7 +61,7 @@ impl MultibootTagString { unsafe { - tools::from_c_str((&self.str_ptr as *const _) as *const u8) + ferramenta::from_c_str((&self.str_ptr as *const _) as *const u8) } } } @@ -248,7 +248,7 @@ pub fn parse(address: u32) -> bool _ => {}//crate::println!("found tag of type {} and size {}", type_name((*tag).tag_type), (*tag).size) }; - address += ((*tag).size + 7) & !7; + address += ferramenta::align((*tag).size as usize, 8) as u32; } } diff --git a/src/serial.rs b/src/serial.rs index 164172c..79558b5 100644 --- a/src/serial.rs +++ b/src/serial.rs @@ -1,5 +1,5 @@ use core::fmt; -use crate::tools::{inb, outb}; +use crate::ferramenta::{inb, outb}; #[macro_export] macro_rules! serial_print diff --git a/src/tty/basic_commands.rs b/src/tty/basic_commands.rs index c1de7a0..990829e 100644 --- a/src/tty/basic_commands.rs +++ b/src/tty/basic_commands.rs @@ -1,5 +1,5 @@ use core::arch::asm; -use crate::tools; +use crate::ferramenta; use crate::vga; pub fn execute(command: &str) @@ -60,7 +60,7 @@ fn clear() fn halt() { - tools::shutdown_qemu(); + ferramenta::shutdown_qemu(); } fn reboot() @@ -96,11 +96,11 @@ fn printmem_at(address: *const u8, binary: bool) { if binary { - tools::print_memory_bin(address, 256); + ferramenta::print_memory_bin(address, 256); } else { - tools::print_memory(address, 256); + ferramenta::print_memory(address, 256); } } } @@ -109,7 +109,7 @@ fn print_stack() { unsafe { - tools::print_memory(crate::get_reg!("esp") as *const u8, 10 * 16); + ferramenta::print_memory(crate::get_reg!("esp") as *const u8, 10 * 16); } } diff --git a/src/vga/cursor.rs b/src/vga/cursor.rs index 14c2465..0768387 100644 --- a/src/vga/cursor.rs +++ b/src/vga/cursor.rs @@ -1,4 +1,4 @@ -use crate::tools::{inb, outb}; +use crate::ferramenta::{inb, outb}; use crate::vga::BUFFER_WIDTH; const CRT_ADDR_REG: u32 = 0x3D4;