19 #define _STIVALE2_SPLIT_64
20 #include <stivale/stivale2.h>
22 #define KERNEL_STACK_SZ 4 * ARCH_PAGE_SIZE // stage2 & stage3 (kernel) stack size
23 #define STIVALE2_MAGIC 0x73747632 // "stv2"
35 struct
Table lowMemoryPageTable;
39 struct
Table kernelPageTable[2];
43 struct
Table bootPageTable;
47 struct
Table stackPageTable;
51 struct stivale2_struct *stivale2Info;
65 static
void stage1MapBootloader(
void);
66 static
void stage1MapHighMemory(
void);
67 static
void stage1MapLowMemory(
void);
68 static
void stage1Entry(struct stivale2_struct *info);
69 static uint32_t stage1GetBootInfoAddr(struct stivale2_tag* tag);
78 static uint32_t stage1GetBootInfoAddr(struct stivale2_tag* tag)
81 switch (tag->identifier) {
82 case STIVALE2_STRUCT_TAG_MEMMAP_ID:
84 struct stivale2_struct_tag_memmap* memmap = (
struct stivale2_struct_tag_memmap*)tag;
85 for (
size_t i = 0; i < memmap->entries; i++) {
86 switch (memmap->memmap[i].type)
88 case STIVALE2_MMAP_BOOTLOADER_RECLAIMABLE:
89 if (((uint32_t)memmap->memmap[i].base) == (uint32_t)tag) {
90 return (uint32_t)memmap->memmap[i].length;
102 tag = (
struct stivale2_tag*)(uint32_t)tag->next;
105 EarlyPanic(
"Error: Cannot detect bootloader info length!");
114 static
void stage1EnablePaging(
void)
116 setPageDirectory((uintptr_t)&pageDirectory);
118 struct CR0 cr0 = readCR0();
128 static void stage1JumpToStage2(
void)
131 for (
size_t i = 0; i < (size_t)&
_BSS_SIZE; i++) {
144 :
"i" ((stage2Stack +
sizeof(stage2Stack)))
146 ,
"rm" (stivale2Info)
150 __builtin_unreachable();
159 static
void stage1MapBootloader(
void)
162 uint32_t stivale2InfoAddr = (uint32_t)stivale2Info->tags;
166 struct DirectoryEntry* bootDirectoryEntry = &pageDirectory.entries[bootDirectoryEntryIdx];
169 struct Table *bootTable;
170 if (bootDirectoryEntry->present) {
173 bootDirectoryEntry->present = 1;
174 bootDirectoryEntry->readWrite = 1;
176 bootTable = &bootPageTable;
180 struct stivale2_tag *tags = (
struct stivale2_tag *)(uintptr_t)stivale2Info->tags;
181 uint32_t stivale2InfoLength = stage1GetBootInfoAddr(tags);
182 uint32_t stivale2InfoEnd = stivale2InfoAddr + stivale2InfoLength;
185 for (uintptr_t addr = stivale2InfoAddr; addr < stivale2InfoEnd; addr +=
ARCH_PAGE_SIZE) {
190 bootTableEntry->
frame = bootMemoryIdx;
200 static
void stage1MapHighMemory(
void)
205 struct DirectoryEntry* kernelDirectoryEntry = &pageDirectory.entries[kernelDirectoryEntryIdx];
206 kernelDirectoryEntry->
present = 1;
211 struct DirectoryEntry* pagesDirectoryEntry = kernelDirectoryEntry + 1;
212 pagesDirectoryEntry->
present = 1;
221 kernelMemoryTableEntry->
present = 1;
232 static
void stage1MapLowMemory(
void)
246 lowMemoryTableEntry->
present = 1;
248 lowMemoryTableEntry->
frame = pageIdx;
259 static
void stage1Entry(struct stivale2_struct *info)
266 EarlyPanic(
"Error: Missing bootloader information!");
274 stage1MapLowMemory();
275 stage1MapHighMemory();
276 stage1MapBootloader();
277 stage1EnablePaging();
278 stage1JumpToStage2();
294 const struct stivale2_header_tag_framebuffer framebuffer_hdr_tag = {
296 .identifier = STIVALE2_HEADER_TAG_FRAMEBUFFER_ID,
299 .framebuffer_width = 0,
300 .framebuffer_height = 0,
301 .framebuffer_bpp = 0,
305 const struct stivale2_header stivale_hdr = {
306 .entry_point = (uint32_t)stage1Entry,
307 .stack = (uint32_t)stage1Stack +
sizeof(stage1Stack),
309 .tags = (uint32_t)&framebuffer_hdr_tag,