Added rm_int function to execute real mode interrupts from pmode

This commit is contained in:
mintsuki 2019-05-31 05:47:13 +02:00
parent 6d53345231
commit d1a4f7856f
3 changed files with 132 additions and 3 deletions

106
lib/real.c Normal file
View File

@ -0,0 +1,106 @@
#include <lib/real.h>
__attribute__((naked))
void rm_int(
uint8_t int_no,
struct rm_regs *out_regs,
struct rm_regs *in_regs) {
asm (
// Self-modifying code: int $int_no
"mov al, byte ptr ss:[esp+4]\n\t"
"mov byte ptr ds:[3f], al\n\t"
// Save out_regs
"mov eax, dword ptr ss:[esp+8]\n\t"
"mov dword ptr ds:[6f], eax\n\t"
// Save in_regs
"mov eax, dword ptr ss:[esp+12]\n\t"
"mov dword ptr ds:[7f], eax\n\t"
// Save non-scratch GPRs
"push ebx\n\t"
"push esi\n\t"
"push edi\n\t"
"push ebp\n\t"
// Jump to real mode
"jmp 0x08:1f\n\t"
"1: .code16\n\t"
"mov ax, 0x10\n\t"
"mov ds, ax\n\t"
"mov es, ax\n\t"
"mov fs, ax\n\t"
"mov gs, ax\n\t"
"mov ss, ax\n\t"
"mov eax, cr0\n\t"
"and al, 0xfe\n\t"
"mov cr0, eax\n\t"
"jmp 0:2f\n\t"
"2:\n\t"
"mov ax, 0\n\t"
"mov ds, ax\n\t"
"mov es, ax\n\t"
"mov fs, ax\n\t"
"mov gs, ax\n\t"
"mov ss, ax\n\t"
// Load in_regs
"mov dword ptr ds:[5f], esp\n\t"
"mov esp, dword ptr ds:[7f]\n\t"
"pop ebp\n\t"
"pop edi\n\t"
"pop esi\n\t"
"pop edx\n\t"
"pop ecx\n\t"
"pop ebx\n\t"
"pop eax\n\t"
"mov esp, dword ptr ds:[5f]\n\t"
// Indirect interrupt call
".byte 0xcd\n\t"
"3: .byte 0\n\t"
// Load out_regs
"mov dword ptr ds:[5f], esp\n\t"
"mov esp, dword ptr ds:[6f]\n\t"
"add esp, 7*4\n\t"
"push eax\n\t"
"push ebx\n\t"
"push ecx\n\t"
"push edx\n\t"
"push esi\n\t"
"push edi\n\t"
"push ebp\n\t"
"mov esp, dword ptr ds:[5f]\n\t"
// Jump back to pmode
"mov eax, cr0\n\t"
"or al, 1\n\t"
"mov cr0, eax\n\t"
"jmp 0x18:4f\n\t"
"4: .code32\n\t"
"mov ax, 0x20\n\t"
"mov ds, ax\n\t"
"mov es, ax\n\t"
"mov fs, ax\n\t"
"mov gs, ax\n\t"
"mov ss, ax\n\t"
// Restore non-scratch GPRs
"pop ebp\n\t"
"pop edi\n\t"
"pop esi\n\t"
"pop ebx\n\t"
// Exit
"ret\n\t"
// ESP
"5: .long 0\n\t"
// out_regs
"6: .long 0\n\t"
// in_regs
"7: .long 0\n\t"
);
}

18
lib/real.h Normal file
View File

@ -0,0 +1,18 @@
#ifndef __REAL_H__
#define __REAL_H__
#include <stdint.h>
struct rm_regs {
uint32_t ebp;
uint32_t edi;
uint32_t esi;
uint32_t edx;
uint32_t ecx;
uint32_t ebx;
uint32_t eax;
};
void rm_int(uint8_t, struct rm_regs *, struct rm_regs *);
#endif

11
main.c
View File

@ -6,10 +6,15 @@ asm (
);
#include <drivers/vga_textmode.h>
#include <lib/real.h>
void main(int boot_drive) {
// TODO
init_vga_textmode();
text_write("hello world", 11);
for (;;);
text_write("qLoader 2\n\n", 11);
for (;;) {
struct rm_regs r = {0};
rm_int(0x16, &r, &r); // Real mode interrupt 16h
char c = (char)(r.eax & 0xff);
text_write(&c, 1);
}
}