.set SEL_SCODE,0x8
.set SEL_SDATA,0x10
.set SEL_RCODE,0x18
.set SEL_RDATA,0x20
.p2align 4
.globl relocater
relocater:
cli
movl %eax, %esi
add $(relocater.1-relocater), %eax
jmp *%eax
relocater.1:
lea (relocater.2-relocater)(%esi), %eax
movl %eax, (jump_vector-relocater) (%esi)
lea (gdt-relocater) (%esi), %eax
movl %eax, (gdtaddr-relocater) (%esi)
lgdt (gdtdesc - relocater) (%esi)
lidt (idt-relocater) (%esi)
ljmp *(jump_vector-relocater) (%esi)
.code32
relocater.2:
xorl %eax, %eax
movb $SEL_SDATA, %al
movw %ax, %ss
movw %ax, %ds
movw %ax, %es
movw %ax, %fs
movw %ax, %gs
movl %cr0, %eax
andl $~0x80000000,%eax
movl %eax, %cr0
xorl %ecx, %ecx
movl %ecx, %cr3
cld
movl %esi, %ebx
xorl %edx, %edx
loop.1:
movl (relocater_data-relocater)(%ebx, %edx, 4), %eax
testl %eax, %eax
jz loop.2
movl (relocater_data-relocater)(%ebx, %edx, 4), %esi
inc %edx
movl (relocater_data-relocater)(%ebx, %edx, 4), %edi
inc %edx
movl (relocater_data-relocater)(%ebx, %edx, 4), %ecx
inc %edx
rep
movsb
jmp loop.1
loop.2:
movl %ebx, %esi
lea (relocater.3-relocater)(%esi), %eax
movl %eax, (jump_vector-relocater) (%esi)
movl $SEL_RCODE, %eax
movl %eax, (jump_vector-relocater+4) (%esi)
ljmp *(jump_vector-relocater) (%esi)
relocater.3:
.code16
movw $SEL_RDATA, %ax
movw %ax, %ds
movw %ax, %es
movw %ax, %fs
movw %ax, %gs
movw %ax, %ss
lidt (idt-relocater) (%esi)
lea (relocater.4-relocater)(%esi), %eax
movl %eax, (jump_vector-relocater) (%esi)
xorl %eax, %eax
movl %eax, (jump_vector-relocater+4) (%esi)
movl %cr0, %eax
dec %al
movl %eax, %cr0
ljmp *(jump_vector-relocater) (%esi)
relocater.4:
xorw %ax, %ax
movw %ax, %ds
movw %ax, %es
movw %ax, %fs
movw %ax, %gs
movw %ax, %ss
movw $0x7008,%bx
in $0x21,%al # Save master
push %ax # IMR
in $0xa1,%al # Save slave
push %ax # IMR
movb $0x11,%al # ICW1 to
outb %al,$0x20 # master,
outb %al,$0xa0 # slave
movb %bl,%al # ICW2 to
outb %al,$0x21 # master
movb %bh,%al # ICW2 to
outb %al,$0xa1 # slave
movb $0x4,%al # ICW3 to
outb %al,$0x21 # master
movb $0x2,%al # ICW3 to
outb %al,$0xa1 # slave
movb $0x1,%al # ICW4 to
outb %al,$0x21 # master,
outb %al,$0xa1 # slave
pop %ax # Restore slave
outb %al,$0xa1 # IMR
pop %ax # Restore master
outb %al,$0x21 # IMR
.byte 0xb8
.globl relocator_a20_enabled
relocator_a20_enabled:
.word 0
test %ax, %ax
jnz a20_done
movw $0xa00, %ax
movw %ax, %sp
movw %ax, %bp
movw $0x2400, %ax
int $0x15
call a20_check_state
testb %al, %al
jz a20_done
inb $0x92
andb $(~0x03), %al
outb $0x92
jmp a20_done
a20_check_state:
movw $100, %cx
1:
xorw %ax, %ax
movw %ax, %ds
decw %ax
movw %ax, %es
xorw %ax, %ax
movw $0x8000, %ax
movw %ax, %si
addw $0x10, %ax
movw %ax, %di
movb %ds:(%si), %dl
movb %es:(%di), %al
movb %al, %dh
decb %dh
movb %dh, %ds:(%si)
outb %al, $0x80
outb %al, $0x80
movb %es:(%di), %dh
subb %dh, %al
xorb $1, %al
movb %dl, %ds:(%si)
testb %al, %al
jz a20_done
loop 1b
ret
a20_done:
.byte 0xb8
.globl relocator_ds
relocator_ds: .word 0
movw %ax, %ds
.byte 0xb8
.globl relocator_es
relocator_es: .word 0
movw %ax, %es
.byte 0xb8
.globl relocator_fs
relocator_fs: .word 0
movw %ax, %fs
.byte 0xb8
.globl relocator_gs
relocator_gs: .word 0
movw %ax, %gs
.byte 0xb8
.globl relocator_ss
relocator_ss: .word 0
movw %ax, %ss
.byte 0xb8
.globl relocator_sp
relocator_sp: .word 0
movzwl %ax, %esp
.byte 0x66, 0xb8
.globl relocator_esi
relocator_esi: .long 0
movl %eax, %esi
.byte 0x66, 0xba
.globl relocator_edx
relocator_edx: .long 0
.byte 0x66, 0xbb
.globl relocator_ebx
relocator_ebx: .long 0
.byte 0x66, 0xb8
.globl relocator_eax
relocator_eax: .long 0
.byte 0x66, 0xbd
.globl relocator_ebp
relocator_ebp: .long 0
sti
.byte 0xea
.globl relocator_ip
relocator_ip:
.word 0
.globl relocator_cs
relocator_cs:
.word 0
.code32
.p2align 4
jump_vector: .long 0
.long SEL_SCODE
gdt: .word 0x0, 0x0
.byte 0x0, 0x0, 0x0, 0x0
.word 0xffff, 0x0
.byte 0x0, 0x9a, 0xcf, 0x0
.word 0xffff, 0x0
.byte 0x0, 0x92, 0xcf, 0x0
.word 0xffff, 0x0
.byte 0x0, 0x9a, 0x0f, 0x0
.word 0xffff, 0x0
.byte 0x0, 0x92, 0x0f, 0x0
gdt.1:
gdtdesc: .word gdt.1 - gdt - 1
gdtaddr: .long 0
idt: .word 0x3ff
.long 0
.globl relocater_data
relocater_data:
.long 0
.long 0
.long 0
.long 0
.long 0
.long 0
.long 0
.long 0
.long 0
.long 0
.globl relocater_size
relocater_size:
.long relocater_size-relocater