user: implement mlibc as the libc, finally.

It's finally done..

Signed-off-by: kaguya <vpshinomiya@protonmail.com>
This commit is contained in:
kaguya
2026-05-02 03:31:49 -04:00
parent 2fa39ad85a
commit 9a9b91c940
2387 changed files with 152741 additions and 315 deletions
+2 -2
View File
@@ -55,14 +55,14 @@ void x86_64_ISR_Initialize(void)
x86_64_ISR_InitializeGates();
for (int i = 0; i < 256; i++)
x86_64_IDT_EnableGate(i);
x86_64_IDT_DisableGate(0x80); // syscall gate if you want
x86_64_IDT_DisableGate(0x80); // syscall gate
}
void page_fault_handler(Registers* regs, uint64_t cr2)
{
// You can decode error bits here:
// bit 0: present
// bit 1: write
// bit 2: user-mode
+29 -45
View File
@@ -40,10 +40,14 @@ struct pagemap *create_user_pagemap(void)
}
/* Copy kernel higher-half mappings (kernel + HHDM) */
for (size_t i = 256; i < 512; i++) {
for (size_t i = 0; i < 512; i++) {
pm->top_level[i] = kernel_pagemap->top_level[i];
}
for (size_t i = 0; i < 256; i++) {
pm->top_level[i] = 0;
}
/* Lower half remains zero (user address space) */
printf("[usermode] user pagemap created (PML4 phys = 0x%lx)\n",
(uint64_t)pm->top_level - MEM_PHYS_OFFSET);
@@ -53,7 +57,7 @@ struct pagemap *create_user_pagemap(void)
uintptr_t setup_user_stack(struct pagemap *pagemap)
{
user_stack_phys_base = (uint64_t)pmm_alloc(USER_STACK_PAGES);
user_stack_phys_base = (uint64_t)pmm_allocz(USER_STACK_PAGES);
if (!user_stack_phys_base) {
printf("Failed to allocate user stack pages!\n");
@@ -83,45 +87,9 @@ uintptr_t setup_user_stack(struct pagemap *pagemap)
return rsp;
}
__attribute__((naked))
void enter_user_mode(uint64_t rip, uint64_t rsp)
{
asm volatile(
"cli\n\t"
"mov $0x1B, %%ax\n\t"
"mov %%ax, %%ds\n\t"
"mov %%ax, %%es\n\t"
"mov %%ax, %%fs\n\t"
"mov %%ax, %%gs\n\t"
// SS
"pushq $0x1B\n\t"
// RSP
"pushq %1\n\t"
// RFLAGS
"pushfq\n\t"
"pop %%rax\n\t"
"or $0x200, %%rax\n\t"
"push %%rax\n\t"
// CS
"pushq $0x23\n\t"
// RIP
"pushq %0\n\t"
"iretq\n\t"
:
: "r"(rip), "r"(rsp)
: "rax", "memory"
);
}
void start_userspace(void)
{
struct pagemap *user_pagemap = create_user_pagemap();
if (!user_pagemap) {
printf("Failed to create user pagemap\n");
@@ -129,19 +97,35 @@ void start_userspace(void)
}
void *elf_entry = NULL;
if (!ELF_Read("init.elf", &elf_entry, user_pagemap)) {
printf("Failed to load init.elf\n");
uint64_t tls_fs_base = 0;
uint64_t phdr_va = 0;
uint16_t phent = 0;
uint16_t phnum = 0;
if (!ELF_Read("helloworld.elf",
&elf_entry,
user_pagemap,
&tls_fs_base,
&phdr_va,
&phent,
&phnum)) {
printf("Failed to load helloworld.elf\n");
for(;;);
}
if (!elf_entry) {
printf("ELF has no entry point\n");
for(;;);
}
printf("ELF: entry=0x%lx TLS_FS=0x%lx PHDR=0x%lx PHENT=0x%x PHNUM=%u\n",
(uint64_t)elf_entry, tls_fs_base, phdr_va, phent, phnum);
uintptr_t user_rsp = setup_user_stack(user_pagemap);
printf("Entering usermode RIP=%p RSP=%p\n", elf_entry, (void*)user_rsp);
sched_create_user_task("init", (uint64_t)elf_entry, user_rsp, user_pagemap);
sched_create_user_task("init",
(uint64_t)elf_entry,
user_rsp,
user_pagemap,
tls_fs_base,
phdr_va,
phent,
phnum);
}
+1 -1
View File
@@ -138,7 +138,7 @@ void lapic_init(void) {
* ── Step 8: Set Task Priority to 0 ───────────────────────────────────
*
* TPR = 0 means the CPU will accept all interrupt priorities.
* Raise this later if you need to block lower-priority interrupts.
* Raise this later if need to block lower-priority interrupts.
*/
lapic_write(LAPIC_TPR, 0);
-3
View File
@@ -64,9 +64,6 @@ void lapic_init(void);
/**
* lapic_eoi - Signal end-of-interrupt to the LAPIC.
* Must be called from interrupt handlers that go through the LAPIC
* (i.e. IOAPIC-routed interrupts). ExtINT (i8259) interrupts only
* need the i8259 EOI, which your existing irq.c already sends.
*/
void lapic_eoi(void);
+2 -2
View File
@@ -237,7 +237,7 @@ void ioapic_init(void) {
* MEM_PHYS_OFFSET. Two MMIO registers are accessed (offsets 0 and
* 0x10) so one 4 KiB page is sufficient.
*
* TODO: Mark the page UC (cache-disable) in the PTE when your VMM
* TODO: Mark the page UC (cache-disable) in the PTE when VMM
* gains support for PAT / PCD flags.
*/
uint64_t phys = (uint64_t)e->address;
@@ -343,7 +343,7 @@ void irq_redirect_to_apic(uint8_t isa_irq, uint8_t vector,
/* Mask in the 8259 so it stops firing through LINT0 */
if (g_Driver) {
g_Driver->Mask(isa_irq); // from your irq.c / i8259
g_Driver->Mask(isa_irq);
}
/* Programme IOAPIC redirection entry */
+5 -2
View File
@@ -22,6 +22,8 @@ extern bool g_IOAPIC;
void x86_64_IRQ_Handler(Registers *regs)
{
int irq = regs->interrupt - PIC_REMAP_OFFSET;
g_Driver->SendEndOfInterrupt(irq);
if (g_IRQHandlers[irq] != NULL)
{
@@ -33,7 +35,7 @@ void x86_64_IRQ_Handler(Registers *regs)
log_warn(MODULE, "Unhandled IRQ %d...", irq);
}
g_Driver->SendEndOfInterrupt(irq);
@@ -42,6 +44,7 @@ void x86_64_IRQ_Handler(Registers *regs)
void x86_64_APIC_IRQ_Handler(Registers* regs)
{
uint8_t vector = regs->interrupt;
lapic_eoi();
if (g_APICHandlers[vector] != NULL) {
g_APICHandlers[vector](regs);
@@ -49,7 +52,7 @@ void x86_64_APIC_IRQ_Handler(Registers* regs)
log_warn("APIC", "Unhandled vector 0x%02x", vector);
}
lapic_eoi(); // ← This is the key difference from PIC!
// ← This is the key difference from PIC!
}