mirror of
https://github.com/asterinas/asterinas.git
synced 2025-06-22 08:53:29 +00:00
Understanding memory space and move higher the stack
This commit is contained in:
committed by
Tate, Hongliang Tian
parent
dede22843a
commit
52f07458f7
@ -14,9 +14,8 @@ pub(crate) use alloc::{
|
||||
pub(crate) use core::{any::Any, ffi::CStr, fmt::Debug};
|
||||
|
||||
pub(crate) use aster_frame::{
|
||||
config::PAGE_SIZE,
|
||||
sync::{Mutex, MutexGuard, RwLock, RwMutex, SpinLock, SpinLockGuard},
|
||||
vm::Vaddr,
|
||||
vm::{Vaddr, PAGE_SIZE},
|
||||
};
|
||||
pub(crate) use bitflags::bitflags;
|
||||
pub(crate) use int_to_c_enum::TryFromInt;
|
||||
|
@ -14,30 +14,40 @@ use user_heap::UserHeap;
|
||||
use crate::vm::vmar::Vmar;
|
||||
|
||||
/*
|
||||
* The user vm space layout is look like below.
|
||||
* |-----------------------|-------The highest user vm address
|
||||
* | |
|
||||
* | Mmap Areas |
|
||||
* | |
|
||||
* | |
|
||||
* --------------------------------The init stack base
|
||||
* | |
|
||||
* | User Stack(Init Stack)|
|
||||
* | |
|
||||
* | || |
|
||||
* ----------||----------------------The user stack top, grows down
|
||||
* | \/ |
|
||||
* | |
|
||||
* | Unmapped Areas |
|
||||
* | |
|
||||
* | /\ |
|
||||
* ----------||---------------------The user heap top, grows up
|
||||
* | || |
|
||||
* | |
|
||||
* | User Heap |
|
||||
* | |
|
||||
* ----------------------------------The user heap base
|
||||
*/
|
||||
* The user's virtual memory space layout looks like below.
|
||||
* TODO: The layout of the userheap does not match the current implementation,
|
||||
* And currently the initial program break is a fixed value.
|
||||
*
|
||||
* (high address)
|
||||
* +---------------------+ <------+ The top of Vmar, which is the highest address usable
|
||||
* | | Randomly padded pages
|
||||
* +---------------------+ <------+ The base of the initial user stack
|
||||
* | User stack |
|
||||
* | |
|
||||
* +---------||----------+ <------+ The user stack limit, can be extended lower
|
||||
* | \/ |
|
||||
* | ... |
|
||||
* | |
|
||||
* | MMAP Spaces |
|
||||
* | |
|
||||
* | ... |
|
||||
* | /\ |
|
||||
* +---------||----------+ <------+ The current program break
|
||||
* | User heap |
|
||||
* | |
|
||||
* +---------------------+ <------+ The original program break
|
||||
* | | Randomly padded pages
|
||||
* +---------------------+ <------+ The end of the program's last segment
|
||||
* | |
|
||||
* | Loaded segments |
|
||||
* | .text, .data, .bss |
|
||||
* | , etc. |
|
||||
* | |
|
||||
* +---------------------+ <------+ The bottom of Vmar at 0x1_0000
|
||||
* | | 64 KiB unusable space
|
||||
* +---------------------+
|
||||
* (low address)
|
||||
*/
|
||||
|
||||
/// The virtual space usage.
|
||||
/// This struct is used to control brk and mmap now.
|
||||
|
@ -7,7 +7,7 @@
|
||||
use core::mem;
|
||||
|
||||
use align_ext::AlignExt;
|
||||
use aster_frame::vm::{VmIo, VmPerm};
|
||||
use aster_frame::vm::{VmIo, VmPerm, MAX_USERSPACE_VADDR};
|
||||
use aster_rights::{Full, Rights};
|
||||
|
||||
use super::{
|
||||
@ -20,15 +20,16 @@ use crate::{
|
||||
vm::{perms::VmPerms, vmar::Vmar, vmo::VmoOptions},
|
||||
};
|
||||
|
||||
pub const INIT_STACK_BASE: Vaddr = 0x0000_0000_2000_0000;
|
||||
pub const INIT_STACK_SIZE: usize = 0x1000 * 16; // 64KB
|
||||
pub const INIT_STACK_SIZE: usize = 64 * 1024; // 64 KiB
|
||||
|
||||
/*
|
||||
* The initial stack of a process looks like below(This figure is from occlum):
|
||||
* Illustration of the virtual memory space containing the processes' init stack:
|
||||
*
|
||||
*
|
||||
* +---------------------+ <------+ Top of stack
|
||||
* | | (high address)
|
||||
* (high address)
|
||||
* +---------------------+ <------+ Highest address
|
||||
* | | Random stack paddings
|
||||
* +---------------------+ <------+ The base of stack (stack grows down)
|
||||
* | |
|
||||
* | Null-terminated |
|
||||
* | strings referenced |
|
||||
* | by variables below |
|
||||
@ -62,8 +63,10 @@ pub const INIT_STACK_SIZE: usize = 0x1000 * 16; // 64KB
|
||||
* +---------------------+
|
||||
* | |
|
||||
* | |
|
||||
* + +
|
||||
*
|
||||
* +---------------------+
|
||||
* | |
|
||||
* +---------------------+ <------+ User stack default rlimit
|
||||
* (low address)
|
||||
*/
|
||||
pub struct InitStack {
|
||||
/// The high address of init stack
|
||||
@ -93,9 +96,13 @@ impl InitStack {
|
||||
}
|
||||
}
|
||||
|
||||
/// This function only work for first process
|
||||
pub fn new_default_config(argv: Vec<CString>, envp: Vec<CString>) -> Self {
|
||||
let init_stack_top = INIT_STACK_BASE - PAGE_SIZE;
|
||||
let nr_pages_padding = {
|
||||
let mut random_nr_pages_padding: u8 = 0;
|
||||
getrandom::getrandom(random_nr_pages_padding.as_bytes_mut()).unwrap();
|
||||
random_nr_pages_padding as usize
|
||||
};
|
||||
let init_stack_top = MAX_USERSPACE_VADDR - PAGE_SIZE * nr_pages_padding;
|
||||
let init_stack_size = INIT_STACK_SIZE;
|
||||
InitStack::new(init_stack_top, init_stack_size, argv, envp)
|
||||
}
|
||||
|
@ -13,7 +13,10 @@
|
||||
|
||||
use alloc::{boxed::Box, sync::Arc};
|
||||
|
||||
use aster_frame::{config::PAGE_SIZE, sync::Mutex, vm::VmIo};
|
||||
use aster_frame::{
|
||||
sync::Mutex,
|
||||
vm::{VmIo, PAGE_SIZE},
|
||||
};
|
||||
use aster_rights::Rights;
|
||||
use aster_time::Instant;
|
||||
use aster_util::coeff::Coeff;
|
||||
|
@ -11,7 +11,7 @@ pub mod vm_mapping;
|
||||
use core::ops::Range;
|
||||
|
||||
use align_ext::AlignExt;
|
||||
use aster_frame::vm::VmSpace;
|
||||
use aster_frame::vm::{VmSpace, MAX_USERSPACE_VADDR};
|
||||
use aster_rights::Rights;
|
||||
|
||||
use self::{
|
||||
@ -124,11 +124,8 @@ impl VmarInner {
|
||||
}
|
||||
}
|
||||
|
||||
// FIXME: How to set the correct root vmar range?
|
||||
// We should not include addr 0 here(is this right?), since the 0 addr means the null pointer.
|
||||
// We should include addr 0x0040_0000, since non-pie executables typically are put on 0x0040_0000.
|
||||
const ROOT_VMAR_LOWEST_ADDR: Vaddr = 0x0010_0000;
|
||||
const ROOT_VMAR_HIGHEST_ADDR: Vaddr = 0x1000_0000_0000;
|
||||
const ROOT_VMAR_LOWEST_ADDR: Vaddr = 0x001_0000; // 64 KiB is the Linux configurable default
|
||||
const ROOT_VMAR_CAP_ADDR: Vaddr = MAX_USERSPACE_VADDR;
|
||||
|
||||
impl Interval<usize> for Arc<Vmar_> {
|
||||
fn range(&self) -> Range<usize> {
|
||||
@ -161,7 +158,7 @@ impl Vmar_ {
|
||||
|
||||
pub fn new_root() -> Arc<Self> {
|
||||
let mut free_regions = BTreeMap::new();
|
||||
let root_region = FreeRegion::new(ROOT_VMAR_LOWEST_ADDR..ROOT_VMAR_HIGHEST_ADDR);
|
||||
let root_region = FreeRegion::new(ROOT_VMAR_LOWEST_ADDR..ROOT_VMAR_CAP_ADDR);
|
||||
free_regions.insert(root_region.start(), root_region);
|
||||
let vmar_inner = VmarInner {
|
||||
is_destroyed: false,
|
||||
@ -169,7 +166,7 @@ impl Vmar_ {
|
||||
vm_mappings: BTreeMap::new(),
|
||||
free_regions,
|
||||
};
|
||||
Vmar_::new(vmar_inner, VmSpace::new(), 0, ROOT_VMAR_HIGHEST_ADDR, None)
|
||||
Vmar_::new(vmar_inner, VmSpace::new(), 0, ROOT_VMAR_CAP_ADDR, None)
|
||||
}
|
||||
|
||||
fn is_root_vmar(&self) -> bool {
|
||||
@ -279,7 +276,7 @@ impl Vmar_ {
|
||||
inner.child_vmar_s.clear();
|
||||
inner.vm_mappings.clear();
|
||||
inner.free_regions.clear();
|
||||
let root_region = FreeRegion::new(ROOT_VMAR_LOWEST_ADDR..ROOT_VMAR_HIGHEST_ADDR);
|
||||
let root_region = FreeRegion::new(ROOT_VMAR_LOWEST_ADDR..ROOT_VMAR_CAP_ADDR);
|
||||
inner.free_regions.insert(root_region.start(), root_region);
|
||||
Ok(())
|
||||
}
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
//! Options for allocating child VMARs.
|
||||
|
||||
use aster_frame::{config::PAGE_SIZE, Error, Result};
|
||||
use aster_frame::{vm::PAGE_SIZE, Error, Result};
|
||||
|
||||
use super::Vmar;
|
||||
|
||||
@ -142,14 +142,14 @@ mod test {
|
||||
use crate::vm::{
|
||||
page_fault_handler::PageFaultHandler,
|
||||
perms::VmPerms,
|
||||
vmar::ROOT_VMAR_HIGHEST_ADDR,
|
||||
vmar::ROOT_VMAR_CAP_ADDR,
|
||||
vmo::{VmoOptions, VmoRightsOp},
|
||||
};
|
||||
|
||||
#[ktest]
|
||||
fn root_vmar() {
|
||||
let vmar = Vmar::<Full>::new_root();
|
||||
assert!(vmar.size() == ROOT_VMAR_HIGHEST_ADDR);
|
||||
assert!(vmar.size() == ROOT_VMAR_CAP_ADDR);
|
||||
}
|
||||
|
||||
#[ktest]
|
||||
|
@ -49,7 +49,7 @@ use self::{
|
||||
prelude::*,
|
||||
};
|
||||
|
||||
pub const BLOCK_SIZE: usize = aster_frame::config::PAGE_SIZE;
|
||||
pub const BLOCK_SIZE: usize = aster_frame::vm::PAGE_SIZE;
|
||||
pub const SECTOR_SIZE: usize = 512;
|
||||
|
||||
pub trait BlockDevice: Send + Sync + Any + Debug {
|
||||
|
@ -13,7 +13,12 @@ use core::{
|
||||
ops::{Index, IndexMut},
|
||||
};
|
||||
|
||||
use aster_frame::{boot, config::PAGE_SIZE, io_mem::IoMem, sync::SpinLock, vm::VmIo};
|
||||
use aster_frame::{
|
||||
boot,
|
||||
io_mem::IoMem,
|
||||
sync::SpinLock,
|
||||
vm::{VmIo, PAGE_SIZE},
|
||||
};
|
||||
use component::{init_component, ComponentInitError};
|
||||
use font8x8::UnicodeFonts;
|
||||
use spin::Once;
|
||||
|
@ -4,7 +4,7 @@ use alloc::{boxed::Box, fmt::Debug, string::ToString, sync::Arc, vec::Vec};
|
||||
use core::hint::spin_loop;
|
||||
|
||||
use aster_console::{AnyConsoleDevice, ConsoleCallback};
|
||||
use aster_frame::{config::PAGE_SIZE, io_mem::IoMem, sync::SpinLock, trap::TrapFrame};
|
||||
use aster_frame::{io_mem::IoMem, sync::SpinLock, trap::TrapFrame, vm::PAGE_SIZE};
|
||||
use aster_util::safe_ptr::SafePtr;
|
||||
use log::debug;
|
||||
|
||||
|
@ -8,12 +8,11 @@ use aster_frame::{
|
||||
bus::MmioDevice,
|
||||
device::{MmioCommonDevice, VirtioMmioVersion},
|
||||
},
|
||||
config::PAGE_SIZE,
|
||||
io_mem::IoMem,
|
||||
offset_of,
|
||||
sync::RwLock,
|
||||
trap::IrqCallbackFunction,
|
||||
vm::DmaCoherent,
|
||||
vm::{DmaCoherent, PAGE_SIZE},
|
||||
};
|
||||
use aster_rights::{ReadOp, WriteOp};
|
||||
use aster_util::{field_ptr, safe_ptr::SafePtr};
|
||||
|
Reference in New Issue
Block a user