numbuf: .space 16
-# this is not boot loader code. It's called later on by the main
-# kernel code in 32bit protected mode. It's placed here because
-# it needs to be in base memory as it returns and runs in real mode.
-
+# this is not boot loader code. It's called later on by the main kernel
+# code in 32bit protected mode. It's placed here because it needs to be
+# located in base memory as it returns and runs in real mode.
.code32
.align 4
# place to save the protected mode IDTR pseudo-descriptor
rmidt: .short 0x3ff
.long 0
- # drop back to unreal mode to set video mode
- .global set_mode13h
-set_mode13h:
+saved_esp: .long 0
+saved_ebp: .long 0
+
+ # drop back to unreal mode to call 16bit interrupt
+ .global int86
+int86:
+ push %ebp
+ mov %esp, %ebp
pushal
cli
# save protected mode IDTR and replace it with the real mode vectors
mov %ax, %ss
nop
- # switch video mode by calling the video bios
- mov $0x13, %ax
- int $0x10
+ # modify the int instruction
+ mov $int_op, %ebx
+ movb 4(%ebp), %al
+ movb %al, 1(%ebx)
+
+ # load registers from the int86regs struct
+ mov %esp, saved_esp
+ mov %ebp, saved_ebp
+ mov 8(%ebp), %esp
+ popal
+ mov saved_esp, %esp
+
+ # call 16bit interrupt
+int_op: int $0
+
+ mov saved_ebp, %ebp
+ mov 8(%ebp), %esp
+ add $32, %esp
+ pushal
+ mov saved_esp, %esp
# re-enable protection
mov %cr0, %eax
lidt (saved_idtr)
sti
popal
+ pop %ebp
ret
--- /dev/null
+#ifndef INT86_H_
+#define INT86_H_
+
+#include <inttypes.h>
+
+struct int86regs {
+ uint32_t edi, esi, ebp, esp;
+ uint32_t ebx, edx, ecx, eax;
+ uint16_t flags;
+ uint16_t es, ds, fs, gs;
+} __attribute__ ((packed));
+
+void int86(int inum, struct int86regs *regs);
+
+#endif /* INT86_H_ */
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#include <stdio.h>
+#include <string.h>
#include <ctype.h>
#include "segm.h"
#include "intr.h"
#include "keyb.h"
#include "timer.h"
#include "contty.h"
+#include "int86.h"
+
+static void set_mode13h(void)
+{
+ struct int86regs regs;
+
+ memset(®s, 0, sizeof regs);
+ regs.eax = 0x13;
+ int86(0x10, ®s);
+}
-void set_mode13h(void);
void logohack(void);
void pcboot_main(void)