| 1 | section .realmode |
| 2 | |
| 3 | global pxe_call |
| 4 | global set_pxe_fp |
| 5 | |
| 6 | set_pxe_fp: |
| 7 | mov eax, [esp + 4] |
| 8 | mov [pxe_call.pxe_fp], eax |
| 9 | ret |
| 10 | |
| 11 | pxe_call: |
| 12 | ; Save GDT in case BIOS overwrites it |
| 13 | sgdt [.gdt] |
| 14 | |
| 15 | ; Save IDT |
| 16 | sidt [.idt] |
| 17 | |
| 18 | ; Load BIOS IVT |
| 19 | lidt [.rm_idt] |
| 20 | |
| 21 | ; Save non-scratch GPRs |
| 22 | push ebx |
| 23 | push esi |
| 24 | push edi |
| 25 | push ebp |
| 26 | |
| 27 | lea ebp, [esp + 20] |
| 28 | |
| 29 | ; Jump to real mode |
| 30 | jmp 0x08:.bits16 |
| 31 | .bits16: |
| 32 | bits 16 |
| 33 | mov ax, 0x10 |
| 34 | mov ds, ax |
| 35 | mov es, ax |
| 36 | mov fs, ax |
| 37 | mov gs, ax |
| 38 | mov ss, ax |
| 39 | mov eax, cr0 |
| 40 | and al, 0xfe |
| 41 | mov cr0, eax |
| 42 | jmp 0x00:.cszero |
| 43 | .cszero: |
| 44 | xor ax, ax |
| 45 | mov ss, ax |
| 46 | mov ds, ax |
| 47 | mov es, ax |
| 48 | mov fs, ax |
| 49 | mov gs, ax |
| 50 | |
| 51 | sti |
| 52 | |
| 53 | push word [bp + 4] |
| 54 | push word [bp + 8] |
| 55 | push word [bp + 0] |
| 56 | call far [.pxe_fp] |
| 57 | add sp, 6 |
| 58 | |
| 59 | cli |
| 60 | |
| 61 | ; Restore GDT |
| 62 | o32 lgdt [cs:.gdt] |
| 63 | |
| 64 | ; Restore IDT |
| 65 | o32 lidt [cs:.idt] |
| 66 | |
| 67 | ; Jump back to pmode |
| 68 | mov ebx, cr0 |
| 69 | or bl, 1 |
| 70 | mov cr0, ebx |
| 71 | jmp 0x18:.bits32 |
| 72 | .bits32: |
| 73 | bits 32 |
| 74 | mov bx, 0x20 |
| 75 | mov ds, bx |
| 76 | mov es, bx |
| 77 | mov fs, bx |
| 78 | mov gs, bx |
| 79 | mov ss, bx |
| 80 | |
| 81 | and eax, 0xffff |
| 82 | |
| 83 | ; Restore non-scratch GPRs |
| 84 | pop ebp |
| 85 | pop edi |
| 86 | pop esi |
| 87 | pop ebx |
| 88 | |
| 89 | ; Exit |
| 90 | ret |
| 91 | |
| 92 | align 16 |
| 93 | .pxe_fp: dd 0 |
| 94 | .gdt: dq 0 |
| 95 | .idt: dq 0 |
| 96 | .rm_idt: dw 0x3ff |
| 97 | dd 0 |
| 98 | |
| 99 | section .note.GNU-stack noalloc noexec nowrite progbits |
