Commit work

This commit is contained in:
pjht 2023-09-29 15:44:53 -05:00
parent bf09798825
commit 8fd2b83b40
Signed by: pjht
GPG Key ID: CA239FC6934E6F3A
17 changed files with 277 additions and 137 deletions

View File

@ -3,8 +3,8 @@ build-std-features = ["compiler-builtins-mem"]
build-std = ["core", "compiler_builtins", "alloc"] build-std = ["core", "compiler_builtins", "alloc"]
[build] [build]
target = "x86_64-unknown-none.json" target = "x86_64-unknown-none"
rustflags = ["-C", "link-args=--image-base 0xffff800000000000", "-C", "force-unwind-tables", "-C", "link-arg=/home/pjht/projects/os-rust/kernel/eh_frame.ld"] rustflags = ["-C", "link-args=--image-base 0xffff800000000000", "-C", "force-unwind-tables", "-C", "link-args=/home/pjht/projects/os-rust/kernel/eh_frame.ld"]
[target.'cfg(target_os = "none")'] [target.'cfg(target_os = "none")']
runner = "./run.sh" runner = "./run.sh"

8
Cargo.lock generated
View File

@ -38,10 +38,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
[[package]] [[package]]
name = "bootloader" name = "bootloader_api"
version = "0.10.13" version = "0.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "24e13520aa8580a2850fc9f5390dc6753f1062fb66f90e5a61bd5c72b55df731" checksum = "babfb07dea4565842980315ad530a023aa348db43d03dfa104a70fdaca97d48e"
[[package]] [[package]]
name = "cfg-if" name = "cfg-if"
@ -118,7 +118,7 @@ dependencies = [
name = "kernel" name = "kernel"
version = "0.1.0" version = "0.1.0"
dependencies = [ dependencies = [
"bootloader", "bootloader_api",
"crossbeam-queue", "crossbeam-queue",
"elfloader", "elfloader",
"hashbrown", "hashbrown",

View File

@ -8,39 +8,17 @@ x86_64 = { git = "https://github.com/pjht/x86_64", features = ["experimental"] }
tar-no-std = { path = "../tar-no-std" } tar-no-std = { path = "../tar-no-std" }
unwinding = { path = "../unwinding", default-features = false, features = ["personality", "panic", "unwinder", "fde-static", "hide-trace"] } unwinding = { path = "../unwinding", default-features = false, features = ["personality", "panic", "unwinder", "fde-static", "hide-trace"] }
uart_16550 = "0.2.15" uart_16550 = "0.2.18"
spin = "0.9.2" spin = "0.9.4"
linked_list_allocator = "0.9.1" linked_list_allocator = "0.10.4"
elfloader = "0.14.0" elfloader = "0.16.0"
tap = "1.0.1" tap = "1.0.1"
replace_with = { version = "0.1.7", default-features = false, features = ["nightly"] } replace_with = { version = "0.1.7", default-features = false, features = ["nightly"] }
hashbrown = "0.12.0" hashbrown = "0.13.1"
pic8259 = "0.10.2" pic8259 = "0.10.2"
bootloader = "0.10.13" bootloader_api = "0.11.0"
static_assertions = "1.1.0" static_assertions = "1.1.0"
crossbeam-queue = { version = "0.3.4", default-features = false, features = ["alloc"] } crossbeam-queue = { version = "0.3.8", default-features = false, features = ["alloc"] }
slab = { version = "0.4.6", default-features = false } slab = { version = "0.4.7", default-features = false }
intrusive-collections = "0.9.4" intrusive-collections = "0.9.4"
xmas-elf = "0.8.0"
[profile.dev]
panic = "abort"
[profile.release]
panic = "abort"
strip = true
[features]
[package.metadata.bootimage]
run-args = ["-nographic", "-m", "4G", "-device", "isa-debug-exit,iobase=0xf4,iosize=0x04", "--no-reboot", "-hdb", "../ext2.img"]
[package.metadata.bootloader]
map-physical-memory = true
dynamic-range-start = "0xFFFF_8000_0000_0000"
# physical-memory-offset = "0xFFFFFF8000000000"
# kernel-stack-address = "0xFFFFFF7FFFE00000"
# boot-info-address = "0xFFFFFF7FFFC00000"
# kernel-stack-size = 2093056 # 511 pages
[patch.crates-io]
x86_64 = { git = "https://github.com/pjht/x86_64" }

Binary file not shown.

3
run.sh
View File

@ -1,3 +0,0 @@
#! /bin/bash
cd ../simple_boot
cargo run -- $@

View File

@ -1,4 +1,4 @@
use bootloader::boot_info::BootInfo; use bootloader_api::BootInfo;
use core::ops::Deref; use core::ops::Deref;
use spin::Once; use spin::Once;

View File

@ -1,5 +1,5 @@
use crate::{ use crate::{
print, println, dbg, print, println,
virtual_memory::{ASpaceMutex, AddressSpace, ACTIVE_SPACE, KERNEL_SPACE}, virtual_memory::{ASpaceMutex, AddressSpace, ACTIVE_SPACE, KERNEL_SPACE},
INITRD, TASKING, INITRD, TASKING,
}; };
@ -215,6 +215,9 @@ extern "C" fn syscall_handler() {
let mut retval = 0; let mut retval = 0;
let mut retval2 = regs.rcx; let mut retval2 = regs.rcx;
let mut retval3 = regs.rdx; let mut retval3 = regs.rdx;
// if regs.rax == 16 {
// println!("Syscall {}", regs.rax);
// }
match regs.rax { match regs.rax {
0 => { 0 => {
retval = if let Some(chr) = char::from_u32(regs.rcx as u32) { retval = if let Some(chr) = char::from_u32(regs.rcx as u32) {
@ -358,11 +361,16 @@ extern "C" fn syscall_handler() {
let size = regs.rcx as usize; let size = regs.rcx as usize;
let rounded_size = size + (4096 - (size % 4096)); let rounded_size = size + (4096 - (size % 4096));
KERNEL_SPACE.lock().alloc_force_user = true; KERNEL_SPACE.lock().alloc_force_user = true;
let buffer = Box::into_raw( // let buffer = Box::into_raw(
Vec::with_capacity_in(rounded_size, &*KERNEL_SPACE) // Vec::with_capacity_in(rounded_size, &*KERNEL_SPACE)
.tap_mut(|v| v.resize(rounded_size, 0)) // .tap_mut(|v| v.resize(rounded_size, 0))
.into_boxed_slice(), // .into_boxed_slice(),
); // );
let mut buffer = Vec::with_capacity_in(rounded_size, &*KERNEL_SPACE);
// dbg!(KERNEL_SPACE.lock().translate(VirtAddr::new(0xffff_8000_003f_f000)));
buffer.resize(rounded_size, 0);
let buffer = buffer.into_boxed_slice();
let buffer = Box::into_raw(buffer);
KERNEL_SPACE.lock().alloc_force_user = false; KERNEL_SPACE.lock().alloc_force_user = false;
retval = TASKING.lock().data_buffers_mut().insert(buffer) as u64; retval = TASKING.lock().data_buffers_mut().insert(buffer) as u64;
retval2 = buffer as *mut u8 as u64; retval2 = buffer as *mut u8 as u64;
@ -370,6 +378,9 @@ extern "C" fn syscall_handler() {
} }
_ => (), _ => (),
}; };
// if regs.rax == 16 {
// println!("Syscall {} done", regs.rax);
// }
unsafe { unsafe {
asm!( asm!(
"mov rbx, [rip+SYSCALL_REGS+8]", "mov rbx, [rip+SYSCALL_REGS+8]",

View File

@ -1,13 +1,50 @@
use crate::virtual_memory::KERNEL_SPACE; use crate::virtual_memory::KERNEL_SPACE;
use alloc::{alloc::Layout, boxed::Box};
use linked_list_allocator::LockedHeap; use core::{
alloc::{GlobalAlloc, Layout},
ptr::NonNull,
};
use linked_list_allocator::hole::HoleList;
use spin::Mutex;
use x86_64::structures::paging::PageTableFlags;
struct Heap(Mutex<HoleList>);
unsafe impl Send for Heap {}
unsafe impl Sync for Heap {}
unsafe impl GlobalAlloc for Heap {
unsafe fn alloc(&self, layout: Layout) -> *mut u8 {
let mut locked_self = self.0.lock();
let ptr = locked_self
.allocate_first_fit(layout)
.map(|(allocation, _)| allocation.as_ptr())
.unwrap_or_else(|_| {
drop(locked_self);
let num_pages = layout.size().div_ceil(4096) * 2;
unsafe {
self.dealloc(
KERNEL_SPACE.lock().map_free(num_pages, PageTableFlags::empty()).unwrap(),
Layout::from_size_align(num_pages * 4096, 4096).unwrap(),
);
}
self.0
.lock()
.allocate_first_fit(layout)
.map(|(allocation, _)| allocation.as_ptr())
.unwrap()
});
assert!((ptr as usize & (layout.align() - 1)) == 0);
ptr
}
unsafe fn dealloc(&self, ptr: *mut u8, layout: Layout) {
unsafe { self.0.lock().deallocate(NonNull::new_unchecked(ptr), layout) };
}
}
#[global_allocator] #[global_allocator]
static HEAP: LockedHeap = LockedHeap::empty(); static HEAP: Heap = Heap(Mutex::new(HoleList::empty()));
pub fn init() {
HEAP.lock().init_from_slice(Box::leak(Box::new_uninit_slice_in(131_072 * 4, &*KERNEL_SPACE)));
}
#[alloc_error_handler] #[alloc_error_handler]
fn alloc_error_handler(layout: Layout) -> ! { fn alloc_error_handler(layout: Layout) -> ! {

View File

@ -24,32 +24,40 @@ mod start;
mod tasking; mod tasking;
mod virtual_memory; mod virtual_memory;
use simple_loader::SimpleLoader;
use tasking::TASKING;
pub static INITRD: &[u8] = include_bytes!("../initrd.tar");
use elfloader::ElfBinary; use elfloader::ElfBinary;
use simple_loader::SimpleLoader;
use tar_no_std::TarArchiveRef; use tar_no_std::TarArchiveRef;
use tasking::TASKING;
use x86_64::registers::rflags::{self, RFlags}; use x86_64::registers::rflags::{self, RFlags};
pub static INITRD: &[u8] = include_bytes!("../initrd.tar");
pub fn main() { pub fn main() {
dbg!();
let mut rflags_data = rflags::read(); let mut rflags_data = rflags::read();
dbg!();
rflags_data |= RFlags::IOPL_HIGH | RFlags::IOPL_LOW; rflags_data |= RFlags::IOPL_HIGH | RFlags::IOPL_LOW;
dbg!();
unsafe { unsafe {
rflags::write(rflags_data); rflags::write(rflags_data);
} }
dbg!();
gdt::init(); gdt::init();
dbg!();
interrupts::init(); interrupts::init();
kernel_heap::init(); dbg!();
pit::init(100); pit::init(100);
dbg!();
let initrd = TarArchiveRef::new(INITRD); let initrd = TarArchiveRef::new(INITRD);
let init = ElfBinary::new( dbg!();
initrd let init = initrd
.entries() .entries()
.find(|x| x.filename() == *"bin/init") .find(|x| x.filename() == *"bin/init")
.expect("Could not find init in initrd") .expect("Could not find init in initrd")
.data(), .data();
) dbg!();
.expect("Init not an ELF binary"); let init = ElfBinary::new(init).expect("Init not an ELF binary");
dbg!();
TASKING TASKING
.lock() .lock()
.new_process( .new_process(
@ -57,4 +65,5 @@ pub fn main() {
SimpleLoader::load(&init).expect("Failed to load init"), SimpleLoader::load(&init).expect("Failed to load init"),
) )
.expect("Failed to create init process"); .expect("Failed to create init process");
dbg!();
} }

View File

@ -1,5 +1,5 @@
use crate::{bootinfo::BOOTINFO, println, virtual_memory::AsVirt}; use crate::{bootinfo::BOOTINFO, dbg, println, virtual_memory::AsVirt};
use bootloader::boot_info::MemoryRegionKind; use bootloader_api::info::MemoryRegionKind;
use core::mem; use core::mem;
use spin::{Lazy, Mutex}; use spin::{Lazy, Mutex};
use tap::Tap; use tap::Tap;

View File

@ -1,10 +1,14 @@
use crate::virtual_memory::{AddressSpace, PagingError}; use crate::virtual_memory::{AddressSpace, PagingError};
use core::slice; use core::slice;
use elfloader::{ElfBinary, ElfLoader, ElfLoaderErr, Flags, LoadableHeaders, Rela, VAddr, P64}; use elfloader::{
arch::x86_64::RelocationTypes, ElfBinary, ElfLoader, ElfLoaderErr, Flags, LoadableHeaders,
RelocationEntry, RelocationType, VAddr,
};
use x86_64::{ use x86_64::{
structures::paging::{Page, PageTableFlags}, structures::paging::{Page, PageTableFlags},
VirtAddr, VirtAddr,
}; };
#[derive(Debug)] #[derive(Debug)]
pub enum LoadError { pub enum LoadError {
Paging(PagingError), Paging(PagingError),
@ -37,20 +41,60 @@ impl ElfLoader for SimpleLoader {
fn allocate(&mut self, load_headers: LoadableHeaders) -> Result<(), ElfLoaderErr> { fn allocate(&mut self, load_headers: LoadableHeaders) -> Result<(), ElfLoaderErr> {
for header in load_headers { for header in load_headers {
let start_page = Page::containing_address(VirtAddr::new(header.virtual_addr())); let start_page = Page::containing_address(VirtAddr::new(header.virtual_addr()));
let num_pages = (header.mem_size().div_ceil(4096)
+ (header.virtual_addr() & 0xFFF).div_ceil(4096))
as usize;
assert!(
(start_page.start_address().as_u64() + num_pages as u64 * 4096)
>= (header.virtual_addr() + header.mem_size())
);
#[allow(clippy::cast_possible_truncation)] #[allow(clippy::cast_possible_truncation)]
self.0 self.0
.map_assert_unused( .map_only_unused(start_page, num_pages, PageTableFlags::USER_ACCESSIBLE)
start_page,
((header.mem_size() + (header.virtual_addr() % 4096)).div_ceil(4096)) as usize,
PageTableFlags::USER_ACCESSIBLE,
)
.expect("Unable to map region"); .expect("Unable to map region");
} }
Ok(()) Ok(())
} }
fn relocate(&mut self, _entry: &Rela<P64>) -> Result<(), ElfLoaderErr> { fn relocate(&mut self, entry: RelocationEntry) -> Result<(), ElfLoaderErr> {
Err(ElfLoaderErr::UnsupportedRelocationEntry) let rel = match entry.rtype {
RelocationType::x86_64(rel) => rel,
_ => panic!("Non x86_64 relocation"),
};
match rel {
RelocationTypes::R_AMD64_NONE => (),
RelocationTypes::R_AMD64_64 => todo!(),
RelocationTypes::R_AMD64_PC32 => todo!(),
RelocationTypes::R_AMD64_GOT32 => todo!(),
RelocationTypes::R_AMD64_PLT32 => todo!(),
RelocationTypes::R_AMD64_COPY => todo!(),
RelocationTypes::R_AMD64_GLOB_DAT => todo!(),
RelocationTypes::R_AMD64_JMP_SLOT => todo!(),
RelocationTypes::R_AMD64_RELATIVE => {
self.0.run(|| unsafe {
let ptr = entry.offset as *mut u64;
ptr.write(entry.addend.unwrap());
});
}
RelocationTypes::R_AMD64_GOTPCREL => todo!(),
RelocationTypes::R_AMD64_32 => todo!(),
RelocationTypes::R_AMD64_32S => todo!(),
RelocationTypes::R_AMD64_16 => todo!(),
RelocationTypes::R_AMD64_PC16 => todo!(),
RelocationTypes::R_AMD64_8 => todo!(),
RelocationTypes::R_AMD64_PC8 => todo!(),
RelocationTypes::R_AMD64_DTPMOD64 => todo!(),
RelocationTypes::R_AMD64_DTPOFF64 => todo!(),
RelocationTypes::R_AMD64_TPOFF64 => todo!(),
RelocationTypes::R_AMD64_TLSGD => todo!(),
RelocationTypes::R_AMD64_TLSLD => todo!(),
RelocationTypes::R_AMD64_DTPOFF32 => todo!(),
RelocationTypes::R_AMD64_GOTTPOFF => todo!(),
RelocationTypes::R_AMD64_TPOFF32 => todo!(),
RelocationTypes::Unknown(_) => todo!(),
}
// Err(ElfLoaderErr::UnsupportedRelocationEntry)
Ok(())
} }
fn load(&mut self, _flags: Flags, base: VAddr, region: &[u8]) -> Result<(), ElfLoaderErr> { fn load(&mut self, _flags: Flags, base: VAddr, region: &[u8]) -> Result<(), ElfLoaderErr> {

View File

@ -1,7 +1,14 @@
use crate::{bootinfo::BOOTINFO, main, tasking::TASKING}; use crate::{bootinfo::BOOTINFO, main, tasking::TASKING};
use bootloader::{boot_info::BootInfo, entry_point}; use bootloader_api::{config::Mapping, entry_point, BootInfo, BootloaderConfig};
entry_point!(start); pub static BOOTLOADER_CONFIG: BootloaderConfig = {
let mut config = BootloaderConfig::new_default();
config.mappings.physical_memory = Some(Mapping::Dynamic);
config.mappings.dynamic_range_start = Some(0xFFFF_8000_0000_0000);
config
};
entry_point!(start, config = &BOOTLOADER_CONFIG);
#[allow(clippy::missing_panics_doc)] #[allow(clippy::missing_panics_doc)]
#[allow(clippy::missing_errors_doc)] #[allow(clippy::missing_errors_doc)]

View File

@ -1,6 +1,6 @@
mod holes; mod holes;
use crate::{bootinfo::BOOTINFO, physical_memory::PHYSICAL_MEMORY}; use crate::{bootinfo::BOOTINFO, dbg, physical_memory::PHYSICAL_MEMORY, println};
use alloc::alloc::{AllocError, Allocator, Layout}; use alloc::alloc::{AllocError, Allocator, Layout};
use core::{fmt, ops::Deref, ptr::NonNull, slice}; use core::{fmt, ops::Deref, ptr::NonNull, slice};
use replace_with::replace_with_or_abort; use replace_with::replace_with_or_abort;
@ -132,7 +132,8 @@ pub static KERNEL_SPACE: Lazy<ASpaceMutex> = Lazy::new(|| {
} }
for i in 256..512 { for i in 256..512 {
if table[i].flags().contains(PageTableFlags::PRESENT) { if table[i].flags().contains(PageTableFlags::PRESENT) {
let new_flags = table[i].flags() & !PageTableFlags::USER_ACCESSIBLE; let new_flags =
table[i].flags() | PageTableFlags::WRITABLE | PageTableFlags::USER_ACCESSIBLE;
table[i].set_flags(new_flags); table[i].set_flags(new_flags);
} else { } else {
// SAFETY: We initialize the newly allocated table before we make a reference to it, so // SAFETY: We initialize the newly allocated table before we make a reference to it, so
@ -144,7 +145,9 @@ pub static KERNEL_SPACE: Lazy<ASpaceMutex> = Lazy::new(|| {
new_child.write(PageTable::new()); new_child.write(PageTable::new());
new_child_phys new_child_phys
}, },
PageTableFlags::PRESENT | PageTableFlags::WRITABLE, PageTableFlags::PRESENT
| PageTableFlags::WRITABLE
| PageTableFlags::USER_ACCESSIBLE,
); );
} }
} }
@ -190,7 +193,6 @@ impl AddressSpace {
} }
} }
#[allow(unused)]
pub fn activate(self) -> Self { pub fn activate(self) -> Self {
// This assert should never fire, as the only address space with the is_kernel bool set is // This assert should never fire, as the only address space with the is_kernel bool set is
// stored in the KERNEL_SPACE_INTERNAL static, which is a Mutex, and you can never get // stored in the KERNEL_SPACE_INTERNAL static, which is a Mutex, and you can never get
@ -213,7 +215,6 @@ impl AddressSpace {
} }
} }
#[allow(unused)]
fn check_request_unmapped(&self, start: Page, length: usize) -> Result<(), PagingError> { fn check_request_unmapped(&self, start: Page, length: usize) -> Result<(), PagingError> {
for page in Page::range(start, start + length as u64) { for page in Page::range(start, start + length as u64) {
if self.translate_addr(page.start_address()).is_some() { if self.translate_addr(page.start_address()).is_some() {
@ -230,7 +231,6 @@ impl AddressSpace {
/// let address_space = AddressSpace::new(); /// let address_space = AddressSpace::new();
/// address_space.run(|| {/* your closure here */}); /// address_space.run(|| {/* your closure here */});
/// ``` /// ```
#[allow(unused)]
pub fn run<F: FnOnce()>(&mut self, func: F) { pub fn run<F: FnOnce()>(&mut self, func: F) {
replace_with_or_abort(self, |cl_self| { replace_with_or_abort(self, |cl_self| {
let old_space = cl_self.activate(); let old_space = cl_self.activate();
@ -272,22 +272,22 @@ impl AddressSpace {
flags: PageTableFlags, flags: PageTableFlags,
) -> Result<*mut u8, PagingError> { ) -> Result<*mut u8, PagingError> {
self.check_request_valid(page, num_pages)?; self.check_request_valid(page, num_pages)?;
unsafe { for (page, frame) in (PageRange { start: page, end: page + num_pages as u64 })
self.mapper .zip(PhysFrameRange { start: phys_frame, end: phys_frame + num_pages as u64 })
.map_to_range_with_table_flags( {
PageRange { start: page, end: page + num_pages as u64 }, unsafe {
PhysFrameRange { start: phys_frame, end: phys_frame + num_pages as u64 }, self.mapper
flags | PageTableFlags::PRESENT, .map_to_with_table_flags(
PageTableFlags::PRESENT page,
| PageTableFlags::WRITABLE frame,
| PageTableFlags::USER_ACCESSIBLE, flags | PageTableFlags::PRESENT,
&mut *PHYSICAL_MEMORY.lock(), PageTableFlags::PRESENT
) | PageTableFlags::WRITABLE
.map_err(|(err, flush_range)| { | PageTableFlags::USER_ACCESSIBLE,
flush_range.flush_range(); &mut *PHYSICAL_MEMORY.lock(),
err )?
})? .flush();
.flush_range(); }
} }
Ok(page.start_address().as_mut_ptr()) Ok(page.start_address().as_mut_ptr())
} }
@ -319,22 +319,46 @@ impl AddressSpace {
flags: PageTableFlags, flags: PageTableFlags,
) -> Result<*mut u8, PagingError> { ) -> Result<*mut u8, PagingError> {
self.check_request_valid(page, num_pages)?; self.check_request_valid(page, num_pages)?;
unsafe { for page in (PageRange { start: page, end: page + num_pages as u64 }) {
self.mapper unsafe {
.map_range_with_table_flags( let mut phys_mem = PHYSICAL_MEMORY.lock();
PageRange { start: page, end: page + num_pages as u64 }, let frame = phys_mem.allocate_frame().unwrap();
flags | PageTableFlags::PRESENT | PageTableFlags::WRITABLE, self.mapper
PageTableFlags::PRESENT .map_to_with_table_flags(
| PageTableFlags::WRITABLE page,
| PageTableFlags::USER_ACCESSIBLE, frame,
&mut *PHYSICAL_MEMORY.lock(), flags
) | PageTableFlags::PRESENT
.map_err(|(err, flush_range)| { | PageTableFlags::WRITABLE
flush_range.flush_range(); | if self.alloc_force_user {
err PageTableFlags::USER_ACCESSIBLE
})? } else {
.flush_range(); PageTableFlags::empty()
},
PageTableFlags::PRESENT
| PageTableFlags::WRITABLE
| PageTableFlags::USER_ACCESSIBLE,
&mut *phys_mem,
)?
.flush();
}
} }
// unsafe {
// self.mapper
// .map_range_with_table_flags(
// PageRange { start: page, end: page + num_pages as u64 },
// flags | PageTableFlags::PRESENT | PageTableFlags::WRITABLE,
// PageTableFlags::PRESENT
// | PageTableFlags::WRITABLE
// | PageTableFlags::USER_ACCESSIBLE,
// &mut *PHYSICAL_MEMORY.lock(),
// )
// .map_err(|(err, flush_range)| {
// flush_range.flush_range();
// err
// })?
// .flush_range();
// }
Ok(page.start_address().as_mut_ptr()) Ok(page.start_address().as_mut_ptr())
} }
@ -383,6 +407,42 @@ impl AddressSpace {
unsafe { self.map(page, num_pages, flags) } unsafe { self.map(page, num_pages, flags) }
} }
/// Same behavior as `map`, but only maps unmapped pages, and
/// thus is safe.
#[allow(unused)]
pub fn map_only_unused(
&mut self,
page: Page,
num_pages: usize,
flags: PageTableFlags,
) -> Result<*mut u8, PagingError> {
self.check_request_valid(page, num_pages)?;
if self.alloc_force_user {
panic!();
}
for page in (PageRange { start: page, end: page + num_pages as u64 }) {
if self.translate_addr(page.start_address()).is_some() {
continue;
}
unsafe {
let mut phys_mem = PHYSICAL_MEMORY.lock();
let frame = phys_mem.allocate_frame().unwrap();
self.mapper
.map_to_with_table_flags(
page,
frame,
flags | PageTableFlags::PRESENT | PageTableFlags::WRITABLE,
PageTableFlags::PRESENT
| PageTableFlags::WRITABLE
| PageTableFlags::USER_ACCESSIBLE,
&mut *phys_mem,
)?
.flush();
}
}
Ok(page.start_address().as_mut_ptr())
}
/// Finds a range of free pages and returns the starting page /// Finds a range of free pages and returns the starting page
fn find_free_pages(&self, num_pages: usize) -> Result<Page, PagingError> { fn find_free_pages(&self, num_pages: usize) -> Result<Page, PagingError> {
let mut remaining_pages = num_pages; let mut remaining_pages = num_pages;
@ -459,18 +519,29 @@ unsafe impl Allocator for ASpaceMutex {
PageTableFlags::empty() PageTableFlags::empty()
}; };
let start = space.map_free(size / 4096, flags).map_err(|_| AllocError)?; let start = space.map_free(size / 4096, flags).map_err(|_| AllocError)?;
// if space.alloc_force_user {
// dbg!(start);
// }
Ok(unsafe { slice::from_raw_parts_mut(start.cast::<u8>(), size) }.into()) Ok(unsafe { slice::from_raw_parts_mut(start.cast::<u8>(), size) }.into())
} }
unsafe fn deallocate(&self, ptr: NonNull<u8>, layout: Layout) { unsafe fn deallocate(&self, ptr: NonNull<u8>, layout: Layout) {
let start_page = Page::from_start_address(VirtAddr::new(ptr.as_ptr() as u64)).unwrap(); let start_page = Page::from_start_address(VirtAddr::new(ptr.as_ptr() as u64)).unwrap();
unsafe { for page in Page::range(start_page, start_page + (layout.size().div_ceil(4096) - 1) as u64)
self.0.lock().mapper.unmap_range( {
Page::range(start_page, start_page + (layout.size().div_ceil(4096) - 1) as u64), unsafe {
&mut *PHYSICAL_MEMORY.lock(), let (frame, flush) = self.0.lock().mapper.unmap(page).unwrap();
) PHYSICAL_MEMORY.lock().deallocate_frame(frame);
flush.flush();
}
} }
.unwrap() // unsafe {
.flush_all(); // self.0.lock().mapper.unmap_range(
// Page::range(start_page, start_page + (layout.size().div_ceil(4096) - 1) as u64),
// &mut *PHYSICAL_MEMORY.lock(),
// )
// }
// .unwrap()
// .flush_all();
} }
} }

View File

@ -1 +1 @@
{"installs":{"init 0.1.0 (path+file:///home/pjht/projects/os-rust/init)":{"version_req":null,"bins":["init"],"features":[],"all_features":false,"no_default_features":false,"profile":"release","target":"x86_64-unknown-none","rustc":"rustc 1.65.0-nightly (0b79f758c 2022-08-18)\nbinary: rustc\ncommit-hash: 0b79f758c9aa6646606662a6d623a0752286cd17\ncommit-date: 2022-08-18\nhost: x86_64-unknown-linux-gnu\nrelease: 1.65.0-nightly\nLLVM version: 15.0.0\n"},"test_proc 0.1.0 (path+file:///home/pjht/projects/os-rust/test_proc)":{"version_req":null,"bins":["test_proc"],"features":[],"all_features":false,"no_default_features":false,"profile":"release","target":"x86_64-unknown-none","rustc":"rustc 1.65.0-nightly (0b79f758c 2022-08-18)\nbinary: rustc\ncommit-hash: 0b79f758c9aa6646606662a6d623a0752286cd17\ncommit-date: 2022-08-18\nhost: x86_64-unknown-linux-gnu\nrelease: 1.65.0-nightly\nLLVM version: 15.0.0\n"}}} {"installs":{"init 0.1.0 (path+file:///home/pjht/projects/os-rust/init)":{"version_req":null,"bins":["init"],"features":[],"all_features":false,"no_default_features":false,"profile":"release","target":"x86_64-unknown-none","rustc":"rustc 1.68.0-nightly (3020239de 2023-01-09)\nbinary: rustc\ncommit-hash: 3020239de947ec52677e9b4e853a6a9fc073d1f9\ncommit-date: 2023-01-09\nhost: x86_64-unknown-linux-gnu\nrelease: 1.68.0-nightly\nLLVM version: 15.0.6\n"},"test_proc 0.1.0 (path+file:///home/pjht/projects/os-rust/test_proc)":{"version_req":null,"bins":["test_proc"],"features":[],"all_features":false,"no_default_features":false,"profile":"release","target":"x86_64-unknown-none","rustc":"rustc 1.65.0-nightly (0b79f758c 2022-08-18)\nbinary: rustc\ncommit-hash: 0b79f758c9aa6646606662a6d623a0752286cd17\ncommit-date: 2022-08-18\nhost: x86_64-unknown-linux-gnu\nrelease: 1.65.0-nightly\nLLVM version: 15.0.0\n"}}}

Binary file not shown.

Binary file not shown.

View File

@ -1,14 +0,0 @@
{
"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",
"features": "-mmx,-sse,+soft-float"
}