x86-64/mm: limit physical memory, init is slow
This commit is contained in:
parent
d5859d93a9
commit
fbb804f14f
@ -43,9 +43,9 @@ fdt-rs = { version = "0.4.3", default-features = false }
|
|||||||
|
|
||||||
[target.'cfg(target_arch = "x86_64")'.dependencies]
|
[target.'cfg(target_arch = "x86_64")'.dependencies]
|
||||||
yboot-proto = { git = "https://git.alnyan.me/yggdrasil/yboot-proto.git" }
|
yboot-proto = { git = "https://git.alnyan.me/yggdrasil/yboot-proto.git" }
|
||||||
aml = { git = "https://github.com/alnyan/acpi.git", version = "0.16.4" }
|
aml = { git = "https://github.com/alnyan/acpi.git", branch = "acpi-system" }
|
||||||
acpi_lib = { git = "https://github.com/alnyan/acpi.git", version = "4.1.1", package = "acpi" }
|
acpi_lib = { git = "https://github.com/alnyan/acpi.git", package = "acpi", branch = "acpi-system" }
|
||||||
acpi-system = { git = "https://github.com/alnyan/acpi-system.git", version = "0.1.0" }
|
acpi-system = { git = "https://github.com/alnyan/acpi-system.git" }
|
||||||
# TODO currently only supported here
|
# TODO currently only supported here
|
||||||
xhci_lib = { git = "https://github.com/rust-osdev/xhci.git", package = "xhci" }
|
xhci_lib = { git = "https://github.com/rust-osdev/xhci.git", package = "xhci" }
|
||||||
|
|
||||||
|
@ -1,21 +1,24 @@
|
|||||||
//! x86-64 boot and entry functions
|
//! x86-64 boot and entry functions
|
||||||
use core::{arch::global_asm, sync::atomic::Ordering};
|
use core::{arch::global_asm, sync::atomic::Ordering};
|
||||||
|
|
||||||
use tock_registers::interfaces::Writeable;
|
use tock_registers::interfaces::{ReadWriteable, Writeable};
|
||||||
use yboot_proto::{
|
use yboot_proto::{
|
||||||
v1::{FramebufferOption, MemoryMap},
|
v1::{FramebufferOption, MemoryMap},
|
||||||
LoadProtocolHeader, LoadProtocolV1, KERNEL_MAGIC, LOADER_MAGIC, PROTOCOL_VERSION_1,
|
LoadProtocolHeader, LoadProtocolV1, KERNEL_MAGIC, LOADER_MAGIC, PROTOCOL_VERSION_1,
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
arch::x86_64::{registers::MSR_IA32_KERNEL_GS_BASE, smp::CPU_COUNT},
|
arch::x86_64::{
|
||||||
|
registers::{CR0, MSR_IA32_KERNEL_GS_BASE},
|
||||||
|
smp::CPU_COUNT,
|
||||||
|
},
|
||||||
fs::devfs,
|
fs::devfs,
|
||||||
kernel_main, kernel_secondary_main,
|
kernel_main, kernel_secondary_main,
|
||||||
mem::KERNEL_VIRT_OFFSET,
|
mem::KERNEL_VIRT_OFFSET,
|
||||||
task::runtime,
|
task::runtime,
|
||||||
};
|
};
|
||||||
|
|
||||||
use super::{cpuid::init_cpuid, exception, ARCHITECTURE};
|
use super::{cpuid::init_cpuid, exception, registers::CR4, ARCHITECTURE};
|
||||||
|
|
||||||
pub enum BootData {
|
pub enum BootData {
|
||||||
YBoot(&'static LoadProtocolV1),
|
YBoot(&'static LoadProtocolV1),
|
||||||
|
@ -5,14 +5,15 @@ use core::{
|
|||||||
|
|
||||||
use abi::error::Error;
|
use abi::error::Error;
|
||||||
use kernel_util::util::OneTimeInit;
|
use kernel_util::util::OneTimeInit;
|
||||||
use memtables::FixedTables;
|
use memtables::{FixedTables, KERNEL_L3_COUNT};
|
||||||
use static_assertions::{const_assert_eq, const_assert_ne};
|
use static_assertions::{const_assert_eq, const_assert_ne};
|
||||||
|
|
||||||
pub mod process;
|
pub mod process;
|
||||||
pub mod table;
|
pub mod table;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
arch::x86_64::{intrinsics, mem::table::PageAttributes},
|
arch::x86_64::{intrinsics, mem::table::PageAttributes, registers::CR3},
|
||||||
|
device::display::font::PcScreenFont,
|
||||||
mem::{
|
mem::{
|
||||||
address::{FromRaw, IntoRaw, KernelImageObject},
|
address::{FromRaw, IntoRaw, KernelImageObject},
|
||||||
device::RawDeviceMemoryMapping,
|
device::RawDeviceMemoryMapping,
|
||||||
@ -318,6 +319,7 @@ fn clone_kernel_tables(dst: &mut PageTable<L0>) {
|
|||||||
/// * 0xFFFFFF8080000000 .. 0xFFFFFF8080800000 : DEVICE_MAPPING_L3S
|
/// * 0xFFFFFF8080000000 .. 0xFFFFFF8080800000 : DEVICE_MAPPING_L3S
|
||||||
/// * 0xFFFFFF8080800000 .. 0xFFFFFF8100000000 : ...
|
/// * 0xFFFFFF8080800000 .. 0xFFFFFF8100000000 : ...
|
||||||
pub unsafe fn init_fixed_tables() {
|
pub unsafe fn init_fixed_tables() {
|
||||||
|
// TODO this could be built in compile-time too?
|
||||||
let early_mapping_l3_phys = &EARLY_MAPPING_L3 as *const _ as usize - KERNEL_VIRT_OFFSET;
|
let early_mapping_l3_phys = &EARLY_MAPPING_L3 as *const _ as usize - KERNEL_VIRT_OFFSET;
|
||||||
let device_mapping_l2_phys = &DEVICE_MAPPING_L2 as *const _ as usize - KERNEL_VIRT_OFFSET;
|
let device_mapping_l2_phys = &DEVICE_MAPPING_L2 as *const _ as usize - KERNEL_VIRT_OFFSET;
|
||||||
let heap_mapping_l2_phys = &HEAP_MAPPING_L2 as *const _ as usize - KERNEL_VIRT_OFFSET;
|
let heap_mapping_l2_phys = &HEAP_MAPPING_L2 as *const _ as usize - KERNEL_VIRT_OFFSET;
|
||||||
@ -330,19 +332,22 @@ pub unsafe fn init_fixed_tables() {
|
|||||||
DEVICE_MAPPING_L2[i] = PageEntry::table(device_mapping_l3_phys, PageAttributes::WRITABLE);
|
DEVICE_MAPPING_L2[i] = PageEntry::table(device_mapping_l3_phys, PageAttributes::WRITABLE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
assert_eq!(KERNEL_TABLES.kernel_l2.data[EARLY_MAPPING_L2I], 0);
|
||||||
KERNEL_TABLES.kernel_l2.data[EARLY_MAPPING_L2I] = (early_mapping_l3_phys as u64)
|
KERNEL_TABLES.kernel_l2.data[EARLY_MAPPING_L2I] = (early_mapping_l3_phys as u64)
|
||||||
| (PageAttributes::WRITABLE | PageAttributes::PRESENT).bits();
|
| (PageAttributes::WRITABLE | PageAttributes::PRESENT).bits();
|
||||||
|
|
||||||
|
assert_eq!(KERNEL_TABLES.kernel_l1.data[HEAP_MAPPING_L1I], 0);
|
||||||
KERNEL_TABLES.kernel_l1.data[HEAP_MAPPING_L1I] =
|
KERNEL_TABLES.kernel_l1.data[HEAP_MAPPING_L1I] =
|
||||||
(heap_mapping_l2_phys as u64) | (PageAttributes::WRITABLE | PageAttributes::PRESENT).bits();
|
(heap_mapping_l2_phys as u64) | (PageAttributes::WRITABLE | PageAttributes::PRESENT).bits();
|
||||||
|
assert_eq!(KERNEL_TABLES.kernel_l1.data[DEVICE_MAPPING_L1I], 0);
|
||||||
KERNEL_TABLES.kernel_l1.data[DEVICE_MAPPING_L1I] = (device_mapping_l2_phys as u64)
|
KERNEL_TABLES.kernel_l1.data[DEVICE_MAPPING_L1I] = (device_mapping_l2_phys as u64)
|
||||||
| (PageAttributes::WRITABLE | PageAttributes::PRESENT).bits();
|
| (PageAttributes::WRITABLE | PageAttributes::PRESENT).bits();
|
||||||
|
|
||||||
|
assert_eq!(KERNEL_TABLES.l0.data[RAM_MAPPING_L0I], 0);
|
||||||
KERNEL_TABLES.l0.data[RAM_MAPPING_L0I] =
|
KERNEL_TABLES.l0.data[RAM_MAPPING_L0I] =
|
||||||
(ram_mapping_l1_phys as u64) | (PageAttributes::WRITABLE | PageAttributes::PRESENT).bits();
|
(ram_mapping_l1_phys as u64) | (PageAttributes::WRITABLE | PageAttributes::PRESENT).bits();
|
||||||
|
|
||||||
// TODO ENABLE EFER.NXE
|
// TODO ENABLE EFER.NXE
|
||||||
|
|
||||||
let cr3 = &KERNEL_TABLES.l0 as *const _ as usize - KERNEL_VIRT_OFFSET;
|
let cr3 = &KERNEL_TABLES.l0 as *const _ as usize - KERNEL_VIRT_OFFSET;
|
||||||
core::arch::asm!("wbinvd; mov {0}, %cr3", in(reg) cr3, options(att_syntax));
|
CR3.set_address(cr3);
|
||||||
}
|
}
|
||||||
|
@ -390,6 +390,12 @@ impl X86_64 {
|
|||||||
|
|
||||||
debug::init();
|
debug::init();
|
||||||
|
|
||||||
|
infoln!(
|
||||||
|
"Yggdrasil v{} ({})",
|
||||||
|
env!("CARGO_PKG_VERSION"),
|
||||||
|
git_version!()
|
||||||
|
);
|
||||||
|
|
||||||
let ps2 = Box::leak(Box::new(PS2Controller::new(
|
let ps2 = Box::leak(Box::new(PS2Controller::new(
|
||||||
IrqNumber::Isa(1),
|
IrqNumber::Isa(1),
|
||||||
IrqNumber::Isa(12),
|
IrqNumber::Isa(12),
|
||||||
@ -398,12 +404,6 @@ impl X86_64 {
|
|||||||
)));
|
)));
|
||||||
ps2.init()?;
|
ps2.init()?;
|
||||||
|
|
||||||
infoln!(
|
|
||||||
"Yggdrasil v{} ({})",
|
|
||||||
env!("CARGO_PKG_VERSION"),
|
|
||||||
git_version!()
|
|
||||||
);
|
|
||||||
|
|
||||||
if let Some(acpi) = self.acpi.try_get() {
|
if let Some(acpi) = self.acpi.try_get() {
|
||||||
self.init_platform_from_acpi(acpi)?;
|
self.init_platform_from_acpi(acpi)?;
|
||||||
}
|
}
|
||||||
|
@ -1,57 +1,103 @@
|
|||||||
//! Helper types for interfacing with x86-64 registers
|
//! Helper types for interfacing with x86-64 registers
|
||||||
|
|
||||||
macro_rules! msr_impl_read {
|
macro_rules! impl_read {
|
||||||
($t:ident, $addr:expr, $register:ty) => {
|
($t:ident, $register:ty, $body:expr) => {
|
||||||
impl tock_registers::interfaces::Readable for $t {
|
impl tock_registers::interfaces::Readable for $t {
|
||||||
type T = u64;
|
type T = u64;
|
||||||
type R = $register;
|
type R = $register;
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn get(&self) -> u64 {
|
fn get(&self) -> u64 {
|
||||||
let (high, low): (u32, u32);
|
$body
|
||||||
unsafe {
|
|
||||||
core::arch::asm!(
|
|
||||||
"rdmsr",
|
|
||||||
in("ecx") $addr,
|
|
||||||
out("eax") low,
|
|
||||||
out("edx") high,
|
|
||||||
options(att_syntax)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
((high as u64) << 32) | (low as u64)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
macro_rules! impl_write {
|
||||||
|
($t:ident, $register:ty, $value:ident, $body:expr) => {
|
||||||
|
impl tock_registers::interfaces::Writeable for $t {
|
||||||
|
type T = u64;
|
||||||
|
type R = $register;
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn set(&self, $value: u64) {
|
||||||
|
$body
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
macro_rules! msr_impl_read {
|
||||||
|
($t:ident, $addr:expr, $register:ty) => {
|
||||||
|
impl_read!($t, $register, {
|
||||||
|
let (high, low): (u32, u32);
|
||||||
|
unsafe {
|
||||||
|
core::arch::asm!(
|
||||||
|
"rdmsr",
|
||||||
|
in("ecx") $addr,
|
||||||
|
out("eax") low,
|
||||||
|
out("edx") high,
|
||||||
|
options(att_syntax)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
((high as u64) << 32) | (low as u64)
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
($t:ident, $addr:expr) => { msr_impl_read!($t, $addr, ()); };
|
($t:ident, $addr:expr) => { msr_impl_read!($t, $addr, ()); };
|
||||||
}
|
}
|
||||||
|
|
||||||
macro_rules! msr_impl_write {
|
macro_rules! msr_impl_write {
|
||||||
($t:ident, $addr:expr, $register:ty) => {
|
($t:ident, $addr:expr, $register:ty) => {
|
||||||
impl tock_registers::interfaces::Writeable for $t {
|
impl_write!($t, $register, value, {
|
||||||
type T = u64;
|
let low = value as u32;
|
||||||
type R = $register;
|
let high = (value >> 32) as u32;
|
||||||
|
unsafe {
|
||||||
#[inline]
|
core::arch::asm!(
|
||||||
fn set(&self, value: u64) {
|
"wrmsr",
|
||||||
let low = value as u32;
|
in("ecx") $addr,
|
||||||
let high = (value >> 32) as u32;
|
in("eax") low,
|
||||||
unsafe {
|
in("edx") high,
|
||||||
core::arch::asm!(
|
options(att_syntax)
|
||||||
"wrmsr",
|
);
|
||||||
in("ecx") $addr,
|
|
||||||
in("eax") low,
|
|
||||||
in("edx") high,
|
|
||||||
options(att_syntax)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
($t:ident, $addr:expr) => { msr_impl_write!($t, $addr, ()); };
|
($t:ident, $addr:expr) => { msr_impl_write!($t, $addr, ()); };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
macro_rules! cr_impl_read {
|
||||||
|
($t:ident, $cr:ident, $register:ty) => {
|
||||||
|
impl_read!($t, $register, {
|
||||||
|
let value: u64;
|
||||||
|
unsafe {
|
||||||
|
core::arch::asm!(
|
||||||
|
concat!("mov %", stringify!($cr), ", {}"),
|
||||||
|
out(reg) value,
|
||||||
|
options(att_syntax)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
value
|
||||||
|
});
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
macro_rules! cr_impl_write {
|
||||||
|
($t:ident, $cr:ident, $register:ty) => {
|
||||||
|
impl_write!($t, $register, value, {
|
||||||
|
unsafe {
|
||||||
|
core::arch::asm!(
|
||||||
|
concat!("mov {}, %", stringify!($cr)),
|
||||||
|
in(reg) value,
|
||||||
|
options(att_syntax)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
mod msr_ia32_kernel_gs_base {
|
mod msr_ia32_kernel_gs_base {
|
||||||
const ADDR: u32 = 0xC0000102;
|
const ADDR: u32 = 0xC0000102;
|
||||||
pub struct Reg;
|
pub struct Reg;
|
||||||
@ -182,12 +228,73 @@ mod msr_ia32_efer {
|
|||||||
pub const MSR_IA32_EFER: Reg = Reg;
|
pub const MSR_IA32_EFER: Reg = Reg;
|
||||||
}
|
}
|
||||||
|
|
||||||
mod cr4 {
|
mod cr0 {
|
||||||
|
use tock_registers::register_bitfields;
|
||||||
|
|
||||||
|
register_bitfields! {
|
||||||
|
u64,
|
||||||
|
#[allow(missing_docs)]
|
||||||
|
pub CR0 [
|
||||||
|
PG OFFSET(31) NUMBITS(1) [],
|
||||||
|
CD OFFSET(30) NUMBITS(1) [],
|
||||||
|
NW OFFSET(29) NUMBITS(1) [],
|
||||||
|
AM OFFSET(18) NUMBITS(1) [],
|
||||||
|
WP OFFSET(16) NUMBITS(1) [],
|
||||||
|
NE OFFSET(5) NUMBITS(1) [],
|
||||||
|
ET OFFSET(4) NUMBITS(1) [],
|
||||||
|
TS OFFSET(3) NUMBITS(1) [],
|
||||||
|
EM OFFSET(2) NUMBITS(1) [],
|
||||||
|
MP OFFSET(1) NUMBITS(1) [],
|
||||||
|
PE OFFSET(0) NUMBITS(1) [],
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct Reg;
|
||||||
|
|
||||||
|
cr_impl_read!(Reg, cr0, CR0::Register);
|
||||||
|
cr_impl_write!(Reg, cr0, CR0::Register);
|
||||||
|
|
||||||
|
/// x86-64 control register 0
|
||||||
|
pub const CR0: Reg = Reg;
|
||||||
|
}
|
||||||
|
|
||||||
|
mod cr3 {
|
||||||
use tock_registers::{
|
use tock_registers::{
|
||||||
interfaces::{Readable, Writeable},
|
interfaces::{ReadWriteable, Readable},
|
||||||
register_bitfields,
|
register_bitfields,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
register_bitfields! {
|
||||||
|
u64,
|
||||||
|
#[allow(missing_docs)]
|
||||||
|
pub CR3 [
|
||||||
|
ADDR OFFSET(12) NUMBITS(40) [],
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct Reg;
|
||||||
|
|
||||||
|
cr_impl_read!(Reg, cr3, CR3::Register);
|
||||||
|
cr_impl_write!(Reg, cr3, CR3::Register);
|
||||||
|
|
||||||
|
impl Reg {
|
||||||
|
pub fn set_address(&self, address: usize) {
|
||||||
|
assert_eq!(address & 0xFFF, 0);
|
||||||
|
self.modify(CR3::ADDR.val((address as u64) >> 12))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn address(&self) -> usize {
|
||||||
|
(self.read(CR3::ADDR) as usize) << 12
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// x86-64 control register 3
|
||||||
|
pub const CR3: Reg = Reg;
|
||||||
|
}
|
||||||
|
|
||||||
|
mod cr4 {
|
||||||
|
use tock_registers::register_bitfields;
|
||||||
|
|
||||||
register_bitfields! {
|
register_bitfields! {
|
||||||
u64,
|
u64,
|
||||||
#[allow(missing_docs)]
|
#[allow(missing_docs)]
|
||||||
@ -196,36 +303,28 @@ mod cr4 {
|
|||||||
OSXSAVE OFFSET(18) NUMBITS(1) [],
|
OSXSAVE OFFSET(18) NUMBITS(1) [],
|
||||||
/// Indicates OS support for FXSAVE and FXRSTOR instructions
|
/// Indicates OS support for FXSAVE and FXRSTOR instructions
|
||||||
OSFXSR OFFSET(9) NUMBITS(1) [],
|
OSFXSR OFFSET(9) NUMBITS(1) [],
|
||||||
|
/// Performance-Monitoring Counter enable
|
||||||
|
PCE OFFSET(8) NUMBITS(1) [],
|
||||||
/// If set, "page global" attribute is enabled
|
/// If set, "page global" attribute is enabled
|
||||||
PGE OFFSET(8) NUMBITS(1) [],
|
PGE OFFSET(7) NUMBITS(1) [],
|
||||||
|
/// Machine Check enable
|
||||||
|
MCE OFFSET(6) NUMBITS(1) [],
|
||||||
|
/// Physical Address Extension (enabled if 64-bit mode)
|
||||||
|
PAE OFFSET(5) NUMBITS(1) [],
|
||||||
|
/// Page Size Extension (should be enabled by yboot)
|
||||||
|
PSE OFFSET(4) NUMBITS(1) [],
|
||||||
|
/// Debugging extensions
|
||||||
|
DE OFFSET(3) NUMBITS(1) [],
|
||||||
|
TSD OFFSET(2) NUMBITS(1) [],
|
||||||
|
PVI OFFSET(1) NUMBITS(1) [],
|
||||||
|
VME OFFSET(0) NUMBITS(1) [],
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct Reg;
|
pub struct Reg;
|
||||||
|
|
||||||
impl Readable for Reg {
|
cr_impl_read!(Reg, cr4, CR4::Register);
|
||||||
type T = u64;
|
cr_impl_write!(Reg, cr4, CR4::Register);
|
||||||
type R = CR4::Register;
|
|
||||||
|
|
||||||
fn get(&self) -> Self::T {
|
|
||||||
let value: u64;
|
|
||||||
unsafe {
|
|
||||||
core::arch::asm!("mov %cr4, {0}", out(reg) value, options(att_syntax));
|
|
||||||
}
|
|
||||||
value
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Writeable for Reg {
|
|
||||||
type T = u64;
|
|
||||||
type R = CR4::Register;
|
|
||||||
|
|
||||||
fn set(&self, value: Self::T) {
|
|
||||||
unsafe {
|
|
||||||
core::arch::asm!("mov {0}, %cr4", in(reg) value, options(att_syntax));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// x86-64 control register 4
|
/// x86-64 control register 4
|
||||||
pub const CR4: Reg = Reg;
|
pub const CR4: Reg = Reg;
|
||||||
@ -295,6 +394,8 @@ mod xcr0 {
|
|||||||
pub const XCR0: Reg = Reg;
|
pub const XCR0: Reg = Reg;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub use cr0::CR0;
|
||||||
|
pub use cr3::CR3;
|
||||||
pub use cr4::CR4;
|
pub use cr4::CR4;
|
||||||
pub use msr_ia32_apic_base::MSR_IA32_APIC_BASE;
|
pub use msr_ia32_apic_base::MSR_IA32_APIC_BASE;
|
||||||
pub use msr_ia32_efer::MSR_IA32_EFER;
|
pub use msr_ia32_efer::MSR_IA32_EFER;
|
||||||
|
@ -6,6 +6,7 @@
|
|||||||
asm_const,
|
asm_const,
|
||||||
panic_info_message,
|
panic_info_message,
|
||||||
optimize_attribute,
|
optimize_attribute,
|
||||||
|
effects,
|
||||||
const_trait_impl,
|
const_trait_impl,
|
||||||
maybe_uninit_slice,
|
maybe_uninit_slice,
|
||||||
arbitrary_self_types,
|
arbitrary_self_types,
|
||||||
@ -14,7 +15,7 @@
|
|||||||
linked_list_cursors,
|
linked_list_cursors,
|
||||||
rustc_private,
|
rustc_private,
|
||||||
allocator_api,
|
allocator_api,
|
||||||
async_fn_in_trait,
|
trait_alias,
|
||||||
strict_provenance
|
strict_provenance
|
||||||
)]
|
)]
|
||||||
#![allow(clippy::new_without_default, clippy::fn_to_numeric_cast)]
|
#![allow(clippy::new_without_default, clippy::fn_to_numeric_cast)]
|
||||||
|
@ -163,14 +163,21 @@ pub unsafe fn init_from_iter<I: Iterator<Item = PhysicalMemoryRegion> + Clone>(
|
|||||||
);
|
);
|
||||||
|
|
||||||
let mut manager = PhysicalMemoryManager::new(page_bitmap_phys_base, total_count);
|
let mut manager = PhysicalMemoryManager::new(page_bitmap_phys_base, total_count);
|
||||||
|
let mut collected = 0;
|
||||||
|
const MAX_MEMORY: usize = 16 * 1024;
|
||||||
|
|
||||||
for (start, end) in it.into_iter().filter_map(PhysicalMemoryRegion::clamp) {
|
for (start, end) in it.into_iter().filter_map(PhysicalMemoryRegion::clamp) {
|
||||||
for page in (start..end).step_by(0x1000) {
|
for page in (start..end).step_by(0x1000) {
|
||||||
|
if collected >= MAX_MEMORY {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
if is_reserved(page) {
|
if is_reserved(page) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
manager.add_available_page(page);
|
manager.add_available_page(page);
|
||||||
|
collected += 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -20,7 +20,7 @@ bitflags! {
|
|||||||
struct PageFlags: u64 {
|
struct PageFlags: u64 {
|
||||||
const PRESENT = 1 << 0;
|
const PRESENT = 1 << 0;
|
||||||
const WRITABLE = 1 << 1;
|
const WRITABLE = 1 << 1;
|
||||||
const NX = 1 << 63;
|
// const NX = 1 << 63;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -38,12 +38,12 @@ pub struct X8664Builder<F: Seek + Read> {
|
|||||||
impl PageFlags {
|
impl PageFlags {
|
||||||
fn from_elf(flags: u32) -> Self {
|
fn from_elf(flags: u32) -> Self {
|
||||||
let mut out = Self::empty();
|
let mut out = Self::empty();
|
||||||
if flags & PF_W != 0 {
|
// if flags & PF_W != 0 {
|
||||||
out |= Self::WRITABLE;
|
out |= Self::WRITABLE;
|
||||||
}
|
// }
|
||||||
if flags & PF_X == 0 {
|
// if flags & PF_X == 0 {
|
||||||
out |= Self::NX;
|
// // out |= Self::NX;
|
||||||
}
|
// }
|
||||||
out
|
out
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -58,7 +58,7 @@ impl fmt::Display for PageFlags {
|
|||||||
} else {
|
} else {
|
||||||
'-'
|
'-'
|
||||||
},
|
},
|
||||||
if self.contains(Self::NX) { '-' } else { 'x' }
|
'x' // if self.contains(Self::NX) { '-' } else { 'x' }
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -98,24 +98,27 @@ impl<F: Seek + Read> X8664Builder<F> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn build(mut self) -> Result<(FixedTables, u64), GenError> {
|
pub fn build(mut self) -> Result<(FixedTables, u64), GenError> {
|
||||||
// L0 -> L1
|
assert_eq!(offset_of!(FixedTables, l0), 0);
|
||||||
let l1_physical_address =
|
let l1_physical_address =
|
||||||
self.data.table_physical_address + offset_of!(FixedTables, kernel_l1) as u64;
|
self.data.table_physical_address + offset_of!(FixedTables, kernel_l1) as u64;
|
||||||
|
let l2_physical_address =
|
||||||
|
self.data.table_physical_address + offset_of!(FixedTables, kernel_l2) as u64;
|
||||||
|
|
||||||
|
// L0 -> L1
|
||||||
self.tables.l0.data[self.l0i] =
|
self.tables.l0.data[self.l0i] =
|
||||||
l1_physical_address | (PageFlags::PRESENT | PageFlags::WRITABLE).bits();
|
l1_physical_address | (PageFlags::PRESENT | PageFlags::WRITABLE).bits();
|
||||||
|
|
||||||
// L1 -> L2
|
// L1 -> L2
|
||||||
let l2_physical_address =
|
|
||||||
self.data.table_physical_address + offset_of!(FixedTables, kernel_l2) as u64;
|
|
||||||
self.tables.kernel_l1.data[self.l1i] =
|
self.tables.kernel_l1.data[self.l1i] =
|
||||||
l2_physical_address | (PageFlags::PRESENT | PageFlags::WRITABLE).bits();
|
l2_physical_address | (PageFlags::PRESENT | PageFlags::WRITABLE).bits();
|
||||||
|
|
||||||
// L2 -> L3s
|
// L2 -> L3s
|
||||||
for i in 0..KERNEL_L3_COUNT {
|
for l2i in self.start_l2i..self.end_l2i {
|
||||||
|
let l3_table_index = l2i - self.start_l2i;
|
||||||
let l3_physical_address = self.data.table_physical_address
|
let l3_physical_address = self.data.table_physical_address
|
||||||
+ (offset_of!(FixedTables, kernel_l3s) + 0x1000 * i) as u64;
|
+ (offset_of!(FixedTables, kernel_l3s) + 0x1000 * l3_table_index) as u64;
|
||||||
|
|
||||||
self.tables.kernel_l2.data[i + self.start_l2i] =
|
self.tables.kernel_l2.data[l2i] =
|
||||||
l3_physical_address | (PageFlags::PRESENT | PageFlags::WRITABLE).bits();
|
l3_physical_address | (PageFlags::PRESENT | PageFlags::WRITABLE).bits();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user