feat(boot+shell): add bootable disk image, unified scheduler and interactive user-space shell
- Implement Limine v8 boot protocol requests in dedicated PT_LOAD RW segment - Configure IOPL=3 and SSE in arch setup for Ring 3 drivers and libc - Unify scheduler context switching via switch_to and preempt_tick - Support dual-source keyboard/serial input in sys_key_read - Add automated 'make image' and 'make run' targets for instant QEMU launch - Complete interactive UNIX-like shell (osh) with built-in commands & ramdisk
This commit is contained in:
+51
-8
@@ -1,14 +1,15 @@
|
||||
/* opencoreC - Thread Context Switch */
|
||||
/* opencoreC - Thread Context Switch & Entry Trampoline */
|
||||
.global switch_to
|
||||
.global thread_entry_trampoline
|
||||
|
||||
.section .text
|
||||
/*
|
||||
* void switch_to(uint64_t **prev_rsp_ptr, uint64_t *next_rsp);
|
||||
* RDI = pointer to current thread's stored RSP
|
||||
* RSI = target thread's RSP
|
||||
* switch_to(uint64_t *prev_rsp_ptr, uint64_t next_rsp)
|
||||
* RDI = ¤t_thread.context.rsp (save current RSP here)
|
||||
* RSI = next thread's saved RSP
|
||||
*/
|
||||
switch_to:
|
||||
/* Push callee-saved registers of outgoing thread */
|
||||
/* Save callee-saved registers of outgoing thread */
|
||||
push rbp
|
||||
push rbx
|
||||
push r12
|
||||
@@ -16,13 +17,13 @@ switch_to:
|
||||
push r14
|
||||
push r15
|
||||
|
||||
/* Save current stack pointer */
|
||||
/* Save RSP of outgoing thread */
|
||||
mov [rdi], rsp
|
||||
|
||||
/* Load target stack pointer */
|
||||
/* Load RSP of incoming thread */
|
||||
mov rsp, rsi
|
||||
|
||||
/* Pop callee-saved registers of incoming thread */
|
||||
/* Restore callee-saved registers of incoming thread */
|
||||
pop r15
|
||||
pop r14
|
||||
pop r13
|
||||
@@ -31,3 +32,45 @@ switch_to:
|
||||
pop rbp
|
||||
|
||||
ret
|
||||
|
||||
/*
|
||||
* thread_entry_trampoline:
|
||||
* Jumped to via 'ret' in switch_to when a newly created thread runs for the first time.
|
||||
* When create_user_thread created the stack:
|
||||
* R12 was populated with user_rsp
|
||||
* R13 was populated with entry_rip
|
||||
*/
|
||||
thread_entry_trampoline:
|
||||
/* Set user data segments (0x18 | 3 = 0x1B) */
|
||||
mov ax, 0x1B
|
||||
mov ds, ax
|
||||
mov es, ax
|
||||
mov fs, ax
|
||||
mov gs, ax
|
||||
|
||||
/* Build hardware IRETQ frame on kernel stack */
|
||||
push 0x1B /* User SS */
|
||||
push r12 /* User RSP */
|
||||
push 0x3202 /* RFLAGS (IF=1, IOPL=3 for hardware drivers) */
|
||||
push 0x23 /* User CS (0x20 | 3 = 0x23) */
|
||||
push r13 /* User RIP */
|
||||
|
||||
/* Clear all general-purpose registers */
|
||||
xor rax, rax
|
||||
xor rbx, rbx
|
||||
xor rcx, rcx
|
||||
xor rdx, rdx
|
||||
xor rsi, rsi
|
||||
xor rdi, rdi
|
||||
xor rbp, rbp
|
||||
xor r8, r8
|
||||
xor r9, r9
|
||||
xor r10, r10
|
||||
xor r11, r11
|
||||
xor r12, r12
|
||||
xor r13, r13
|
||||
xor r14, r14
|
||||
xor r15, r15
|
||||
|
||||
/* Transition to Ring 3 */
|
||||
iretq
|
||||
|
||||
+36
-17
@@ -2,25 +2,46 @@
|
||||
.global syscall_entry
|
||||
.extern kernel_syscall_dispatcher
|
||||
|
||||
/* Per-CPU scratch: user RSP saved here on syscall entry */
|
||||
.section .bss
|
||||
.align 16
|
||||
user_scratch_rsp:
|
||||
.quad 0
|
||||
kernel_temp_stack:
|
||||
.skip 4096
|
||||
kernel_temp_stack_top:
|
||||
.align 8
|
||||
.global cpu0_scratch_user_rsp
|
||||
cpu0_scratch_user_rsp: .quad 0
|
||||
|
||||
.section .text
|
||||
/*
|
||||
* syscall_entry:
|
||||
* On entry (SYSCALL from Ring 3):
|
||||
* RCX = user RIP
|
||||
* R11 = user RFLAGS
|
||||
* RAX = syscall number
|
||||
* RDI,RSI,RDX,R10,R8,R9 = args
|
||||
* RSP = user RSP
|
||||
*
|
||||
* Strategy:
|
||||
* 1. Save user RSP into scratch area
|
||||
* 2. Load kernel RSP from TSS.RSP0 via gdt.rs TSS symbol
|
||||
* 3. Build SyscallRegisters on kernel stack
|
||||
* 4. Dispatch to Rust handler
|
||||
* 5. Restore & sysretq
|
||||
*/
|
||||
syscall_entry:
|
||||
/* Save user stack pointer */
|
||||
mov [rip + user_scratch_rsp], rsp
|
||||
lea rsp, [rip + kernel_temp_stack_top]
|
||||
/* Save user RSP */
|
||||
mov [rip + cpu0_scratch_user_rsp], rsp
|
||||
|
||||
/* Save user RIP (in RCX) and user RFLAGS (in R11) */
|
||||
/* Load kernel stack from TSS.rsp0.
|
||||
* TSS is exported as 'TSS' from gdt.rs.
|
||||
* Layout: _reserved1(u32=4 bytes), rsp0(u64=8 bytes)
|
||||
* So TSS.rsp0 is at offset 4 from TSS start.
|
||||
*/
|
||||
lea rsp, [rip + TSS]
|
||||
mov rsp, [rsp + 4]
|
||||
|
||||
/* Push user RIP and RFLAGS */
|
||||
push rcx
|
||||
push r11
|
||||
|
||||
/* Save argument and volatile registers to construct SyscallRegisters */
|
||||
/* Push syscall arguments as SyscallRegisters */
|
||||
push rax
|
||||
push rdi
|
||||
push rsi
|
||||
@@ -29,11 +50,10 @@ syscall_entry:
|
||||
push r9
|
||||
push r10
|
||||
|
||||
/* Pass pointer to SyscallRegisters struct in RDI */
|
||||
mov rdi, rsp
|
||||
call kernel_syscall_dispatcher
|
||||
|
||||
/* Restore registers (rax, rdx, r8 may have return values from dispatcher) */
|
||||
/* Restore args */
|
||||
pop r10
|
||||
pop r9
|
||||
pop r8
|
||||
@@ -42,12 +62,11 @@ syscall_entry:
|
||||
pop rdi
|
||||
pop rax
|
||||
|
||||
/* Restore user RIP and RFLAGS */
|
||||
/* Restore user context */
|
||||
pop r11
|
||||
pop rcx
|
||||
|
||||
/* Restore user stack */
|
||||
mov rsp, [rip + user_scratch_rsp]
|
||||
/* Restore user RSP */
|
||||
mov rsp, [rip + cpu0_scratch_user_rsp]
|
||||
|
||||
/* Return to Ring 3 */
|
||||
sysretq
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
.section .text
|
||||
timer_isr_entry:
|
||||
/* 1. Save all general-purpose registers to form a complete interrupt context frame */
|
||||
/* 1. Save all general-purpose registers to form complete interrupt context frame */
|
||||
push rax
|
||||
push rbx
|
||||
push rcx
|
||||
@@ -21,14 +21,10 @@ timer_isr_entry:
|
||||
push r14
|
||||
push r15
|
||||
|
||||
/* 2. Pass current saved stack pointer in RDI */
|
||||
mov rdi, rsp
|
||||
/* 2. Call handler in Rust (sends EOI and invokes sched.preempt_tick) */
|
||||
call timer_interrupt_handler
|
||||
|
||||
/* 3. Switch stack pointer to returned value (RAX contains next thread's RSP) */
|
||||
mov rsp, rax
|
||||
|
||||
/* 4. Restore all general-purpose registers */
|
||||
/* 3. Restore all general-purpose registers */
|
||||
pop r15
|
||||
pop r14
|
||||
pop r13
|
||||
@@ -45,5 +41,5 @@ timer_isr_entry:
|
||||
pop rbx
|
||||
pop rax
|
||||
|
||||
/* 5. Return from interrupt (IRETQ restores RIP, CS, RFLAGS, RSP, SS) */
|
||||
/* 4. Return from interrupt (IRETQ restores RIP, CS, RFLAGS, RSP, SS) */
|
||||
iretq
|
||||
|
||||
Reference in New Issue
Block a user