summaryrefslogtreecommitdiff
path: root/rt
diff options
context:
space:
mode:
Diffstat (limited to 'rt')
-rw-r--r--rt/+x86_64/realcall.S74
-rw-r--r--rt/+x86_64/stage0.s1
-rw-r--r--rt/+x86_64/stage0_drive.S3
-rw-r--r--rt/hare.sc2
4 files changed, 57 insertions, 23 deletions
diff --git a/rt/+x86_64/realcall.S b/rt/+x86_64/realcall.S
index 46745f8..9e9afb4 100644
--- a/rt/+x86_64/realcall.S
+++ b/rt/+x86_64/realcall.S
@@ -1,7 +1,7 @@
.code64
-.globl real.regs
-real.regs:
+.globl bios.regs
+bios.regs:
reax:
.int 0x0
rebx:
@@ -14,6 +14,17 @@ redi:
.int 0x0
resi:
.int 0x0
+rds:
+ .short 0x0
+res:
+ .short 0x0
+rss:
+ .short 0x0
+rgs:
+ .short 0x0
+rfs:
+ .short 0x0
+
# :real_call
@@ -26,9 +37,9 @@ resi:
# above.
# The procedure to go from Long Mode back to Real Mode is explained in much details
# in the AMD64 Programmer's Manual Vol. 2, in particular, the figure 1-6. in section 1.3.
-.globl real.call
-real.call:
- # :Push all the segments registers
+.globl bios.call
+bios.call:
+ xchg %bx, %bx
push %rbx
push %r12
push %r13
@@ -80,27 +91,44 @@ real_call_to_16bits_rmode_down:
mov %ax, %gs
mov %ax, %fs
- # :real mode, yay
-
lidt bios_idtr
-
sti
- mov rebx, %ebx
- mov recx, %ecx
- mov redx, %edx
- mov redi, %edi
- mov resi, %esi
-
- pop %ax
- call *%ax
-
- mov %eax, reax
- mov %ebx, rebx
- mov %ecx, recx
- mov %edx, redx
- mov %edi, redi
- mov %esi, resi
+ # :Self modifying code to call arbitrary interrupts
+ pop %ax
+ mov $real_call_int, %bx
+ mov %al, 1(%bx)
+
+ push %ds
+
+ # :Load registers
+ mov (reax), %eax
+ mov (rebx), %ebx
+ mov (recx), %ecx
+ mov (redx), %edx
+ mov (redi), %edi
+ mov (resi), %esi
+ mov %ds:(res), %es
+ mov %ds:(rss), %ss
+ mov %ds:(rgs), %gs
+ mov %ds:(rfs), %fs
+ mov %ds:(rds), %ds
+ xchg %bx, %bx
+
+real_call_int:
+ int $0x0
+
+ pop %ds
+ mov %ds:(rfs), %fs
+ mov %ds:(rgs), %gs
+ mov %ds:(rss), %ss
+ mov %ds:(res), %es
+ mov %eax, (reax)
+ mov %ebx, (rebx)
+ mov %ecx, (recx)
+ mov %edx, (redx)
+ mov %edi, (redi)
+ mov %esi, (resi)
cli
diff --git a/rt/+x86_64/stage0.s b/rt/+x86_64/stage0.s
index de0b0e4..e17c06b 100644
--- a/rt/+x86_64/stage0.s
+++ b/rt/+x86_64/stage0.s
@@ -13,6 +13,7 @@ _stage0:
# :Clear segment registers
# this is important if memory accesses are done later before proper segmentation
# as these registers can have arbitrary values
+ xchg %bx, %bx
xor %ax, %ax
mov %ax, %ds
mov %ax, %es
diff --git a/rt/+x86_64/stage0_drive.S b/rt/+x86_64/stage0_drive.S
index 1b6a801..c376b6b 100644
--- a/rt/+x86_64/stage0_drive.S
+++ b/rt/+x86_64/stage0_drive.S
@@ -1,12 +1,15 @@
# :Boot drive number
+.globl drive_no
drive_no:
.byte 0
# :Boot drive sectors per track
+.globl drive_spt
drive_spt:
.byte 0
# :Boot drive number of heads
+.globl drive_heads
drive_heads:
.byte 0
diff --git a/rt/hare.sc b/rt/hare.sc
index 0cb9c02..3de964c 100644
--- a/rt/hare.sc
+++ b/rt/hare.sc
@@ -20,6 +20,8 @@ SECTIONS {
. += 4096;
_p1 = .;
. += 4096;
+ _ws = .;
+ . += 512;
. = 0x7c00;
stack_top = .;