123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601 |
-
-
- FILE_LICENCE ( GPL2_OR_LATER )
-
-
- #include "librm.h"
-
-
- #define CR0_PE 1
-
-
- #define SIZEOF_I386_SEG_REGS 12
- #define SIZEOF_I386_REGS 32
- #define SIZEOF_REAL_MODE_REGS ( SIZEOF_I386_SEG_REGS + SIZEOF_I386_REGS )
- #define SIZEOF_I386_FLAGS 4
- #define SIZEOF_I386_ALL_REGS ( SIZEOF_REAL_MODE_REGS + SIZEOF_I386_FLAGS )
-
- .arch i386
-
-
- .section ".data16", "aw", @progbits
- .align 16
- gdt:
- gdtr:
- gdt_limit: .word gdt_length - 1
- gdt_base: .long 0
- .word 0
-
- .org gdt + VIRTUAL_CS, 0
- virtual_cs:
- .word 0xffff, 0
- .byte 0, 0x9f, 0xcf, 0
-
- .org gdt + VIRTUAL_DS, 0
- virtual_ds:
- .word 0xffff, 0
- .byte 0, 0x93, 0xcf, 0
-
- .org gdt + PHYSICAL_CS, 0
- physical_cs:
- .word 0xffff, 0
- .byte 0, 0x9f, 0xcf, 0
-
- .org gdt + PHYSICAL_DS, 0
- physical_ds:
- .word 0xffff, 0
- .byte 0, 0x93, 0xcf, 0
-
- .org gdt + REAL_CS, 0
- real_cs:
- .word 0xffff, 0
- .byte 0, 0x9b, 0x00, 0
-
- .org gdt + REAL_DS
- real_ds:
- .word 0xffff, 0
- .byte 0, 0x93, 0x00, 0
-
- gdt_end:
- .equ gdt_length, gdt_end - gdt
-
-
- .section ".text16", "ax", @progbits
- .code16
- .globl init_librm
- init_librm:
-
- pushl %eax
- pushl %ebx
-
-
- movl %edi, %eax
- movw $virtual_cs, %bx
- call set_seg_base
- movw $virtual_ds, %bx
- call set_seg_base
- movl %edi, rm_virt_offset
-
-
- negl %edi
-
-
- xorl %eax, %eax
- movw %cs, %ax
- movw %ax, rm_cs
- shll $4, %eax
- movw $real_cs, %bx
- call set_seg_base
- addr32 leal (%eax, %edi), %ebx
- movl %ebx, rm_text16
-
-
- xorl %eax, %eax
- movw %ds, %ax
- movw %ax, %cs:rm_ds
- shll $4, %eax
- movw $real_ds, %bx
- call set_seg_base
- addr32 leal (%eax, %edi), %ebx
- movl %ebx, rm_data16
-
-
- movl %eax, gdt_base
- addl $gdt, gdt_base
- call idt_init
-
-
- negl %edi
- popl %ebx
- popl %eax
- lret
-
- .section ".text16", "ax", @progbits
- .code16
- .weak idt_init
- set_seg_base:
- 1: movw %ax, 2(%bx)
- rorl $16, %eax
- movb %al, 4(%bx)
- movb %ah, 7(%bx)
- roll $16, %eax
- idt_init:
- ret
-
-
- .section ".text16", "ax", @progbits
- .code16
- real_to_prot:
-
- call enable_a20
-
-
- 1: jc 1b
-
-
- movw %cs:rm_ds, %ax
- movw %ax, %ds
-
-
-
- pushl rm_virt_offset
- pushl rm_text16
- pushl rm_data16
- addw $16, %cx
-
-
- xorl %ebp, %ebp
- movw %ss, %bp
- movzwl %sp, %edx
- movl %ebp, %eax
- shll $4, %eax
- addr32 leal (%eax,%edx), %esi
- subl rm_virt_offset, %esi
-
-
- cli
- data32 lgdt gdtr
- data32 lidt idtr
- movl %cr0, %eax
- orb $CR0_PE, %al
- movl %eax, %cr0
- data32 ljmp $VIRTUAL_CS, $1f
- .section ".text", "ax", @progbits
- .code32
- 1:
-
- movw $VIRTUAL_DS, %ax
- movw %ax, %ds
- movw %ax, %es
- movw %ax, %fs
- movw %ax, %gs
- movw %ax, %ss
- movl pm_esp, %esp
-
-
- movw %bp, rm_ss
- addl %ecx, %edx
- movw %dx, rm_sp
-
-
- subl %ecx, %esp
- movl %esp, %edi
- rep movsb
-
-
- popl data16
- popl text16
- popl virt_offset
-
-
- ret
-
-
- .section ".data16", "aw", @progbits
- .weak idtr
- idtr:
- rm_idtr:
- .word 0xffff
- .long 0
-
-
- .section ".text", "ax", @progbits
- .code32
- prot_to_real:
-
- addl $4, %ecx
-
-
- movzwl rm_ss, %ebp
- movzwl rm_sp, %edx
- subl %ecx, %edx
- movl %ebp, %eax
- shll $4, %eax
- leal (%eax,%edx), %edi
- subl virt_offset, %edi
-
-
- movl %esp, %esi
- rep movsb
-
-
- movl %esi, pm_esp
-
-
- movw $REAL_DS, %ax
- movw %ax, %ds
- movw %ax, %es
- movw %ax, %fs
- movw %ax, %gs
- movw %ax, %ss
- ljmp $REAL_CS, $1f
- .section ".text16", "ax", @progbits
- .code16
- 1:
-
- movl %cr0, %eax
- andb $0!CR0_PE, %al
- movl %eax, %cr0
- ljmp *p2r_jump_vector
- p2r_jump_target:
-
-
- movw %cs:rm_ds, %ax
- movw %ax, %ds
- movw %ax, %es
- movw %ax, %fs
- movw %ax, %gs
- movw %bp, %ss
- movl %edx, %esp
-
-
- data32 lidt rm_idtr
-
-
- data32 ret
-
-
-
-
- .section ".data16", "aw", @progbits
- p2r_jump_vector:
- .word p2r_jump_target
- .globl rm_cs
- rm_cs: .word 0
- .globl rm_ds
- .section ".text16.data", "aw", @progbits
- rm_ds: .word 0
-
-
-
- #define PC_OFFSET_GDT ( 0 )
- #define PC_OFFSET_IDT ( PC_OFFSET_GDT + 8 )
- #define PC_OFFSET_IX86 ( PC_OFFSET_IDT + 8 )
- #define PC_OFFSET_RETADDR ( PC_OFFSET_IX86 + SIZEOF_I386_ALL_REGS )
- #define PC_OFFSET_FUNCTION ( PC_OFFSET_RETADDR + 4 )
- #define PC_OFFSET_END ( PC_OFFSET_FUNCTION + 4 )
-
- .section ".text16", "ax", @progbits
- .code16
- .globl prot_call
- prot_call:
-
- pushfl
- pushal
- pushw %gs
- pushw %fs
- pushw %es
- pushw %ds
- pushw %ss
- pushw %cs
- subw $16, %sp
- movw %sp, %bp
- sidt 8(%bp)
- sgdt (%bp)
-
-
- cld
-
-
- movl $PC_OFFSET_END, %ecx
- pushl $1f
- jmp real_to_prot
- .section ".text", "ax", @progbits
- .code32
- 1:
-
- leal PC_OFFSET_IX86(%esp), %eax
- pushl %eax
- call *(PC_OFFSET_FUNCTION+4)(%esp)
- popl %eax
-
-
- movl $PC_OFFSET_END, %ecx
- pushl $1f
- jmp prot_to_real
- .section ".text16", "ax", @progbits
- .code16
- 1:
-
- movw %sp, %bp
- data32 lgdt (%bp)
- data32 lidt 8(%bp)
- addw $20, %sp
- popw %ds
- popw %es
- popw %fs
- popw %gs
- popal
-
-
- addr32 movl -20(%esp), %esp
- popfl
- lret
-
-
-
- #define RC_OFFSET_PRESERVE_REGS ( 0 )
- #define RC_OFFSET_RETADDR ( RC_OFFSET_PRESERVE_REGS + SIZEOF_I386_REGS )
- #define RC_OFFSET_FUNCTION ( RC_OFFSET_RETADDR + 4 )
- #define RC_OFFSET_END ( RC_OFFSET_FUNCTION + 4 )
-
- .section ".text", "ax", @progbits
- .code32
- .globl real_call
- real_call:
-
- pushal
- pushl RC_OFFSET_FUNCTION(%esp)
-
-
- movl $( RC_OFFSET_RETADDR + 4 ), %ecx
- pushl $1f
- jmp prot_to_real
- .section ".text16", "ax", @progbits
- .code16
- 1:
-
- popl rc_function
- popal
- call *rc_function
- pushal
-
-
- cld
-
-
- movl $RC_OFFSET_RETADDR, %ecx
- pushl $1f
- jmp real_to_prot
- .section ".text", "ax", @progbits
- .code32
- 1:
-
- popal
- ret
-
-
-
-
- .section ".data16", "aw", @progbits
- rc_function: .word 0, 0
-
-
- .section ".text16", "ax", @progbits
- .code16
- .globl flatten_real_mode
- flatten_real_mode:
-
- movb $0x8f, real_cs + 6
- movb $0x8f, real_ds + 6
-
- pushl $flatten_dummy
- pushw %cs
- call prot_call
- addw $4, %sp
-
- movb $0x00, real_cs + 6
- movb $0x00, real_ds + 6
-
- ret
-
- .section ".text", "ax", @progbits
- .code32
- flatten_dummy:
- ret
-
-
- .section ".data", "aw", @progbits
- .globl rm_sp
- rm_sp: .word 0
- .globl rm_ss
- rm_ss: .word 0
- pm_esp: .long _estack
-
-
-
- .section ".data16", "aw", @progbits
- rm_virt_offset: .long 0
- rm_text16: .long 0
- rm_data16: .long 0
-
-
- .section ".data", "aw", @progbits
- .globl virt_offset
- virt_offset: .long 0
- .globl text16
- text16: .long 0
- .globl data16
- data16: .long 0
|