diff options
author | Sebastian Schmelzer | 2010-10-25 16:53:54 +0200 |
---|---|---|
committer | Sebastian Schmelzer | 2010-10-25 16:53:54 +0200 |
commit | 3050a9253437f4a4b5ad4bf3b3efdc3c660a5137 (patch) | |
tree | 91ac22153e416aac7ca20916b314b5e2ffa871b1 /contrib/syslinux-4.02/dosutil | |
download | preboot-master.tar.gz preboot-master.tar.xz preboot-master.zip |
Diffstat (limited to 'contrib/syslinux-4.02/dosutil')
-rw-r--r-- | contrib/syslinux-4.02/dosutil/.gitignore | 1 | ||||
-rw-r--r-- | contrib/syslinux-4.02/dosutil/Makefile | 60 | ||||
-rw-r--r-- | contrib/syslinux-4.02/dosutil/README | 10 | ||||
-rw-r--r-- | contrib/syslinux-4.02/dosutil/copybs.asm | 271 | ||||
-rw-r--r-- | contrib/syslinux-4.02/dosutil/eltorito.asm | 1099 | ||||
-rw-r--r-- | contrib/syslinux-4.02/dosutil/eltorito.txt | 50 | ||||
-rw-r--r-- | contrib/syslinux-4.02/dosutil/mdiskchk.c | 357 | ||||
-rw-r--r-- | contrib/syslinux-4.02/dosutil/mdiskchk.com | bin | 0 -> 8106 bytes |
8 files changed, 1848 insertions, 0 deletions
diff --git a/contrib/syslinux-4.02/dosutil/.gitignore b/contrib/syslinux-4.02/dosutil/.gitignore new file mode 100644 index 0000000..0aec5f2 --- /dev/null +++ b/contrib/syslinux-4.02/dosutil/.gitignore @@ -0,0 +1 @@ +!mdiskchk.com diff --git a/contrib/syslinux-4.02/dosutil/Makefile b/contrib/syslinux-4.02/dosutil/Makefile new file mode 100644 index 0000000..fc10ff9 --- /dev/null +++ b/contrib/syslinux-4.02/dosutil/Makefile @@ -0,0 +1,60 @@ +# +# OpenWatcom compile and link utility +# +topdir = .. +include $(topdir)/MCONFIG + +WCL = wcl +WCLOPT = -6 -osx -mt -bt=DOS -l=COM + +UPX = upx + +NASM = nasm +NASMOPT = -O9999 + +WCTARGETS = mdiskchk.com +NSTARGETS = eltorito.sys copybs.com +TARGETS = $(WCTARGETS) $(NSTARGETS) + +%.obj: %.c + $(WCL) $(WCLOPT) -c -fo=$@ $< + +%.com: %.obj + $(WCL) $(WCLOPT) -fe=$@ $< + $(UPX) --ultra-brute --lzma $@ || \ + $(UPX) --ultra-brute $@ || \ + true + rm -f $*.0* + chmod a-x $@ + +%.sys: %.asm + $(NASM) $(NASMOPT) -f bin -o $@ -l $*.lst $< + $(UPX) --ultra-brute --lzma $@ || \ + $(UPX) --ultra-brute $@ || \ + true + rm -f $*.0* + chmod a-x $@ + +%.com: %.asm + $(NASM) $(NASMOPT) -f bin -o $@ -l $*.lst $< + $(UPX) --ultra-brute --lzma $@ || \ + $(UPX) --ultra-brute $@ || \ + true + rm -f $*.0* + chmod a-x $@ + +all: $(TARGETS) + +tidy dist: + -rm -f *.obj *.lst *.o *.0* + +clean: tidy + +spotless: clean + -rm -f $(NSTARGETS) *~ + +installer: all + +install: installer + mkdir -m 755 -p $(INSTALLROOT)$(AUXDIR)/dosutil + install -m 644 $(TARGETS) $(INSTALLROOT)$(AUXDIR)/dosutil diff --git a/contrib/syslinux-4.02/dosutil/README b/contrib/syslinux-4.02/dosutil/README new file mode 100644 index 0000000..0b7b2a9 --- /dev/null +++ b/contrib/syslinux-4.02/dosutil/README @@ -0,0 +1,10 @@ +This directory contains utilities for use under DOS. +Although not part of Syslinux per se, they might be useful with MEMDISK. + +eltorito.sys - Generic El Torito CD-ROM driver + Written by Gary Tong and Bart Lagerweij. + Ported to NASM by H. Peter Anvin. + +mdiskchk.com - Simple program to query for the existence of a + MEMDISK and display parameters. + diff --git a/contrib/syslinux-4.02/dosutil/copybs.asm b/contrib/syslinux-4.02/dosutil/copybs.asm new file mode 100644 index 0000000..2640714 --- /dev/null +++ b/contrib/syslinux-4.02/dosutil/copybs.asm @@ -0,0 +1,271 @@ +; -*- fundamental -*- (asm-mode sucks) +; ----------------------------------------------------------------------- +; +; Copyright 1998-2008 H. Peter Anvin - All Rights Reserved +; +; This program is free software; you can redistribute it and/or modify +; it under the terms of the GNU General Public License as published by +; the Free Software Foundation, Inc., 53 Temple Place Ste 330, +; Boston MA 02111-1307, USA; either version 2 of the License, or +; (at your option) any later version; incorporated herein by reference. +; +; ----------------------------------------------------------------------- + +; +; copybs.asm +; +; Small DOS program to copy the boot sector from a drive +; to a file +; +; Usage: copybs <drive>: <file> +; + + absolute 0 +pspInt20: resw 1 +pspNextParagraph: resw 1 + resb 1 ; reserved +pspDispatcher: resb 5 +pspTerminateVector: resd 1 +pspControlCVector: resd 1 +pspCritErrorVector: resd 1 + resw 11 ; reserved +pspEnvironment: resw 1 + resw 23 ; reserved +pspFCB_1: resb 16 +pspFCB_2: resb 16 + resd 1 ; reserved +pspCommandLen: resb 1 +pspCommandArg: resb 127 + + section .text + org 100h ; .COM format +_start: + mov ax,3000h ; Get DOS version + int 21h + xchg al,ah + mov [DOSVersion],ax + cmp ax,0200h ; DOS 2.00 minimum + jae dosver_ok + mov dx,msg_ancient_err + jmp die + + section .bss + alignb 2 +DOSVersion: resw 1 + + section .text +; +; Scan command line for a drive letter followed by a colon +; +dosver_ok: + xor cx,cx + mov si,pspCommandArg + mov cl,[pspCommandLen] + +cmdscan1: jcxz bad_usage ; End of command line? + lodsb ; Load character + dec cx + cmp al,' ' ; White space + jbe cmdscan1 + or al,020h ; -> lower case + cmp al,'a' ; Check for letter + jb bad_usage + cmp al,'z' + ja bad_usage + sub al,'a' ; Convert to zero-based index + mov [DriveNo],al ; Save away drive index + + section .bss +DriveNo: resb 1 + + section .text +; +; Got the leading letter, now the next character must be a colon +; +got_letter: jcxz bad_usage + lodsb + dec cx + cmp al,':' + jne bad_usage +; +; Got the colon; now we should have at least one whitespace +; followed by a filename +; +got_colon: jcxz bad_usage + lodsb + dec cx + cmp al,' ' + ja bad_usage + +skipspace: jcxz bad_usage + lodsb + dec cx + cmp al,' ' + jbe skipspace + + mov di,FileName +copyfile: stosb + jcxz got_cmdline + lodsb + dec cx + cmp al,' ' + ja copyfile + jmp short got_cmdline + +; +; We end up here if the command line doesn't parse +; +bad_usage: mov dx,msg_unfair + jmp die + + section .data +msg_unfair: db 'Usage: copybs <drive>: <filename>', 0Dh, 0Ah, '$' + + section .bss + alignb 4 +FileName resb 256 + +; +; Parsed the command line OK. Get device parameter block to get the +; sector size. +; + struc DPB +dpbDrive: resb 1 +dpbUnit: resb 1 +dpbSectorSize: resw 1 +dpbClusterMask: resb 1 +dpbClusterShift: resb 1 +dpbFirstFAT: resw 1 +dpbFATCount: resb 1 +dpbRootEntries: resw 1 +dpbFirstSector: resw 1 +dpbMaxCluster: resw 1 +dpbFATSize: resw 1 +dpbDirSector: resw 1 +dpbDriverAddr: resd 1 +dpbMedia: resb 1 +dpbFirstAccess: resb 1 +dpbNextDPB: resd 1 +dpbNextFree: resw 1 +dpbFreeCnt: resw 1 + endstruc + + section .bss + alignb 2 +SectorSize resw 1 + + section .text +got_cmdline: + xor al,al ; Zero-terminate filename + stosb + + mov dl,[DriveNo] + inc dl ; 1-based + mov ah,32h + int 21h ; Get Drive Parameter Block + + and al,al + jnz filesystem_error + + mov dx,[bx+dpbSectorSize] ; Save sector size +; +; Read the boot sector. +; + section .data + align 4, db 0 +DISKIO equ $ +diStartSector: dd 0 ; Absolute sector 0 +diSectors: dw 1 ; One sector +diBuffer: dw SectorBuffer ; Buffer offset + dw 0 ; Buffer segment + + section .text +read_bootsect: + mov ax,cs ; Set DS <- CS + mov ds,ax + + mov [SectorSize],dx ; Saved sector size from above + + cmp word [DOSVersion],0400h ; DOS 4.00 has a new interface + jae .new +.old: + mov bx,SectorBuffer + mov cx,1 ; One sector + jmp short .common +.new: + mov [diBuffer+2],ax ; == DS + mov bx,DISKIO + mov cx,-1 +.common: + xor dx,dx ; Absolute sector 0 + mov al,[DriveNo] + int 25h ; DOS absolute disk read + pop ax ; Remove flags from stack + jc disk_read_error + +; +; Open the file and write the boot sector to the file. +; + mov dx,FileName + mov cx,0020h ; Attribute = ARCHIVE + mov ah,3Ch ; Create file + int 21h + jc file_write_error + + mov bx,ax + push ax ; Handle + + mov cx,[SectorSize] + mov dx,SectorBuffer + mov ah,40h ; Write file + int 21h + jc file_write_error + cmp ax,[SectorSize] + jne file_write_error + + pop bx ; Handle + mov ah,3Eh ; Close file + int 21h + jc file_write_error +; +; We're done! +; + mov ax,4C00h ; exit(0) + int 21h + +; +; Error routine jump +; +filesystem_error: + mov dx,msg_filesystem_err + jmp short die +disk_read_error: + mov dx,msg_read_err + jmp short die +file_write_error: + mov dx,msg_write_err +die: + push cs + pop ds + push dx + mov dx,msg_error + mov ah,09h + int 21h + pop dx + + mov ah,09h ; Write string + int 21h + + mov ax,4C01h ; Exit error status + int 21h + + section .data +msg_error: db 'ERROR: $' +msg_ancient_err: db 'DOS version 2.00 or later required', 0Dh, 0Ah, '$' +msg_filesystem_err: db 'Filesystem not found on disk', 0Dh, 0Ah, '$' +msg_read_err: db 'Boot sector read failed', 0Dh, 0Ah, '$' +msg_write_err: db 'File write failed', 0Dh, 0Ah, '$' + + section .bss + alignb 4 +SectorBuffer: resb 4096 diff --git a/contrib/syslinux-4.02/dosutil/eltorito.asm b/contrib/syslinux-4.02/dosutil/eltorito.asm new file mode 100644 index 0000000..d6b6b50 --- /dev/null +++ b/contrib/syslinux-4.02/dosutil/eltorito.asm @@ -0,0 +1,1099 @@ + +;----------------------------------------------------------------------------- +; ElTorito.asm +; +; El Torito Bootable CD-ROM driver which does not reset the CD-ROM drive upon +; loading, but instead accesses the drive through BIOS system calls +; +; MIT License +; +; (c) 2000 by Gary Tong +; (c) 2001-2009 by Bart Lagerweij +; +; Permission is hereby granted, free of charge, to any person obtaining a copy +; of this software and associated documentation files (the "Software"), to deal +; in the Software without restriction, including without limitation the rights +; to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +; copies of the Software, and to permit persons to whom the Software is +; furnished to do so, subject to the following conditions: +; +; The above copyright notice and this permission notice shall be included in +; all copies or substantial portions of the Software. +; +; THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +; IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +; FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +; AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +; LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +; OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +; THE SOFTWARE. +; +;----------------------------------------------------------------------------- + +; To assemble and link, use these commands with NASM 2.x: +; nasm -Ox -f bin -o eltorito.sys eltorito.asm + +; To enable Trace markers uncomment the line below +; DEBUG_TRACERS=1 + +; To enable debug info uncomment the line below +; DEBUG=1 + +%ifdef DEBUG_TRACERS + %macro TRACER 1 + call debug_tracer + db %1 + %endmacro +%else + %macro TRACER 1 + %endmacro +%endif ; DEBUG_TRACERS + +%define Ver '1.5' +%define CR 0DH, 0Ah +RPolyH equ 0EDB8h +RPolyL equ 08320h + + section .text align=16 + org 0 + +;============================================================================= + +Cdrom: + +NextDriver dd -1 ;-+ +Attributes dw 0C800h ; | +Pointers dw Strategy ; | + dw Commands ; | MSCDEX requires this +DeviceName db 'ELTORITO' ; | data in these locations + dw 0 ; | +DriveLetter db 0 ; | +NumUnitsSupp db 1 ;-+ + +DriverName db 'El-Torito CD-ROM Device Driver',0 + align 4, db 0 +ReqHdrLoc dd 0 +XferAddr dd 0 +Checksum dd -1 +DriveNumber db 0 +ReadBytes db 0 ;0 --> 2048 bytes/sector + ;1 --> 1024 bytes/sector + ;2 --> 512 bytes/sector + +Routines dw Init ;Init ;0 + dw Unsupported ;MediaCheck ;1 + dw Unsupported ;BuildBPB ;2 + dw IoctlInput ;IoctlInput ;3 + dw Unsupported ;Input ;4 + dw Unsupported ;NonDesInput ;5 + dw Unsupported ;InputStatus ;6 + dw Unsupported ;InputFlush ;7 + dw Unsupported ;Output ;8 + dw Unsupported ;OutputVerify ;9 + dw Unsupported ;OutputStatus ;10 + dw Unsupported ;OutputFlush ;11 + dw IoctlOutput ;IoctlOutput ;12 + dw DoNothing ;DeviceOpen ;13 + dw DoNothing ;DeviceClose ;14 + dw ReadL ;ReadL ;128 + +IoctlICtrl dw Raddr ;Raddr ;0 + dw Unsupported ;LocHead ;1 + dw Unsupported ;(Reserved) ;2 + dw Unsupported ;ErrStat ;3 + dw Unsupported ;AudInfo ;4 + dw DrvBytes ;DrvBytes ;5 + dw DevStat ;DevStat ;6 + dw SectSize ;SectSize ;7 + dw VolSize ;VolSize ;8 + dw MedChng ;MedChng ;9 + +SpecPkt times 19 db 0 ; offset 77h in 1.4 + times 13 db 0 ; unknown extra 00s in 1.4 + +Greeting db 'El-Torito Bootable CD-ROM Driver for Dos v',Ver,', http://www.nu2.nu/eltorito/',CR + db ' (c) 2000 by Gary Tong',CR + db ' (c) 2001-2002 by Bart Lagerweij',CR,0 +DblSpace db ' ',0 + +;============================================================================= + +Strategy: + + mov word [cs:ReqHdrLoc],bx + mov word [cs:ReqHdrLoc+2],es + retf + + +;============================================================================= + +Commands: + + push ax + push bx + push cx + push dx + push si + push di + push bp +; pushad + push ds + push es + TRACER 'C' + + cld ;Clear direction + sti ;Enable interrupts + + mov ax, cs ;ds=cs + mov ds, ax + + les bx,[ReqHdrLoc] ;seg:offset ptr into es:bx + xor ax,ax + mov al,[es:bx+2] ;Get Command code +%ifdef DEBUG + call print_hex8 +%endif + cmp al,15 + jb Mult2 ;If 0-14 + cmp al,128 + jb UnknownCmd ;If 15-127 + cmp al,129 + jb ShiftDown ;If 128 +UnknownCmd: mov al,121 ;8 = Unsupported (Reserved) +ShiftDown: sub al,113 ;128 --> 15, 121 --> 8 +Mult2: shl al,1 ;Convert into offset (*2) + mov di,Routines + add di,ax + call word [di] ;Execute desired command + or ax,100h ;Set Return Status's Done bit + lds bx,[ReqHdrLoc] ;seg:offset ptr into ds:bx + mov [bx+3],ax ;Save Status + +%ifdef DEBUG + cmp byte [cs:buffer+2048], 96h + je buffer_ok + mov al, '!' + call print_char + jmp $ +buffer_ok: +%endif + + TRACER 'c' + pop es + pop ds +; popad + pop bp + pop di + pop si + pop dx + pop cx + pop bx + pop ax + retf + + +;============================================================================= + +Unsupported: ;Unsupported Command + + mov ax,8003h ;Set Status Error bit, + TRACER 'U' + TRACER 'C' + retn ; Error 3 = Unknown Command + + +;============================================================================= + +IoctlInput: ;IOCTL Input Routine + + mov di,[es:bx+14] ;es:bx --> Request Header + mov es,[es:bx+16] ;Get Xfer Address into es:di + xor ax,ax ;Get Control Block Code + mov al,[es:di] +%ifdef DEBUG + TRACER 'I' + TRACER 'O' + call print_hex8 +%endif + cmp al,10 + jb UnkIoctlI ;If 0-9 + mov al,2 ;Map to Unsupported +UnkIoctlI: shl al,1 ;Convert into offset (*2) + mov si,IoctlICtrl + add si,ax + call word [si] ;Execute desired command + retn + + +;============================================================================= + +Raddr: ;Return Device Header Address + + TRACER 'A' + mov word [es:di+1],0 + mov [es:di+3],cs + xor ax, ax ;Set Return Status = success + TRACER 'a' + retn + + +;============================================================================= + +DrvBytes: ;Read Drive Bytes + + TRACER 'B' + push di ;Save original Xfer Addr + add di,2 ;Point to 1st dest byte + mov si,Greeting ;Point to Greeting +DrvB: movsb ;Copy over a byte + cmp byte [si],13 ;Is next char a CR? + jne DrvB ;Loop if not + + sub di,2 ;Get #bytes copied into ax + mov ax,di + pop di ;Retrieve original Xfer Addr + sub ax,di + mov byte [es:di+1],al ;and save it + mov ax,0 ;Set Return Status = success + TRACER 'b' + retn + + +;============================================================================= + +DevStat: ;Return Device Status + + TRACER 'D' + mov word [es:di+1],202h ;Door closed + mov word [es:di+3],0 ;Door unlocked + ;Supports only cooked reading + ;Read only + ;Data read only + ;No interleaving + ;No prefetching + ;No audio channel manipulation + ;Supports both HSG and Redbook + ; addressing modes + + xor ax, ax ;Set Return Status = success + TRACER 'd' + retn + + +;============================================================================= + +SectSize: ;Return Sector Size + + TRACER 'S' + mov word [es:di+2],2048 + mov ax,0 ;Set Return Status = success + TRACER 's' + retn + + +;============================================================================= + +VolSize: ;Return Volume Size + + TRACER 'V' + call PriVolDesc ;Get and Check Primary Volume + ; Descriptor + mov ax,800Fh ;Assume Invalid Disk Change + jc VolExit ;If Read Failure + + mov ax,word [Buffer+80] ;Read Successful + mov word [es:di+1],ax ;Copy over Volume Size + mov ax,word [Buffer+82] + mov word [es:di+3],ax + mov ax,0 ;Set Return Status = success +VolExit: + TRACER 'v' + retn + + +;============================================================================= + +MedChng: ;Return Media Changed Status + + TRACER 'M' + call PriVolDesc ;Get and Check Primary Volume + ; Descriptor + mov byte [es:di+1],-1 ;Assume Media Changed + mov ax,800Fh ; and Invalid Disk Change + jc MedExit ;If Media Changed or Bad + + mov byte [es:di+1],1 ;Media has not changed + mov ax,0 ;Set Return Status = success +MedExit: + TRACER 'm' + retn + + +;============================================================================= + +PriVolDesc: ;Get and Check Primary Volume + ; Descriptor + TRACER 'P' + mov ax,cs ;Set ds:si --> SpecPkt + mov ds,ax + + mov cx, 5 +PriVolAgain: + mov byte [SpecPkt],16 ;SpecPkt Size + mov byte [SpecPkt+1],0 ;Reserved + mov word [SpecPkt+2],1 ;Transfer one 2048-byte sector + push cx + mov cl,byte [ReadBytes] ;Multiply by 4 if reading 512 + shl word [SpecPkt+2],cl ; bytes at a time + pop cx + mov word [SpecPkt+6],cs ;Into our Buffer + mov word [SpecPkt+4], Buffer + mov word [SpecPkt+8],16 ;From CD Sector 16 + mov word [SpecPkt+10],0 + mov word [SpecPkt+12],0 + mov word [SpecPkt+14],0 + + mov si, SpecPkt + mov dl, [DriveNumber] + mov ah, 42h ;Extended Read + int 13h + jnc PriVolPass ;If success + +; TRACER '1' + ; read error + loop PriVolAgain + + TRACER '2' + ; read retries exhausted + ; flow into below + jmp PriReadErr + +PriVolPass: + mov si,Buffer ;Point input to Buffer + mov ax,-1 ;Init Checksum registers + mov bx,ax ; bx,ax = 0FFFFFFFFh + jc PriNew ;If Read Failure + + push di ;Read Successful, + ; so Calculate Checksum + mov di,1024 ;Init Word counter +PriWord: mov dx,[cs:si] ;Grab next word from buffer + mov cx,16 ;Init bit counter +PriBit: shr dx,1 ;Shift everything right 1 bit + rcr bx,1 + rcr ax,1 + jnc NoMult ;If a zero shifted out + + xor bx,RPolyH ;A one shifted out, so XOR + xor ax,RPolyL ; Checksum with RPoly +NoMult: + loop PriBit + + add si,2 ;Inc Word Pointer + dec di + ja PriWord + TRACER '3' + + pop di ;Checksum calculation complete + cmp bx,[Checksum+2] ;Has Checksum changed? + jne PriNew ;If Checksum Changed + + cmp ax,[Checksum] + jne PriNew ;If Checksum Changed + + clc ;Checksum not changed, CF=0 + mov ax,0 ;Status = success + jmp PriOld + +PriReadErr: + mov WORD [Checksum+2],bx ;Save New Checksum + mov [Checksum],ax ; or 0FFFFFFFFh if bad read + stc ;Checksum change, CF=1 + mov ax, 800bh ;Status = read fault + jmp PriOld + +PriNew: mov WORD [Checksum+2],bx ;Save New Checksum + mov [Checksum],ax ; or 0FFFFFFFFh if bad read + stc ;Checksum Changed, CF=1 + mov ax,800Fh ;Status = Invalid Media Change +PriOld: + TRACER 'p' + retn + + +;============================================================================= + +IoctlOutput: ;IOCTL Output Routine + + TRACER 'O' + mov di,[es:bx+14] ;es:bx --> Request Header + mov es,[es:bx+16] ;Get Xfer Address into es:di + xor ax,ax ;Get Control Block Code + mov al,[es:di] + cmp al,2 + jne UnkIoctlO ;If not 2 (ResetDrv) + call DoNothing ;Reset Drive + jmp IoctlODone +UnkIoctlO: + call Unsupported ;Unsupported command +IoctlODone: + TRACER 'o' + retn + + +;============================================================================= + +DoNothing: ;Do Nothing Command + + mov ax,0 ;Set Return Status = success + retn + + +;============================================================================= + +ReadL: ;Read Long Command + + TRACER 'R' + mov ax,cs ;Set ds=cs + mov ds,ax + ;es:bx --> Request Header + cmp byte [es:bx+24],0 ;Check Data Read Mode + jne ReadLErr ;If Cooked Mode + + cmp byte [es:bx+13],2 ;Check Addressing Mode + jb ReadLOK ;If HSG or Redbook Mode + +ReadLErr: + TRACER '8' + mov ax,8003h ;Set Return Status = Unknown + jmp ReadLExit ; Command Error and exit + +ReadLOK: + mov ax,[es:bx+20] ;Get Starting Sector Number, + mov dx,[es:bx+22] ; Assume HSG Addressing Mode + cmp byte [es:bx+13],0 ;Check Addressing Mode again + je ReadLHSG ;If HSG Addressing Mode + + TRACER '7' + ;Using Redbook Addressing Mode. Convert to HSG format + mov al,dl ;Get Minutes + mov dl,60 + mul dl ;ax = Minutes * 60 + add al,byte [es:bx+21] ;Add in Seconds + adc ah,0 + mov dx,75 ;dx:ax = + mul dx ; ((Min * 60) + Sec) * 75 + add al,byte [es:bx+20] ;Add in Frames + adc ah,0 + adc dx,0 + sub ax,150 ;Subtract 2-Second offset + sbb dx,0 ;dx:ax = HSG Starting Sector + +ReadLHSG: + mov word [SpecPkt+8], ax ;Store Starting + mov word [SpecPkt+10], dx ; Sector Number + mov word [SpecPkt+12], 0 ; (HSG Format) + mov word [SpecPkt+14], 0 + + mov ax,[es:bx+14] ;Get Transfer Address + mov word [SpecPkt+4],ax + mov ax,[es:bx+16] + mov word [SpecPkt+6],ax + + mov byte [SpecPkt],16 ;Size of Disk Address Packet + mov byte [SpecPkt+1],0 ;Reserved + + mov cx, 5 +ReadLAgain: + mov ax,[es:bx+18] ;Get number of sectors to read + mov word [SpecPkt+2],ax + cmp ax, 3FFFh ;Too large? + ja ReadLBad ;If yes + + push cx + mov cl,byte [ReadBytes] ;Multiply by 4 if reading 512 + shl word [SpecPkt+2],cl ; bytes at a time + pop cx + +%ifdef DEBUG + push ax + push cx + push si + mov cx, 16 + mov si,SpecPkt +ReadDump: mov al, ' ' + call print_char + mov al, byte [si] ;Hexdump a SpecPkt byte + call print_hex8 + inc si ;Point to next byte + loop ReadDump + pop si + pop cx + pop ax +%endif + mov si,SpecPkt + mov dl,[DriveNumber] + mov ah,42h ;Extended Read + int 13h + jnc ReadLGd ;If success + +;hang: +; jmp hang +; TRACER '1' + loop ReadLAgain + TRACER '2' + jmp short ReadLBad +ReadLGd: + TRACER '3' + xor ax, ax ;Status 0 = success + jmp short ReadLExit + +ReadLBad: + TRACER '9' + mov ax, 800Bh ;Set Read Fault Error + ; flow into ReadLExit +ReadLExit: + TRACER 'r' + retn + + + +%ifdef DEBUG_TRACERS +debug_tracer: pushad + pushfd + + mov al, '[' + mov ah,0Eh ;BIOS video teletype output + xor bh, bh + int 10h ;Print it + + mov bp,sp + mov bx,[bp+9*4] ; Get return address + mov al,[cs:bx] ; Get data byte + inc word [bp+9*4] ; Return to after data byte + + mov ah,0Eh ;BIOS video teletype output + xor bh, bh + int 10h ;Print it + + mov al, ']' + mov ah,0Eh ;BIOS video teletype output + xor bh, bh + int 10h ;Print it + + popfd + popad + retn +%endif + +;----------------------------------------------------------------------------- +; PRINT_HEX4 +;----------------------------------------------------------------------------- +; print a 4 bits integer in hex +; +; Input: +; AL - 4 bits integer to print (low) +; +; Output: None +; +; Registers destroyed: None +; +print_hex4: + + push ax + and al, 0fh ; we only need the first nibble + cmp al, 10 + jae hex_A_F + add al, '0' + jmp hex_0_9 +hex_A_F: + add al, 'A'-10 +hex_0_9: + call print_char + pop ax + retn + + +;----------------------------------------------------------------------------- +; print_hex8 +;----------------------------------------------------------------------------- +; print a 8 bits integer in hex +; +; Input: +; AL - 8 bits integer to print +; +; Output: None +; +; Registers destroyed: None +; +print_hex8: + + push ax + push bx + + mov ah, al + shr al, 4 + call print_hex4 + + mov al, ah + and al, 0fh + call print_hex4 + + pop bx + pop ax + retn + + +;============================================================================= +; print_hex16 - print a 16 bits integer in hex +; +; Input: +; AX - 16 bits integer to print +; +; Output: None +; +; Registers destroyed: None +;============================================================================= +print_hex16: + + push ax + push bx + push cx + + mov cx, 4 +print_hex16_loop: + rol ax, 4 + call print_hex4 + loop print_hex16_loop + + pop cx + pop bx + pop ax + retn + +;============================================================================= +; print_hex32 - print a 32 bits integer in hex +; +; Input: +; EAX - 32 bits integer to print +; +; Output: None +; +; Registers destroyed: None +;============================================================================= +print_hex32: + + push eax + push bx + push cx + + mov cx, 8 +print_hex32_loop: + rol eax, 4 + call print_hex4 + loop print_hex32_loop + + pop cx + pop bx + pop eax + retn + +;============================================================================= +; print_string - print string at current cursor location +; +; Input: +; DS:SI - ASCIIZ string to print +; +; Output: None +; +; Registers destroyed: None +;============================================================================= +print_string: + push ax + push si + +print_string_again: + mov al, [si] + or al, al + jz print_string_exit + call print_char + inc si + jmp print_string_again + +print_string_exit: + pop si + pop ax + retn + +;----------------------------------------------------------------------------- +; PRINT_CHAR +;----------------------------------------------------------------------------- +; Print's a character at current cursor position +; +; Input: +; AL - Character to print +; +; Output: None +; +; Registers destroyed: None +; +print_char: + + push ax + push bx + + mov ah,0Eh ;BIOS video teletype output + xor bh, bh + int 10h ;Print it + +print_char_exit: + pop bx + pop ax + retn + + +;============================================================================= + +;This space is used as a 2048-byte read buffer plus one test byte. +;The 96h data is used for testing the number of bytes returned by an Extended +; CD-ROM sector read + + align 16, db 0 +Buffer times 2049 db 96h + +;============================================================================= + +Init: ;Initialization Routine + + TRACER 'I' + mov ax,cs ;ds=cs + mov ds,ax + +%ifdef DEBUG +; print CS value (load segment) + call print_hex16 +%endif + + mov si, Greeting ;Display Greeting + call print_string + + mov ax,Unsupported ;Init is executed only once + mov [Routines],ax + + mov ax, 5400h + int 13h ; Get diskemu status + jc FindBoot ; If CF=1 no diskemu loaded + + mov [DriveNumber], cl ; Store drive number + + call keyflag + and al, 8 ; alt key ? + jz extread + + mov si, DrvNumMsg ; Display "drive number=" + call print_string + mov al, [DriveNumber] + call print_hex8 + mov si, LineEnd ; CR/LF + call print_string + jmp extread + +; Diskemu is not loaded +; so loop to find drive number + ; *** start of 1.4 changes *** + ; ??? mov dl, 0ffh ;Start at Drive 0xff + ; *** FindBoot at c47 in 1.4, at c0c in 1.3 *** +FindBoot: call ScanDrives ; call new helper in 1.4 + jnc FoundBoot ; ded*df3 +; mov si,offset SpecPkt ;Locate booted CD-ROM drive +; mov [SpecPkt],0 ;Clear 1st byte of SpecPkt +; mov ax,4B01h ;Get Bootable CD-ROM Status +; int 13h +; jnc FindPass ;If booted CD found +; +; Carry is not cleared in buggy Dell BIOSes, +; so I'm checking packet size byte +; some bogus bioses (Dell Inspiron 2500) returns packet size 0xff when failed +; Dell Dimension XPsT returns packet size 0x14 when OK + +; cmp [SpecPkt], 0 +; jne FoundBoot + +; cmp [SpecPkt], 13h ; anything between 13h and 20h should be OK +; jb FindFail +; cmp [SpecPkt], 20h +; ja FindFail +; jmp short FoundBoot +; +; FindFail: +; dec dl ;Next drive +; cmp dl, 80h +; jae FindBoot ;Check from ffh..80h + ; *** end of 1.4 changes *** + + mov si,NoBootCD ;No booted CD found, + call print_string + jmp NoEndAddr ;Do not install driver + +FoundBoot: +; mov dl, [SpecPkt+2] ; 1.4 change + ; *** next line at c57 in 1.4, at c3d in 1.3 *** + mov [DriveNumber],dl ;Booted CD-ROM found, + ; so save Drive # + + call keyflag + and al, 8 ; alt key ? + jz extread + + mov si, CDStat + call print_string + mov si, SpecPkt ;Point to returned CD SpecPkt + mov cx, 19 ; containing 19 bytes +StatDump: mov al, ' ' ;Print a space + call print_char + mov al, byte [si] ;Hexdump a SpecPkt byte + call print_hex8 + inc si ;Point to next byte + loop StatDump + + mov si, LineEnd ;Print a CR/LF + call print_string + +extread: +;See how many CD Sector bytes are returned by an Extended Read + mov byte [SpecPkt],16 ;SpecPkt Size + mov byte [SpecPkt+1],0 ;Reserved + mov word [SpecPkt+2],1 ;Transfer one sector + mov word [SpecPkt+6],cs ;Into our Buffer + mov word [SpecPkt+4],Buffer + mov word [SpecPkt+8],16 ;From CD Sector 16 + mov word [SpecPkt+10],0 + mov word [SpecPkt+12],0 + mov word [SpecPkt+14],0 + + mov si, SpecPkt ;Set ds:si --> SpecPkt + mov dl, [DriveNumber] + mov ah, 42h ;Extended Read + int 13h + jnc SecSize ;If success + + mov ah, 42h ;Always make 2 read attempts + int 13h + ;How many bytes did we get? +SecSize: std ;Count down + mov ax,cs ;Point to end of Buffer + mov es,ax + mov di,Buffer+2047 ;Find end of read data + mov si,Buffer+2048 + mov cx,2049 + repe cmpsb ;cx = number of bytes read + + cld ;Restore count direction to up + mov si,CDBytes ;Display number of bytes read + call print_string + + mov al, [DriveNumber] + call print_hex8 + + mov si,CDBytesA ;Remainder A of message + call print_string + + mov al,ch ;Hex-dump cx + and al,0Fh ;Second nibble + call print_hex8 ; (don't need the First) + mov al,cl + call print_hex8 ; (don't need the First) + + mov si,CDBytesB ;Remainder B of message + call print_string + + cmp cx,2048 ;Did we read 2048 bytes? + je ParseParm ;If yes <-- O.K. + + mov byte [ReadBytes],1 + cmp cx,1024 ;Did we read 1024 bytes? + je ParseParm ;If yes <-- O.K. + + mov byte [ReadBytes],2 + cmp cx,512 ;Did we read 512 bytes? + jne NoEndAddr ;If not, do not load driver + +ParseParm: mov bx,word [cs:ReqHdrLoc] ;Parse command line + mov es,word [cs:ReqHdrLoc+2] ; parameters + mov si,[es:bx+18] ;Get BPB array ptr into DS:SI + mov ds,[es:bx+20] +FindParm: inc si +FindParm1: cmp byte [si],0Dh ;CR? (End of parameters) + je EndOfParms + + cmp byte [si],0Ah ;LF? + je EndOfParms + + cmp byte [si],'/' ;A parameter? + jne FindParm + + inc si + cmp byte [si],'D' ;Device Name parameter? + jne FindParm1 + + inc si + cmp byte [si],':' + jne FindParm1 + +;bbb + push si + mov si, DevName ;Device Name is at ds:si + push ds ;Keep ptr to Device Name + mov ax, cs + mov ds, ax + call print_string + pop ds ;Retrieve Device Name ptr + pop si + mov cx, 8 ;Get next 8 chars + inc si ; = Device Name + mov ax, cs + mov es, ax + mov di, DeviceName +NextChar: cmp byte [si],' ' + ja AboveSpace + + mov ax,cs ;Pad end of Device Name with + mov ds,ax ; spaces if necessary + mov si,DblSpace ;A space +AboveSpace: mov al, [si] + call print_char + movsb ;ds:[si] --> es:[di] + loop NextChar + + mov si,LineEnd + mov ax,cs + mov ds,ax + call print_string + + mov ax,Init-2 ;Last byte of driver to keep + jmp EndAddr ;Install driver + +EndOfParms: + mov ax, cs ; Restore segment registers (fix) + mov ds, ax + mov es, ax + + mov si,NoDevName ;No Device Name Found + call print_string + +NoEndAddr: mov ax,0 ;Do not install driver + +EndAddr: mov es,[ReqHdrLoc+2] ;Write End Address + mov bx,[ReqHdrLoc] + mov [es:bx+14],ax + mov [es:bx+16],cs + mov bx,ax ;Hold onto install status + + mov si, DrvInst ;Display driver install status + call print_string + mov si, DrvInst1 ;Assume driver installed + cmp bx,0 ;Was driver installed? + jne DrvStatus ;If yes + mov si, NoDrvInst ;Driver not installed +DrvStatus: call print_string + + mov ax,0 ;Set Return Status = success + cmp bx,0 ;Was INIT successful? + jne InitStat ;If yes + mov ax,800Ch ;Status = General Failure +InitStat: + push ax ;Save Return Status + + call keyflag + and al, 8 ; alt key ? + jz InitExit + +WaitHere: + mov si, WaitMsg ;Display Halted message + call print_string + +AltWait: + call keyflag + and al, 8 ; Alt key? + jnz AltWait ; Pressed? yes -> wait + +InitExit: + pop ax ;Retrieve Return Status + TRACER 'i' + retn ;That's it for Init! + + ; *** start 1.4 changes at ded *** +SpecGo: mov si,SpecPkt + int 13h + retn + +ScanDrives: push ax ; at df3 in 1.4 + push si + mov dl, 7fh ;Start at Drive 0x80 +NextDrv: inc dl + clc + mov ax,4B01h ;Get Bootable CD-ROM Status + mov BYTE [SpecPkt],0 ;Clear 1st byte of SpecPkt + call SpecGo +; Carry is not cleared in buggy Dell BIOSes, +; so I'm checking packet size byte +; some bogus bioses (Dell Inspiron 2500) returns packet size 0xff when failed +; Dell Dimension XPsT returns packet size 0x14 when OK + + cmp BYTE [SpecPkt], 13h ; anything between 13h and 20h should be OK + jb FindFail + cmp BYTE [SpecPkt], 20h + ja FindFail ; in 1.4 at e16 + jmp short SendFound ; in 1.4 at e26 + +FindFail: cmp dl, 0ffh + je SendFail ; Check from 80h..ffh + jmp short NextDrv ;Next drive +SendFail: xor dl,dl + stc + jmp short ThingDone +SendFound: mov dl, [SpecPkt+2] + clc +ThingDone: pop si + pop ax + retn + ; *** end 1.4 changes *** + +;============================================================================= + +;------------------------------------------------------------ +; keyboard flags - return keyboard flags in AL +; bit 3 = ALT key +keyflag: ; at dbc in 1.3, at e2e in 1.4 + push bx + mov ah, 2 + int 16h + pop bx + retn + +;============================================================================= + +DrvNumMsg db ' Diskemxx.bin returned drive number=', 0 +NoBootCD db ' No booted CD-ROM found.',CR,0 + +CDStat db ' INT 13h / AX=4B01h Specification Packet for ' + db 'Booted CD-ROM:',CR,' ', 0 + +CDBytes db ' Drive ', 0 +CDBytesA db ' returns ', 0 +CDBytesB db 'h bytes per Sector.',CR,0 + +DevName db ' Device Name: ', 0 +NoDevName db ' No Device Name found. ' + db 'Usage: device=eltorito.sys /D:<DevName>',CR,0 + +DrvInst db ' Driver ', 0 +NoDrvInst db 7,'not ' ;7 = Ctrl-G = Beep +DrvInst1 db 'installed',CR,0 + +WaitMsg db ' Alt pressed, waiting...', CR, 0 +;ContMsg db ' Continuing...' +LineEnd db CR,0 + + +;============================================================================= diff --git a/contrib/syslinux-4.02/dosutil/eltorito.txt b/contrib/syslinux-4.02/dosutil/eltorito.txt new file mode 100644 index 0000000..956e54f --- /dev/null +++ b/contrib/syslinux-4.02/dosutil/eltorito.txt @@ -0,0 +1,50 @@ + +Change log for eltorito.asm, by Bart Lagerweij + +Jun 25, 2009 - License source code under the MIT license + +Jun 6, 2002 - v1.2 +Eltorito.sys does now also finds the correct driver number for the booted CD-Rom +on a Dell PC with very buggy BIOS. It does not clear the carry flag after a +succesfull call to int13/ax=4b01h call. Other PC's also using Phoenix BIOS +version 1.10 A14, or alike maybe also benefit from this "workaround". + +Mar 9, 2002 +- All read requests are now retried 5 times. +- Bug fix, had... + cmp ax, 3FFFh ;Too large? + ja ReadLBad ;If yes + seperated from... + mov ax,es:[bx+18] ;Get number of sectors to read + mov word ptr [SpecPkt+2],ax + so, it was checking "wild" ax values... +- Some cleanup and small changes +- The tracers give trouble when using SHCD.. +- Reverted proc ReadL back to Rev. 0.15BETA + +Mar 5, 2002 +- Bug fix, when changing CD media some machines would "hang" in the PriVolDesc + routine. +- Added printing of TRACER characters to trace the bug above +- Major cleanup and now using ASCIIZ strings + +May 9, 2001 +- Fixed a "pad devicename with spaces" bug, this only happened when a device + name was used with less than 8 characters, for example, "MSCD000" became + "MSCD000(" +- Bug fix, when eltorito.sys was called with invalid command line parameters, + garbage was printed and sometimes followed by "system halted" that has been + there since the very first version of eltorito.sys. I know that because I + had the bug back then. When loading eltorito.sys using a device loader, + for example "device.com eltorito.sys /test:123" garbage was printed instead + of "No device name found." "driver not installed". + Changed the error message to include a "usage" string. + +May 8, 2001 +- If diskemu.bin is loaded eltorito.sys uses the drivenumber from diskemu + A call is made to "diskemu/Get status" (INT13/AX=5400) and the drivenumber is returned in CL + This should fix boot problems on Dell PCs (YES!) + When diskemu.bin is not loaded, eltorito still loops all drive numbers using eltorito calls. +- Removed "press Escape..." +- When the Alt-key is pressed (and holded) more info is printed and eltorito.sys halts + diff --git a/contrib/syslinux-4.02/dosutil/mdiskchk.c b/contrib/syslinux-4.02/dosutil/mdiskchk.c new file mode 100644 index 0000000..47bb08e --- /dev/null +++ b/contrib/syslinux-4.02/dosutil/mdiskchk.c @@ -0,0 +1,357 @@ +/* -*- c -*- ------------------------------------------------------------- * + * + * Copyright 2003-2008 H. Peter Anvin - All Rights Reserved + * Portions copyright 2010 Shao Miller + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, Inc., 53 Temple Place Ste 330, + * Boston MA 02111-1307, USA; either version 2 of the License, or + * (at your option) any later version; incorporated herein by reference. + * + * ----------------------------------------------------------------------- */ + +/* + * mdiskchk.c + * + * DOS program to check for the existence of a memdisk. + * + * This program can be compiled for DOS with the OpenWatcom compiler + * (http://www.openwatcom.org/): + * + * wcl -3 -osx -mt mdiskchk.c + */ + +#include <ctype.h> +#include <stdio.h> +#include <string.h> +#include <i86.h> /* For MK_FP() */ + +typedef unsigned long uint32_t; +typedef unsigned short uint16_t; +typedef unsigned char uint8_t; + +/* Pull in MEMDISK common structures */ +#include "../memdisk/mstructs.h" + +struct memdiskinfo { + struct mdi mdi; + + /* We add our own fields at the end */ + int cylinders; + int heads; + int sectors; +}; + +struct memdiskinfo *query_memdisk(int drive) +{ + static struct memdiskinfo mm; + uint32_t _eax, _ebx, _ecx, _edx; + uint16_t _es, _di; + unsigned char _dl = drive; + uint16_t bytes; + + __asm { + .386; + mov eax, 454d0800h; + mov ecx, 444d0000h; + mov edx, 53490000h; + mov dl, _dl; + mov ebx, 3f4b0000h; + int 13h; + mov _eax, eax; + mov _ecx, ecx; + mov _edx, edx; + mov _ebx, ebx; + mov _es, es; + mov _di, di; + } + + if (_eax >> 16 != 0x4d21 || + _ecx >> 16 != 0x4d45 || _edx >> 16 != 0x4944 || _ebx >> 16 != 0x4b53) + return NULL; + + memset(&mm, 0, sizeof mm); + + bytes = *(uint16_t far *) MK_FP(_es, _di); + + /* 27 is the most we know how to handle */ + if (bytes > 27) + bytes = 27; + + _fmemcpy((void far *)&mm, (void far *)MK_FP(_es, _di), bytes); + + mm.cylinders = ((_ecx >> 8) & 0xff) + ((_ecx & 0xc0) << 2) + 1; + mm.heads = ((_edx >> 8) & 0xff) + 1; + mm.sectors = (_ecx & 0x3f); + + return &mm; +} + +const char *bootloadername(uint8_t id) +{ + static const struct { + uint8_t id, mask; + const char *name; + } *lp, list[] = { + {0x00, 0xf0, "LILO"}, + {0x10, 0xf0, "LOADLIN"}, + {0x31, 0xff, "SYSLINUX"}, + {0x32, 0xff, "PXELINUX"}, + {0x33, 0xff, "ISOLINUX"}, + {0x34, 0xff, "EXTLINUX"}, + {0x30, 0xf0, "SYSLINUX family"}, + {0x40, 0xf0, "Etherboot"}, + {0x50, 0xf0, "ELILO"}, + {0x70, 0xf0, "GrUB"}, + {0x80, 0xf0, "U-Boot"}, + {0xA0, 0xf0, "Gujin"}, + {0xB0, 0xf0, "Qemu"}, + {0x00, 0x00, "unknown"} + }; + + for (lp = list;; lp++) { + if (((id ^ lp->id) & lp->mask) == 0) + return lp->name; + } +} + +/* The function type for an output function */ +#define OUTPUT_FUNC_DECL(x) \ +void x(const int d, const struct memdiskinfo * const m) +typedef OUTPUT_FUNC_DECL((*output_func)); + +/* Show MEMDISK information for the passed structure */ +static OUTPUT_FUNC_DECL(normal_output) +{ + if (m == NULL) + return; + printf("Drive %02X is MEMDISK %u.%02u:\n" + "\tAddress = 0x%08lx, len = %lu sectors, chs = %u/%u/%u,\n" + "\tloader = 0x%02x (%s),\n" + "\tcmdline = %Fs\n", + d, m->mdi.version_major, m->mdi.version_minor, + m->mdi.diskbuf, m->mdi.disksize, m->cylinders, m->heads, m->sectors, + m->mdi.bootloaderid, bootloadername(m->mdi.bootloaderid), + MK_FP(m->mdi.cmdline.seg_off.segment, + m->mdi.cmdline.seg_off.offset)); +} + +/* Yield DOS SET command(s) as output for each MEMDISK kernel argument */ +static OUTPUT_FUNC_DECL(batch_output) +{ + if (m != NULL) { + char buf[256], *bc; + const char far *c = + MK_FP(m->mdi.cmdline.seg_off.segment, + m->mdi.cmdline.seg_off.offset); + const char *have_equals, is_set[] = "=1"; + + while (*c != '\0') { + /* Skip whitespace */ + while (isspace(*c)) + c++; + if (*c == '\0') + /* Trailing whitespace. That's enough processing */ + break; + /* Walk the kernel arguments while filling the buffer, + * looking for space or NUL or checking for a full buffer + */ + bc = buf; + have_equals = is_set; + while ((*c != '\0') && !isspace(*c) && + (bc < &buf[sizeof(buf) - 1])) { + /* Check if the param is "x=y" */ + if (*c == '=') + /* "=1" not needed */ + have_equals = &is_set[sizeof(is_set) - 1]; + *bc = *c; + c++; + bc++; + } + /* Found the end of the parameter and optional value sequence */ + *bc = '\0'; + printf("set %s%s\n", buf, have_equals); + } + } +} + +/* We do not output batch file output by default. We show MEMDISK info */ +static output_func show_memdisk = normal_output; + +/* A generic function type */ +#define MDISKCHK_FUNC_DECL(x) \ +void x(void) +typedef MDISKCHK_FUNC_DECL((*mdiskchk_func)); + +static MDISKCHK_FUNC_DECL(do_nothing) +{ + return; +} + +static MDISKCHK_FUNC_DECL(show_usage) +{ + printf("\nUsage: mdiskchk [--safe-hooks] [--mbfts] [--batch-output]\n" + "\n" + "Action: --safe-hooks . . Will scan INT 13h \"safe hook\" chain\n" + " --mbfts . . . . Will scan memory for MEMDISK mBFTs\n" + " --batch-output . Will output SET command output based\n" + " on MEMDISK kernel arguments\n" + " --no-sequential Suppresses probing all drive numbers\n"); +} + +/* Search memory for mBFTs and report them via the output method */ +static MDISKCHK_FUNC_DECL(show_mbfts) +{ + const uint16_t far * const free_base_mem = + MK_FP(0x0040, 0x0013); + int seg; + uint8_t chksum; + uint32_t i; + const struct mBFT far *mbft; + struct memdiskinfo m; + struct patch_area far *patch_area; + + for (seg = *free_base_mem / 16; seg < 0x9FFF; seg++) { + mbft = MK_FP(seg, 0); + /* Check for signature */ + if (mbft->acpi.signature[0] != 'm' || + mbft->acpi.signature[1] != 'B' || + mbft->acpi.signature[2] != 'F' || + mbft->acpi.signature[3] != 'T') + continue; + if (mbft->acpi.length != sizeof(struct mBFT)) + continue; + /* Check sum */ + chksum = 0; + for (i = 0; i < sizeof(struct mBFT); i++) + chksum += ((const uint8_t far *)mbft)[i]; + if (chksum) + continue; + /* Copy the MDI from the mBFT */ + _fmemcpy((void far *)&m, &mbft->mdi, sizeof(struct mdi)); + /* Adjust C/H/S since we actually know + * it directly for any MEMDISK with an mBFT + */ + patch_area = (struct patch_area far *)&mbft->mdi; + m.cylinders = patch_area->cylinders; + m.heads = patch_area->heads; + m.sectors = patch_area->sectors; + show_memdisk(patch_area->driveno, &m); + } +} + +/* Walk the "safe hook" chain as far as possible + * and report MEMDISKs that we find via the output method + */ +static MDISKCHK_FUNC_DECL(show_safe_hooks) +{ + const real_addr_t far * const int13 = + MK_FP(0x0000, 0x0013 * sizeof(real_addr_t)); + const struct safe_hook far *hook = + MK_FP(int13->seg_off.segment, int13->seg_off.offset); + + while ((hook->signature[0] == '$') && + (hook->signature[1] == 'I') && + (hook->signature[2] == 'N') && + (hook->signature[3] == 'T') && + (hook->signature[4] == '1') && + (hook->signature[5] == '3') && + (hook->signature[6] == 'S') && + (hook->signature[7] == 'F')) { + /* Found a valid "safe hook" */ + if ((hook->vendor[0] == 'M') && + (hook->vendor[1] == 'E') && + (hook->vendor[2] == 'M') && + (hook->vendor[3] == 'D') && + (hook->vendor[4] == 'I') && + (hook->vendor[5] == 'S') && + (hook->vendor[6] == 'K')) { + /* Found a valid MEMDISK "safe hook". It will have an mBFT */ + const struct mBFT far *mbft; + struct memdiskinfo m; + struct patch_area far *patch_area; + + /* Copy the MDI from the mBFT. Offset is a misnomer here */ + mbft = MK_FP(hook->mbft >> 4, 0); /* Always aligned */ + _fmemcpy((void far *)&m, &mbft->mdi, sizeof(struct mdi)); + /* Adjust C/H/S since we actually know + * it directly for any MEMDISK with an mBFT + */ + patch_area = (struct patch_area far *)&mbft->mdi; + m.cylinders = patch_area->cylinders; + m.heads = patch_area->heads; + m.sectors = patch_area->sectors; + show_memdisk(patch_area->driveno, &m); + } /* if */ + /* Step to the next hook in the "safe hook" chain */ + hook = MK_FP(hook->old_hook.seg_off.segment, + hook->old_hook.seg_off.offset); + } /* while */ +} + +int main(int argc, char *argv[]) +{ + int d; + int found = 0; + int sequential_scan = 1; /* Classic behaviour */ + const struct memdiskinfo *m; + + /* Default behaviour */ + mdiskchk_func usage = do_nothing, + safe_hooks = do_nothing, + mbfts = do_nothing; + + /* For each argument */ + while (--argc) { + /* Argument should begin with one of these chars */ + if ((*argv[argc] != '/') && (*argv[argc] != '-')) { + /* It doesn't. Print usage soon */ + usage = show_usage; + break; + } + argv[argc]++; + + /* Next char might be '-' as in "--safe-hooks" */ + if (*argv[argc] == '-') + argv[argc]++; + + switch (*argv[argc]) { + case 'S': + case 's': + safe_hooks = show_safe_hooks; + break; + case 'M': + case 'm': + mbfts = show_mbfts; + break; + case 'B': + case 'b': + show_memdisk = batch_output; + break; + case 'N': + case 'n': + sequential_scan = 0; + break; + default: + usage = show_usage; + } /* switch */ + } /* while */ + + safe_hooks(); + mbfts(); + if (!sequential_scan) + goto skip_sequential; + for (d = 0; d <= 0xff; d++) { + m = query_memdisk(d); + if (m != NULL) { + found++; + show_memdisk(d, m); + } + } +skip_sequential: + usage(); + + return found; +} + diff --git a/contrib/syslinux-4.02/dosutil/mdiskchk.com b/contrib/syslinux-4.02/dosutil/mdiskchk.com Binary files differnew file mode 100644 index 0000000..22ccfe5 --- /dev/null +++ b/contrib/syslinux-4.02/dosutil/mdiskchk.com |