1 ;; -----------------------------------------------------------------------
3 ;; Copyright 2007 H. Peter Anvin - All Rights Reserved
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 ;; -----------------------------------------------------------------------
16 ;; The auxillary data vector and its routines
18 ;; The auxillary data vector is a 512-byte aligned block that on the
19 ;; disk-based derivatives can be part of the syslinux file itself. It
20 ;; exists in two copies; when written, both copies are written (with a
21 ;; sync in between, if from the operating system.) The first two
22 ;; dwords are magic number and inverse checksum, then follows the data
23 ;; area as a tagged array similar to BOOTP/DHCP, finally a tail
26 ;; Note that unlike BOOTP/DHCP, zero terminates the chain, and FF
27 ;; has no special meaning.
31 ;; List of ADV tags...
38 ADV_MAGIC1 equ 0x5a2d2fa5 ; Head signature
39 ADV_MAGIC2 equ 0xa3041767 ; Total checksum
40 ADV_MAGIC3 equ 0xdd28bf64 ; Tail signature
42 ADV_LEN equ 500 ; Data bytes
44 adv_retries equ 6 ; Disk retries
47 ; Introduce the ADVs to valid but blank
63 ; This is called after config file parsing, so we know
64 ; the intended location of the ADV
67 cmp byte [ADVDrive],-1
70 ;%if IS_SYSLINUX || IS_MDSLINUX || IS_EXTLINUX
71 %if IS_EXTLINUX ; Not yet implemented for the other derivatives
73 ; Update pointers to default ADVs...
78 mov eax,[bx+SectorPtrs-8]
79 mov edx,[bx+SectorPtrs-4]
87 ; ** fall through to adv_verify **
90 ; Initialize the ADV data structure in memory
95 jz .ok ; Primary ADV okay
100 ; Neither ADV is usable; initialize to blank
115 ; The primary ADV is bad, but the backup is OK
123 ; SI points to the putative ADV; unchanged by routine
124 ; ZF=1 on return if good
129 jne .done ; ZF=0, i.e. bad
131 mov cx,ADV_LEN/4+1 ; Remaining dwords
145 ; adv_get: find an ADV string if present
148 ; Output: CX = byte count (zero on not found)
149 ; SI = pointer to data
158 xor ax,ax ; Keep AH=0 at all times
174 add ax,si ; Make sure it fits
184 ; adv_set: insert a string into the ADV in memory
187 ; FS:BX = input buffer
188 ; CX = byte count (max = 255!)
189 ; Output: CF=1 on error
192 ; Assumes CS == DS == ES.
216 .found: ; Found, need to delete old copy
224 rep movsb ; Remove the old one
225 mov [di],ah ; Termination zero
234 ; Now SI points to where we want to put our data
253 rep stosb ; Zero-fill remainder
266 ; adv_cleanup: checksum adv0 and copy to adv1
267 ; Assumes CS == DS == ES.
282 mov [si+4],eax ; Store checksum
283 mov cx,(ADV_LEN+12)/4
289 ; adv_write: write the ADV to disk.
291 ; Location is in memory variables.
292 ; Assumes CS == DS == ES.
294 ; Returns CF=1 if the ADV cannot be written.
297 cmp dword [ADVSec0],0
299 cmp dword [ADVSec1],0
301 cmp byte [ADVDrive],-1
312 .bad: ; No location for ADV set
317 ; adv_read: read the ADV from disk
319 ; Location is in memory variables.
320 ; Assumes CS == DS == ES.
331 ; adv_read_write: disk I/O for the ADV
333 ; On input, AH=2 for read, AH=3 for write.
334 ; Assumes CS == DS == ES.
342 ; Floppies: can't trust INT 13h 08h, we better know
343 ; the geometry a priori, which means it better be our
344 ; boot device. Handle that later.
345 ; jns .floppy ; Floppy drive... urk
347 mov ah,08h ; Get disk parameters
356 mov [ADVSecPerTrack],cx
361 mov ah,41h ; EDD existence query
381 xor edx,edx ; Zero-extend LBA
393 push word 1 ; Sector count
394 push word 16 ; DAPA size
406 lea sp,[si+16] ; Remove DAPA
421 movzx esi,word [ADVSecPerTrack]
422 movzx edi,word [ADVHeads]
424 ; Dividing by sectors to get (track,sector): we may have
425 ; up to 2^18 tracks, so we need to use 32-bit arithmetric.
429 xchg cx,dx ; CX <- sector index (0-based)
432 div edi ; Convert track to head/cyl
434 ; Watch out for overflow, we might be writing!
439 ; Now we have AX = cyl, DX = head, CX = sector (0-based),
440 ; BP = sectors to transfer, SI = bsSecPerTrack,
441 ; ES:BX = data target
444 shl ah,6 ; Because IBM was STOOPID
445 ; and thought 8 bits were enough
446 ; then thought 10 bits were enough...
447 inc cx ; Sector numbers are 1-based, sigh
452 xchg ax,bp ; Sector to transfer count
453 mov ah,[ADVOp] ; Operation
477 ADVSec0 db 0 ; Undefined
478 ADVSec1 db 0 ; Undefined
479 ADVDrive db -1 ; No ADV defined
483 ADVSecPerTrack resw 1