1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
use core::mem::size_of;
use crate::paging::*;
use crate::address::VirtualAddress;
use sunrise_libutils::log2_ceil;
pub const STACK_SIZE: usize = 8;
pub const STACK_SIZE_WITH_GUARD: usize = STACK_SIZE + 1;
const STACK_SIZE_WITH_GUARD_IN_BYTES: usize = STACK_SIZE_WITH_GUARD * PAGE_SIZE;
const STACK_ALIGNMENT: usize = log2_ceil(STACK_SIZE_WITH_GUARD_IN_BYTES);
#[derive(Debug)]
pub struct BootstrapStack {
stack_address: VirtualAddress
}
impl BootstrapStack {
pub fn allocate_stack() -> Option<BootstrapStack> {
let mut tables = ACTIVE_PAGE_TABLES.lock();
tables.find_available_virtual_space_aligned::<KernelLand>(STACK_SIZE_WITH_GUARD, STACK_ALIGNMENT)
.map(|va| {
tables.map_range_allocate(VirtualAddress(va.addr() + PAGE_SIZE), STACK_SIZE,
EntryFlags::WRITABLE);
tables.map_page_guard(va);
let mut me = BootstrapStack { stack_address: va };
unsafe {
me.create_poison_pointers();
};
me
})
}
const STACK_POISON_SIZE: usize = 2 * size_of::<usize>();
unsafe fn create_poison_pointers(&mut self) {
let saved_eip: *mut usize = (self.stack_address.addr() + STACK_SIZE_WITH_GUARD * PAGE_SIZE
- size_of::<usize>()
) as *mut usize;
let saved_ebp: *mut usize = saved_eip.offset(-1);
*saved_eip = 0x00000000;
*saved_ebp = 0x00000000;
}
pub fn get_stack_start(&self) -> usize {
self.stack_address.addr() + STACK_SIZE_WITH_GUARD * PAGE_SIZE
- Self::STACK_POISON_SIZE
}
}