Correctly handle switches between graphics and text mode
[syslinux.git] / bootsect.inc
blob69899565e67542af9e833b4fb5431db2a9d1b192
1 ;; -----------------------------------------------------------------------
2 ;;
3 ;;   Copyright 1994-2006 H. Peter Anvin - All Rights Reserved
4 ;;
5 ;;   This program is free software; you can redistribute it and/or modify
6 ;;   it under the terms of the GNU General Public License as published by
7 ;;   the Free Software Foundation, Inc., 53 Temple Place Ste 330,
8 ;;   Boston MA 02111-1307, USA; either version 2 of the License, or
9 ;;   (at your option) any later version; incorporated herein by reference.
11 ;; -----------------------------------------------------------------------
14 ;; bootsect.inc
16 ;; Load a boot sector (or other bootstrap program.)
18 ;; Unlike previous versions of this software, this doesn't require that
19 ;; the length is 512 bytes.  This allows PXE bootstraps and WinNT
20 ;; "CD boot sectors" to be invoked.
24 ; Load a boot sector
26 is_bootsector:
27 %if IS_SYSLINUX || IS_MDSLINUX
28                 ; Transfer zero bytes
29                 mov byte [CopySuper],0
30                 jmp short load_bootsec
32 is_bss_sector:
33                 ; Transfer the superblock
34                 mov byte [CopySuper],superblock_len
35 %endif
36 load_bootsec:
37                 xchg dx,ax
38                 shl eax,16
39                 xchg dx,ax              ; Now EAX = file length
40                 mov edi, 100000h
41                 mov [trackbuf+4],edi    ; Copy from this address
42                 push edi                ; Save load address
43                 xor dx,dx               ; No padding
44                 mov bx,abort_check      ; Don't print dots, but allow abort
45                 call load_high
47                 sub edi,100000h
48                 mov [trackbuf+8],edi    ; Save length
50                 mov eax,7C00h           ; Entry point
51                 mov [trackbuf],eax      ; Copy to this address
52                 mov [EntryPoint],eax    ; Jump to this address when done
54 %if IS_SYSLINUX || IS_MDSLINUX
55                 movzx ecx,byte [CopySuper]
56                 jcxz .not_bss
58                 ; For a BSS boot sector we have to patch.
59                 mov esi,superblock
60                 mov edi,100000h+(superblock-bootsec)
61                 call bcopy
63 .not_bss:
64 %endif
66                 xor edx,edx
67                 xor esi,esi
68 %if IS_SYSLINUX || IS_MDSLINUX || IS_EXTLINUX
69                 ; Restore original FDC table
70                 mov eax,[OrigFDCTabPtr]
71                 mov [fdctab],eax
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 %elif IS_ISOLINUX
82                 mov dl,[DriveNo]
83 %elif IS_PXELINUX
84                 mov byte [KeepPXE],1    ; Chainloading another NBP
85                 call reset_pxe
86 %endif
87                 xor bx,bx
90 ; replace_bootstrap for the special case where we have exactly one
91 ; descriptor, and it's the first entry in the trackbuf
94 replace_bootstrap_one:
95                 push word 1                     ; Length of descriptor list
96                 push word trackbuf              ; Address of descriptor list
97                 ; Fall through
100 ; Entrypoint for "shut down and replace bootstrap" -- also invoked by
101 ; the COMBOOT API.  This routine expects two words on the stack:
102 ; address of the copy list (versus DS) and count.  Additionally,
103 ; the values of ESI and EDX are passed on to the new bootstrap;
104 ; the value of BX becomes the new DS.
106 replace_bootstrap:
107                 ;
108                 ; Prepare for shutting down
109                 ;
110                 call vgaclearmode
111                 call cleanup_hardware
113                 ;
114                 ; Set up initial stack frame (not used by PXE if keeppxe is
115                 ; set - we use the PXE stack then.)
116                 ; AFTER THIS POINT ONLY .earlybss IS AVAILABLE, NOT .bss
117                 ;
118                 xor ax,ax
119                 mov ds,ax
120                 mov es,ax
122 %if IS_PXELINUX
123                 test byte [KeepPXE],01h
124                 jz .stdstack
125                 les di,[InitStack]      ; Reset stack to PXE original
126                 jmp .stackok
127 %endif
128 .stdstack:
129                 mov di,7C00h-44
130                 push di
131                 mov cx,22               ; 44 bytes
132                 rep stosw
133                 pop di
134 .stackok:
136                 mov [es:di+28],edx      ; New EDX
137                 mov [es:di+12],esi      ; New ESI
138                 mov [es:di+6],bx        ; New DS
140 %if IS_PXELINUX == 0
141                 ; DON'T DO THIS FOR PXELINUX...
142                 ; For PXE, ES:BX -> PXENV+, and this would corrupt
143                 ; that use.
145                 ; Hunt for $PnP header if one exists
146                 mov ax,0F000h
147                 mov fs,ax
148                 xor bx,bx
149 .findpnp:
150                 cmp dword [fs:bx], "$PnP"
151                 jz .foundpnp
152                 inc bx
153                 cmp bx,-3               ; Don't get a segment overflow error!
154                 jb .findpnp
155                 jmp .donepnp            ; No $PnP header found
156 .foundpnp:
157                 movzx cx,byte [fs:bx+5] ; Size of $PnP header
158                 cmp cl,21h
159                 jb .findpnp             ; Invalid $PnP header (too short)
160                 push bx
161                 xor ax,ax
162 .checkpnp:
163                 add al,byte [fs:bx]
164                 inc bx
165                 loop .checkpnp
166                 pop bx
167                 and al,al
168                 jnz .findpnp
170                 ; Found a valid $PnP header, point ES:DI to it
171                 mov [es:di+8], bx       ; New DI
172                 mov [es:di+4], fs       ; New ES
173 %endif
175 .donepnp:
176                 pop bx                  ; Copy from...
177                 pop ax                  ; Copy list count
179                 cli
180                 mov cx,es
181                 mov ss,cx
182                 movzx esp,di
184                 jmp shuffle_and_boot