diff --git a/boot1/asm/bios_call.s b/boot1/asm/bios_call.s index cad000c..990932d 100644 --- a/boot1/asm/bios_call.s +++ b/boot1/asm/bios_call.s @@ -12,7 +12,7 @@ section .text [bits 32] ; FIXME: use a separate stack for real mode -bios_call: +_bios_call: .PARAMS_START equ 36 .PARAM_BIOS_INTR_NUM equ .PARAMS_START .PARAM_BIOS_INTR_ARGS_PTR equ .PARAMS_START + 4 @@ -83,13 +83,30 @@ bios_call: call [bp + 2] pop bp - ; TODO: return resulting registers to the caller + ; Copy the resulting register values back into the `BiosIntr` struct provided by the caller. + pushfd + push es + push ds + push edi + push esi + push edx + push ecx + push ebx + push eax + mov cx, 32 + mov si, sp + mov di, [bp + .PARAM_BIOS_INTR_ARGS_PTR] + rep movsb + add sp, 32 ; Reset the segment registers that were changed to the caller-provided values. xor ax, ax mov ds, ax mov es, ax + ; Pop the `int` function off the stack. + add sp, 4 + ; Reload the GDT in case the BIOS call changed it. mov bx, sp lgdt [bx] @@ -116,7 +133,7 @@ bios_call: popad ret -global bios_call +global _bios_call %macro int_fn 1 diff --git a/boot1/src/main.rs b/boot1/src/main.rs index c9be456..391da11 100644 --- a/boot1/src/main.rs +++ b/boot1/src/main.rs @@ -25,7 +25,7 @@ struct BiosIntr { } unsafe extern "C" { - unsafe fn bios_call(intr: u32, args: *mut BiosIntr); + unsafe fn _bios_call(intr: u32, args: *mut BiosIntr); } #[panic_handler] @@ -54,7 +54,7 @@ pub extern "C" fn _start() -> ! { }; unsafe { - bios_call(0x15, &raw mut args); + _bios_call(0x15, &raw mut args); } for (i, b) in STR.iter().copied().enumerate() {