mirror of
https://github.com/limine-bootloader/limine
synced 2025-03-21 00:42:56 +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 <drivers/vga_textmode.h>
|
||||||
|
#include <lib/real.h>
|
||||||
|
|
||||||
void main(int boot_drive) {
|
void main(int boot_drive) {
|
||||||
// TODO
|
|
||||||
init_vga_textmode();
|
init_vga_textmode();
|
||||||
text_write("hello world", 11);
|
text_write("qLoader 2\n\n", 11);
|
||||||
for (;;);
|
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