fix: spwan_proc0 invoking APIC functionality before it's initialization.
// 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()
#include <arch/x86/interrupts.h>
-#include <hal/ioapic.h>
#include <hal/acpi/acpi.h>
+#include <hal/ioapic.h>
+#include <lunaix/common.h>
-
-#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;
}
}
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
#ifndef __LUNAIX_APIC_H
#define __LUNAIX_APIC_H
+#include <lunaix/common.h>
#include <stdint.h>
-#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();
/**
* @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);
}
#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 <stddef.h>
* @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 */
#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)
/* 四个页挂载点,两个页目录挂载点: 用于临时创建&编辑页表 */
#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) \
{
__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) {
apic_done_servicing();
}
-#ifdef USE_KERNEL_PT
- cpu_lcr3(__current->page_table);
-#endif
return;
}
\ No newline at end of file
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)
{
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;
// 向调度器注册进程。
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");
LOG_MODULE("INIT")
// #define FORK_BOMB_DEMO
-// #define WAIT_DEMO
+#define WAIT_DEMO
void
_lxinit_main()
#include <lunaix/spike.h>
#include <lunaix/syscall.h>
-extern void __kernel_heap_start;
-
__DEFINE_LXSYSCALL1(int, sbrk, size_t, size)
{
heap_context_t* uheap = &__current->mm.u_heap;
mutex_init(&heap->lock);
int perm = PG_ALLOW_USER;
- if (heap->brk >= &__kernel_heap_start) {
+ if (heap->brk >= KHEAP_START) {
perm = 0;
}
// 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,
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();
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);
{
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;
{
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) {
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) {
}
not_copy:
- vmm_unmount_pd(PD_MOUNT_2);
+ vmm_unmount_pd(PD_MOUNT_1);
// 正如同fork,返回两次。
pcb.intr_ctx.registers.eax = 0;
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
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;
}
struct proc_info dummy;
-extern void __proc_table;
-
struct scheduler sched_ctx;
LOG_MODULE("SCHED")
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 };
}
}
}
- 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;
}
}
__kernel_end = ALIGN(4K);
- __proc_table = ALIGN(4K);
- . += 4M;
- __kernel_heap_start = ALIGN(4K); /* 内核结束的地方即堆开始的地方 */
}
\ No newline at end of file