Commit work
This commit is contained in:
parent
bf09798825
commit
8fd2b83b40
@ -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
8
Cargo.lock
generated
@ -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",
|
||||||
|
40
Cargo.toml
40
Cargo.toml
@ -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" }
|
|
||||||
|
BIN
initrd.tar
BIN
initrd.tar
Binary file not shown.
@ -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;
|
||||||
|
|
||||||
|
@ -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]",
|
||||||
|
@ -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) -> ! {
|
||||||
|
27
src/main.rs
27
src/main.rs
@ -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!();
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
|
@ -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> {
|
||||||
|
11
src/start.rs
11
src/start.rs
@ -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)]
|
||||||
|
@ -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)?;
|
||||||
|
for (page, frame) in (PageRange { start: page, end: page + num_pages as u64 })
|
||||||
|
.zip(PhysFrameRange { start: phys_frame, end: phys_frame + num_pages as u64 })
|
||||||
|
{
|
||||||
unsafe {
|
unsafe {
|
||||||
self.mapper
|
self.mapper
|
||||||
.map_to_range_with_table_flags(
|
.map_to_with_table_flags(
|
||||||
PageRange { start: page, end: page + num_pages as u64 },
|
page,
|
||||||
PhysFrameRange { start: phys_frame, end: phys_frame + num_pages as u64 },
|
frame,
|
||||||
flags | PageTableFlags::PRESENT,
|
flags | PageTableFlags::PRESENT,
|
||||||
PageTableFlags::PRESENT
|
PageTableFlags::PRESENT
|
||||||
| PageTableFlags::WRITABLE
|
| PageTableFlags::WRITABLE
|
||||||
| PageTableFlags::USER_ACCESSIBLE,
|
| PageTableFlags::USER_ACCESSIBLE,
|
||||||
&mut *PHYSICAL_MEMORY.lock(),
|
&mut *PHYSICAL_MEMORY.lock(),
|
||||||
)
|
)?
|
||||||
.map_err(|(err, flush_range)| {
|
.flush();
|
||||||
flush_range.flush_range();
|
}
|
||||||
err
|
|
||||||
})?
|
|
||||||
.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)?;
|
||||||
|
for page in (PageRange { start: page, end: page + num_pages as u64 }) {
|
||||||
unsafe {
|
unsafe {
|
||||||
|
let mut phys_mem = PHYSICAL_MEMORY.lock();
|
||||||
|
let frame = phys_mem.allocate_frame().unwrap();
|
||||||
self.mapper
|
self.mapper
|
||||||
.map_range_with_table_flags(
|
.map_to_with_table_flags(
|
||||||
PageRange { start: page, end: page + num_pages as u64 },
|
page,
|
||||||
flags | PageTableFlags::PRESENT | PageTableFlags::WRITABLE,
|
frame,
|
||||||
|
flags
|
||||||
|
| PageTableFlags::PRESENT
|
||||||
|
| PageTableFlags::WRITABLE
|
||||||
|
| if self.alloc_force_user {
|
||||||
|
PageTableFlags::USER_ACCESSIBLE
|
||||||
|
} else {
|
||||||
|
PageTableFlags::empty()
|
||||||
|
},
|
||||||
PageTableFlags::PRESENT
|
PageTableFlags::PRESENT
|
||||||
| PageTableFlags::WRITABLE
|
| PageTableFlags::WRITABLE
|
||||||
| PageTableFlags::USER_ACCESSIBLE,
|
| PageTableFlags::USER_ACCESSIBLE,
|
||||||
&mut *PHYSICAL_MEMORY.lock(),
|
&mut *phys_mem,
|
||||||
)
|
)?
|
||||||
.map_err(|(err, flush_range)| {
|
.flush();
|
||||||
flush_range.flush_range();
|
|
||||||
err
|
|
||||||
})?
|
|
||||||
.flush_range();
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
// 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();
|
||||||
|
for page in Page::range(start_page, start_page + (layout.size().div_ceil(4096) - 1) as u64)
|
||||||
|
{
|
||||||
unsafe {
|
unsafe {
|
||||||
self.0.lock().mapper.unmap_range(
|
let (frame, flush) = self.0.lock().mapper.unmap(page).unwrap();
|
||||||
Page::range(start_page, start_page + (layout.size().div_ceil(4096) - 1) as u64),
|
PHYSICAL_MEMORY.lock().deallocate_frame(frame);
|
||||||
&mut *PHYSICAL_MEMORY.lock(),
|
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();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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"}}}
|
BIN
sysroot/bin/init
BIN
sysroot/bin/init
Binary file not shown.
Binary file not shown.
@ -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"
|
|
||||||
}
|
|
Loading…
Reference in New Issue
Block a user