Cleanup some
This commit is contained in:
@@ -20,13 +20,13 @@ use self::rsdt::Rsdt;
|
||||
use self::sdt::Sdt;
|
||||
use self::xsdt::Xsdt;
|
||||
|
||||
pub mod dmar;
|
||||
pub mod dsdt;
|
||||
pub mod fadt;
|
||||
pub mod madt;
|
||||
pub mod rsdt;
|
||||
pub mod sdt;
|
||||
pub mod xsdt;
|
||||
mod dmar;
|
||||
mod dsdt;
|
||||
mod fadt;
|
||||
mod madt;
|
||||
mod rsdt;
|
||||
mod sdt;
|
||||
mod xsdt;
|
||||
|
||||
const TRAMPOLINE: usize = 0x7E00;
|
||||
const AP_STARTUP: usize = TRAMPOLINE + 512;
|
||||
|
||||
65
arch/x86_64/src/consts.rs
Normal file
65
arch/x86_64/src/consts.rs
Normal file
@@ -0,0 +1,65 @@
|
||||
// Because the memory map is so important to not be aliased, it is defined here, in one place
|
||||
// The lower 256 PML4 entries are reserved for userspace
|
||||
// Each PML4 entry references up to 512 GB of memory
|
||||
// The top (511) PML4 is reserved for recursive mapping
|
||||
// The second from the top (510) PML4 is reserved for the kernel
|
||||
/// The size of a single PML4
|
||||
pub const PML4_SIZE: usize = 0x0000_0080_0000_0000;
|
||||
|
||||
/// Offset of recursive paging
|
||||
pub const RECURSIVE_PAGE_OFFSET: usize = (-(PML4_SIZE as isize)) as usize;
|
||||
|
||||
/// Offset of kernel
|
||||
pub const KERNEL_OFFSET: usize = RECURSIVE_PAGE_OFFSET - PML4_SIZE;
|
||||
|
||||
/// Offset to kernel heap
|
||||
pub const KERNEL_HEAP_OFFSET: usize = KERNEL_OFFSET + PML4_SIZE/2;
|
||||
/// Size of kernel heap
|
||||
pub const KERNEL_HEAP_SIZE: usize = 256 * 1024 * 1024; // 256 MB
|
||||
|
||||
/// Offset to kernel percpu variables
|
||||
//TODO: Use 64-bit fs offset to enable this pub const KERNEL_PERCPU_OFFSET: usize = KERNEL_HEAP_OFFSET - PML4_SIZE;
|
||||
pub const KERNEL_PERCPU_OFFSET: usize = 0xC000_0000;
|
||||
/// Size of kernel percpu variables
|
||||
pub const KERNEL_PERCPU_SIZE: usize = 64 * 1024; // 64 KB
|
||||
|
||||
/// Offset to user image
|
||||
pub const USER_OFFSET: usize = 0;
|
||||
|
||||
/// Offset to user TCB
|
||||
pub const USER_TCB_OFFSET: usize = 0xB000_0000;
|
||||
|
||||
/// Offset to user arguments
|
||||
pub const USER_ARG_OFFSET: usize = USER_OFFSET + PML4_SIZE/2;
|
||||
|
||||
/// Offset to user heap
|
||||
pub const USER_HEAP_OFFSET: usize = USER_OFFSET + PML4_SIZE;
|
||||
|
||||
/// Offset to user grants
|
||||
pub const USER_GRANT_OFFSET: usize = USER_HEAP_OFFSET + PML4_SIZE;
|
||||
|
||||
/// Offset to user stack
|
||||
pub const USER_STACK_OFFSET: usize = USER_GRANT_OFFSET + PML4_SIZE;
|
||||
/// Size of user stack
|
||||
pub const USER_STACK_SIZE: usize = 1024 * 1024; // 1 MB
|
||||
|
||||
/// Offset to user TLS
|
||||
pub const USER_TLS_OFFSET: usize = USER_STACK_OFFSET + PML4_SIZE;
|
||||
|
||||
/// Offset to user temporary image (used when cloning)
|
||||
pub const USER_TMP_OFFSET: usize = USER_TLS_OFFSET + PML4_SIZE;
|
||||
|
||||
/// Offset to user temporary heap (used when cloning)
|
||||
pub const USER_TMP_HEAP_OFFSET: usize = USER_TMP_OFFSET + PML4_SIZE;
|
||||
|
||||
/// Offset to user temporary page for grants
|
||||
pub const USER_TMP_GRANT_OFFSET: usize = USER_TMP_HEAP_OFFSET + PML4_SIZE;
|
||||
|
||||
/// Offset to user temporary stack (used when cloning)
|
||||
pub const USER_TMP_STACK_OFFSET: usize = USER_TMP_GRANT_OFFSET + PML4_SIZE;
|
||||
|
||||
/// Offset to user temporary tls (used when cloning)
|
||||
pub const USER_TMP_TLS_OFFSET: usize = USER_TMP_STACK_OFFSET + PML4_SIZE;
|
||||
|
||||
/// Offset for usage in other temporary pages
|
||||
pub const USER_TMP_MISC_OFFSET: usize = USER_TMP_TLS_OFFSET + PML4_SIZE;
|
||||
@@ -81,23 +81,6 @@ bitflags! {
|
||||
}
|
||||
}
|
||||
|
||||
#[repr(packed)]
|
||||
pub struct IdtDescriptor {
|
||||
size: u16,
|
||||
offset: u64
|
||||
}
|
||||
|
||||
impl IdtDescriptor {
|
||||
pub fn set_slice(&mut self, slice: &'static [IdtEntry]) {
|
||||
self.size = (slice.len() * mem::size_of::<IdtEntry>() - 1) as u16;
|
||||
self.offset = slice.as_ptr() as u64;
|
||||
}
|
||||
|
||||
pub unsafe fn load(&self) {
|
||||
asm!("lidt [rax]" : : "{rax}"(self as *const _ as usize) : : "intel", "volatile");
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug)]
|
||||
#[repr(packed)]
|
||||
pub struct IdtEntry {
|
||||
|
||||
@@ -20,273 +20,17 @@ extern crate spin;
|
||||
extern crate syscall;
|
||||
pub extern crate x86;
|
||||
|
||||
// Because the memory map is so important to not be aliased, it is defined here, in one place
|
||||
// The lower 256 PML4 entries are reserved for userspace
|
||||
// Each PML4 entry references up to 512 GB of memory
|
||||
// The top (511) PML4 is reserved for recursive mapping
|
||||
// The second from the top (510) PML4 is reserved for the kernel
|
||||
/// The size of a single PML4
|
||||
pub const PML4_SIZE: usize = 0x0000_0080_0000_0000;
|
||||
pub use consts::*;
|
||||
|
||||
/// Offset of recursive paging
|
||||
pub const RECURSIVE_PAGE_OFFSET: usize = (-(PML4_SIZE as isize)) as usize;
|
||||
/// Macros like print, println, and interrupt
|
||||
#[macro_use]
|
||||
pub mod macros;
|
||||
|
||||
/// Offset of kernel
|
||||
pub const KERNEL_OFFSET: usize = RECURSIVE_PAGE_OFFSET - PML4_SIZE;
|
||||
|
||||
/// Offset to kernel heap
|
||||
pub const KERNEL_HEAP_OFFSET: usize = KERNEL_OFFSET + PML4_SIZE/2;
|
||||
/// Size of kernel heap
|
||||
pub const KERNEL_HEAP_SIZE: usize = 256 * 1024 * 1024; // 256 MB
|
||||
|
||||
/// Offset to kernel percpu variables
|
||||
//TODO: Use 64-bit fs offset to enable this pub const KERNEL_PERCPU_OFFSET: usize = KERNEL_HEAP_OFFSET - PML4_SIZE;
|
||||
pub const KERNEL_PERCPU_OFFSET: usize = 0xC000_0000;
|
||||
/// Size of kernel percpu variables
|
||||
pub const KERNEL_PERCPU_SIZE: usize = 64 * 1024; // 64 KB
|
||||
|
||||
/// Offset to user image
|
||||
pub const USER_OFFSET: usize = 0;
|
||||
|
||||
/// Offset to user TCB
|
||||
pub const USER_TCB_OFFSET: usize = 0xB000_0000;
|
||||
|
||||
/// Offset to user arguments
|
||||
pub const USER_ARG_OFFSET: usize = USER_OFFSET + PML4_SIZE/2;
|
||||
|
||||
/// Offset to user heap
|
||||
pub const USER_HEAP_OFFSET: usize = USER_OFFSET + PML4_SIZE;
|
||||
|
||||
/// Offset to user grants
|
||||
pub const USER_GRANT_OFFSET: usize = USER_HEAP_OFFSET + PML4_SIZE;
|
||||
|
||||
/// Offset to user stack
|
||||
pub const USER_STACK_OFFSET: usize = USER_GRANT_OFFSET + PML4_SIZE;
|
||||
/// Size of user stack
|
||||
pub const USER_STACK_SIZE: usize = 1024 * 1024; // 1 MB
|
||||
|
||||
/// Offset to user TLS
|
||||
pub const USER_TLS_OFFSET: usize = USER_STACK_OFFSET + PML4_SIZE;
|
||||
|
||||
/// Offset to user temporary image (used when cloning)
|
||||
pub const USER_TMP_OFFSET: usize = USER_TLS_OFFSET + PML4_SIZE;
|
||||
|
||||
/// Offset to user temporary heap (used when cloning)
|
||||
pub const USER_TMP_HEAP_OFFSET: usize = USER_TMP_OFFSET + PML4_SIZE;
|
||||
|
||||
/// Offset to user temporary page for grants
|
||||
pub const USER_TMP_GRANT_OFFSET: usize = USER_TMP_HEAP_OFFSET + PML4_SIZE;
|
||||
|
||||
/// Offset to user temporary stack (used when cloning)
|
||||
pub const USER_TMP_STACK_OFFSET: usize = USER_TMP_GRANT_OFFSET + PML4_SIZE;
|
||||
|
||||
/// Offset to user temporary tls (used when cloning)
|
||||
pub const USER_TMP_TLS_OFFSET: usize = USER_TMP_STACK_OFFSET + PML4_SIZE;
|
||||
|
||||
/// Offset for usage in other temporary pages
|
||||
pub const USER_TMP_MISC_OFFSET: usize = USER_TMP_TLS_OFFSET + PML4_SIZE;
|
||||
|
||||
|
||||
/// Print to console
|
||||
#[macro_export]
|
||||
macro_rules! print {
|
||||
($($arg:tt)*) => ({
|
||||
use core::fmt::Write;
|
||||
let _ = write!($crate::console::CONSOLE.lock(), $($arg)*);
|
||||
});
|
||||
}
|
||||
|
||||
/// Print with new line to console
|
||||
#[macro_export]
|
||||
macro_rules! println {
|
||||
($fmt:expr) => (print!(concat!($fmt, "\n")));
|
||||
($fmt:expr, $($arg:tt)*) => (print!(concat!($fmt, "\n"), $($arg)*));
|
||||
}
|
||||
|
||||
/// Create an interrupt function that can safely run rust code
|
||||
#[macro_export]
|
||||
macro_rules! interrupt {
|
||||
($name:ident, $func:block) => {
|
||||
#[naked]
|
||||
pub unsafe extern fn $name () {
|
||||
#[inline(never)]
|
||||
unsafe fn inner() {
|
||||
$func
|
||||
}
|
||||
|
||||
// Push scratch registers
|
||||
asm!("push rax
|
||||
push rcx
|
||||
push rdx
|
||||
push rdi
|
||||
push rsi
|
||||
push r8
|
||||
push r9
|
||||
push r10
|
||||
push r11
|
||||
push fs
|
||||
mov rax, 0x18
|
||||
mov fs, ax"
|
||||
: : : : "intel", "volatile");
|
||||
|
||||
// Call inner rust function
|
||||
inner();
|
||||
|
||||
// Pop scratch registers and return
|
||||
asm!("pop fs
|
||||
pop r11
|
||||
pop r10
|
||||
pop r9
|
||||
pop r8
|
||||
pop rsi
|
||||
pop rdi
|
||||
pop rdx
|
||||
pop rcx
|
||||
pop rax
|
||||
iretq"
|
||||
: : : : "intel", "volatile");
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
#[repr(packed)]
|
||||
pub struct InterruptStack {
|
||||
fs: usize,
|
||||
r11: usize,
|
||||
r10: usize,
|
||||
r9: usize,
|
||||
r8: usize,
|
||||
rsi: usize,
|
||||
rdi: usize,
|
||||
rdx: usize,
|
||||
rcx: usize,
|
||||
rax: usize,
|
||||
rip: usize,
|
||||
cs: usize,
|
||||
rflags: usize,
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! interrupt_stack {
|
||||
($name:ident, $stack: ident, $func:block) => {
|
||||
#[naked]
|
||||
pub unsafe extern fn $name () {
|
||||
#[inline(never)]
|
||||
unsafe fn inner($stack: &$crate::InterruptStack) {
|
||||
$func
|
||||
}
|
||||
|
||||
// Push scratch registers
|
||||
asm!("push rax
|
||||
push rcx
|
||||
push rdx
|
||||
push rdi
|
||||
push rsi
|
||||
push r8
|
||||
push r9
|
||||
push r10
|
||||
push r11
|
||||
push fs
|
||||
mov rax, 0x18
|
||||
mov fs, ax"
|
||||
: : : : "intel", "volatile");
|
||||
|
||||
// Get reference to stack variables
|
||||
let rsp: usize;
|
||||
asm!("" : "={rsp}"(rsp) : : : "intel", "volatile");
|
||||
|
||||
// Call inner rust function
|
||||
inner(&*(rsp as *const $crate::InterruptStack));
|
||||
|
||||
// Pop scratch registers and return
|
||||
asm!("pop fs
|
||||
pop r11
|
||||
pop r10
|
||||
pop r9
|
||||
pop r8
|
||||
pop rsi
|
||||
pop rdi
|
||||
pop rdx
|
||||
pop rcx
|
||||
pop rax
|
||||
iretq"
|
||||
: : : : "intel", "volatile");
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
#[repr(packed)]
|
||||
pub struct InterruptErrorStack {
|
||||
fs: usize,
|
||||
r11: usize,
|
||||
r10: usize,
|
||||
r9: usize,
|
||||
r8: usize,
|
||||
rsi: usize,
|
||||
rdi: usize,
|
||||
rdx: usize,
|
||||
rcx: usize,
|
||||
rax: usize,
|
||||
code: usize,
|
||||
rip: usize,
|
||||
cs: usize,
|
||||
rflags: usize,
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! interrupt_error {
|
||||
($name:ident, $stack:ident, $func:block) => {
|
||||
#[naked]
|
||||
pub unsafe extern fn $name () {
|
||||
#[inline(never)]
|
||||
unsafe fn inner($stack: &$crate::InterruptErrorStack) {
|
||||
$func
|
||||
}
|
||||
|
||||
// Push scratch registers
|
||||
asm!("push rax
|
||||
push rcx
|
||||
push rdx
|
||||
push rdi
|
||||
push rsi
|
||||
push r8
|
||||
push r9
|
||||
push r10
|
||||
push r11
|
||||
push fs
|
||||
mov rax, 0x18
|
||||
mov fs, ax"
|
||||
: : : : "intel", "volatile");
|
||||
|
||||
// Get reference to stack variables
|
||||
let rsp: usize;
|
||||
asm!("" : "={rsp}"(rsp) : : : "intel", "volatile");
|
||||
|
||||
// Call inner rust function
|
||||
inner(&*(rsp as *const $crate::InterruptErrorStack));
|
||||
|
||||
// Pop scratch registers, error code, and return
|
||||
asm!("pop fs
|
||||
pop r11
|
||||
pop r10
|
||||
pop r9
|
||||
pop r8
|
||||
pop rsi
|
||||
pop rdi
|
||||
pop rdx
|
||||
pop rcx
|
||||
pop rax
|
||||
add rsp, 8
|
||||
iretq"
|
||||
: : : : "intel", "volatile");
|
||||
}
|
||||
};
|
||||
}
|
||||
/// Constants like memory locations
|
||||
pub mod consts;
|
||||
|
||||
/// ACPI table parsing
|
||||
pub mod acpi;
|
||||
mod acpi;
|
||||
|
||||
/// Console handling
|
||||
pub mod console;
|
||||
@@ -297,14 +41,11 @@ pub mod context;
|
||||
/// Devices
|
||||
pub mod device;
|
||||
|
||||
/// Memcpy, memmove, etc.
|
||||
pub mod externs;
|
||||
|
||||
/// Global descriptor table
|
||||
pub mod gdt;
|
||||
|
||||
/// Interrupt descriptor table
|
||||
pub mod idt;
|
||||
mod idt;
|
||||
|
||||
/// Interrupt instructions
|
||||
pub mod interrupt;
|
||||
|
||||
198
arch/x86_64/src/macros.rs
Normal file
198
arch/x86_64/src/macros.rs
Normal file
@@ -0,0 +1,198 @@
|
||||
/// Print to console
|
||||
#[macro_export]
|
||||
macro_rules! print {
|
||||
($($arg:tt)*) => ({
|
||||
use core::fmt::Write;
|
||||
let _ = write!($crate::console::CONSOLE.lock(), $($arg)*);
|
||||
});
|
||||
}
|
||||
|
||||
/// Print with new line to console
|
||||
#[macro_export]
|
||||
macro_rules! println {
|
||||
() => (print!("\n"));
|
||||
($fmt:expr) => (print!(concat!($fmt, "\n")));
|
||||
($fmt:expr, $($arg:tt)*) => (print!(concat!($fmt, "\n"), $($arg)*));
|
||||
}
|
||||
|
||||
/// Create an interrupt function that can safely run rust code
|
||||
#[macro_export]
|
||||
macro_rules! interrupt {
|
||||
($name:ident, $func:block) => {
|
||||
#[naked]
|
||||
pub unsafe extern fn $name () {
|
||||
#[inline(never)]
|
||||
unsafe fn inner() {
|
||||
$func
|
||||
}
|
||||
|
||||
// Push scratch registers
|
||||
asm!("push rax
|
||||
push rcx
|
||||
push rdx
|
||||
push rdi
|
||||
push rsi
|
||||
push r8
|
||||
push r9
|
||||
push r10
|
||||
push r11
|
||||
push fs
|
||||
mov rax, 0x18
|
||||
mov fs, ax"
|
||||
: : : : "intel", "volatile");
|
||||
|
||||
// Call inner rust function
|
||||
inner();
|
||||
|
||||
// Pop scratch registers and return
|
||||
asm!("pop fs
|
||||
pop r11
|
||||
pop r10
|
||||
pop r9
|
||||
pop r8
|
||||
pop rsi
|
||||
pop rdi
|
||||
pop rdx
|
||||
pop rcx
|
||||
pop rax
|
||||
iretq"
|
||||
: : : : "intel", "volatile");
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
#[repr(packed)]
|
||||
pub struct InterruptStack {
|
||||
pub fs: usize,
|
||||
pub r11: usize,
|
||||
pub r10: usize,
|
||||
pub r9: usize,
|
||||
pub r8: usize,
|
||||
pub rsi: usize,
|
||||
pub rdi: usize,
|
||||
pub rdx: usize,
|
||||
pub rcx: usize,
|
||||
pub rax: usize,
|
||||
pub rip: usize,
|
||||
pub cs: usize,
|
||||
pub rflags: usize,
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! interrupt_stack {
|
||||
($name:ident, $stack: ident, $func:block) => {
|
||||
#[naked]
|
||||
pub unsafe extern fn $name () {
|
||||
#[inline(never)]
|
||||
unsafe fn inner($stack: &$crate::macros::InterruptStack) {
|
||||
$func
|
||||
}
|
||||
|
||||
// Push scratch registers
|
||||
asm!("push rax
|
||||
push rcx
|
||||
push rdx
|
||||
push rdi
|
||||
push rsi
|
||||
push r8
|
||||
push r9
|
||||
push r10
|
||||
push r11
|
||||
push fs
|
||||
mov rax, 0x18
|
||||
mov fs, ax"
|
||||
: : : : "intel", "volatile");
|
||||
|
||||
// Get reference to stack variables
|
||||
let rsp: usize;
|
||||
asm!("" : "={rsp}"(rsp) : : : "intel", "volatile");
|
||||
|
||||
// Call inner rust function
|
||||
inner(&*(rsp as *const $crate::macros::InterruptStack));
|
||||
|
||||
// Pop scratch registers and return
|
||||
asm!("pop fs
|
||||
pop r11
|
||||
pop r10
|
||||
pop r9
|
||||
pop r8
|
||||
pop rsi
|
||||
pop rdi
|
||||
pop rdx
|
||||
pop rcx
|
||||
pop rax
|
||||
iretq"
|
||||
: : : : "intel", "volatile");
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
#[repr(packed)]
|
||||
pub struct InterruptErrorStack {
|
||||
pub fs: usize,
|
||||
pub r11: usize,
|
||||
pub r10: usize,
|
||||
pub r9: usize,
|
||||
pub r8: usize,
|
||||
pub rsi: usize,
|
||||
pub rdi: usize,
|
||||
pub rdx: usize,
|
||||
pub rcx: usize,
|
||||
pub rax: usize,
|
||||
pub code: usize,
|
||||
pub rip: usize,
|
||||
pub cs: usize,
|
||||
pub rflags: usize,
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! interrupt_error {
|
||||
($name:ident, $stack:ident, $func:block) => {
|
||||
#[naked]
|
||||
pub unsafe extern fn $name () {
|
||||
#[inline(never)]
|
||||
unsafe fn inner($stack: &$crate::macros::InterruptErrorStack) {
|
||||
$func
|
||||
}
|
||||
|
||||
// Push scratch registers
|
||||
asm!("push rax
|
||||
push rcx
|
||||
push rdx
|
||||
push rdi
|
||||
push rsi
|
||||
push r8
|
||||
push r9
|
||||
push r10
|
||||
push r11
|
||||
push fs
|
||||
mov rax, 0x18
|
||||
mov fs, ax"
|
||||
: : : : "intel", "volatile");
|
||||
|
||||
// Get reference to stack variables
|
||||
let rsp: usize;
|
||||
asm!("" : "={rsp}"(rsp) : : : "intel", "volatile");
|
||||
|
||||
// Call inner rust function
|
||||
inner(&*(rsp as *const $crate::macros::InterruptErrorStack));
|
||||
|
||||
// Pop scratch registers, error code, and return
|
||||
asm!("pop fs
|
||||
pop r11
|
||||
pop r10
|
||||
pop r9
|
||||
pop r8
|
||||
pop rsi
|
||||
pop rdi
|
||||
pop rdx
|
||||
pop rcx
|
||||
pop rax
|
||||
add rsp, 8
|
||||
iretq"
|
||||
: : : : "intel", "volatile");
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -6,7 +6,7 @@ use paging::PhysicalAddress;
|
||||
use super::{Frame, FrameAllocator, MemoryArea, MemoryAreaIter};
|
||||
|
||||
|
||||
pub struct AreaFrameAllocator {
|
||||
pub struct BumpAllocator {
|
||||
next_free_frame: Frame,
|
||||
current_area: Option<&'static MemoryArea>,
|
||||
areas: MemoryAreaIter,
|
||||
@@ -14,9 +14,9 @@ pub struct AreaFrameAllocator {
|
||||
kernel_end: Frame
|
||||
}
|
||||
|
||||
impl AreaFrameAllocator {
|
||||
pub fn new(kernel_start: usize, kernel_end: usize, memory_areas: MemoryAreaIter) -> AreaFrameAllocator {
|
||||
let mut allocator = AreaFrameAllocator {
|
||||
impl BumpAllocator {
|
||||
pub fn new(kernel_start: usize, kernel_end: usize, memory_areas: MemoryAreaIter) -> BumpAllocator {
|
||||
let mut allocator = BumpAllocator {
|
||||
next_free_frame: Frame::containing_address(PhysicalAddress::new(0)),
|
||||
current_area: None,
|
||||
areas: memory_areas,
|
||||
@@ -42,7 +42,7 @@ impl AreaFrameAllocator {
|
||||
}
|
||||
}
|
||||
|
||||
impl FrameAllocator for AreaFrameAllocator {
|
||||
impl FrameAllocator for BumpAllocator {
|
||||
fn free_frames(&self) -> usize {
|
||||
let mut count = 0;
|
||||
|
||||
@@ -121,7 +121,7 @@ impl FrameAllocator for AreaFrameAllocator {
|
||||
}
|
||||
}
|
||||
|
||||
fn deallocate_frames(&mut self, frame: Frame, count: usize) {
|
||||
//panic!("AreaFrameAllocator::deallocate_frame: not supported: {:?}", frame);
|
||||
fn deallocate_frames(&mut self, _frame: Frame, _count: usize) {
|
||||
//panic!("BumpAllocator::deallocate_frame: not supported: {:?}", frame);
|
||||
}
|
||||
}
|
||||
@@ -3,11 +3,11 @@
|
||||
|
||||
pub use paging::{PAGE_SIZE, PhysicalAddress};
|
||||
|
||||
use self::area_frame_allocator::AreaFrameAllocator;
|
||||
use self::bump::BumpAllocator;
|
||||
|
||||
use spin::Mutex;
|
||||
|
||||
pub mod area_frame_allocator;
|
||||
pub mod bump;
|
||||
|
||||
/// The current memory map. It's size is maxed out to 512 entries, due to it being
|
||||
/// from 0x500 to 0x5000 (800 is the absolute total)
|
||||
@@ -64,7 +64,7 @@ impl Iterator for MemoryAreaIter {
|
||||
}
|
||||
}
|
||||
|
||||
static ALLOCATOR: Mutex<Option<AreaFrameAllocator>> = Mutex::new(None);
|
||||
static ALLOCATOR: Mutex<Option<BumpAllocator>> = Mutex::new(None);
|
||||
|
||||
/// Init memory module
|
||||
/// Must be called once, and only once,
|
||||
@@ -77,17 +77,7 @@ pub unsafe fn init(kernel_start: usize, kernel_end: usize) {
|
||||
}
|
||||
}
|
||||
|
||||
*ALLOCATOR.lock() = Some(AreaFrameAllocator::new(kernel_start, kernel_end, MemoryAreaIter::new(MEMORY_AREA_FREE)));
|
||||
}
|
||||
|
||||
/// Allocate a frame
|
||||
pub fn allocate_frame() -> Option<Frame> {
|
||||
allocate_frames(1)
|
||||
}
|
||||
|
||||
/// Deallocate a frame
|
||||
pub fn deallocate_frame(frame: Frame) {
|
||||
deallocate_frames(frame, 1)
|
||||
*ALLOCATOR.lock() = Some(BumpAllocator::new(kernel_start, kernel_end, MemoryAreaIter::new(MEMORY_AREA_FREE)));
|
||||
}
|
||||
|
||||
/// Get the number of frames available
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
use core::mem;
|
||||
use core::ptr::Unique;
|
||||
|
||||
use memory::{allocate_frame, deallocate_frame, Frame};
|
||||
use memory::{allocate_frames, deallocate_frames, Frame};
|
||||
|
||||
use super::{ActivePageTable, Page, PAGE_SIZE, PhysicalAddress, VirtualAddress};
|
||||
use super::entry::{self, EntryFlags};
|
||||
@@ -113,7 +113,7 @@ impl Mapper {
|
||||
|
||||
/// Map a page to the next free frame
|
||||
pub fn map(&mut self, page: Page, flags: EntryFlags) -> MapperFlush {
|
||||
let frame = allocate_frame().expect("out of frames");
|
||||
let frame = allocate_frames(1).expect("out of frames");
|
||||
self.map_to(page, frame, flags)
|
||||
}
|
||||
|
||||
@@ -143,7 +143,7 @@ impl Mapper {
|
||||
let frame = p1[page.p1_index()].pointed_frame().unwrap();
|
||||
p1[page.p1_index()].set_unused();
|
||||
// TODO free p(1,2,3) table if empty
|
||||
deallocate_frame(frame);
|
||||
deallocate_frames(frame, 1);
|
||||
MapperFlush::new(page)
|
||||
}
|
||||
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
//! # Paging
|
||||
//! Some code was borrowed from [Phil Opp's Blog](http://os.phil-opp.com/modifying-page-tables.html)
|
||||
|
||||
use core::mem;
|
||||
use core::{mem, ptr};
|
||||
use core::ops::{Deref, DerefMut};
|
||||
use x86::{msr, tlb};
|
||||
|
||||
use memory::{allocate_frame, Frame};
|
||||
use memory::{allocate_frames, Frame};
|
||||
|
||||
use self::entry::{EntryFlags, PRESENT, GLOBAL, WRITABLE, NO_EXECUTE};
|
||||
use self::mapper::Mapper;
|
||||
@@ -67,8 +67,8 @@ unsafe fn init_tcb(cpu_id: usize) -> usize {
|
||||
let end = start + size;
|
||||
tcb_offset = end - mem::size_of::<usize>();
|
||||
|
||||
::externs::memcpy(start as *mut u8, & __tdata_start as *const u8, tbss_offset);
|
||||
::externs::memset((start + tbss_offset) as *mut u8, 0, size - tbss_offset);
|
||||
ptr::copy(& __tdata_start as *const u8, start as *mut u8, tbss_offset);
|
||||
ptr::write_bytes((start + tbss_offset) as *mut u8, 0, size - tbss_offset);
|
||||
|
||||
*(tcb_offset as *mut usize) = end;
|
||||
}
|
||||
@@ -113,7 +113,7 @@ pub unsafe fn init(cpu_id: usize, stack_start: usize, stack_end: usize) -> (Acti
|
||||
let mut temporary_page = TemporaryPage::new(Page::containing_address(VirtualAddress::new(::USER_TMP_MISC_OFFSET)));
|
||||
|
||||
let mut new_table = {
|
||||
let frame = allocate_frame().expect("no more frames in paging::init new_table");
|
||||
let frame = allocate_frames(1).expect("no more frames in paging::init new_table");
|
||||
InactivePageTable::new(frame, &mut active_table, &mut temporary_page)
|
||||
};
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
use core::marker::PhantomData;
|
||||
use core::ops::{Index, IndexMut};
|
||||
|
||||
use memory::allocate_frame;
|
||||
use memory::allocate_frames;
|
||||
|
||||
use super::entry::*;
|
||||
use super::ENTRY_COUNT;
|
||||
@@ -65,7 +65,7 @@ impl<L> Table<L> where L: HierarchicalLevel {
|
||||
if self.next_table(index).is_none() {
|
||||
assert!(!self[index].flags().contains(HUGE_PAGE),
|
||||
"next_table_create does not support huge pages");
|
||||
let frame = allocate_frame().expect("no frames available");
|
||||
let frame = allocate_frames(1).expect("no frames available");
|
||||
self[index].set(frame, PRESENT | WRITABLE | USER_ACCESSIBLE /* Allow users to go down the page table, implement permissions at the page level */);
|
||||
self.next_table_mut(index).unwrap().zero();
|
||||
}
|
||||
|
||||
@@ -3,12 +3,12 @@
|
||||
/// It must create the IDT with the correct entries, those entries are
|
||||
/// defined in other files inside of the `arch` module
|
||||
|
||||
use core::ptr;
|
||||
use core::sync::atomic::{AtomicBool, ATOMIC_BOOL_INIT, AtomicUsize, ATOMIC_USIZE_INIT, Ordering};
|
||||
|
||||
use acpi;
|
||||
use allocator;
|
||||
use device;
|
||||
use externs::memset;
|
||||
use gdt;
|
||||
use idt;
|
||||
use interrupt;
|
||||
@@ -58,7 +58,7 @@ pub unsafe extern fn kstart() -> ! {
|
||||
|
||||
if start_ptr as usize <= end_ptr {
|
||||
let size = end_ptr - start_ptr as usize;
|
||||
memset(start_ptr, 0, size);
|
||||
ptr::write_bytes(start_ptr, 0, size);
|
||||
}
|
||||
|
||||
assert_eq!(BSS_TEST_ZERO, 0);
|
||||
@@ -113,7 +113,7 @@ pub unsafe extern fn kstart() -> ! {
|
||||
// Init the allocator
|
||||
allocator::init(::KERNEL_HEAP_OFFSET, ::KERNEL_HEAP_SIZE);
|
||||
}
|
||||
|
||||
|
||||
// Initialize devices
|
||||
device::init(&mut active_table);
|
||||
|
||||
|
||||
13
src/lib.rs
13
src/lib.rs
@@ -54,6 +54,9 @@ pub mod context;
|
||||
/// ELF file parsing
|
||||
pub mod elf;
|
||||
|
||||
/// External functions
|
||||
pub mod externs;
|
||||
|
||||
/// Schemes, filesystem handlers
|
||||
pub mod scheme;
|
||||
|
||||
@@ -150,14 +153,7 @@ pub extern fn kmain(cpus: usize) {
|
||||
|
||||
/// This is the main kernel entry point for secondary CPUs
|
||||
#[no_mangle]
|
||||
pub extern fn kmain_ap(_id: usize) {
|
||||
// Disable APs for now
|
||||
loop {
|
||||
unsafe { interrupt::disable(); }
|
||||
unsafe { interrupt::halt(); }
|
||||
}
|
||||
|
||||
/*
|
||||
pub extern fn kmain_ap(id: usize) {
|
||||
CPU_ID.store(id, Ordering::SeqCst);
|
||||
|
||||
context::init();
|
||||
@@ -176,5 +172,4 @@ pub extern fn kmain_ap(_id: usize) {
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@ use core::ops::DerefMut;
|
||||
use spin::Mutex;
|
||||
|
||||
use arch;
|
||||
use arch::memory::allocate_frame;
|
||||
use arch::memory::allocate_frames;
|
||||
use arch::paging::{ActivePageTable, InactivePageTable, Page, VirtualAddress, entry};
|
||||
use arch::paging::temporary_page::TemporaryPage;
|
||||
use arch::start::usermode;
|
||||
@@ -324,7 +324,7 @@ pub fn clone(flags: usize, stack_base: usize) -> Result<ContextId> {
|
||||
let mut temporary_page = TemporaryPage::new(Page::containing_address(VirtualAddress::new(arch::USER_TMP_MISC_OFFSET)));
|
||||
|
||||
let mut new_table = {
|
||||
let frame = allocate_frame().expect("no more frames in syscall::clone new_table");
|
||||
let frame = allocate_frames(1).expect("no more frames in syscall::clone new_table");
|
||||
InactivePageTable::new(frame, &mut active_table, &mut temporary_page)
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user