| 1 | ;; ----------------------------------------------------------------------- |
|---|
| 2 | ;; |
|---|
| 3 | ;; Copyright 1994-2009 H. Peter Anvin - All Rights Reserved |
|---|
| 4 | ;; Copyright 2009-2012 Intel Corporation; author: H. Peter Anvin |
|---|
| 5 | ;; |
|---|
| 6 | ;; This program is free software; you can redistribute it and/or modify |
|---|
| 7 | ;; it under the terms of the GNU General Public License as published by |
|---|
| 8 | ;; the Free Software Foundation, Inc., 53 Temple Place Ste 330, |
|---|
| 9 | ;; Boston MA 02111-1307, USA; either version 2 of the License, or |
|---|
| 10 | ;; (at your option) any later version; incorporated herein by reference. |
|---|
| 11 | ;; |
|---|
| 12 | ;; ----------------------------------------------------------------------- |
|---|
| 13 | |
|---|
| 14 | ;; |
|---|
| 15 | ;; bootsect.inc |
|---|
| 16 | ;; |
|---|
| 17 | ;; Load a boot sector (or other bootstrap program.) |
|---|
| 18 | ;; |
|---|
| 19 | ;; Unlike previous versions of this software, this doesn't require that |
|---|
| 20 | ;; the length is 512 bytes. This allows PXE bootstraps and WinNT |
|---|
| 21 | ;; "CD boot sectors" to be invoked. |
|---|
| 22 | ;; |
|---|
| 23 | |
|---|
| 24 | ; |
|---|
| 25 | ; Load a boot sector |
|---|
| 26 | ; |
|---|
| 27 | is_bootsector: |
|---|
| 28 | %if IS_SYSLINUX |
|---|
| 29 | ; Transfer zero bytes |
|---|
| 30 | push word 0 |
|---|
| 31 | jmp short load_bootsec |
|---|
| 32 | |
|---|
| 33 | is_bss_sector: |
|---|
| 34 | ; Transfer the superblock |
|---|
| 35 | SuperSize equ $+1 |
|---|
| 36 | push word superblock_len_fat16 |
|---|
| 37 | %endif |
|---|
| 38 | load_bootsec: |
|---|
| 39 | mov edi,free_high_memory |
|---|
| 40 | mov [trackbuf+4],edi ; Copy from this address |
|---|
| 41 | mov eax,0xA0000 ; Maximum load |
|---|
| 42 | xor dx,dx ; No padding |
|---|
| 43 | mov bx,abort_check ; Don't print dots, but allow abort |
|---|
| 44 | call load_high |
|---|
| 45 | |
|---|
| 46 | sub edi,free_high_memory |
|---|
| 47 | mov [trackbuf+8],edi ; Save length |
|---|
| 48 | |
|---|
| 49 | cmp edi,0xA0000-7C00h |
|---|
| 50 | ja bs_too_big |
|---|
| 51 | |
|---|
| 52 | mov eax,7C00h ; Entry point |
|---|
| 53 | mov [trackbuf],eax ; Copy to this address |
|---|
| 54 | |
|---|
| 55 | %if IS_SYSLINUX |
|---|
| 56 | xor ecx,ecx |
|---|
| 57 | pop cx |
|---|
| 58 | |
|---|
| 59 | ; For a BSS boot sector we have to patch. |
|---|
| 60 | mov esi,superblock |
|---|
| 61 | mov edi,free_high_memory+(superblock-bootsec) |
|---|
| 62 | call bcopy |
|---|
| 63 | %endif |
|---|
| 64 | push eax ; Save entry point |
|---|
| 65 | |
|---|
| 66 | xor edx,edx |
|---|
| 67 | xor esi,esi |
|---|
| 68 | %if IS_SYSLINUX || IS_EXTLINUX |
|---|
| 69 | ; Restore original FDC table |
|---|
| 70 | mov eax,[OrigFDCTabPtr] |
|---|
| 71 | mov [fdctab],eax |
|---|
| 72 | |
|---|
| 73 | mov dl,[DriveNumber] |
|---|
| 74 | mov si,PartInfo ; Partition info buffer |
|---|
| 75 | mov di,800h-18 ; Put partition info here |
|---|
| 76 | push di |
|---|
| 77 | mov cx,8 ; 16 bytes |
|---|
| 78 | xor ax,ax |
|---|
| 79 | rep movsw |
|---|
| 80 | pop si ; DS:SI points to partition info |
|---|
| 81 | xor bx,bx |
|---|
| 82 | %elif IS_ISOLINUX |
|---|
| 83 | mov dl,[DriveNumber] |
|---|
| 84 | xor bx,bx |
|---|
| 85 | %elif IS_PXELINUX |
|---|
| 86 | mov byte [KeepPXE],03h ; Chainloading + keep PXE |
|---|
| 87 | pm_call reset_pxe |
|---|
| 88 | lfs si,[InitStack] |
|---|
| 89 | ; Put restore DS, EDX and ESI to the true initial values |
|---|
| 90 | mov bx,[fs:si+6] |
|---|
| 91 | mov edx,[fs:si+28] |
|---|
| 92 | mov esi,[fs:si+12] |
|---|
| 93 | %endif |
|---|
| 94 | |
|---|
| 95 | ; |
|---|
| 96 | ; replace_bootstrap for the special case where we have exactly one |
|---|
| 97 | ; descriptor, based in low memory. We will generate a second descriptor |
|---|
| 98 | ; to clear remaining FBM. |
|---|
| 99 | ; |
|---|
| 100 | |
|---|
| 101 | replace_bootstrap_one: |
|---|
| 102 | mov eax,[trackbuf] ; Base address |
|---|
| 103 | add eax,[trackbuf+8] ; Length |
|---|
| 104 | movzx ecx,word [BIOS_fbm] |
|---|
| 105 | shl ecx,10 ; Free Base Memory |
|---|
| 106 | sub ecx,eax |
|---|
| 107 | mov [trackbuf+12],eax |
|---|
| 108 | or dword [trackbuf+16],-1 ; Zero memory |
|---|
| 109 | mov [trackbuf+20],ecx |
|---|
| 110 | push word 2 ; Length of descriptor list |
|---|
| 111 | ; Fall through |
|---|
| 112 | |
|---|
| 113 | ; |
|---|
| 114 | ; Entrypoint for "shut down and replace bootstrap" -- also invoked by |
|---|
| 115 | ; the COMBOOT API. This routine expects the entry point (CS, IP) and the |
|---|
| 116 | ; count of the descriptor sequence on the stack; the shuffle |
|---|
| 117 | ; descriptors start at the first byte of the trackbuf. |
|---|
| 118 | ; |
|---|
| 119 | ; The registers EDX and ESI are passed on to the called program, |
|---|
| 120 | ; and BX is passed on as DS. |
|---|
| 121 | ; |
|---|
| 122 | replace_bootstrap: |
|---|
| 123 | ; |
|---|
| 124 | ; Prepare for shutting down |
|---|
| 125 | ; |
|---|
| 126 | call vgaclearmode |
|---|
| 127 | |
|---|
| 128 | ; |
|---|
| 129 | ; We jump here when loading a kernel image, so that we don't reset |
|---|
| 130 | ; the screen mode in "quiet" mode |
|---|
| 131 | ; |
|---|
| 132 | replace_bootstrap_noclearmode: |
|---|
| 133 | call cleanup_hardware |
|---|
| 134 | |
|---|
| 135 | ; |
|---|
| 136 | ; Set up initial stack frame (not used by PXE if keeppxe is |
|---|
| 137 | ; set - we use the PXE stack then.) |
|---|
| 138 | ; |
|---|
| 139 | xor ax,ax |
|---|
| 140 | mov ds,ax |
|---|
| 141 | mov es,ax |
|---|
| 142 | |
|---|
| 143 | %if IS_PXELINUX |
|---|
| 144 | cmp byte [KeepPXE],0 |
|---|
| 145 | je .stdstack |
|---|
| 146 | les di,[InitStack] ; Reset stack to PXE original |
|---|
| 147 | jmp .stackok |
|---|
| 148 | %endif |
|---|
| 149 | .stdstack: |
|---|
| 150 | ; StackBuf is guaranteed to have 44 bytes free immediately |
|---|
| 151 | ; above it, and it will not interfere with our existing stack. |
|---|
| 152 | mov di,StackBuf |
|---|
| 153 | push di |
|---|
| 154 | mov cx,22 ; 44 bytes |
|---|
| 155 | rep stosw |
|---|
| 156 | pop di |
|---|
| 157 | .stackok: |
|---|
| 158 | |
|---|
| 159 | mov [es:di+28],edx ; New EDX |
|---|
| 160 | mov [es:di+12],esi ; New ESI |
|---|
| 161 | mov [es:di+6],bx ; New DS |
|---|
| 162 | |
|---|
| 163 | %if IS_PXELINUX == 0 |
|---|
| 164 | ; DON'T DO THIS FOR PXELINUX... |
|---|
| 165 | ; For PXE, ES:BX -> PXENV+, and this would corrupt |
|---|
| 166 | ; that use. |
|---|
| 167 | |
|---|
| 168 | ; Restore ES:DI -> $PnP (if we were ourselves called |
|---|
| 169 | ; that way...) |
|---|
| 170 | mov ax,[OrigESDI] |
|---|
| 171 | mov bx,[OrigESDI+2] |
|---|
| 172 | |
|---|
| 173 | mov [es:di+8],ax ; New DI |
|---|
| 174 | mov [es:di+4],bx ; New ES |
|---|
| 175 | %endif |
|---|
| 176 | pop ax ; descriptor list entries count |
|---|
| 177 | |
|---|
| 178 | push di |
|---|
| 179 | push es |
|---|
| 180 | |
|---|
| 181 | push ds |
|---|
| 182 | pop es |
|---|
| 183 | |
|---|
| 184 | mov ebx,trackbuf |
|---|
| 185 | imul di,ax,12 |
|---|
| 186 | push di ; length of list |
|---|
| 187 | add di,bx ; DI <- end of list |
|---|
| 188 | |
|---|
| 189 | ; Terminating entry... |
|---|
| 190 | lea eax,[replace_stub] ; Entrypoint |
|---|
| 191 | push ax |
|---|
| 192 | stosd |
|---|
| 193 | xor ax,ax ; EAX[31:16] == 0 already |
|---|
| 194 | stosd ; 16-bit mode |
|---|
| 195 | stosd ; End of list |
|---|
| 196 | |
|---|
| 197 | ; Copy the stub |
|---|
| 198 | pop di |
|---|
| 199 | mov si,__replacestub_lma |
|---|
| 200 | mov cx,__replacestub_dwords |
|---|
| 201 | rep movsd |
|---|
| 202 | |
|---|
| 203 | ; ECX <- final list length |
|---|
| 204 | xor ecx,ecx |
|---|
| 205 | pop cx ; original length in bytes |
|---|
| 206 | add cx, 12 ; + termination entry size |
|---|
| 207 | |
|---|
| 208 | pop word [replace_stub.ss] |
|---|
| 209 | pop word [replace_stub.esp] |
|---|
| 210 | pop dword [replace_stub.csip] |
|---|
| 211 | |
|---|
| 212 | cli |
|---|
| 213 | mov ss,[replace_stub.ss] |
|---|
| 214 | mov esp,[replace_stub.esp] |
|---|
| 215 | |
|---|
| 216 | mov edi,trackbuf |
|---|
| 217 | mov esi,edi |
|---|
| 218 | |
|---|
| 219 | jmp shuffle_and_boot_raw |
|---|
| 220 | |
|---|
| 221 | ; This stub gets run after the shuffle. It is copied |
|---|
| 222 | ; below 0x7c00 in order to properly handle the case |
|---|
| 223 | ; of bootstrap replacement. |
|---|
| 224 | section .replacestub |
|---|
| 225 | replace_stub: |
|---|
| 226 | mov cr0,eax |
|---|
| 227 | jmp 0:.next |
|---|
| 228 | .next: |
|---|
| 229 | mov ax,strict word 0 |
|---|
| 230 | .ss equ $-2 |
|---|
| 231 | mov ss,ax |
|---|
| 232 | mov esp,strict dword 0 |
|---|
| 233 | .esp equ $-4 |
|---|
| 234 | pop gs |
|---|
| 235 | pop fs |
|---|
| 236 | pop es |
|---|
| 237 | pop ds |
|---|
| 238 | popad |
|---|
| 239 | popfd |
|---|
| 240 | jmp 0:0 |
|---|
| 241 | .csip equ $-4 |
|---|
| 242 | |
|---|
| 243 | section .text16 |
|---|
| 244 | bs_too_big: |
|---|
| 245 | call close |
|---|
| 246 | mov si,err_bs_too_big |
|---|
| 247 | jmp abort_load |
|---|
| 248 | |
|---|
| 249 | section .data16 |
|---|
| 250 | err_bs_too_big db "Too large for a bootstrap (need LINUX instead of KERNEL?)" |
|---|
| 251 | db CR, LF, 0 |
|---|
| 252 | |
|---|
| 253 | section .text16 |
|---|