From ec61eadeca1df920ba4fa2bdae174d4944ad37e2 Mon Sep 17 00:00:00 2001 From: Christoph von Wittich Date: Sun, 27 Aug 2006 11:59:01 +0000 Subject: [PATCH] * added bootloader which can be used for automated regression tests using buildbot svn path=/trunk/; revision=23740 --- reactos/boot/freeldr/bootsect/bootsect.rbuild | 4 + .../boot/freeldr/bootsect/isoboot_regtest.asm | 1023 +++++++++++++++++ 2 files changed, 1027 insertions(+) create mode 100644 reactos/boot/freeldr/bootsect/isoboot_regtest.asm diff --git a/reactos/boot/freeldr/bootsect/bootsect.rbuild b/reactos/boot/freeldr/bootsect/bootsect.rbuild index 715e840a131..f384f10ee8d 100644 --- a/reactos/boot/freeldr/bootsect/bootsect.rbuild +++ b/reactos/boot/freeldr/bootsect/bootsect.rbuild @@ -18,6 +18,10 @@ isoboot.asm + + + isoboot_regtest.asm + diff --git a/reactos/boot/freeldr/bootsect/isoboot_regtest.asm b/reactos/boot/freeldr/bootsect/isoboot_regtest.asm new file mode 100644 index 00000000000..118863400fb --- /dev/null +++ b/reactos/boot/freeldr/bootsect/isoboot_regtest.asm @@ -0,0 +1,1023 @@ +; **************************************************************************** +; +; isolinux.asm +; +; A program to boot Linux kernels off a CD-ROM using the El Torito +; boot standard in "no emulation" mode, making the entire filesystem +; available. It is based on the SYSLINUX boot loader for MS-DOS +; floppies. +; +; Copyright (C) 1994-2001 H. Peter Anvin +; +; 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., 675 Mass Ave, Cambridge MA 02139, +; USA; either version 2 of the License, or (at your option) any later +; version; incorporated herein by reference. +; +; **************************************************************************** +; +; THIS FILE IS A MODIFIED VERSION OF ISOLINUX.ASM +; MODIFICATION DONE BY MICHAEL K TER LOUW +; LAST UPDATED 3-9-2002 +; SEE "COPYING" FOR INFORMATION ABOUT THE LICENSE THAT APPLIES TO THIS RELEASE +; +; **************************************************************************** +; +; This file is a modified version of ISOLINUX.ASM. +; Modification done by Eric Kohl +; Last update 04-25-2002 +; +; **************************************************************************** +; +; This file is a modified version of ISOLINUX.ASM. +; (for ReactOS regression testing) +; Modification done by Christoph von Wittich +; Last update 08-27-2006 +; +; **************************************************************************** + + +; Note: The Makefile builds one version with DEBUG_MESSAGES automatically. +;%define DEBUG_MESSAGES ; Uncomment to get debugging messages + +%define WAIT_FOR_KEY + + +; --------------------------------------------------------------------------- +; BEGIN THE BIOS/CODE/DATA SEGMENT +; --------------------------------------------------------------------------- + + absolute 0400h +serial_base resw 4 ; Base addresses for 4 serial ports + absolute 0413h +BIOS_fbm resw 1 ; Free Base Memory (kilobytes) + absolute 046Ch +BIOS_timer resw 1 ; Timer ticks + absolute 0472h +BIOS_magic resw 1 ; BIOS reset magic + absolute 0484h +BIOS_vidrows resb 1 ; Number of screen rows + +; +; Memory below this point is reserved for the BIOS and the MBR +; + absolute 1000h +trackbuf resb 8192 ; Track buffer goes here +trackbufsize equ $-trackbuf +; trackbuf ends at 3000h + + struc open_file_t +file_sector resd 1 ; Sector pointer (0 = structure free) +file_left resd 1 ; Number of sectors left + endstruc + + struc dir_t +dir_lba resd 1 ; Directory start (LBA) +dir_len resd 1 ; Length in bytes +dir_clust resd 1 ; Length in clusters + endstruc + + +MAX_OPEN_LG2 equ 2 ; log2(Max number of open files) +MAX_OPEN equ (1 << MAX_OPEN_LG2) +SECTORSIZE_LG2 equ 11 ; 2048 bytes/sector (El Torito requirement) +SECTORSIZE equ (1 << SECTORSIZE_LG2) +CR equ 13 ; Carriage Return +LF equ 10 ; Line Feed +retry_count equ 6 ; How patient are we with the BIOS? + + + + absolute 5000h ; Here we keep our BSS stuff + +DriveNo resb 1 ; CD-ROM BIOS drive number +DiskError resb 1 ; Error code for disk I/O +RetryCount resb 1 ; Used for disk access retries +TimeoutCount resb 1 ; Timeout counter +ISOFlags resb 1 ; Flags for ISO directory search +RootDir resb dir_t_size ; Root directory +CurDir resb dir_t_size ; Current directory +ISOFileName resb 64 ; ISO filename canonicalization buffer +ISOFileNameEnd equ $ + + + alignb open_file_t_size +Files resb MAX_OPEN*open_file_t_size + + + + section .text + org 7000h + +start: + cli ; Disable interrupts + xor ax, ax ; ax = segment zero + mov ss, ax ; Initialize stack segment + mov sp, start ; Set up stack + mov ds, ax ; Initialize other segment registers + mov es, ax + mov fs, ax + mov gs, ax + sti ; Enable interrupts + cld ; Increment pointers + + mov cx, 2048 >> 2 ; Copy the bootsector + mov si, 0x7C00 ; from 0000:7C00 + mov di, 0x7000 ; to 0000:7000 + rep movsd ; copy the program + jmp 0:relocate ; jump into relocated code + +relocate: + ; Display the banner and copyright +%ifdef DEBUG_MESSAGES + mov si, isolinux_banner ; si points to hello message + call writestr ; display the message + mov si,copyright_str + call writestr +%endif + + + ; Make sure the keyboard buffer is empty +%ifdef WAIT_FOR_KEY +.kbd_buffer_test: + call pollchar + jz .kbd_buffer_empty + call getchar + jmp .kbd_buffer_test +.kbd_buffer_empty: + + ; Check if there is harddisk + pusha + mov ax, 0800h + mov dx, 0080h + int 13h + popa + jmp .boot_cdrom + + ; Display the 'Press key' message and wait for a maximum of 5 seconds + call crlf + mov si, presskey_msg ; si points to 'Press key' message + call writestr ; display the message + + mov byte [TimeoutCount], 5 +.next_second: + mov eax, [BIOS_timer] ; load current tick counter + add eax, 19 ; + +.poll_again: + call pollchar + jnz .boot_cdrom + + mov ebx, [BIOS_timer] + cmp eax, ebx + jnz .poll_again + + mov si, dot_msg ; print '.' + call writestr + dec byte [TimeoutCount] ; decrement timeout counter + jz .boot_harddisk + jmp .next_second + +.boot_harddisk: + call crlf + + ; Boot first harddisk (drive 0x80) + mov ax, 0201h + mov dx, 0080h + mov cx, 0001h + mov bx, 7C00h + int 13h + jnc .go_hd + jmp kaboom +.go_hd: + mov ax, cs + mov ds, ax + mov es, ax + mov fs, ax + mov gs, ax + mov dx, 0080h + + jmp 0:0x7C00 +%endif + +.boot_cdrom: +%ifdef WAIT_FOR_KEY + call crlf + call crlf +%endif + + ; Save and display the boot drive number + mov [DriveNo], dl +%ifdef DEBUG_MESSAGES + mov si, startup_msg + call writemsg + mov al, dl + call writehex2 + call crlf +%endif + + ; Now figure out what we're actually doing + ; Note: use passed-in DL value rather than 7Fh because + ; at least some BIOSes will get the wrong value otherwise + mov ax, 4B01h ; Get disk emulation status + mov dl, [DriveNo] + mov si, spec_packet + int 13h + jc near spec_query_failed ; Shouldn't happen (BIOS bug) + mov dl, [DriveNo] + cmp [sp_drive], dl ; Should contain the drive number + jne near spec_query_failed + +%ifdef DEBUG_MESSAGES + mov si, spec_ok_msg + call writemsg + mov al, byte [sp_drive] + call writehex2 + call crlf +%endif + +found_drive: + ; Get drive information + mov ah, 48h + mov dl, [DriveNo] + mov si, drive_params + int 13h + jnc params_ok + + ; mov si, nosecsize_msg No use in reporting this + ; call writemsg + +params_ok: + ; Check for the sector size (should be 2048, but + ; some BIOSes apparently think we're 512-byte media) + ; + ; FIX: We need to check what the proper behaviour + ; is for getlinsec when the BIOS thinks the sector + ; size is 512!!! For that, we need such a BIOS, though... +%ifdef DEBUG_MESSAGES + mov si, secsize_msg + call writemsg + mov ax, [dp_secsize] + call writehex4 + call crlf +%endif + + + ; + ; Clear Files structures + ; + mov di, Files + mov cx, (MAX_OPEN*open_file_t_size)/4 + xor eax, eax + rep stosd + + ; + ; Now, we need to sniff out the actual filesystem data structures. + ; mkisofs gave us a pointer to the primary volume descriptor + ; (which will be at 16 only for a single-session disk!); from the PVD + ; we should be able to find the rest of what we need to know. + ; +get_fs_structures: + mov eax, 16 ; Primary Volume Descriptor (sector 16) + mov bx, trackbuf + call getonesec + + mov eax, [trackbuf+156+2] + mov [RootDir+dir_lba],eax + mov [CurDir+dir_lba],eax +%ifdef DEBUG_MESSAGES + mov si, rootloc_msg + call writemsg + call writehex8 + call crlf +%endif + + mov eax,[trackbuf+156+10] + mov [RootDir+dir_len],eax + mov [CurDir+dir_len],eax +%ifdef DEBUG_MESSAGES + mov si, rootlen_msg + call writemsg + call writehex8 + call crlf +%endif + add eax,SECTORSIZE-1 + shr eax,SECTORSIZE_LG2 + mov [RootDir+dir_clust],eax + mov [CurDir+dir_clust],eax +%ifdef DEBUG_MESSAGES + mov si, rootsect_msg + call writemsg + call writehex8 + call crlf +%endif + + ; Look for the "REACTOS" directory, and if found, + ; make it the current directory instead of the root + ; directory. + mov di,isolinux_dir + mov al,02h ; Search for a directory + call searchdir_iso + jnz .dir_found + mov si,no_dir_msg + call writemsg + jmp kaboom + +.dir_found: + mov [CurDir+dir_len],eax + mov eax,[si+file_left] + mov [CurDir+dir_clust],eax + xor eax,eax ; Free this file pointer entry + xchg eax,[si+file_sector] + mov [CurDir+dir_lba],eax + + + mov di, isolinux_bin ; di points to Isolinux filename + call searchdir ; look for the file + jnz .isolinux_opened ; got the file + mov si, no_isolinux_msg ; si points to error message + call writemsg ; display the message + jmp kaboom ; fail boot + +.isolinux_opened: + mov di, si ; save file pointer + +%ifdef DEBUG_MESSAGES + mov si, filelen_msg + call writemsg + call writehex8 + call crlf +%endif + + mov ecx, eax ; calculate sector count + shr ecx, 11 + test eax, 0x7FF + jz .full_sector + inc ecx +.full_sector: + +%ifdef DEBUG_MESSAGES + mov eax, ecx + mov si, filesect_msg + call writemsg + call writehex8 + call crlf +%endif + + mov bx, 0x8000 ; bx = load address + mov si, di ; restore file pointer + mov cx, 0xFFFF ; load the whole file + call getfssec ; get the whole file + +%ifdef DEBUG_MESSAGES + mov si, startldr_msg + call writemsg + call crlf +%endif + + mov dl, [DriveNo] ; dl = boot drive + mov dh, 0 ; dh = boot partition + jmp 0:0x8000 ; jump into OSLoader + + + +; +; searchdir: +; +; Open a file +; +; On entry: +; DS:DI = filename +; If successful: +; ZF clear +; SI = file pointer +; DX:AX or EAX = file length in bytes +; If unsuccessful +; ZF set +; + +; +; searchdir_iso is a special entry point for ISOLINUX only. In addition +; to the above, searchdir_iso passes a file flag mask in AL. This is useful +; for searching for directories. +; +alloc_failure: + xor ax,ax ; ZF <- 1 + ret + +searchdir: + xor al,al +searchdir_iso: + mov [ISOFlags],al + call allocate_file ; Temporary file structure for directory + jnz alloc_failure + push es + push ds + pop es ; ES = DS + mov si,CurDir + cmp byte [di],'\' ; If filename begins with slash + jne .not_rooted + inc di ; Skip leading slash + mov si,RootDir ; Reference root directory instead +.not_rooted: + mov eax,[si+dir_clust] + mov [bx+file_left],eax + mov eax,[si+dir_lba] + mov [bx+file_sector],eax + mov edx,[si+dir_len] + +.look_for_slash: + mov ax,di +.scan: + mov cl,[di] + inc di + and cl,cl + jz .isfile + cmp cl,'\' + jne .scan + mov [di-1],byte 0 ; Terminate at directory name + mov cl,02h ; Search for directory + xchg cl,[ISOFlags] + push di + push cx + push word .resume ; Where to "return" to + push es +.isfile: + xchg ax,di + +.getsome: + ; Get a chunk of the directory + mov si,trackbuf + pushad + xchg bx,si + mov cx,1 ; load one sector + call getfssec + popad + +.compare: + movzx eax, byte [si] ; Length of directory entry + cmp al, 33 + jb .next_sector + mov cl, [si+25] + xor cl, [ISOFlags] + test cl, byte 8Eh ; Unwanted file attributes! + jnz .not_file + pusha + movzx cx, byte [si+32] ; File identifier length + add si, byte 33 ; File identifier offset + call iso_compare_names + popa + je .success +.not_file: + sub edx, eax ; Decrease bytes left + jbe .failure + add si, ax ; Advance pointer + +.check_overrun: + ; Did we finish the buffer? + cmp si, trackbuf+trackbufsize + jb .compare ; No, keep going + + jmp short .getsome ; Get some more directory + +.next_sector: + ; Advance to the beginning of next sector + lea ax, [si+SECTORSIZE-1] + and ax, ~(SECTORSIZE-1) + sub ax, si + jmp short .not_file ; We still need to do length checks + +.failure: +%ifdef DEBUG_MESSAGES + mov si, findfail_msg + call writemsg + call crlf +%endif + xor eax, eax ; ZF = 1 + mov [bx+file_sector], eax + pop es + ret + +.success: + mov eax, [si+2] ; Location of extent + mov [bx+file_sector], eax + mov eax, [si+10] ; Data length + push eax + add eax, SECTORSIZE-1 + shr eax, SECTORSIZE_LG2 + mov [bx+file_left], eax + pop eax + mov edx, eax + shr edx, 16 + and bx, bx ; ZF = 0 + mov si, bx + pop es + ret + +.resume: + ; We get here if we were only doing part of a lookup + ; This relies on the fact that .success returns bx == si + xchg edx, eax ; Directory length in edx + pop cx ; Old ISOFlags + pop di ; Next filename pointer + + mov byte [di-1], '\' ; restore the backslash in the filename + + mov [ISOFlags], cl ; Restore the flags + jz .failure ; Did we fail? If so fail for real! + jmp .look_for_slash ; Otherwise, next level + +; +; allocate_file: Allocate a file structure +; +; If successful: +; ZF set +; BX = file pointer +; In unsuccessful: +; ZF clear +; +allocate_file: + push cx + mov bx, Files + mov cx, MAX_OPEN +.check: + cmp dword [bx], byte 0 + je .found + add bx, open_file_t_size ; ZF = 0 + loop .check + ; ZF = 0 if we fell out of the loop +.found: + pop cx + ret + +; +; iso_compare_names: +; Compare the names DS:SI and DS:DI and report if they are +; equal from an ISO 9660 perspective. SI is the name from +; the filesystem; CX indicates its length, and ';' terminates. +; DI is expected to end with a null. +; +; Note: clobbers AX, CX, SI, DI; assumes DS == ES == base segment +; +iso_compare_names: + ; First, terminate and canonicalize input filename + push di + mov di, ISOFileName +.canon_loop: + jcxz .canon_end + lodsb + dec cx + cmp al, ';' + je .canon_end + and al, al + je .canon_end + stosb + cmp di, ISOFileNameEnd-1 ; Guard against buffer overrun + jb .canon_loop +.canon_end: + cmp di, ISOFileName + jbe .canon_done + cmp byte [di-1], '.' ; Remove terminal dots + jne .canon_done + dec di + jmp short .canon_end +.canon_done: + mov [di], byte 0 ; Null-terminate string + pop di + mov si, ISOFileName +.compare: + lodsb + mov ah, [di] + inc di + and ax, ax + jz .success ; End of string for both + and al, al ; Is either one end of string? + jz .failure ; If so, failure + and ah, ah + jz .failure + or ax, 2020h ; Convert to lower case + cmp al, ah + je .compare +.failure: + and ax, ax ; ZF = 0 (at least one will be nonzero) +.success: + ret + + + + + + + +; +; getfssec: Get multiple clusters from a file, given the file pointer. +; +; On entry: +; ES:BX -> Buffer +; SI -> File pointer +; CX -> Cluster count; 0FFFFh = until end of file +; On exit: +; SI -> File pointer (or 0 on EOF) +; CF = 1 -> Hit EOF +; +getfssec: + cmp cx, [si+file_left] + jna .ok_size + mov cx, [si+file_left] + +.ok_size: + mov bp, cx + push cx + push si + mov eax, [si+file_sector] + call getlinsec + xor ecx, ecx + pop si + pop cx + + add [si+file_sector], ecx + sub [si+file_left], ecx + ja .not_eof ; CF = 0 + + xor ecx, ecx + mov [si+file_sector], ecx ; Mark as unused + xor si,si + stc + +.not_eof: + ret + + + +; INT 13h, AX=4B01h, DL= failed. +; Try to scan the entire 80h-FFh from the end. +spec_query_failed: + mov si,spec_err_msg + call writemsg + + mov dl, 0FFh +.test_loop: + pusha + mov ax, 4B01h + mov si, spec_packet + mov byte [si], 13 ; Size of buffer + int 13h + popa + jc .still_broken + + mov si, maybe_msg + call writemsg + mov al, dl + call writehex2 + call crlf + + cmp byte [sp_drive], dl + jne .maybe_broken + + ; Okay, good enough... + mov si, alright_msg + call writemsg + mov [DriveNo], dl +.found_drive: + jmp found_drive + + ; Award BIOS 4.51 apparently passes garbage in sp_drive, + ; but if this was the drive number originally passed in + ; DL then consider it "good enough" +.maybe_broken: + cmp byte [DriveNo], dl + je .found_drive + +.still_broken: + dec dx + cmp dl, 80h + jnb .test_loop + +fatal_error: + mov si, nothing_msg + call writemsg + +.norge: + jmp short .norge + + + + ; Information message (DS:SI) output + ; Prefix with "isolinux: " + ; +writemsg: + push ax + push si + mov si, isolinux_str + call writestr + pop si + call writestr + pop ax + ret + +; +; crlf: Print a newline +; +crlf: + mov si, crlf_msg + ; Fall through + +; +; writestr: write a null-terminated string to the console, saving +; registers on entry. +; +writestr: + pushfd + pushad +.top: + lodsb + and al, al + jz .end + call writechr + jmp short .top +.end: + popad + popfd + ret + + +; +; writehex[248]: Write a hex number in (AL, AX, EAX) to the console +; +writehex2: + pushfd + pushad + shl eax, 24 + mov cx, 2 + jmp short writehex_common +writehex4: + pushfd + pushad + shl eax, 16 + mov cx, 4 + jmp short writehex_common +writehex8: + pushfd + pushad + mov cx, 8 +writehex_common: +.loop: + rol eax, 4 + push eax + and al, 0Fh + cmp al, 10 + jae .high +.low: + add al, '0' + jmp short .ischar +.high: + add al, 'A'-10 +.ischar: + call writechr + pop eax + loop .loop + popad + popfd + ret + +; +; Write a character to the screen. There is a more "sophisticated" +; version of this in the subsequent code, so we patch the pointer +; when appropriate. +; + +writechr: + pushfd + pushad + mov ah, 0Eh + xor bx, bx + int 10h + popad + popfd + ret + +; +; Get one sector. Convenience entry point. +; +getonesec: + mov bp, 1 + ; Fall through to getlinsec + +; +; Get linear sectors - EBIOS LBA addressing, 2048-byte sectors. +; +; Note that we can't always do this as a single request, because at least +; Phoenix BIOSes has a 127-sector limit. To be on the safe side, stick +; to 32 sectors (64K) per request. +; +; Input: +; EAX - Linear sector number +; ES:BX - Target buffer +; BP - Sector count +; +getlinsec: + mov si,dapa ; Load up the DAPA + mov [si+4],bx + mov bx,es + mov [si+6],bx + mov [si+8],eax +.loop2: + push bp ; Sectors left + cmp bp,[MaxTransfer] + jbe .bp_ok + mov bp,[MaxTransfer] +.bp_ok: + mov [si+2],bp + push si + mov dl,[DriveNo] + mov ah,42h ; Extended Read + call xint13 + pop si + pop bp + movzx eax,word [si+2] ; Sectors we read + add [si+8],eax ; Advance sector pointer + sub bp,ax ; Sectors left + shl ax,SECTORSIZE_LG2-4 ; 2048-byte sectors -> segment + add [si+6],ax ; Advance buffer pointer + and bp,bp + jnz .loop2 + mov eax,[si+8] ; Next sector + ret + + ; INT 13h with retry +xint13: + mov byte [RetryCount], retry_count +.try: + pushad + int 13h + jc .error + add sp, byte 8*4 ; Clean up stack + ret +.error: + mov [DiskError], ah ; Save error code + popad + dec byte [RetryCount] + jz .real_error + push ax + mov al,[RetryCount] + mov ah,[dapa+2] ; Sector transfer count + cmp al,2 ; Only 2 attempts left + ja .nodanger + mov ah,1 ; Drop transfer size to 1 + jmp short .setsize +.nodanger: + cmp al,retry_count-2 + ja .again ; First time, just try again + shr ah,1 ; Otherwise, try to reduce + adc ah,0 ; the max transfer size, but not to 0 +.setsize: + mov [MaxTransfer],ah + mov [dapa+2],ah +.again: + pop ax + jmp .try + +.real_error: + mov si, diskerr_msg + call writemsg + mov al, [DiskError] + call writehex2 + mov si, ondrive_str + call writestr + mov al, dl + call writehex2 + call crlf + ; Fall through to kaboom + +; +; kaboom: write a message and bail out. Wait for a user keypress, +; then do a hard reboot. +; +kaboom: + mov ax, cs + mov ds, ax + mov es, ax + mov fs, ax + mov gs, ax + sti + mov si, err_bootfailed + call writestr + call getchar + cli + mov word [BIOS_magic], 0 ; Cold reboot + jmp 0F000h:0FFF0h ; Reset vector address + +getchar: +.again: + mov ah, 1 ; Poll keyboard + int 16h + jz .again +.kbd: + xor ax, ax ; Get keyboard input + int 16h +.func_key: + ret + + +; +; pollchar: check if we have an input character pending (ZF = 0) +; +pollchar: + pushad + mov ah,1 ; Poll keyboard + int 16h + popad + ret + + + +isolinux_banner db CR, LF, 'Loading IsoBoot...', CR, LF, 0 +copyright_str db ' Copyright (C) 1994-2002 H. Peter Anvin', CR, LF, 0 +presskey_msg db 'Press any key to boot from CD', 0 +dot_msg db '.',0 + +%ifdef DEBUG_MESSAGES +startup_msg: db 'Starting up, DL = ', 0 +spec_ok_msg: db 'Loaded spec packet OK, drive = ', 0 +secsize_msg: db 'Sector size appears to be ', 0 +rootloc_msg: db 'Root directory location: ', 0 +rootlen_msg: db 'Root directory length: ', 0 +rootsect_msg: db 'Root directory length(sectors): ', 0 +fileloc_msg: db 'SETUPLDR.SYS location: ', 0 +filelen_msg: db 'SETUPLDR.SYS length: ', 0 +filesect_msg: db 'SETUPLDR.SYS length(sectors): ', 0 +findfail_msg: db 'Failed to find file!', 0 +startldr_msg: db 'Starting SETUPLDR.SYS', 0 +%endif + +nosecsize_msg: db 'Failed to get sector size, assuming 0800', CR, LF, 0 +spec_err_msg: db 'Loading spec packet failed, trying to wing it...', CR, LF, 0 +maybe_msg: db 'Found something at drive = ', 0 +alright_msg: db 'Looks like it might be right, continuing...', CR, LF, 0 +nothing_msg: db 'Failed to locate CD-ROM device; boot failed.', CR, LF, 0 +isolinux_str db 'IsoBoot: ', 0 +crlf_msg db CR, LF, 0 +diskerr_msg: db 'Disk error ', 0 +ondrive_str: db ', drive ', 0 +err_bootfailed db CR, LF, 'Boot failed: press a key to retry...' +isolinux_dir db '\LOADER', 0 +no_dir_msg db 'Could not find the LOADER directory.', CR, LF, 0 +isolinux_bin db 'SETUPLDR.SYS', 0 +no_isolinux_msg db 'Could not find SETUPLDR.SYS.', CR, LF, 0 + +; +; El Torito spec packet +; + align 8, db 0 +spec_packet: db 13h ; Size of packet +sp_media: db 0 ; Media type +sp_drive: db 0 ; Drive number +sp_controller: db 0 ; Controller index +sp_lba: dd 0 ; LBA for emulated disk image +sp_devspec: dw 0 ; IDE/SCSI information +sp_buffer: dw 0 ; User-provided buffer +sp_loadseg: dw 0 ; Load segment +sp_sectors: dw 0 ; Sector count +sp_chs: db 0,0,0 ; Simulated CHS geometry +sp_dummy: db 0 ; Scratch, safe to overwrite + +; +; EBIOS drive parameter packet +; + align 8, db 0 +drive_params: dw 30 ; Buffer size +dp_flags: dw 0 ; Information flags +dp_cyl: dd 0 ; Physical cylinders +dp_head: dd 0 ; Physical heads +dp_sec: dd 0 ; Physical sectors/track +dp_totalsec: dd 0,0 ; Total sectors +dp_secsize: dw 0 ; Bytes per sector +dp_dpte: dd 0 ; Device Parameter Table +dp_dpi_key: dw 0 ; 0BEDDh if rest valid +dp_dpi_len: db 0 ; DPI len + db 0 + dw 0 +dp_bus: times 4 db 0 ; Host bus type +dp_interface: times 8 db 0 ; Interface type +db_i_path: dd 0,0 ; Interface path +db_d_path: dd 0,0 ; Device path + db 0 +db_dpi_csum: db 0 ; Checksum for DPI info + +; +; EBIOS disk address packet +; + align 8, db 0 +dapa: dw 16 ; Packet size +.count: dw 0 ; Block count +.off: dw 0 ; Offset of buffer +.seg: dw 0 ; Segment of buffer +.lba: dd 0 ; LBA (LSW) + dd 0 ; LBA (MSW) + + alignb 4, db 0 +MaxTransfer dw 2 ;32 ; Max sectors per transfer + + times 2046-($-$$) db 0 ; Pad to file offset 2046 + dw 0aa55h ; BootSector signature