TTrapHandler
#include <lib/string.h>
#include <lib/trap.h>
#include <lib/syscall.h>
#include <lib/debug.h>
#include <lib/x86.h>
#include <dev/intr.h>
#include <vmm/MPTOp/export.h>
#include "import.h"<lib/string.h>: Provides utilities for string manipulation.<lib/trap.h>: Defines structures and functions for trap handling.<lib/syscall.h>: Includes syscall-related constants and functions.<lib/debug.h>: Debugging macros such asKERN_DEBUGandKERN_PANIC.<lib/x86.h>: Architecture-specific utilities for x86.<dev/intr.h>: Handles device-level interrupt utilities.<vmm/MPTOp/export.h>: Manages virtual memory operations."import.h": Imports kernel-specific constants and functions.
trap_dump
trap_dumpPurpose
Prints the contents of the trap frame for debugging.
Code Analysis
static void trap_dump(tf_t *tf)
{
if (tf == NULL)
return;Checks: Verifies that the trap frame pointer is valid.
uintptr_t base = (uintptr_t) tf;
KERN_DEBUG("trapframe at %x\n", base);
KERN_DEBUG("\t%08x:\tedi: \t\t%08x\n", &tf->regs.edi, tf->regs.edi);
...
}Registers: Logs the values of all general-purpose registers, segment selectors, error codes, and instruction pointers stored in the trap frame.
Use Case: Helps debug unexpected traps by providing a snapshot of the CPU state.
default_exception_handler
default_exception_handlerPurpose
Handles unrecognized exceptions by dumping the trap frame and halting the system.
Code Analysis
void default_exception_handler(void)
{
unsigned int cur_pid;
cur_pid = get_curid();
trap_dump(&uctx_pool[cur_pid]);
KERN_PANIC("Trap %d @ 0x%08x.\n", uctx_pool[cur_pid].trapno, uctx_pool[cur_pid].eip);
}Dumps the trap frame for the current process and halts execution with a panic message.
pgflt_handler
pgflt_handlerPurpose
Handles page faults caused by invalid memory access.
Code Analysis
void pgflt_handler(void)
{
unsigned int cur_pid = get_curid();
unsigned int errno = uctx_pool[cur_pid].err;
unsigned int fault_va = rcr2();rcr2(): Retrieves the faulting virtual address from the CR2 register.
if ((errno & 0x3) == 0x3) {
pte_entry = get_ptbl_entry_by_va(cur_pid, fault_va);
if (pte_entry & PTE_COW) {
// handling copy-on-write
} else {
KERN_PANIC("Writing to read-only page: va = %p\n", fault_va);
}
}Copy-on-Write Handling:
Checks if the fault is caused by writing to a copy-on-write (COW) page.
If not, the kernel panics.
if (errno & PFE_PR) {
KERN_PANIC("Permission denied: va = 0x%08x, errno = 0x%08x.\n", fault_va, errno);
return;
}
if (alloc_page(cur_pid, fault_va, PTE_W | PTE_U | PTE_P) == MagicNumber) {
KERN_PANIC("Page allocation failed: va = 0x%08x, errno = 0x%08x.\n", fault_va, errno);
}
}Page Allocation:
Handles allocation of pages for valid page faults.
Panics if allocation fails.
exception_handler
exception_handlerPurpose
Routes exceptions to their respective handlers.
Code Analysis
void exception_handler(void)
{
unsigned int current_pid = get_curid();
tf_t tf = uctx_pool[current_pid];
if (tf.trapno == T_PGFLT) {
pgflt_handler();
} else {
default_exception_handler();
}
}Delegates page faults to
pgflt_handlerand all other exceptions todefault_exception_handler.
Interrupt Handlers
spurious_intr_handler
static int spurious_intr_handler(void)
{
return 0;
}Handles spurious interrupts (false positives).
timer_intr_handler
static int timer_intr_handler(void)
{
intr_eoi();
return 0;
}Acknowledges and clears the timer interrupt.
default_intr_handler
static int default_intr_handler(void)
{
intr_eoi();
return 0;
}Handles all other interrupts by acknowledging and clearing them.
interrupt_handler
void interrupt_handler(void)
{
unsigned int arg1 = syscall_get_arg1();
if (arg1 == T_IRQ0 + IRQ_TIMER) {
timer_intr_handler();
} else if (arg1 == T_IRQ0 + IRQ_SPURIOUS) {
spurious_intr_handler();
} else {
default_intr_handler();
}
}Routes interrupts to their respective handlers.
trap
trapPurpose
Central entry point for handling traps, exceptions, and interrupts.
Code Analysis
void trap(tf_t *tf)
{
unsigned int cur_pid = get_curid();
uctx_pool[cur_pid] = *tf; // Save user context
set_pdir_base(0); // Switch to kernel page tableSaves the trap frame and switches to the kernel's address space.
if (T_DIVIDE <= tf->trapno && tf->trapno <= T_SECEV)
exception_handler();
else if (T_IRQ0 + IRQ_TIMER <= tf->trapno && tf->trapno <= T_IRQ0 + IRQ_IDE2)
interrupt_handler();
else if (tf->trapno == T_SYSCALL)
syscall_dispatch();Routes traps based on their type:
Exceptions: Handled by
exception_handler.Interrupts: Routed to
interrupt_handler.System Calls: Dispatched to the appropriate syscall handler.
proc_start_user(); // Restore user mode
}Restores user mode and resumes execution.
Summary of Use Cases
Trap Debugging:
trap_dumphelps analyze the state during unexpected exceptions.Page Fault Handling:
pgflt_handlerhandles dynamic memory allocation and copy-on-write scenarios.Interrupt Routing:
interrupt_handlerensures proper routing of timer, spurious, and other interrupts.Trap Handling: The
trapfunction is the central mechanism for transitioning between user and kernel modes.
Last updated