user: implement mlibc as the libc, finally.
It's finally done.. Signed-off-by: kaguya <vpshinomiya@protonmail.com>
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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!
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user