|
1 | | -;;;Pasaje 16 to 64 bits |
| 1 | +;;============================================================================== |
| 2 | +;; |
| 3 | +;;============================================================================== |
2 | 4 |
|
3 | | - mov [p_BootDisk], bh ; Save disk from where system was booted from |
| 5 | +;; Primera parte: pasa real mode a protected mode. |
4 | 6 |
|
5 | | - mov eax, 16 ; Set the correct segment registers |
| 7 | + |
| 8 | +start16: |
| 9 | + |
| 10 | + |
| 11 | + |
| 12 | +; Get the BIOS E820 Memory Map |
| 13 | +; https://wiki.osdev.org/Detecting_Memory_(x86)#BIOS_Function:_INT_0x15,_EAX_=_0xE820 |
| 14 | +; The code below is from https://wiki.osdev.org/Detecting_Memory_(x86)#Getting_an_E820_Memory_Map |
| 15 | +; inputs: es:di -> destination buffer for 24 byte entries |
| 16 | +; outputs: bp = entry count, trashes all registers except esi |
| 17 | +; The function below creates a memory map at address 0x6000 and the records are: |
| 18 | +; 64-bit Base |
| 19 | +; 64-bit Length |
| 20 | +; 32-bit Type (1 = normal, 2 reserved, ACPI reclaimable) |
| 21 | +; 32-bit ACPI |
| 22 | +; 64-bit Padding |
| 23 | +do_e820: |
| 24 | + mov edi, 0x00006000 ; location that memory map will be stored to |
| 25 | + xor ebx, ebx ; ebx must be 0 to start |
| 26 | + xor bp, bp ; keep an entry count in bp |
| 27 | + mov edx, 0x0534D4150 ; Place "SMAP" into edx |
| 28 | + mov eax, 0xe820 |
| 29 | + mov [es:di + 20], dword 1 ; force a valid ACPI 3.X entry |
| 30 | + mov ecx, 24 ; ask for 24 bytes |
| 31 | + int 0x15 |
| 32 | + jc nomemmap ; carry set on first call means "unsupported function" |
| 33 | + mov edx, 0x0534D4150 ; Some BIOSes apparently trash this register? |
| 34 | + cmp eax, edx ; on success, eax must have been reset to "SMAP" |
| 35 | + jne nomemmap |
| 36 | + test ebx, ebx ; ebx = 0 implies list is only 1 entry long (worthless) |
| 37 | + je nomemmap |
| 38 | + jmp jmpin |
| 39 | +e820lp: |
| 40 | + mov eax, 0xe820 ; eax, ecx get trashed on every int 0x15 call |
| 41 | + mov [es:di + 20], dword 1 ; force a valid ACPI 3.X entry |
| 42 | + mov ecx, 24 ; ask for 24 bytes again |
| 43 | + int 0x15 |
| 44 | + jc memmapend ; carry set means "end of list already reached" |
| 45 | + mov edx, 0x0534D4150 ; repair potentially trashed register |
| 46 | +jmpin: |
| 47 | + jcxz skipent ; skip any 0 length entries |
| 48 | + cmp cl, 20 ; got a 24 byte ACPI 3.X response? |
| 49 | + jbe notext |
| 50 | + test byte [es:di + 20], 1 ; if so: is the "ignore this data" bit clear? |
| 51 | + je skipent |
| 52 | +notext: |
| 53 | + mov ecx, [es:di + 8] ; get lower dword of memory region length |
| 54 | + test ecx, ecx ; is the qword == 0? |
| 55 | + jne goodent |
| 56 | + mov ecx, [es:di + 12] ; get upper dword of memory region length |
| 57 | + jecxz skipent ; if length qword is 0, skip entry |
| 58 | +goodent: |
| 59 | + inc bp ; got a good entry: ++count, move to next storage spot |
| 60 | + add di, 32 ; Pad to 32 bytes for each record |
| 61 | +skipent: |
| 62 | + test ebx, ebx ; if ebx resets to 0, list is complete |
| 63 | + jne e820lp |
| 64 | +nomemmap: |
| 65 | +memmapend: |
| 66 | + xor eax, eax ; Create a blank record for termination (32 bytes) |
| 67 | + mov ecx, 8 |
| 68 | + rep stosd |
| 69 | + |
| 70 | +; Enable the A20 gate |
| 71 | +set_A20: |
| 72 | + in al, 0x64 |
| 73 | + test al, 0x02 |
| 74 | + jnz set_A20 |
| 75 | + mov al, 0xD1 |
| 76 | + out 0x64, al |
| 77 | +check_A20: |
| 78 | + in al, 0x64 |
| 79 | + test al, 0x02 |
| 80 | + jnz check_A20 |
| 81 | + mov al, 0xDF |
| 82 | + out 0x60, al |
| 83 | + |
| 84 | + mov cx, 0x4000 - 1 ; Start looking from here |
| 85 | +VBESearch: |
| 86 | + inc cx |
| 87 | + mov bx, cx ; Mode is saved to BX for the set command later |
| 88 | + cmp cx, 0x5000 |
| 89 | + je halt |
| 90 | + mov edi, VBEModeInfoBlock ; VBE data will be stored at this address |
| 91 | + mov ax, 0x4F01 ; VESA SuperVGA BIOS - GET SuperVGA MODE INFORMATION - http://www.ctyme.com/intr/rb-0274.htm |
| 92 | + int 0x10 |
| 93 | + cmp ax, 0x004F ; Return value in AX should equal 0x004F if command supported and successful |
| 94 | + jne VBESearch ; Try next mode |
| 95 | + cmp byte [VBEModeInfoBlock.BitsPerPixel], 32 ; Desired bit depth |
| 96 | + jne VBESearch ; If not equal, try next mode |
| 97 | + cmp word [VBEModeInfoBlock.XResolution], Horizontal_Resolution ; Desired XRes here |
| 98 | + jne VBESearch |
| 99 | + cmp word [VBEModeInfoBlock.YResolution], Vertical_Resolution ; Desired YRes here |
| 100 | + jne VBESearch |
| 101 | + or bx, 0x4000 ; Use linear/flat frame buffer model (set bit 14) |
| 102 | + mov ax, 0x4F02 ; VESA SuperVGA BIOS - SET SuperVGA VIDEO MODE - http://www.ctyme.com/intr/rb-0275.htm |
| 103 | + int 0x10 |
| 104 | + cmp ax, 0x004F ; Return value in AX should equal 0x004F if supported and successful |
| 105 | + jne halt |
| 106 | + |
| 107 | + |
| 108 | + |
| 109 | + |
| 110 | + |
| 111 | + mov bl, 'B' ; 'B' as we booted via BIOS |
| 112 | + |
| 113 | + ; At this point we are done with real mode and BIOS interrupts. Jump to 32-bit mode. |
| 114 | + cli ; No more interrupts |
| 115 | + lgdt [cs:GDTR32] ; Load GDT register |
| 116 | + mov eax, cr0 |
| 117 | + or al, 0x01 ; Set protected mode bit |
| 118 | + mov cr0, eax |
| 119 | + ;;jmp 8:0x8000 ; Jump to 32-bit protected mode |
| 120 | +jmp 8:0x8000 |
| 121 | + |
| 122 | +;;;;;;;;;;;;;;; here ends mbr completion |
| 123 | + |
| 124 | + |
| 125 | + |
| 126 | + |
| 127 | + |
| 128 | + |
| 129 | +;;;Pasaje 32 to 64 bits |
| 130 | +start32: |
| 131 | + mov [p_BootDisk], bh ;; Save disk from where system was booted from |
| 132 | + |
| 133 | + mov eax, 16 ;; Set the correct segment registers |
6 | 134 | mov ds, ax |
7 | 135 | mov es, ax |
8 | 136 | mov ss, ax |
9 | 137 | mov fs, ax |
10 | 138 | mov gs, ax |
11 | 139 |
|
12 | | - xor eax, eax ; Clear all registers |
| 140 | + xor eax, eax ;; Clear all registers |
13 | 141 | xor ebx, ebx |
14 | 142 | xor ecx, ecx |
15 | 143 | xor edx, edx |
|
0 commit comments