From: Minep Date: Sat, 18 Jun 2022 18:20:22 +0000 (+0100) Subject: refactor: re-structure the kernel address space for a more integral layout. X-Git-Url: https://scm.lunaixsky.com/lunaix-os.git/commitdiff_plain/728194869c3dc89b0e1c625480d486ada309ae40 refactor: re-structure the kernel address space for a more integral layout. fix: spwan_proc0 invoking APIC functionality before it's initialization. --- diff --git a/lunaix-os/hal/apic.c b/lunaix-os/hal/apic.c index 0d427d1..289dd56 100644 --- a/lunaix-os/hal/apic.c +++ b/lunaix-os/hal/apic.c @@ -38,51 +38,51 @@ apic_init() // Hardware enable the APIC // By setting bit 11 of IA32_APIC_BASE register - // Note: After this point, you can't disable then re-enable it until a reset (i.e., reboot) - asm volatile ( - "movl %0, %%ecx\n" - "rdmsr\n" - "orl %1, %%eax\n" - "wrmsr\n" - ::"i"(IA32_MSR_APIC_BASE), "i"(IA32_APIC_ENABLE) - : "eax", "ecx", "edx" - ); + // Note: After this point, you can't disable then re-enable it until a reset + // (i.e., reboot) + asm volatile("movl %0, %%ecx\n" + "rdmsr\n" + "orl %1, %%eax\n" + "wrmsr\n" ::"i"(IA32_MSR_APIC_BASE), + "i"(IA32_APIC_ENABLE) + : "eax", "ecx", "edx"); // Print the basic information of our current local APIC uint32_t apic_id = apic_read_reg(APIC_IDR) >> 24; uint32_t apic_ver = apic_read_reg(APIC_VER); kprintf(KINFO "ID: %x, Version: %x, Max LVT: %u\n", - apic_id, - apic_ver & 0xff, - (apic_ver >> 16) & 0xff); + apic_id, + apic_ver & 0xff, + (apic_ver >> 16) & 0xff); // initialize the local vector table (LVT) apic_setup_lvts(); // initialize priority registers - - // set the task priority to the lowest possible, so all external interrupts are acceptable - // Note, the lowest possible priority class is 2, not 0, 1, as they are reserved for - // internal interrupts (vector 0-31, and each p-class resposible for 16 vectors). - // See Intel Manual Vol. 3A, 10-29 + + // set the task priority to the lowest possible, so all external interrupts + // are acceptable + // Note, the lowest possible priority class is 2, not 0, 1, as they are + // reserved for internal interrupts (vector 0-31, and each p-class + // resposible for 16 vectors). See Intel Manual Vol. 3A, 10-29 apic_write_reg(APIC_TPR, APIC_PRIORITY(2, 0)); // enable APIC uint32_t spiv = apic_read_reg(APIC_SPIVR); // install our handler for spurious interrupt. - spiv = (spiv & ~0xff) | APIC_SPIV_APIC_ENABLE | APIC_SPIV_IV; + spiv = (spiv & ~0xff) | APIC_SPIV_APIC_ENABLE | APIC_SPIV_IV; apic_write_reg(APIC_SPIVR, spiv); } -#define LVT_ENTRY_LINT0(vector) (LVT_DELIVERY_FIXED | vector) +#define LVT_ENTRY_LINT0(vector) (LVT_DELIVERY_FIXED | vector) // Pin LINT#1 is configured for relaying NMI, but we masked it here as I think // it is too early for that // LINT#1 *must* be edge trigged (Intel manual vol3. 10-14) -#define LVT_ENTRY_LINT1 (LVT_DELIVERY_NMI | LVT_MASKED | LVT_TRIGGER_EDGE) -#define LVT_ENTRY_ERROR(vector) (LVT_DELIVERY_FIXED | vector) +#define LVT_ENTRY_LINT1 (LVT_DELIVERY_NMI | LVT_MASKED | LVT_TRIGGER_EDGE) +#define LVT_ENTRY_ERROR(vector) (LVT_DELIVERY_FIXED | vector) void apic_setup_lvts() diff --git a/lunaix-os/hal/ioapic.c b/lunaix-os/hal/ioapic.c index 3ca3dee..dbe9106 100644 --- a/lunaix-os/hal/ioapic.c +++ b/lunaix-os/hal/ioapic.c @@ -1,36 +1,40 @@ #include -#include #include +#include +#include - -#define IOAPIC_REG_SEL *((volatile uint32_t*)(IOAPIC_BASE_VADDR + IOAPIC_IOREGSEL)) -#define IOAPIC_REG_WIN *((volatile uint32_t*)(IOAPIC_BASE_VADDR + IOAPIC_IOWIN)) +#define IOAPIC_REG_SEL *((volatile uint32_t*)(MMIO_IOAPIC + IOAPIC_IOREGSEL)) +#define IOAPIC_REG_WIN *((volatile uint32_t*)(MMIO_IOAPIC + IOAPIC_IOWIN)) uint8_t ioapic_get_irq(acpi_context* acpi_ctx, uint8_t old_irq); void -ioapic_init() { +ioapic_init() +{ // Remapping the IRQs - + acpi_context* acpi_ctx = acpi_get_context(); // Remap the IRQ 8 (rtc timer's vector) to RTC_TIMER_IV in ioapic // (Remarks IRQ 8 is pin INTIN8) // See IBM PC/AT Technical Reference 1-10 for old RTC IRQ - // See Intel's Multiprocessor Specification for IRQ - IOAPIC INTIN mapping config. - + // See Intel's Multiprocessor Specification for IRQ - IOAPIC INTIN + // mapping config. + // The ioapic_get_irq is to make sure we capture those overriden IRQs // grab ourselves these irq numbers uint8_t irq_rtc = ioapic_get_irq(acpi_ctx, PC_AT_IRQ_RTC); - // PC_AT_IRQ_RTC -> RTC_TIMER_IV, fixed, edge trigged, polarity=high, physical, APIC ID 0 + // PC_AT_IRQ_RTC -> RTC_TIMER_IV, fixed, edge trigged, polarity=high, + // physical, APIC ID 0 ioapic_redirect(irq_rtc, RTC_TIMER_IV, 0, IOAPIC_DELMOD_FIXED); } uint8_t -ioapic_get_irq(acpi_context* acpi_ctx, uint8_t old_irq) { +ioapic_get_irq(acpi_context* acpi_ctx, uint8_t old_irq) +{ if (old_irq >= 24) { return old_irq; } @@ -39,19 +43,22 @@ ioapic_get_irq(acpi_context* acpi_ctx, uint8_t old_irq) { } void -ioapic_write(uint8_t sel, uint32_t val) { +ioapic_write(uint8_t sel, uint32_t val) +{ IOAPIC_REG_SEL = sel; IOAPIC_REG_WIN = val; } uint32_t -ioapic_read(uint8_t sel) { +ioapic_read(uint8_t sel) +{ IOAPIC_REG_SEL = sel; return IOAPIC_REG_WIN; } void -ioapic_redirect(uint8_t irq, uint8_t vector, uint8_t dest, uint32_t flags) { +ioapic_redirect(uint8_t irq, uint8_t vector, uint8_t dest, uint32_t flags) +{ uint8_t reg_sel = IOAPIC_IOREDTBL_BASE + irq * 2; // Write low 32 bits diff --git a/lunaix-os/includes/hal/apic.h b/lunaix-os/includes/hal/apic.h index 42a211e..f96799c 100644 --- a/lunaix-os/includes/hal/apic.h +++ b/lunaix-os/includes/hal/apic.h @@ -1,70 +1,73 @@ #ifndef __LUNAIX_APIC_H #define __LUNAIX_APIC_H +#include #include -#define APIC_BASE_VADDR 0x1000 #define __APIC_BASE_PADDR 0xFEE00000 #define IA32_MSR_APIC_BASE 0x1B -#define IA32_APIC_ENABLE 0x800 +#define IA32_APIC_ENABLE 0x800 /* - * Common APIC memory-mapped registers + * Common APIC memory-mapped registers * Ref: Intel Manual, Vol. 3A, Table 10-1 */ -#define APIC_IDR 0x20 // ID Reg -#define APIC_VER 0x30 // Version Reg -#define APIC_TPR 0x80 // Task Priority -#define APIC_APR 0x90 // Arbitration Priority -#define APIC_PPR 0xA0 // Processor Priority -#define APIC_EOI 0xB0 // End-Of-Interrupt -#define APIC_RRD 0xC0 // Remote Read -#define APIC_LDR 0xD0 // Local Destination Reg -#define APIC_DFR 0xE0 // Destination Format Reg -#define APIC_SPIVR 0xF0 // Spurious Interrupt Vector Reg -#define APIC_ISR_BASE 0x100 // Base address for In-Service-Interrupt bitmap register (256bits) -#define APIC_TMR_BASE 0x180 // Base address for Trigger-Mode bitmap register (256bits) -#define APIC_IRR_BASE 0x200 // Base address for Interrupt-Request bitmap register (256bits) -#define APIC_ESR 0x280 // Error Status Reg -#define APIC_ICR_BASE 0x300 // Interrupt Command -#define APIC_LVT_LINT0 0x350 -#define APIC_LVT_LINT1 0x360 -#define APIC_LVT_ERROR 0x370 +#define APIC_IDR 0x20 // ID Reg +#define APIC_VER 0x30 // Version Reg +#define APIC_TPR 0x80 // Task Priority +#define APIC_APR 0x90 // Arbitration Priority +#define APIC_PPR 0xA0 // Processor Priority +#define APIC_EOI 0xB0 // End-Of-Interrupt +#define APIC_RRD 0xC0 // Remote Read +#define APIC_LDR 0xD0 // Local Destination Reg +#define APIC_DFR 0xE0 // Destination Format Reg +#define APIC_SPIVR 0xF0 // Spurious Interrupt Vector Reg +#define APIC_ISR_BASE \ + 0x100 // Base address for In-Service-Interrupt bitmap register (256bits) +#define APIC_TMR_BASE \ + 0x180 // Base address for Trigger-Mode bitmap register (256bits) +#define APIC_IRR_BASE \ + 0x200 // Base address for Interrupt-Request bitmap register (256bits) +#define APIC_ESR 0x280 // Error Status Reg +#define APIC_ICR_BASE 0x300 // Interrupt Command +#define APIC_LVT_LINT0 0x350 +#define APIC_LVT_LINT1 0x360 +#define APIC_LVT_ERROR 0x370 // APIC Timer specific -#define APIC_TIMER_LVT 0x320 -#define APIC_TIMER_ICR 0x380 // Initial Count -#define APIC_TIMER_CCR 0x390 // Current Count -#define APIC_TIMER_DCR 0x3E0 // Divide Configuration +#define APIC_TIMER_LVT 0x320 +#define APIC_TIMER_ICR 0x380 // Initial Count +#define APIC_TIMER_CCR 0x390 // Current Count +#define APIC_TIMER_DCR 0x3E0 // Divide Configuration -#define APIC_SPIV_FOCUS_DISABLE 0x200 -#define APIC_SPIV_APIC_ENABLE 0x100 -#define APIC_SPIV_EOI_BROADCAST 0x1000 +#define APIC_SPIV_FOCUS_DISABLE 0x200 +#define APIC_SPIV_APIC_ENABLE 0x100 +#define APIC_SPIV_EOI_BROADCAST 0x1000 -#define LVT_DELIVERY_FIXED 0 -#define LVT_DELIVERY_NMI (0x4 << 8) -#define LVT_TRIGGER_EDGE (0 << 15) -#define LVT_TRIGGER_LEVEL (1 << 15) -#define LVT_MASKED (1 << 16) -#define LVT_TIMER_ONESHOT (0 << 17) -#define LVT_TIMER_PERIODIC (1 << 17) +#define LVT_DELIVERY_FIXED 0 +#define LVT_DELIVERY_NMI (0x4 << 8) +#define LVT_TRIGGER_EDGE (0 << 15) +#define LVT_TRIGGER_LEVEL (1 << 15) +#define LVT_MASKED (1 << 16) +#define LVT_TIMER_ONESHOT (0 << 17) +#define LVT_TIMER_PERIODIC (1 << 17) // Dividers for timer. See Intel Manual Vol3A. 10-17 (pp. 3207), Figure 10-10 -#define APIC_TIMER_DIV1 0b1011 -#define APIC_TIMER_DIV2 0b0000 -#define APIC_TIMER_DIV4 0b0001 -#define APIC_TIMER_DIV8 0b0010 -#define APIC_TIMER_DIV16 0b0011 -#define APIC_TIMER_DIV32 0b1000 -#define APIC_TIMER_DIV64 0b1001 -#define APIC_TIMER_DIV128 0b1010 +#define APIC_TIMER_DIV1 0b1011 +#define APIC_TIMER_DIV2 0b0000 +#define APIC_TIMER_DIV4 0b0001 +#define APIC_TIMER_DIV8 0b0010 +#define APIC_TIMER_DIV16 0b0011 +#define APIC_TIMER_DIV32 0b1000 +#define APIC_TIMER_DIV64 0b1001 +#define APIC_TIMER_DIV128 0b1010 -#define APIC_PRIORITY(cls, subcls) (((cls) << 4) | (subcls)) +#define APIC_PRIORITY(cls, subcls) (((cls) << 4) | (subcls)) -#define apic_read_reg(reg) (*(uint32_t*)(APIC_BASE_VADDR + (reg))) -#define apic_write_reg(reg, val) (*(uint32_t*)(APIC_BASE_VADDR + (reg)) = (val)) +#define apic_read_reg(reg) (*(uint32_t*)(MMIO_APIC + (reg))) +#define apic_write_reg(reg, val) (*(uint32_t*)(MMIO_APIC + (reg)) = (val)) void apic_init(); @@ -72,10 +75,11 @@ apic_init(); /** * @brief Tell the APIC that the handler for current interrupt is finished. * This will issue a write action to EOI register. - * + * */ inline static void -apic_done_servicing() { +apic_done_servicing() +{ apic_write_reg(APIC_EOI, 0); } diff --git a/lunaix-os/includes/lunaix/common.h b/lunaix-os/includes/lunaix/common.h index 6482008..f9ab67f 100644 --- a/lunaix-os/includes/lunaix/common.h +++ b/lunaix-os/includes/lunaix/common.h @@ -1,29 +1,42 @@ #ifndef __LUNAIX_CONSTANTS_H #define __LUNAIX_CONSTANTS_H -#define KSTACK_SIZE (64 << 10) -#define KSTACK_START ((0xFFBFFFFFU - KSTACK_SIZE) + 1) -#define KSTACK_TOP 0xffbffff0 -#define HIGHER_HLF_BASE 0xC0000000 -#define MEM_1MB 0x100000 - -#define VGA_BUFFER_VADDR 0xB0000000 -#define VGA_BUFFER_PADDR 0xB8000 -#define VGA_BUFFER_SIZE 4096 - -#define KCODE_SEG 0x08 -#define KDATA_SEG 0x10 -#define UCODE_SEG 0x1B -#define UDATA_SEG 0x23 -#define TSS_SEG 0x28 - -#define USER_START 0x400000 -#define USTACK_SIZE 0x100000 -#define USTACK_TOP 0x9fffffff -#define USTACK_END (USTACK_TOP - USTACK_SIZE + 1) -#define UMMAP_AREA 0x4D000000 - -#define SYS_TIMER_FREQUENCY_HZ 2048 +#define KSTACK_SIZE (64 << 10) +#define KSTACK_START ((0x3FFFFFU - KSTACK_SIZE) + 1) +#define KSTACK_TOP 0x3FFFF0U + +#define KERNEL_MM_BASE 0xC0000000 +#define MEM_1MB 0x100000 +#define MEM_4MB 0x400000 + +#define KCODE_MAX_SIZE MEM_4MB +#define KHEAP_START (KERNEL_MM_BASE + KCODE_MAX_SIZE) +#define KHEAP_SIZE_MB 256 + +#define PROC_TABLE_SIZE_MB 4 +#define PROC_START (KHEAP_START + (KHEAP_SIZE_MB * MEM_1MB)) + +#define VGA_BUFFER_VADDR (PROC_START + (PROC_TABLE_SIZE_MB * MEM_1MB)) +#define VGA_BUFFER_PADDR 0xB8000 +#define VGA_BUFFER_SIZE 4096 + +#define MMIO_BASE (VGA_BUFFER_VADDR + MEM_4MB) +#define MMIO_APIC (MMIO_BASE) +#define MMIO_IOAPIC (MMIO_BASE + 4096) + +#define KCODE_SEG 0x08 +#define KDATA_SEG 0x10 +#define UCODE_SEG 0x1B +#define UDATA_SEG 0x23 +#define TSS_SEG 0x28 + +#define USER_START 0x400000 +#define USTACK_SIZE 0x100000 +#define USTACK_TOP 0x9fffffff +#define USTACK_END (USTACK_TOP - USTACK_SIZE + 1) +#define UMMAP_AREA 0x4D000000 + +#define SYS_TIMER_FREQUENCY_HZ 2048 #ifndef __ASM__ #include @@ -36,9 +49,11 @@ * @member: the name of the member within the struct. * */ -#define container_of(ptr, type, member) ({ \ - const typeof( ((type *)0)->member ) *__mptr = (ptr); \ - (type *)( (char *)__mptr - offsetof(type,member) );}) +#define container_of(ptr, type, member) \ + ({ \ + const typeof(((type*)0)->member)* __mptr = (ptr); \ + (type*)((char*)__mptr - offsetof(type, member)); \ + }) #endif #endif /* __LUNAIX_CONSTANTS_H */ diff --git a/lunaix-os/includes/lunaix/mm/page.h b/lunaix-os/includes/lunaix/mm/page.h index 446e14e..087e455 100644 --- a/lunaix-os/includes/lunaix/mm/page.h +++ b/lunaix-os/includes/lunaix/mm/page.h @@ -13,8 +13,8 @@ #define PTE_NULL 0 -#define P2V(paddr) ((uintptr_t)(paddr) + HIGHER_HLF_BASE) -#define V2P(vaddr) ((uintptr_t)(vaddr)-HIGHER_HLF_BASE) +#define P2V(paddr) ((uintptr_t)(paddr) + KERNEL_MM_BASE) +#define V2P(vaddr) ((uintptr_t)(vaddr)-KERNEL_MM_BASE) #define PG_ALIGN(addr) ((uintptr_t)(addr)&0xFFFFF000UL) @@ -99,13 +99,13 @@ extern void __pg_mount_point; /* 四个页挂载点,两个页目录挂载点: 用于临时创建&编辑页表 */ #define PG_MOUNT_RANGE(l1_index) (701 <= l1_index && l1_index <= 703) -#define PD_MOUNT_1 0xAFC00000 -#define PD_MOUNT_2 0xAF800000 -#define PG_MOUNT_BASE 0xAF7FF000 +#define PD_MOUNT_1 (MMIO_BASE + MEM_4MB) +#define PG_MOUNT_BASE (PD_MOUNT_1 + MEM_4MB) #define PG_MOUNT_1 (PG_MOUNT_BASE) -#define PG_MOUNT_2 (PG_MOUNT_BASE - 0x1000) -#define PG_MOUNT_3 (PG_MOUNT_BASE - 0x2000) -#define PG_MOUNT_4 (PG_MOUNT_BASE - 0x3000) +#define PG_MOUNT_2 (PG_MOUNT_BASE + 0x1000) +#define PG_MOUNT_3 (PG_MOUNT_BASE + 0x2000) +#define PG_MOUNT_4 (PG_MOUNT_BASE + 0x3000) + #define PD_REFERENCED L2_BASE_VADDR #define CURPROC_PTE(vpn) \ diff --git a/lunaix-os/kernel/asm/x86/interrupts.c b/lunaix-os/kernel/asm/x86/interrupts.c index a59e5f2..688799f 100644 --- a/lunaix-os/kernel/asm/x86/interrupts.c +++ b/lunaix-os/kernel/asm/x86/interrupts.c @@ -41,12 +41,6 @@ intr_handler(isr_param* param) { __current->intr_ctx = *param; -#ifdef USE_KERNEL_PT - cpu_lcr3(__kernel_ptd); - - vmm_mount_pd(PD_MOUNT_1, __current->page_table); -#endif - isr_param* lparam = &__current->intr_ctx; if (lparam->vector <= 255) { @@ -76,8 +70,5 @@ done: apic_done_servicing(); } -#ifdef USE_KERNEL_PT - cpu_lcr3(__current->page_table); -#endif return; } \ No newline at end of file diff --git a/lunaix-os/kernel/asm/x86/pfault.c b/lunaix-os/kernel/asm/x86/pfault.c index 3ad640e..34589cb 100644 --- a/lunaix-os/kernel/asm/x86/pfault.c +++ b/lunaix-os/kernel/asm/x86/pfault.c @@ -20,8 +20,6 @@ kprintf(const char* fmt, ...) extern void __print_panic_msg(const char* msg, const isr_param* param); -extern void __kernel_heap_start; - void intr_routine_page_fault(const isr_param* param) { @@ -98,7 +96,7 @@ int do_kernel(v_mapping* mapping) { uintptr_t addr = mapping->va; - if (addr >= &__kernel_heap_start && addr < L2_BASE_VADDR) { + if (addr >= KHEAP_START && addr < PROC_START) { // This is kernel heap page uintptr_t pa = pmm_alloc_page(KERNEL_PID, 0); *mapping->pte = (*mapping->pte & 0xfff) | pa | PG_PRESENT; diff --git a/lunaix-os/kernel/k_init.c b/lunaix-os/kernel/k_init.c index 427ca51..59d9347 100644 --- a/lunaix-os/kernel/k_init.c +++ b/lunaix-os/kernel/k_init.c @@ -161,8 +161,13 @@ spawn_proc0() // 向调度器注册进程。 push_process(&proc0); - // 由于时钟中断未就绪,我们需要手动通知调度器进行第一次调度。这里也会同时隐式地恢复我们的eflags.IF位 - schedule(); + // 由于时钟中断与APIC未就绪,我们需要手动进行第一次调度。这里也会同时隐式地恢复我们的eflags.IF位 + struct proc_info* proc = get_process(0); + assert_msg(proc, "fail to get proc0!"); + + proc->state = PROC_RUNNING; + asm volatile("pushl %0\n" + "jmp switch_to\n" ::"r"(proc)); /* Should not return */ assert_msg(0, "Unexpected Return"); diff --git a/lunaix-os/kernel/lxinit.c b/lunaix-os/kernel/lxinit.c index 43f0f2d..19e7eff 100644 --- a/lunaix-os/kernel/lxinit.c +++ b/lunaix-os/kernel/lxinit.c @@ -15,7 +15,7 @@ extern uint8_t __kernel_start; LOG_MODULE("INIT") // #define FORK_BOMB_DEMO -// #define WAIT_DEMO +#define WAIT_DEMO void _lxinit_main() diff --git a/lunaix-os/kernel/mm/dmm.c b/lunaix-os/kernel/mm/dmm.c index 44f0f9e..651c6fc 100644 --- a/lunaix-os/kernel/mm/dmm.c +++ b/lunaix-os/kernel/mm/dmm.c @@ -24,8 +24,6 @@ #include #include -extern void __kernel_heap_start; - __DEFINE_LXSYSCALL1(int, sbrk, size_t, size) { heap_context_t* uheap = &__current->mm.u_heap; @@ -53,7 +51,7 @@ dmm_init(heap_context_t* heap) mutex_init(&heap->lock); int perm = PG_ALLOW_USER; - if (heap->brk >= &__kernel_heap_start) { + if (heap->brk >= KHEAP_START) { perm = 0; } diff --git a/lunaix-os/kernel/mm/kalloc.c b/lunaix-os/kernel/mm/kalloc.c index d5116a2..ba00b09 100644 --- a/lunaix-os/kernel/mm/kalloc.c +++ b/lunaix-os/kernel/mm/kalloc.c @@ -62,14 +62,13 @@ lx_grow_heap(heap_context_t* heap, size_t sz); // FIXME: This should be per-process but not global! static heap_context_t kheap; -#define KHEAP_SIZE_MB 256 - int kalloc_init() { - kheap.start = &__kernel_heap_start; + kheap.start = KHEAP_START; kheap.brk = NULL; - kheap.max_addr = (void*)((uintptr_t)kheap.start + (KHEAP_SIZE_MB << 20)); + kheap.max_addr = + (void*)PROC_START; // 在新的布局中,堆结束的地方即为进程表开始的地方 for (size_t i = 0; i < KHEAP_SIZE_MB >> 2; i++) { vmm_set_mapping(PD_REFERENCED, diff --git a/lunaix-os/kernel/proc0.c b/lunaix-os/kernel/proc0.c index 542ef1c..2b21ac7 100644 --- a/lunaix-os/kernel/proc0.c +++ b/lunaix-os/kernel/proc0.c @@ -93,9 +93,9 @@ init_platform() pmm_mark_page_occupied(KERNEL_PID, FLOOR(ioapic_addr, PG_SIZE_BITS), 0); vmm_set_mapping( - PD_REFERENCED, APIC_BASE_VADDR, __APIC_BASE_PADDR, PG_PREM_RW, VMAP_NULL); + PD_REFERENCED, MMIO_APIC, __APIC_BASE_PADDR, PG_PREM_RW, VMAP_NULL); vmm_set_mapping( - PD_REFERENCED, IOAPIC_BASE_VADDR, ioapic_addr, PG_PREM_RW, VMAP_NULL); + PD_REFERENCED, MMIO_IOAPIC, ioapic_addr, PG_PREM_RW, VMAP_NULL); apic_init(); ioapic_init(); diff --git a/lunaix-os/kernel/process.c b/lunaix-os/kernel/process.c index ce491ed..a41c6a6 100644 --- a/lunaix-os/kernel/process.c +++ b/lunaix-os/kernel/process.c @@ -21,19 +21,19 @@ __dup_pagetable(pid_t pid, uintptr_t mount_point) x86_page_table* ptd = PG_MOUNT_1; x86_page_table* pptd = (x86_page_table*)(mount_point | (0x3FF << 12)); + size_t kspace_l1inx = L1_INDEX(KERNEL_MM_BASE); + for (size_t i = 0; i < PG_MAX_ENTRIES - 1; i++) { - // 没有必要拷贝临时挂载点 - if (PG_MOUNT_RANGE(i)) { - ptd->entry[i] = 0; - continue; - } x86_pte_t ptde = pptd->entry[i]; - if (!ptde || !(ptde & PG_PRESENT)) { + // 空或者是未在内存中的L1页表项直接照搬过去。 + // 内核地址空间直接共享过去。 + if (!ptde || i >= kspace_l1inx || !(ptde & PG_PRESENT)) { ptd->entry[i] = ptde; continue; } + // 复制L2页表 void* pt_pp = pmm_alloc_page(pid, PP_FGPERSIST); vmm_set_mapping( PD_REFERENCED, PG_MOUNT_2, pt_pp, PG_PREM_RW, VMAP_NULL); @@ -60,7 +60,8 @@ __del_pagetable(pid_t pid, uintptr_t mount_point) { x86_page_table* pptd = (x86_page_table*)(mount_point | (0x3FF << 12)); - for (size_t i = 0; i < PG_MAX_ENTRIES - 1; i++) { + // only remove user address space + for (size_t i = 0; i < L1_INDEX(KERNEL_MM_BASE); i++) { x86_pte_t ptde = pptd->entry[i]; if (!ptde || !(ptde & PG_PRESENT)) { continue; @@ -149,7 +150,7 @@ __mark_region(uintptr_t start_vpn, uintptr_t end_vpn, int attr) { for (size_t i = start_vpn; i < end_vpn; i++) { x86_pte_t* curproc = &PTE_MOUNTED(PD_REFERENCED, i); - x86_pte_t* newproc = &PTE_MOUNTED(PD_MOUNT_2, i); + x86_pte_t* newproc = &PTE_MOUNTED(PD_MOUNT_1, i); cpu_invplg(newproc); if (attr == REGION_RSHARED) { @@ -175,11 +176,7 @@ dup_proc() region_copy(&__current->mm.regions, &pcb.mm.regions); -#ifdef USE_KERNEL_PG - setup_proc_mem(&pcb, PD_MOUNT_1); //挂载点#1是当前进程的页表 -#else setup_proc_mem(&pcb, PD_REFERENCED); -#endif // 根据 mm_region 进一步配置页表 if (!__current->mm.regions) { @@ -200,7 +197,7 @@ dup_proc() } not_copy: - vmm_unmount_pd(PD_MOUNT_2); + vmm_unmount_pd(PD_MOUNT_1); // 正如同fork,返回两次。 pcb.intr_ctx.registers.eax = 0; @@ -219,11 +216,11 @@ setup_proc_mem(struct proc_info* proc, uintptr_t usedMnt) pid_t pid = proc->pid; void* pt_copy = __dup_pagetable(pid, usedMnt); - vmm_mount_pd(PD_MOUNT_2, pt_copy); // 将新进程的页表挂载到挂载点#2 + vmm_mount_pd(PD_MOUNT_1, pt_copy); // 将新进程的页表挂载到挂载点#2 // copy the kernel stack for (size_t i = KSTACK_START >> 12; i <= KSTACK_TOP >> 12; i++) { - volatile x86_pte_t* ppte = &PTE_MOUNTED(PD_MOUNT_2, i); + volatile x86_pte_t* ppte = &PTE_MOUNTED(PD_MOUNT_1, i); /* This is a fucking nightmare, the TLB caching keep the rewrite to PTE @@ -237,6 +234,7 @@ setup_proc_mem(struct proc_info* proc, uintptr_t usedMnt) x86_pte_t p = *ppte; void* ppa = vmm_dup_page(pid, PG_ENTRY_ADDR(p)); + pmm_free_page(pid, PG_ENTRY_ADDR(p)); *ppte = (p & 0xfff) | (uintptr_t)ppa; } diff --git a/lunaix-os/kernel/sched.c b/lunaix-os/kernel/sched.c index ab04e66..ee25ebb 100644 --- a/lunaix-os/kernel/sched.c +++ b/lunaix-os/kernel/sched.c @@ -21,8 +21,6 @@ volatile struct proc_info* __current; struct proc_info dummy; -extern void __proc_table; - struct scheduler sched_ctx; LOG_MODULE("SCHED") @@ -35,10 +33,10 @@ sched_init() for (size_t i = 0; i <= pg_size; i += 4096) { uintptr_t pa = pmm_alloc_page(KERNEL_PID, PP_FGPERSIST); vmm_set_mapping( - PD_REFERENCED, &__proc_table + i, pa, PG_PREM_RW, VMAP_NULL); + PD_REFERENCED, PROC_START + i, pa, PG_PREM_RW, VMAP_NULL); } - sched_ctx = (struct scheduler){ ._procs = (struct proc_info*)&__proc_table, + sched_ctx = (struct scheduler){ ._procs = (struct proc_info*)PROC_START, .ptable_len = 0, .procs_index = 0 }; } @@ -240,11 +238,11 @@ destroy_process(pid_t pid) } } - vmm_mount_pd(PD_MOUNT_2, proc->page_table); + vmm_mount_pd(PD_MOUNT_1, proc->page_table); - __del_pagetable(pid, PD_MOUNT_2); + __del_pagetable(pid, PD_MOUNT_1); - vmm_unmount_pd(PD_MOUNT_2); + vmm_unmount_pd(PD_MOUNT_1); return pid; } diff --git a/lunaix-os/link/linker.ld b/lunaix-os/link/linker.ld index 958082a..2bd3ded 100644 --- a/lunaix-os/link/linker.ld +++ b/lunaix-os/link/linker.ld @@ -61,7 +61,4 @@ SECTIONS { } __kernel_end = ALIGN(4K); - __proc_table = ALIGN(4K); - . += 4M; - __kernel_heap_start = ALIGN(4K); /* 内核结束的地方即堆开始的地方 */ } \ No newline at end of file