Skip to content

Commit 861c745

Browse files
Attempt userland
1 parent 6c72f8c commit 861c745

6 files changed

Lines changed: 58 additions & 94 deletions

File tree

source/boot/libFrostedWM.so

-196 KB
Binary file not shown.

source/includes/paging.h

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,20 +15,17 @@
1515
#include <userland.h>
1616

1717
#define PAGE_SIZE 4096ULL
18-
#define MEMORY_START 0x10000000ULL
19-
#define MEMORY_END 0x2000000000ULL
20-
#define AMOUNT_OF_PAGES ((MEMORY_END - MEMORY_START) / PAGE_SIZE)
2118

22-
#define KERNEL_OFFSET 0xFFFFFFFE80000000ULL
2319
#define PAGE_PRESENT 0x1
2420
#define PAGE_RW 0x2
2521
#define PAGE_USER 0x4
2622
#define PAGE_NX (1ULL << 63)
27-
#define PAGE_SIZE 0x1000 // 4 KB
2823

2924
#define USER_CODE_FLAGS (PAGE_PRESENT | PAGE_USER) // executable
3025
#define USER_DATA_FLAGS (PAGE_PRESENT | PAGE_USER | PAGE_RW | PAGE_NX)
3126

27+
#define KERNEL_PHYS_OFFSET 0xFFFF800000000000ULL
28+
3229
/**
3330
* @brief Function to initialize the page bitmap
3431
*
@@ -68,6 +65,6 @@ void setup_userland_memory();
6865
* @brief Maps user code in paging.
6966
*
7067
*/
71-
void map_user_code();
68+
void map_user_code(uint64_t code_entry);
7269

7370
#endif

source/includes/userland.h

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -13,16 +13,12 @@
1313

1414
#include <basics.h>
1515
#include <syscalls.h>
16-
17-
#define USER_STACK_SIZE 0x4000 // 16 KB
18-
#define USER_HEAP_VADDR 0x50000000
19-
#define USER_HEAP_SIZE 0x100000 // 1 MB
20-
#define USER_CODE_VADDR 0x1000000ULL
21-
#define USER_STACK_VADDR 0x4000000ULL
22-
#define USER_STACK_TOP 0x7FFFFFF000ULL
2316

17+
#define USER_STACK_SIZE (16 * 1024)
18+
#define USER_HEAP_SIZE (1 * 1024 * 1024)
2419

25-
extern void userland_main();
26-
extern void enter_userland();
20+
#define USER_CODE_VADDR 0x40000000ULL // 1 GB
21+
#define USER_HEAP_VADDR 0x50000000ULL // 1.25 GB
22+
#define USER_STACK_TOP 0x7FFFFFF000ULL // top of canonical user space
2723

28-
#endif
24+
#endif

source/kernel/C/kernel.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -159,7 +159,7 @@ void main(void) {
159159

160160
mm_print_out();
161161

162-
initialize_page_bitmap((int64)virtual_to_physical(kstart), (int64)virtual_to_physical(kend));
162+
initialize_page_bitmap((int64)(kstart), (int64)(kend));
163163

164164
setup_gdt();
165165
initIdt();
@@ -223,7 +223,7 @@ void main(void) {
223223

224224
info("Welcome to FrostWing Operating System!", "(https://github.com/Frost-Wing)");
225225

226-
// enter_userland();
226+
// enter_userland(module_request.response->modules[0]->address, module_request.response->modules[0]->size);
227227
sh_exec();
228228
}
229229

source/kernel/C/paging.c

Lines changed: 13 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -18,22 +18,23 @@ int8* page_bitmap;
1818
extern uint8_t user_code_start[];
1919
extern uint8_t user_code_end[];
2020

21-
static void mark_page_used(uint64_t addr) {
22-
if (addr < MEMORY_START || addr >= MEMORY_END) return;
23-
size_t page_index = (addr - MEMORY_START) / PAGE_SIZE;
24-
size_t byte = page_index / 8;
25-
size_t bit = page_index % 8;
26-
page_bitmap[byte] |= (1 << bit);
21+
inline void* phys_to_virt(uint64_t phys) {
22+
return (void*)(phys + KERNEL_PHYS_OFFSET);
2723
}
2824

29-
static void mark_page_free(uint64_t addr) {
30-
if (addr < MEMORY_START || addr >= MEMORY_END) return;
31-
size_t page_index = (addr - MEMORY_START) / PAGE_SIZE;
32-
size_t byte = page_index / 8;
33-
size_t bit = page_index % 8;
34-
page_bitmap[byte] &= ~(1 << bit);
25+
void mark_page_used(uint64_t addr) {
26+
if (addr < memory_start || addr >= memory_end) return;
27+
size_t page_index = (addr - memory_start) / PAGE_SIZE;
28+
page_bitmap[page_index / 8] |= (1 << (page_index % 8));
3529
}
3630

31+
void mark_page_free(uint64_t addr) {
32+
if (addr < memory_start || addr >= memory_end) return;
33+
size_t page_index = (addr - memory_start) / PAGE_SIZE;
34+
page_bitmap[page_index / 8] &= ~(1 << (page_index % 8));
35+
}
36+
37+
3738
void initialize_page_bitmap(int64 kernel_start, int64 kernel_end) {
3839
info("Initializing paging", __FILE__);
3940

@@ -159,44 +160,3 @@ void map_user_page(uint64_t virt, uint64_t phys, uint64_t flags) {
159160
// Flush TLB
160161
asm volatile("invlpg (%0)" ::"r"(virt) : "memory");
161162
}
162-
163-
void map_user_code() {
164-
uint64_t size = (uint64_t)user_code_end - (uint64_t)user_code_start;
165-
166-
debug_printf("size of user code -> %z\n", size);
167-
debug_printf("user code start -> %z\n", user_code_start);
168-
debug_printf("user code end -> %z\n", user_code_end);
169-
170-
for (uint64_t off = 0; off < size; off += PAGE_SIZE) {
171-
void* kernel_va = allocate_page();
172-
uint64_t phys = (int64)virtual_to_physical((int64)kernel_va);
173-
174-
if (!phys)
175-
error("page allocation failed", __FILE__);
176-
else
177-
info("page allocation is fine", __FILE__);
178-
179-
uint64_t vaddr = USER_CODE_VADDR + off;
180-
map_user_page(vaddr, phys, USER_CODE_FLAGS);
181-
info("map_user_code: mapped executable user page", __FILE__);
182-
183-
// Verify mapping
184-
uint64_t resolved = virtual_to_physical(vaddr) & ~0xFFF;
185-
if (resolved != (phys & ~0xFFF)) {
186-
error("map_user_code: VA->PA mismatch", __FILE__);
187-
} else {
188-
info("map_user_code: VA->PA matches", __FILE__);
189-
}
190-
191-
// The code bytes to copy.
192-
uint64_t copy = (size - off >= PAGE_SIZE) ? PAGE_SIZE : (size - off);
193-
memcpy(kernel_va, user_code_start + off, copy);
194-
195-
// Verify the copy of userland.
196-
if (memcmp(kernel_va, user_code_start + off, copy) != 0) {
197-
error("map_user_code: memcpy verification failed", __FILE__);
198-
} else {
199-
info("map_user_code: memcpy verification succeeded", __FILE__);
200-
}
201-
}
202-
}

source/kernel/C/userland.c

Lines changed: 34 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -17,36 +17,47 @@ void user_entry() {
1717
}
1818

1919
// Map user code and stack
20-
void setup_userland_heap() {
21-
for (uint64_t offset = 0; offset < USER_HEAP_SIZE; offset += 0x1000) {
22-
void *phys = allocate_page(); // get real physical page
23-
map_user_page(USER_HEAP_VADDR + offset, (uint64_t)phys, 0); // non-executable
20+
// void setup_userland_heap() {
21+
// for (uint64_t offset = 0; offset < USER_HEAP_SIZE; offset += 0x1000) {
22+
// void *phys = allocate_page(); // get real physical page
23+
// map_user_page(USER_HEAP_VADDR + offset, (uint64_t)phys, 0); // non-executable
24+
// }
25+
// done("Userland heap mapped", __FILE__);
26+
// }
27+
28+
void map_user_code_physical(uint64_t code_phys, uint64_t code_size) {
29+
uint64_t phys_page = code_phys & ~0xFFFULL; // round down
30+
uint64_t offset = code_phys & 0xFFFULL; // offset into first page
31+
uint64_t mapped = 0;
32+
33+
while (mapped < code_size) {
34+
uint64_t to_map = PAGE_SIZE;
35+
map_user_page(USER_CODE_VADDR + mapped, phys_page, USER_CODE_FLAGS);
36+
37+
mark_page_used(phys_page); // prevent reuse
38+
mapped += to_map - (mapped == 0 ? offset : 0);
39+
phys_page += PAGE_SIZE;
2440
}
25-
done("Userland heap mapped", __FILE__);
2641
}
2742

28-
void enter_userland() {
29-
printf("Setting up kernel to move to userland...\n");
3043

31-
map_user_code();
32-
// setup_userland_heap();
44+
void enter_userland(uint64_t code_phys, uint64_t code_size) {
45+
printf("Setting up kernel to move to userland...\n");
3346

47+
uint64_t code_entry = code_phys;
3448
uint64_t stack_top = USER_STACK_TOP;
35-
uint64_t code_entry = USER_CODE_VADDR;
36-
37-
// Map user stack
38-
for (uint64_t off = 0; off < USER_STACK_SIZE; off += 0x1000) {
39-
void *phys = allocate_page();
40-
map_user_page(USER_STACK_TOP - off - 0x1000,
41-
(uint64_t)phys,
42-
USER_DATA_FLAGS);
43-
}
4449

45-
done("Switching to userland...", __FILE__);
46-
debug_printf("User RIP target = %z\n", code_entry);
47-
debug_printf("User RSP target = %z\n", stack_top);
50+
// Map the user code pages from the passed physical address
51+
map_user_code_physical(code_phys, code_size);
52+
53+
// Map the user stack pages
54+
for (uint64_t off = 0; off < USER_STACK_SIZE; off += PAGE_SIZE) {
55+
uint64_t phys = (uint64_t)allocate_page();
56+
uint64_t vaddr = stack_top - off - PAGE_SIZE;
57+
map_user_page(vaddr, phys, USER_DATA_FLAGS);
58+
}
4859

49-
// 🔥 Actually enter userland
60+
// Switch to userland
5061
asm volatile (
5162
"cli\n"
5263
"pushq $0x23\n" // User SS
@@ -59,4 +70,4 @@ void enter_userland() {
5970
: "r"(stack_top), "r"(code_entry)
6071
: "memory"
6172
);
62-
}
73+
}

0 commit comments

Comments
 (0)