Skip to content

Commit 72a46bc

Browse files
committed
I don't even know what to write at this point
1 parent df0ebbb commit 72a46bc

File tree

12 files changed

+222
-83
lines changed

12 files changed

+222
-83
lines changed

boot/arch/x86_64/common/mm/paging.c

+36-20
Original file line numberDiff line numberDiff line change
@@ -21,48 +21,64 @@
2121
#include <mm/vmm.h>
2222
#include <lib/string.h>
2323
#include <print.h>
24+
#include <axboot.h>
2425
#include <stdint.h>
2526

2627
/* Trimmed down version of */
2728
/* https://github.com/KevinAlavik/nekonix/blob/main/kernel/src/mm/vmm.c */
2829
/* Thanks, Kevin <3 */
2930

30-
void map_page(uintptr_t *pm, uintptr_t virt, uintptr_t phys, uint64_t flags)
31+
void map_pages(pagetable *pm, uintptr_t virt, uintptr_t phys, size_t size, uint64_t flags)
3132
{
32-
uint64_t pml1_idx = (virt & (uint64_t)0x1ff << 12) >> 12;
33-
uint64_t pml2_idx = (virt & (uint64_t)0x1ff << 21) >> 21;
34-
uint64_t pml3_idx = (virt & (uint64_t)0x1ff << 30) >> 30;
35-
uint64_t pml4_idx = (virt & (uint64_t)0x1ff << 39) >> 39;
33+
for (size_t i = 0; i < ROUND_UP(size, PAGE_SIZE); i += PAGE_SIZE) {
34+
map_page(pm, virt + i, phys + i, flags);
35+
}
36+
}
3637

37-
if (!(pm[pml4_idx] & 1)) {
38-
pm[pml4_idx] = (uint64_t)mem_alloc(PAGE_SIZE) | flags;
38+
void map_page(pagetable *pm, uintptr_t virt, uintptr_t phys, uint64_t flags)
39+
{
40+
uint64_t pml1_idx = (virt >> 12) & 0x1ff;
41+
uint64_t pml2_idx = (virt >> 21) & 0x1ff;
42+
uint64_t pml3_idx = (virt >> 30) & 0x1ff;
43+
uint64_t pml4_idx = (virt >> 39) & 0x1ff;
44+
45+
if (!(pm->entries[pml4_idx] & 1)) {
46+
void *pml4 = mem_alloc(PAGE_SIZE);
47+
memset(pml4, 0, sizeof(pagetable));
48+
pm->entries[pml4_idx] = (uint64_t)pml4 | VMM_PRESENT | VMM_WRITABLE | VMM_USER;
3949
}
4050

41-
uint64_t *pml3_table = (uint64_t *)(pm[pml4_idx] & 0x000FFFFFFFFFF000);
42-
if (!(pml3_table[pml3_idx] & 1)) {
43-
pml3_table[pml3_idx] = (uint64_t)mem_alloc(PAGE_SIZE) | flags;
51+
pagetable *pml3_table = (pagetable *)(pm->entries[pml4_idx] & 0x000FFFFFFFFFF000);
52+
if (!(pml3_table->entries[pml3_idx] & 1)) {
53+
void *pml3 = mem_alloc(PAGE_SIZE);
54+
memset(pml3, 0, sizeof(pagetable));
55+
pml3_table->entries[pml3_idx] = (uint64_t)pml3 | VMM_PRESENT | VMM_WRITABLE | VMM_USER;
4456
}
4557

46-
uint64_t *pml2_table = (uint64_t *)(pml3_table[pml3_idx] & 0x000FFFFFFFFFF000);
47-
if (!(pml2_table[pml2_idx] & 1)) {
48-
pml2_table[pml2_idx] = (uint64_t)mem_alloc(PAGE_SIZE) | flags;
58+
pagetable *pml2_table = (pagetable *)(pml3_table->entries[pml3_idx] & 0x000FFFFFFFFFF000);
59+
if (!(pml2_table->entries[pml2_idx] & 1)) {
60+
void *pml2 = mem_alloc(PAGE_SIZE);
61+
memset(pml2, 0, sizeof(pagetable));
62+
pml2_table->entries[pml2_idx] = (uint64_t)pml2 | VMM_PRESENT | VMM_WRITABLE | VMM_USER;
4963
}
5064

51-
uint64_t *pml1_table = (uint64_t *)(pml2_table[pml2_idx] & 0x000FFFFFFFFFF000);
52-
pml1_table[pml1_idx] = phys | flags;
65+
pagetable *pml1_table = (pagetable *)(pml2_table->entries[pml2_idx] & 0x000FFFFFFFFFF000);
66+
if (!(pml1_table->entries[pml1_idx] & 1)) {
67+
pml1_table->entries[pml1_idx] = (phys | 0x000FFFFFFFFFF000) | flags;
68+
}
5369

54-
debug("map_page(): Mapped 0x%lx -> 0x%lx\n", phys, virt);
70+
debug("map_page(): Mapped 0x%llx -> 0x%llx\n", phys, virt);
5571
}
5672

57-
uintptr_t *create_pagemap()
73+
pagetable *create_pagemap()
5874
{
59-
uint64_t *pm = (uint64_t *)mem_alloc(PAGE_SIZE);
75+
pagetable *pm = (pagetable *)mem_alloc(PAGE_SIZE);
6076
if (!pm) {
6177
debug("create_pagemap(): Failed to allocate memory for a new pm.\n");
6278
return NULL;
6379
}
64-
memset(pm, 0, PAGE_SIZE);
80+
memset(pm, 0, sizeof(pagetable));
6581

66-
debug("create_pagemap(): Created new pm at 0x%lx\n", (uint64_t)pm);
82+
debug("create_pagemap(): Created new pm at 0x%llx\n", (uint64_t)pm);
6783
return pm;
6884
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
.globl _aurix_handoff_start
2+
.globl _aurix_handoff_end
3+
.globl aurix_handoff
4+
5+
aurix_handoff:
6+
cli
7+
movq %rsi, %rsp
8+
_aurix_handoff_start:
9+
movq %rdi, %cr3
10+
jmpq *%rdx
11+
_aurix_handoff_end:

boot/common/init.c

+2-17
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
#include <vfs/vfs.h>
2121
#include <mm/mman.h>
2222
#include <mm/vmm.h>
23-
#include <loader/elf.h>
23+
#include <proto/aurix.h>
2424
#include <print.h>
2525

2626
void axboot_init()
@@ -31,22 +31,7 @@ void axboot_init()
3131
while (1);
3232
}
3333

34-
// read kernel -> test read
35-
char *kbuf = NULL;
36-
vfs_read("\\System\\axkrnl", &kbuf);
37-
38-
// TODO: Do something with the kernel :p
39-
uintptr_t *pm = create_pagemap();
40-
if (!pm) {
41-
debug("axboot_init(): Failed to create kernel pagemap! Halting...\n");
42-
// TODO: Halt
43-
while (1);
44-
}
45-
46-
void *kernel_entry = (void *)elf_load(kbuf, pm);
47-
(void)kernel_entry;
48-
49-
mem_free(kbuf);
34+
aurix_load("\\System\\axkrnl");
5035

5136
while (1);
5237
}

boot/common/loader/elf.c

+57-33
Original file line numberDiff line numberDiff line change
@@ -28,58 +28,82 @@
2828
/* https://github.com/KevinAlavik/nekonix/blob/main/kernel/src/proc/elf.c */
2929
/* Thanks, Kevin <3 */
3030

31-
uint64_t elf_load(char *data, uintptr_t *pagemap)
31+
uintptr_t elf32_load(char *data, pagetable *pagemap)
32+
{
33+
(void)data;
34+
(void)pagemap;
35+
return 0;
36+
}
37+
38+
uintptr_t elf64_load(char *data, pagetable *pagemap)
3239
{
3340
struct elf_header *header = (struct elf_header *)data;
41+
struct elf_program_header *ph = (struct elf_program_header *)((uint8_t *)data + header->e_phoff);
3442

35-
if (header->e_magic != ELF_MAGIC) {
36-
debug("Invalid ELF magic: 0x%x", header->e_magic);
37-
return 0;
38-
}
43+
uint64_t lowest = UINT64_MAX;
44+
uint64_t max_align = 0;
3945

40-
if (header->e_class != 2) {
41-
debug("Unsupported ELF class: %u", header->e_class);
42-
return 0;
46+
for (uint16_t i = 0; i < header->e_phnum; i++) {
47+
if (ph[i].p_type != PT_LOAD)
48+
continue;
49+
50+
if (ph[i].p_align > max_align) {
51+
max_align = ph[i].p_align;
52+
}
4353
}
4454

45-
struct elf_program_header *ph = (struct elf_program_header *)(data + header->e_phoff);
46-
4755
for (uint16_t i = 0; i < header->e_phnum; i++) {
4856
if (ph[i].p_type != PT_LOAD)
4957
continue;
50-
51-
uint64_t vaddr_start = ALIGN_DOWN(ph[i].p_vaddr, PAGE_SIZE);
52-
uint64_t vaddr_end = ALIGN_UP(ph[i].p_vaddr + ph[i].p_memsz, PAGE_SIZE);
53-
uint64_t offset = ph[i].p_offset;
58+
59+
if ((ph[i].p_vaddr & (~(max_align - 1))) < lowest) {
60+
lowest = ph[i].p_vaddr & ~(max_align - 1);
61+
}
5462

5563
uint64_t flags = VMM_PRESENT;
5664
if (ph[i].p_flags & PF_W)
5765
flags |= VMM_WRITABLE;
5866
if (!(ph[i].p_flags & PF_X))
5967
flags |= VMM_NX;
68+
69+
debug("elf64_load(): phys=0x%llx, virt=0x%llx, size=%lu\n", ph[i].p_paddr, ph[i].p_vaddr, ph[i].p_filesz);
70+
71+
uint64_t phys = (uint64_t)mem_alloc(ph[i].p_memsz);
72+
if (!phys) {
73+
debug("elf64_load(): Out of memory\n");
74+
return 0;
75+
}
6076

61-
for (uint64_t addr = vaddr_start; addr < vaddr_end; addr += PAGE_SIZE) {
62-
uint64_t phys = (uint64_t)mem_alloc(PAGE_SIZE);
63-
if (!phys) {
64-
debug("Out of physical memory");
65-
return 0;
66-
}
77+
map_page(pagemap, ph[i].p_vaddr, phys, flags);
78+
memcpy((void*)ph[i].p_vaddr - lowest, data + ph[i].p_offset, ph[i].p_filesz);
79+
}
6780

68-
map_page(pagemap, addr, phys, flags);
81+
debug("elf64_load(): ELF loaded successfully, entry: 0x%llx\n", header->e_entry);
82+
return (uintptr_t)((uint8_t *)data + (header->e_entry - lowest));
83+
}
6984

70-
uint64_t file_offset = offset + (addr - vaddr_start);
71-
if (file_offset < offset + ph[i].p_filesz) {
72-
uint64_t to_copy = PAGE_SIZE;
73-
if (file_offset + PAGE_SIZE > offset + ph[i].p_filesz)
74-
to_copy = offset + ph[i].p_filesz - file_offset;
85+
uintptr_t elf_load(char *data, pagetable *pagemap)
86+
{
87+
struct elf_header *header = (struct elf_header *)data;
7588

76-
memcpy((void *)phys, data + file_offset, to_copy);
77-
} else {
78-
memset((void *)phys, 0, PAGE_SIZE);
79-
}
80-
}
89+
if (header->e_magic != ELF_MAGIC) {
90+
debug("Invalid ELF magic: 0x%x", header->e_magic);
91+
return 0;
92+
}
93+
94+
if (header->e_class != 2) {
95+
debug("Unsupported ELF class: %u", header->e_class);
96+
return 0;
97+
}
98+
99+
if (header->e_machine == 20 ||
100+
header->e_machine == 3 ||
101+
header->e_machine == 40) {
102+
return elf32_load(data, pagemap);
103+
} else if (header->e_machine == 62) {
104+
return elf64_load(data, pagemap);
81105
}
82106

83-
debug("ELF loaded successfully, entry: 0x%lx", header->e_entry);
84-
return header->e_entry;
107+
debug("Unsupported ELF machine: %u", header->e_machine);
108+
return 0;
85109
}

boot/common/print.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
#define NANOPRINTF_USE_FIELD_WIDTH_FORMAT_SPECIFIERS 1
2222
#define NANOPRINTF_USE_PRECISION_FORMAT_SPECIFIERS 0
2323
#define NANOPRINTF_USE_FLOAT_FORMAT_SPECIFIERS 0
24-
#define NANOPRINTF_USE_LARGE_FORMAT_SPECIFIERS 0
24+
#define NANOPRINTF_USE_LARGE_FORMAT_SPECIFIERS 1
2525
#define NANOPRINTF_USE_BINARY_FORMAT_SPECIFIERS 0
2626
#define NANOPRINTF_USE_WRITEBACK_FORMAT_SPECIFIERS 0
2727
#include <nanoprintf.h>

boot/common/proto/aurix.c

+69
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
/*********************************************************************************/
2+
/* Module Name: aurix.c */
3+
/* Project: AurixOS */
4+
/* */
5+
/* Copyright (c) 2024-2025 Jozef Nagy */
6+
/* */
7+
/* This source is subject to the MIT License. */
8+
/* See License.txt in the root of this repository. */
9+
/* All other rights reserved. */
10+
/* */
11+
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR */
12+
/* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, */
13+
/* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE */
14+
/* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER */
15+
/* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, */
16+
/* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE */
17+
/* SOFTWARE. */
18+
/*********************************************************************************/
19+
20+
#include <proto/aurix.h>
21+
#include <loader/elf.h>
22+
#include <mm/mman.h>
23+
#include <mm/vmm.h>
24+
#include <vfs/vfs.h>
25+
#include <print.h>
26+
27+
extern __attribute__((noreturn)) void aurix_handoff(void *pagemap, void *stack, uint64_t entry, void *params);
28+
extern char _aurix_handoff_start[], _aurix_handoff_end[];
29+
30+
void aurix_load(char *kernel)
31+
{
32+
// read kernel -> test read
33+
char *kbuf = NULL;
34+
vfs_read(kernel, &kbuf);
35+
36+
// TODO: Do something with the kernel :p
37+
pagetable *pm = create_pagemap();
38+
if (!pm) {
39+
debug("aurix_load(): Failed to create kernel pagemap! Halting...\n");
40+
// TODO: Halt
41+
while (1);
42+
}
43+
44+
map_pages(pm, (uintptr_t)_aurix_handoff_start, (uintptr_t)_aurix_handoff_start, (uint64_t)_aurix_handoff_end - (uint64_t)_aurix_handoff_start, VMM_PRESENT | VMM_USER | VMM_WRITABLE);
45+
46+
void *stack = mem_alloc(16*1024); // 16 KiB stack should be well more than enough
47+
if (!stack) {
48+
debug("aurix_load(): Failed to allocate stack! Halting...\n");
49+
while (1);
50+
}
51+
52+
void *kernel_entry = (void *)elf_load(kbuf, pm);
53+
if (!kernel_entry) {
54+
debug("aurix_load(): Failed to load '%s'! Halting...\n", kernel);
55+
mem_free(kbuf);
56+
while (1);
57+
}
58+
59+
void *parameters = NULL;
60+
61+
debug("aurix_load(): Handoff state: pm=0x%llx, stack=0x%llx, kernel_entry=0x%llx\n", pm, stack, kernel_entry);
62+
63+
aurix_handoff(pm, (void *)((uint8_t)stack - 16*1024), (uint64_t)kernel_entry, (void *)parameters);
64+
65+
// __asm__ volatile("movq %[pml4], %%cr3\n" :: [pml4]"r"(pm) : "memory");
66+
// __asm__ volatile("callq *%[entry]\n"
67+
// :: [entry]"r"(kernel_entry));
68+
69+
}

boot/include/arch/x86_64/arch/mm/paging.h

+11
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,17 @@
2020
#ifndef _MM_PAGING_H
2121
#define _MM_PAGING_H
2222

23+
#include <stdint.h>
24+
2325
#define PAGE_SIZE 0x1000
2426

27+
#define VMM_PRESENT 1
28+
#define VMM_WRITABLE 2
29+
#define VMM_NX (1ull << 63)
30+
#define VMM_USER 4
31+
32+
typedef struct {
33+
uint64_t entries[512];
34+
} pagetable;
35+
2536
#endif /* _MM_PAGING_H */

boot/include/loader/elf.h

+2-1
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
#ifndef _LOADER_ELF_H
2121
#define _LOADER_ELF_H
2222

23+
#include <mm/vmm.h>
2324
#include <stdint.h>
2425
//#include <stddef.h>
2526

@@ -72,6 +73,6 @@ struct elf_program_header {
7273
#define PF_W 0x2
7374
#define PF_R 0x4
7475

75-
uint64_t elf_load(char *kernel, uintptr_t *pagemap);
76+
uintptr_t elf_load(char *kernel, pagetable *pagemap);
7677

7778
#endif /* _LOADER_ELF_H */

boot/include/mm/vmm.h

+3-7
Original file line numberDiff line numberDiff line change
@@ -23,13 +23,9 @@
2323
#include <arch/mm/paging.h>
2424
#include <stdint.h>
2525

26-
#define VMM_PRESENT 1
27-
#define VMM_WRITABLE 2
28-
#define VMM_NX (1ull << 63)
29-
#define VMM_USER 4
26+
pagetable *create_pagemap(void);
3027

31-
uintptr_t *create_pagemap(void);
32-
33-
void map_page(uintptr_t *pm, uintptr_t virt, uintptr_t phys, uint64_t flags);
28+
void map_page(pagetable *pm, uintptr_t virt, uintptr_t phys, uint64_t flags);
29+
void map_pages(pagetable *pm, uintptr_t virt, uintptr_t phys, size_t size, uint64_t flags);
3430

3531
#endif /* _MM_VMM_H */

0 commit comments

Comments
 (0)