omega_dispatch.asm
constants.inc
; ============================================================================
; OS - Project Omega Kernel Dispatcher
; Author: C. Hacker
; Date: 2024-07-26
; Target: x86_64 Bare Metal
; ============================================================================
section .text
global _start
extern kmain ; Defined in C or another ASM file
extern handle_syscall
extern schedule_next_process
extern timer_interrupt_handler
%include "constants.inc" ; Include system constants
%include "macros.inc" ; Useful macros
; --- Kernel Entry Point ---
_start:
cli ; Disable interrupts during setup
mov ax, cs ; Setup segment registers
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax
; Setup stack pointer (assuming stack grows down)
mov esp, KERNEL_STACK_TOP
; Initialize essential subsystems (placeholder calls)
call initialize_gdt
call initialize_idt
call initialize_memory_manager
call initialize_scheduler
call initialize_drivers
sti ; Re-enable interrupts
; Jump to higher-level kernel main function
call kmain
; If kmain returns (it shouldn't), halt the system
hlt_loop:
hlt
jmp hlt_loop
; --- System Call Dispatcher ---
; Expects syscall number in EAX, args in EBX, ECX, EDX, ESI, EDI
system_call_dispatcher:
pushad ; Save all general-purpose registers
push ds
push es
push fs
push gs
mov ax, KERNEL_DS ; Load kernel data segment
mov ds, ax
mov es, ax
cmp eax, SYSCALL_MAX ; Check if syscall number is valid
jae invalid_syscall
; Use syscall number as index into the syscall table
lea esi, [syscall_table]
mov ebx, eax ; Copy syscall number
shl ebx, 2 ; Multiply by 4 (size of dword pointer)
add esi, ebx ; Add offset to table base
; Call the appropriate handler
call [esi]
; Restore segment registers and general registers
pop gs
pop fs
pop es
pop ds
popad
iret ; Return from interrupt (syscall)
invalid_syscall:
mov eax, -1 ; Return error code (example)
jmp syscall_exit ; Go to common exit path
syscall_exit:
pop gs
pop fs
pop es
pop ds
popad
iret
; --- Interrupt Handlers (Example: Timer) ---
irq0_handler:
pushad
; Acknowledge interrupt to PIC (Programmable Interrupt Controller)
out 0x20, 0x20
call timer_interrupt_handler ; Call specific C or ASM handler
call schedule_next_process ; Trigger scheduler on timer tick
popad
iret ; Return from interrupt
; --- Placeholder Subsystem Initialization ---
initialize_gdt:
; ... complex GDT setup code ...
lgdt [gdt_descriptor]
ret
initialize_idt:
; ... complex IDT setup code ...
lidt [idt_descriptor]
ret
initialize_memory_manager:
; ... code to map physical memory, setup paging ...
mov eax, cr0
or eax, 0x80000001 ; Enable paging and protection
mov cr0, eax
ret
initialize_scheduler:
; ... code to setup process queues, timer frequency ...
ret
initialize_drivers:
; ... code to detect and init hardware drivers ...
ret
; ============================================================================
; Data Section
; ============================================================================
section .data
welcome_message db "OS Kernel Initialized.", 0x0A, 0
gdt_descriptor dw gdt_end - gdt_start - 1 ; Limit
dd gdt_start ; Base
idt_descriptor dw 256 * 8 - 1 ; Limit (256 entries * 8 bytes)
dd idt_start ; Base
; Syscall jump table (array of function pointers)
syscall_table:
dd handle_syscall_0 ; Example: Exit
dd handle_syscall_1 ; Example: Fork
dd handle_syscall_2 ; Example: Read
dd handle_syscall_3 ; Example: Write
; ... add pointers for all supported syscalls ...
times SYSCALL_MAX - 4 dd invalid_syscall ; Pad with invalid handler
; ============================================================================
; BSS Section (Uninitialized Data)
; ============================================================================
section .bss
KERNEL_STACK_BOTTOM resb KERNEL_STACK_SIZE ; Reserve stack space
KERNEL_STACK_TOP:
gdt_start resb 256 * 8 ; Reserve space for GDT
gdt_end:
idt_start resb 256 * 8 ; Reserve space for IDT
idt_end:
; ============================================================================
; External Syscall Handlers (Placeholders)
; ============================================================================
%macro DEFINE_SYSCALL_HANDLER 1
global handle_syscall_%1
handle_syscall_%1:
; Placeholder logic for syscall %1
; Result typically returned in EAX
mov eax, %1 ; Return syscall number for demo
jmp syscall_exit
%endmacro
DEFINE_SYSCALL_HANDLER 0
DEFINE_SYSCALL_HANDLER 1
DEFINE_SYSCALL_HANDLER 2
DEFINE_SYSCALL_HANDLER 3
; ... define more syscall handlers ...