Higher-half kernel mapping. Unmap where possible, freeing up lower memory
This commit is contained in:
parent
6e16298e71
commit
83bc8a0da5
|
@ -43,6 +43,13 @@ pub fn init_sdt(sdt: &'static Sdt, active_table: &mut ActivePageTable) {
|
||||||
println!(" XAPIC {}: {:>08X}", me, local_apic.address);
|
println!(" XAPIC {}: {:>08X}", me, local_apic.address);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let trampoline_frame = Frame::containing_address(PhysicalAddress::new(TRAMPOLINE));
|
||||||
|
let trampoline_page = Page::containing_address(VirtualAddress::new(TRAMPOLINE));
|
||||||
|
|
||||||
|
// Map trampoline
|
||||||
|
active_table.map_to(trampoline_page, trampoline_frame, entry::PRESENT | entry::WRITABLE);
|
||||||
|
active_table.flush(trampoline_page);
|
||||||
|
|
||||||
for madt_entry in madt.iter() {
|
for madt_entry in madt.iter() {
|
||||||
println!(" {:?}", madt_entry);
|
println!(" {:?}", madt_entry);
|
||||||
match madt_entry {
|
match madt_entry {
|
||||||
|
@ -50,13 +57,6 @@ pub fn init_sdt(sdt: &'static Sdt, active_table: &mut ActivePageTable) {
|
||||||
println!(" This is my local APIC");
|
println!(" This is my local APIC");
|
||||||
} else {
|
} else {
|
||||||
if ap_local_apic.flags & 1 == 1 {
|
if ap_local_apic.flags & 1 == 1 {
|
||||||
// Map trampoline
|
|
||||||
{
|
|
||||||
if active_table.translate_page(Page::containing_address(VirtualAddress::new(TRAMPOLINE))).is_none() {
|
|
||||||
active_table.identity_map(Frame::containing_address(PhysicalAddress::new(TRAMPOLINE)), entry::PRESENT | entry::WRITABLE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Allocate a stack
|
// Allocate a stack
|
||||||
// TODO: Allocate contiguous
|
// TODO: Allocate contiguous
|
||||||
let stack_start = allocate_frame().expect("no more frames in acpi stack_start").start_address().get();
|
let stack_start = allocate_frame().expect("no more frames in acpi stack_start").start_address().get();
|
||||||
|
@ -128,6 +128,10 @@ pub fn init_sdt(sdt: &'static Sdt, active_table: &mut ActivePageTable) {
|
||||||
_ => ()
|
_ => ()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Unmap trampoline
|
||||||
|
active_table.unmap(trampoline_page);
|
||||||
|
active_table.flush(trampoline_page);
|
||||||
} else {
|
} else {
|
||||||
println!(": Unknown");
|
println!(": Unknown");
|
||||||
}
|
}
|
||||||
|
@ -138,28 +142,43 @@ pub unsafe fn init(active_table: &mut ActivePageTable) -> Option<Acpi> {
|
||||||
let start_addr = 0xE0000;
|
let start_addr = 0xE0000;
|
||||||
let end_addr = 0xFFFFF;
|
let end_addr = 0xFFFFF;
|
||||||
|
|
||||||
// Map all of the ACPI table space
|
// Map all of the ACPI RSDT space
|
||||||
{
|
{
|
||||||
let start_frame = Frame::containing_address(PhysicalAddress::new(start_addr));
|
let start_frame = Frame::containing_address(PhysicalAddress::new(start_addr));
|
||||||
let end_frame = Frame::containing_address(PhysicalAddress::new(end_addr));
|
let end_frame = Frame::containing_address(PhysicalAddress::new(end_addr));
|
||||||
for frame in Frame::range_inclusive(start_frame, end_frame) {
|
for frame in Frame::range_inclusive(start_frame, end_frame) {
|
||||||
if active_table.translate_page(Page::containing_address(VirtualAddress::new(frame.start_address().get()))).is_none() {
|
let page = Page::containing_address(VirtualAddress::new(frame.start_address().get()));
|
||||||
active_table.identity_map(frame, entry::PRESENT | entry::NO_EXECUTE);
|
active_table.map_to(page, frame, entry::PRESENT | entry::NO_EXECUTE);
|
||||||
}
|
active_table.flush(page);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Search for RSDP
|
// Search for RSDP
|
||||||
if let Some(rsdp) = RSDP::search(start_addr, end_addr) {
|
if let Some(rsdp) = RSDP::search(start_addr, end_addr) {
|
||||||
let get_sdt = |sdt_address: usize, active_table: &mut ActivePageTable| -> &'static Sdt {
|
let get_sdt = |sdt_address: usize, active_table: &mut ActivePageTable| -> (&'static Sdt, bool) {
|
||||||
if active_table.translate_page(Page::containing_address(VirtualAddress::new(sdt_address))).is_none() {
|
let mapped = if active_table.translate_page(Page::containing_address(VirtualAddress::new(sdt_address))).is_none() {
|
||||||
let sdt_frame = Frame::containing_address(PhysicalAddress::new(sdt_address));
|
let sdt_frame = Frame::containing_address(PhysicalAddress::new(sdt_address));
|
||||||
active_table.identity_map(sdt_frame, entry::PRESENT | entry::NO_EXECUTE);
|
let sdt_page = Page::containing_address(VirtualAddress::new(sdt_address));
|
||||||
}
|
active_table.map_to(sdt_page, sdt_frame, entry::PRESENT | entry::NO_EXECUTE);
|
||||||
&*(sdt_address as *const Sdt)
|
active_table.flush(sdt_page);
|
||||||
|
true
|
||||||
|
} else {
|
||||||
|
false
|
||||||
|
};
|
||||||
|
(&*(sdt_address as *const Sdt), mapped)
|
||||||
};
|
};
|
||||||
|
|
||||||
let rxsdt = get_sdt(rsdp.sdt_address(), active_table);
|
let drop_sdt = |sdt: &'static Sdt, mapped: bool, active_table: &mut ActivePageTable| {
|
||||||
|
let sdt_address = sdt as *const Sdt as usize;
|
||||||
|
drop(sdt);
|
||||||
|
if mapped {
|
||||||
|
let sdt_page = Page::containing_address(VirtualAddress::new(sdt_address));
|
||||||
|
active_table.unmap(sdt_page);
|
||||||
|
active_table.flush(sdt_page);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let (rxsdt, rxmapped) = get_sdt(rsdp.sdt_address(), active_table);
|
||||||
|
|
||||||
for &c in rxsdt.signature.iter() {
|
for &c in rxsdt.signature.iter() {
|
||||||
print!("{}", c as char);
|
print!("{}", c as char);
|
||||||
|
@ -167,21 +186,36 @@ pub unsafe fn init(active_table: &mut ActivePageTable) -> Option<Acpi> {
|
||||||
println!(":");
|
println!(":");
|
||||||
if let Some(rsdt) = Rsdt::new(rxsdt) {
|
if let Some(rsdt) = Rsdt::new(rxsdt) {
|
||||||
for sdt_address in rsdt.iter() {
|
for sdt_address in rsdt.iter() {
|
||||||
let sdt = get_sdt(sdt_address, active_table);
|
let (sdt, mapped) = get_sdt(sdt_address, active_table);
|
||||||
init_sdt(sdt, active_table);
|
init_sdt(sdt, active_table);
|
||||||
|
drop_sdt(sdt, mapped, active_table);
|
||||||
}
|
}
|
||||||
} else if let Some(xsdt) = Xsdt::new(rxsdt) {
|
} else if let Some(xsdt) = Xsdt::new(rxsdt) {
|
||||||
for sdt_address in xsdt.iter() {
|
for sdt_address in xsdt.iter() {
|
||||||
let sdt = get_sdt(sdt_address, active_table);
|
let (sdt, mapped) = get_sdt(sdt_address, active_table);
|
||||||
init_sdt(sdt, active_table);
|
init_sdt(sdt, active_table);
|
||||||
|
drop_sdt(sdt, mapped, active_table);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
println!("UNKNOWN RSDT OR XSDT SIGNATURE");
|
println!("UNKNOWN RSDT OR XSDT SIGNATURE");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
drop_sdt(rxsdt, rxmapped, active_table);
|
||||||
} else {
|
} else {
|
||||||
println!("NO RSDP FOUND");
|
println!("NO RSDP FOUND");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Unmap all of the ACPI RSDT space
|
||||||
|
{
|
||||||
|
let start_frame = Frame::containing_address(PhysicalAddress::new(start_addr));
|
||||||
|
let end_frame = Frame::containing_address(PhysicalAddress::new(end_addr));
|
||||||
|
for frame in Frame::range_inclusive(start_frame, end_frame) {
|
||||||
|
let page = Page::containing_address(VirtualAddress::new(frame.start_address().get()));
|
||||||
|
active_table.unmap(page);
|
||||||
|
active_table.flush(page);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,7 @@ use ransid::{Console, Event};
|
||||||
use spin::Mutex;
|
use spin::Mutex;
|
||||||
|
|
||||||
use memory::Frame;
|
use memory::Frame;
|
||||||
use paging::{ActivePageTable, PhysicalAddress, entry};
|
use paging::{ActivePageTable, Page, PhysicalAddress, VirtualAddress, entry};
|
||||||
|
|
||||||
#[cfg(target_arch = "x86_64")]
|
#[cfg(target_arch = "x86_64")]
|
||||||
#[allow(unused_assignments)]
|
#[allow(unused_assignments)]
|
||||||
|
@ -117,6 +117,8 @@ pub unsafe fn init(active_table: &mut ActivePageTable) {
|
||||||
));
|
));
|
||||||
*CONSOLE.lock() = Some(Console::new(width/8, height/16));
|
*CONSOLE.lock() = Some(Console::new(width/8, height/16));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
active_table.unmap(Page::containing_address(VirtualAddress::new(0x5200)));
|
||||||
}
|
}
|
||||||
|
|
||||||
pub unsafe fn init_ap(active_table: &mut ActivePageTable) {
|
pub unsafe fn init_ap(active_table: &mut ActivePageTable) {
|
||||||
|
@ -137,6 +139,8 @@ pub unsafe fn init_ap(active_table: &mut ActivePageTable) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
active_table.unmap(Page::containing_address(VirtualAddress::new(0x5200)));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A display
|
/// A display
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
ENTRY(kstart)
|
ENTRY(kstart)
|
||||||
OUTPUT_FORMAT(elf64-x86-64)
|
OUTPUT_FORMAT(elf64-x86-64)
|
||||||
|
|
||||||
/* KERNEL_OFFSET = 0xffffff0000100000; */
|
KERNEL_OFFSET = 0xffffff0000100000;
|
||||||
KERNEL_OFFSET = 0x100000;
|
/* KERNEL_OFFSET = 0x100000; */
|
||||||
|
|
||||||
SECTIONS {
|
SECTIONS {
|
||||||
. = KERNEL_OFFSET;
|
. = KERNEL_OFFSET;
|
||||||
|
|
|
@ -78,25 +78,23 @@ pub unsafe fn init(cpu_id: usize, stack_start: usize, stack_end: usize) -> (Acti
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut remap = |start: usize, end: usize, flags: EntryFlags| {
|
let mut remap = |start: usize, end: usize, flags: EntryFlags, offset: usize| {
|
||||||
if end > start {
|
if end > start {
|
||||||
let start_frame = Frame::containing_address(PhysicalAddress::new(start));
|
let start_frame = Frame::containing_address(PhysicalAddress::new(start));
|
||||||
let end_frame = Frame::containing_address(PhysicalAddress::new(end - 1));
|
let end_frame = Frame::containing_address(PhysicalAddress::new(end - 1));
|
||||||
for frame in Frame::range_inclusive(start_frame, end_frame) {
|
for frame in Frame::range_inclusive(start_frame, end_frame) {
|
||||||
mapper.identity_map(frame.clone(), flags);
|
let page = Page::containing_address(VirtualAddress::new(frame.start_address().get() + offset));
|
||||||
|
mapper.map_to(page, frame, flags);
|
||||||
//let page = Page::containing_address(VirtualAddress::new(frame.start_address().get() + ::KERNEL_OFFSET));
|
|
||||||
//mapper.map_to(page, frame, flags);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// Remap stack writable, no execute
|
// Remap stack writable, no execute
|
||||||
remap(stack_start, stack_end, PRESENT | NO_EXECUTE | WRITABLE);
|
remap(stack_start, stack_end, PRESENT | NO_EXECUTE | WRITABLE, 0);
|
||||||
|
|
||||||
// Remap a section with `flags`
|
// Remap a section with `flags`
|
||||||
let mut remap_section = |start: &u8, end: &u8, flags: EntryFlags| {
|
let mut remap_section = |start: &u8, end: &u8, flags: EntryFlags| {
|
||||||
remap(start as *const _ as usize, end as *const _ as usize, flags);
|
remap(start as *const _ as usize - ::KERNEL_OFFSET, end as *const _ as usize - ::KERNEL_OFFSET, flags, ::KERNEL_OFFSET);
|
||||||
};
|
};
|
||||||
// Remap text read-only
|
// Remap text read-only
|
||||||
remap_section(& __text_start, & __text_end, PRESENT);
|
remap_section(& __text_start, & __text_end, PRESENT);
|
||||||
|
|
|
@ -65,7 +65,7 @@ pub unsafe extern fn kstart() -> ! {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initialize memory management
|
// Initialize memory management
|
||||||
memory::init(0, &__end as *const u8 as usize);
|
memory::init(0, &__end as *const u8 as usize - ::KERNEL_OFFSET);
|
||||||
|
|
||||||
// TODO: allocate a stack
|
// TODO: allocate a stack
|
||||||
let stack_start = 0x00080000;
|
let stack_start = 0x00080000;
|
||||||
|
|
|
@ -126,6 +126,7 @@ long_mode:
|
||||||
|
|
||||||
;rust init
|
;rust init
|
||||||
mov rax, [kernel_base + 0x18]
|
mov rax, [kernel_base + 0x18]
|
||||||
|
xchg bx, bx
|
||||||
jmp rax
|
jmp rax
|
||||||
|
|
||||||
long_mode_ap:
|
long_mode_ap:
|
||||||
|
|
|
@ -79,6 +79,7 @@ pub fn clone(flags: usize, stack_base: usize) -> Result<usize> {
|
||||||
stack.start_address().get() as *const u8,
|
stack.start_address().get() as *const u8,
|
||||||
stack.size());
|
stack.size());
|
||||||
}
|
}
|
||||||
|
new_stack.unmap(true);
|
||||||
stack_option = Some(new_stack);
|
stack_option = Some(new_stack);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue