|
| 1 | +; |
| 2 | +; Master thesis |
| 3 | +; by Alf-Andre Walla 2016-2017 |
| 4 | +; |
| 5 | +; |
| 6 | +ORG 0x8000 |
| 7 | + |
| 8 | +%define code32_segment 0x08 |
| 9 | +%define data32_segment 0x10 |
| 10 | +%define SOFT_RESET_MAGIC 0xFEE1DEAD |
| 11 | + |
| 12 | +[BITS 64] |
| 13 | +ALIGN 16 |
| 14 | +;; first six pointer arguments are passed in |
| 15 | +;; RDI, RSI, RDX, RCX, R8, and R9 |
| 16 | +;; hotswap64( |
| 17 | +;; RDI: char* dest, |
| 18 | +;; RSI: const char* base, |
| 19 | +;; RDX: size_t len, |
| 20 | +;; RCX: void* entry_function, |
| 21 | +;; R8: void* reset_data) |
| 22 | +hotswap_amd64: |
| 23 | + ;; save soft reset data location and entry function |
| 24 | + mov rax, r8 |
| 25 | + mov [startaddr], ecx ; rcx |
| 26 | + mov [bootaddr], eax ; r8 |
| 27 | + |
| 28 | + ;; hotswap 64-bit kernel |
| 29 | + ;; source: RSI |
| 30 | + ;; dest: RDI |
| 31 | + mov rcx, rdx ;; count |
| 32 | + cld |
| 33 | + rep movsb |
| 34 | + |
| 35 | +begin_enter_protected: |
| 36 | + ; load 64-bit GDTR with 32-bit entries |
| 37 | + lgdt [gdtr64] |
| 38 | + ; enter compatibility mode |
| 39 | + push data32_segment |
| 40 | + push rsp |
| 41 | + pushf |
| 42 | + push code32_segment |
| 43 | + mov ecx, compatibility_mode |
| 44 | + push rcx |
| 45 | + iretq |
| 46 | + |
| 47 | +startaddr: dd 0 |
| 48 | +bootaddr: dd 0 |
| 49 | + |
| 50 | +[BITS 32] |
| 51 | +ALIGN 16 |
| 52 | +compatibility_mode: |
| 53 | + ; disable paging |
| 54 | + mov ecx, cr0 |
| 55 | + and ecx, 0x7fffffff ;; clear PG (bit 31) |
| 56 | + mov cr0, ecx |
| 57 | + ; disable LM |
| 58 | + mov ecx, 0xC0000080 ; EFER MSR |
| 59 | + rdmsr |
| 60 | + and eax, ~(1 << 8) ; remove LM-bit |
| 61 | + wrmsr |
| 62 | + |
| 63 | + ;; enter 32-bit protected mode |
| 64 | + jmp code32_segment:protected_mode |
| 65 | +protected_mode: |
| 66 | + mov cx, data32_segment |
| 67 | + mov ss, cx |
| 68 | + mov ds, cx |
| 69 | + mov es, cx |
| 70 | + mov fs, cx |
| 71 | + mov gs, cx |
| 72 | + |
| 73 | + ;;rdtsc |
| 74 | + ;;mov DWORD [0x10000], eax |
| 75 | + ;;mov DWORD [0x10004], edx |
| 76 | + |
| 77 | + ;; enter the new service from its entry point |
| 78 | + ;; in 32-bit protected mode, while passing |
| 79 | + ;; multiboot parameters in eax and ebx |
| 80 | + mov eax, SOFT_RESET_MAGIC |
| 81 | + mov ebx, [bootaddr] |
| 82 | + jmp DWORD [startaddr] |
| 83 | + |
| 84 | +gdtr: |
| 85 | + dw gdt32_end - gdt32 - 1 |
| 86 | + dd gdt32 |
| 87 | +gdt32: |
| 88 | + ;; Entry 0x0: Null descriptor |
| 89 | + dq 0x0 |
| 90 | + ;; Entry 0x18: 32-bit Code segment |
| 91 | + dw 0xffff ;Limit |
| 92 | + dw 0x0000 ;Base 15:00 |
| 93 | + db 0x00 ;Base 23:16 |
| 94 | + dw 0xcf9a ;Flags / Limit / Type [F,L,F,Type] |
| 95 | + db 0x00 ;Base 32:24 |
| 96 | + ;; Entry 0x20: 32-bit Data segment |
| 97 | + dw 0xffff ;Limit |
| 98 | + dw 0x0000 ;Base 15:00 |
| 99 | + db 0x00 ;Base 23:16 |
| 100 | + dw 0xcf92 ;Flags / Limit / Type [F,L,F,Type] |
| 101 | + db 0x00 ;Base 32:24 |
| 102 | +gdt32_end: |
| 103 | +gdtr64: |
| 104 | + dw $ - gdt32 - 1 ; Limit |
| 105 | + dq gdt32 ; Base |
0 commit comments