mirror of
https://github.com/limine-bootloader/limine
synced 2025-03-20 16:33:17 +03:00
Added rm_int function to execute real mode interrupts from pmode
This commit is contained in:
parent
6d53345231
commit
d1a4f7856f
106
lib/real.c
Normal file
106
lib/real.c
Normal 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
18
lib/real.h
Normal 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
11
main.c
@ -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);
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user