diff options
Diffstat (limited to 'rt')
| -rw-r--r-- | rt/+x86_64/realcall.S | 74 | ||||
| -rw-r--r-- | rt/+x86_64/stage0.s | 1 | ||||
| -rw-r--r-- | rt/+x86_64/stage0_drive.S | 3 | ||||
| -rw-r--r-- | rt/hare.sc | 2 |
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 @@ -20,6 +20,8 @@ SECTIONS { . += 4096; _p1 = .; . += 4096; + _ws = .; + . += 512; . = 0x7c00; stack_top = .; |
