From 57490e06f60c494aea1019512ce0e740c8fcb0c1 Mon Sep 17 00:00:00 2001 From: Timo Kreuzer Date: Wed, 8 Jun 2011 18:48:34 +0000 Subject: [PATCH] [ISOBOOT] Add portable asm version of iso boot sector svn path=/trunk/; revision=52150 --- reactos/boot/freeldr/bootsect/isoboot.S | 1073 +++++++++++++++++++++++ 1 file changed, 1073 insertions(+) create mode 100644 reactos/boot/freeldr/bootsect/isoboot.S diff --git a/reactos/boot/freeldr/bootsect/isoboot.S b/reactos/boot/freeldr/bootsect/isoboot.S new file mode 100644 index 00000000000..861886efb76 --- /dev/null +++ b/reactos/boot/freeldr/bootsect/isoboot.S @@ -0,0 +1,1073 @@ +/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS Bootsector for ISO file system + * FILE: + * PURPOSE: + * PROGRAMMERS: ? + */ + +/* INCLUDES ******************************************************************/ + +#include + +.code16 + +// **************************************************************************** +// +// 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 +// +// **************************************************************************** + +//#define DEBUG_MESSAGES /* Uncomment to get debugging messages */ +#define WAIT_FOR_KEY + + +// **************************************************************************** +// BEGIN THE BIOS/CODE/DATA SEGMENT +// **************************************************************************** +serial_base = HEX(0400) // Base addresses for 4 serial ports (4 words) +BIOS_fbm = HEX(0413) // Free Base Memory (kilobytes) (1 word) +BIOS_timer = HEX(046C) // Timer ticks (1 word) +BIOS_magic = HEX(0472) // BIOS reset magic (1 word) +BIOS_vidrows = HEX(0484) // Number of screen rows (1 byte) + +// Memory below this point is reserved for the BIOS and the MBR +trackbuf = HEX(1000) // Track buffer goes here (8192 bytes) +trackbufsize = 8192 // trackbuf ends at 3000h + +// struct open_file_t +file_sector = 0 // Sector pointer (0 = structure free) +file_left = 4 // Number of sectors left + +//struct dir_t +dir_lba = 0 // Directory start (LBA) +dir_len = 4 // Length in bytes +dir_clust = 8 // Length in clusters + +#define dir_t_size 12 +#define open_file_t_size 8 + +MAX_OPEN_LG2 = 2 // log2(Max number of open files) +MAX_OPEN = 4 +SECTORSIZE_LG2 = 11 // 2048 bytes/sector (El Torito requirement) +SECTORSIZE = 2048 +retry_count = 6 // How patient are we with the BIOS? + +/******************************************************************************/ +absolute HEX(5000) // Here we keep our BSS stuff + +resb DriveNo, 1 // CD-ROM BIOS drive number (BYTE) +resb DiskError, 1 // Error code for disk I/O (BYTE) +resb RetryCount, 1 // Used for disk access retries (BYTE) +resb TimeoutCount, 1 // Timeout counter (BYTE) +resb ISOFlags, 1 // Flags for ISO directory search (BYTE) +resb RootDir, dir_t_size // Root directory (dir_t_size BYTES) +resb CurDir, dir_t_size // Current directory (dir_t_size BYTES) +resb ISOFileName, 64 // ISO filename canonicalization buffer +resb ISOFileNameEnd, 1 + +//align open_file_t_size +absolute HEX(5060) +resb Files, MAX_OPEN * open_file_t_size + + +/******************************************************************************/ + + +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 / 4 // Copy the bootsector + mov si, HEX(7C00) // from 0000:7C00 + mov di, HEX(7000) // to 0000:7000 + rep movsd // copy the program + + ljmp16 0, relocate // jump into relocated code + +relocate: +#ifdef DEBUG_MESSAGES + // Display the banner and copyright + mov si, offset isolinux_banner // si points to hello message + call writestr // display the message + mov si, offset copyright_str + call writestr +#endif + + // Make sure the keyboard buffer is empty +#ifdef WAIT_FOR_KEY + call pollchar_and_empty + + // Check for MBR on harddisk + pusha + mov ax, HEX(0201) + mov dx, HEX(0080) + mov cx, HEX(0001) + mov bx, trackbuf + int HEX(13) + popa + jc .boot_cdrom // could not read hdd + + push ax + mov ax, word ptr ds:[trackbuf] + cmp ax, 0 + je .boot_cdrom // no boot sector found (hopefully there are no weird bootsectors which begin with 0) + pop ax + + // 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 ptr ds:[TimeoutCount], 5 +.next_second: + mov eax, ds:[BIOS_timer] // load current tick counter + add eax, 19 + +.poll_again: + call pollchar_and_empty + jnz .boot_cdrom + + mov ebx, ds:[BIOS_timer] + cmp eax, ebx + jnz .poll_again + + mov si, dot_msg // print '.' + call writestr + dec byte ptr ds:[TimeoutCount] // decrement timeout counter + jz .boot_harddisk + jmp .next_second + +.boot_harddisk: + call crlf + + // Boot first harddisk (drive 0x80) + mov ax, HEX(0201) + mov dx, HEX(0080) + mov cx, HEX(0001) + mov bx, HEX(7C00) + int HEX(13) + jnc .go_hd + jmp kaboom +.go_hd: + mov ax, cs + mov ds, ax + mov es, ax + mov fs, ax + mov gs, ax + mov dx, HEX(0080) + + ljmp16 0, HEX(7C00) +#endif + +.boot_cdrom: +#ifdef WAIT_FOR_KEY + call crlf + call crlf +#endif + + // Save and display the boot drive number + mov byte ptr ds:[DriveNo], dl +#ifdef DEBUG_MESSAGES + mov si, offset 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, HEX(4B01) // Get disk emulation status + mov dl, byte ptr ds:[DriveNo] + mov si, spec_packet + int HEX(13) + jc spec_query_failed // Shouldn't happen (BIOS bug) + mov dl, byte ptr ds:[DriveNo] + cmp byte ptr ds:[sp_drive], dl // Should contain the drive number + jne spec_query_failed + +#ifdef DEBUG_MESSAGES + mov si, offset spec_ok_msg + call writemsg + mov al, byte ptr ds:[sp_drive] + call writehex2 + call crlf +#endif + +found_drive: + // Get drive information + mov ah, HEX(48) + mov dl, byte ptr ds:[DriveNo] + mov si, offset drive_params + int HEX(13) + 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, offset secsize_msg + call writemsg + mov ax, word ptr ds:[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, dword ptr ds:[trackbuf+156+2] + mov dword ptr ds:[RootDir+dir_lba],eax + mov dword ptr ds:[CurDir+dir_lba],eax +#ifdef DEBUG_MESSAGES + mov si, offset rootloc_msg + call writemsg + call writehex8 + call crlf +#endif + + mov eax, dword ptr ds:[trackbuf+156+10] + mov dword ptr ds:[RootDir+dir_len],eax + mov dword ptr ds:[CurDir+dir_len],eax +#ifdef DEBUG_MESSAGES + mov si, offset rootlen_msg + call writemsg + call writehex8 + call crlf +#endif + add eax,SECTORSIZE-1 + shr eax,SECTORSIZE_LG2 + mov dword ptr ds:[RootDir+dir_clust],eax + mov dword ptr ds:[CurDir+dir_clust],eax +#ifdef DEBUG_MESSAGES + mov si, offset 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, offset isolinux_dir + mov al, 2 // Search for a directory + call searchdir_iso + jnz .dir_found + mov si, offset no_dir_msg + call writemsg + jmp kaboom + +.dir_found: + mov dword ptr ds:[CurDir+dir_len],eax + mov eax, dword ptr ds:[si+file_left] + mov dword ptr ds:[CurDir+dir_clust],eax + xor eax,eax // Free this file pointer entry + xchg eax,dword ptr ds:[si+file_sector] + mov dword ptr ds:[CurDir+dir_lba],eax + + + mov di, offset isolinux_bin // di points to Isolinux filename + call searchdir // look for the file + jnz .isolinux_opened // got the file + mov si, offset 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, offset filelen_msg + call writemsg + call writehex8 + call crlf +#endif + + mov ecx, eax // calculate sector count + shr ecx, 11 + test eax, HEX(7FF) + jz .full_sector + inc ecx +.full_sector: + +#ifdef DEBUG_MESSAGES + mov eax, ecx + mov si, offset filesect_msg + call writemsg + call writehex8 + call crlf +#endif + + mov bx, HEX(8000) // bx = load address + mov si, di // restore file pointer + mov cx, HEX(0FFFF) // load the whole file + call getfssec // get the whole file + +#ifdef DEBUG_MESSAGES + mov si, offset startldr_msg + call writemsg + call crlf +#endif + + mov dl, byte ptr ds:[DriveNo] // dl = boot drive + mov dh, 0 // dh = boot partition + push 0 // push segment (0x0000) + mov eax, dword ptr ds:[HEX(8000) + HEX(0A8)] // load the RVA of the EntryPoint into eax + add eax, HEX(8000) // RVA -> VA + push ax // push offset + retf // Transfer control to ROSLDR + + +// +// 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 byte ptr ds:[ISOFlags],al + call allocate_file // Temporary file structure for directory + jnz alloc_failure + push es + push ds + pop es // ES = DS + mov si, offset CurDir + cmp byte ptr ds:[di], 92 //'\' // If filename begins with slash + jne .not_rooted + inc di // Skip leading slash + mov si, offset RootDir // Reference root directory instead +.not_rooted: + mov eax, dword ptr ds:[si+dir_clust] + mov dword ptr ds:[bx+file_left],eax + mov eax,dword ptr ds:[si+dir_lba] + mov dword ptr ds:[bx+file_sector],eax + mov edx,dword ptr ds:[si+dir_len] + +.look_for_slash: + mov ax,di +.scan: + mov cl, byte ptr ds:[di] + inc di + and cl,cl + jz .isfile + cmp cl, '\' + jne .scan + mov byte ptr ds:[di-1], 0 // Terminate at directory name + mov cl,2 // Search for directory + xchg cl, byte ptr ds:[ISOFlags] + push di + push cx + push offset .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 ptr ds:[si] // Length of directory entry + cmp al, 33 + jb .next_sector + mov cl, byte ptr ds:[si+25] + xor cl, byte ptr ds:[ISOFlags] + test cl, HEX(8E) // Unwanted file attributes! + jnz .not_file + pusha + movzx cx, byte ptr ds:[si+32] // File identifier length + add si, 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 .getsome // Get some more directory + +.next_sector: + // Advance to the beginning of next sector + lea ax, [si+SECTORSIZE-1] + and ax, not (SECTORSIZE-1) + sub ax, si + jmp .not_file // We still need to do length checks + +.failure: +#ifdef DEBUG_MESSAGES + mov si, offset findfail_msg + call writemsg + call crlf +#endif + xor eax, eax // ZF = 1 + mov dword ptr ds:[bx+file_sector], eax + pop es + ret + +.success: + mov eax, dword ptr ds:[si+2] // Location of extent + mov dword ptr ds:[bx+file_sector], eax + mov eax, dword ptr ds:[si+10] // Data length + push eax + add eax, SECTORSIZE-1 + shr eax, SECTORSIZE_LG2 + mov dword ptr ds:[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 + + // restore the backslash in the filename + mov byte ptr ds:[di-1], '\' + + mov byte ptr ds:[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 ptr ds:[bx], 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, offset ISOFileName +.canon_loop: + jcxz .canon_end + lodsb + dec cx + cmp al, ';' + je .canon_end + and al, al + je .canon_end + stosb + cmp di, offset ISOFileNameEnd-1 // Guard against buffer overrun + jb .canon_loop +.canon_end: + cmp di, ISOFileName + jbe .canon_done + cmp byte ptr ds:[di-1], '.' // Remove terminal dots + jne .canon_done + dec di + jmp short .canon_end +.canon_done: + mov byte ptr ds:[di], 0 // Null-terminate string + pop di + mov si, ISOFileName +.compare2: + lodsb + mov ah, byte ptr ds:[di] + inc di + and ax, ax + jz .success2 // End of string for both + and al, al // Is either one end of string? + jz .failure2 // If so, failure + and ah, ah + jz .failure2 + or ax, HEX(2020) // Convert to lower case + cmp al, ah + je .compare2 +.failure2: + and ax, ax // ZF = 0 (at least one will be nonzero) +.success2: + 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, word ptr ds:[si+file_left] + jna .ok_size + mov cx, word ptr ds:[si+file_left] + +.ok_size: + mov bp, cx + push cx + push si + mov eax, dword ptr ds:[si+file_sector] + call getlinsec + xor ecx, ecx + pop si + pop cx + + add dword ptr ds:[si+file_sector], ecx + sub dword ptr ds:[si+file_left], ecx + ja .not_eof // CF = 0 + + xor ecx, ecx + mov dword ptr ds:[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, offset spec_err_msg + call writemsg + + mov dl, HEX(0FF) +.test_loop: + pusha + mov ax, HEX(4B01) + mov si, spec_packet + mov byte ptr ds:[si], 13 ; Size of buffer + int 13h + popa + jc .still_broken + + mov si, offset maybe_msg + call writemsg + mov al, dl + call writehex2 + call crlf + + cmp byte ptr ds:[sp_drive], dl + jne .maybe_broken + + // Okay, good enough... + mov si, offset alright_msg + call writemsg + mov byte ptr ds:[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 ptr ds:[DriveNo], dl + je .found_drive + +.still_broken: + dec dx + cmp dl, HEX(80) + jnb .test_loop + +fatal_error: + mov si, offset nothing_msg + call writemsg + +.norge: + jmp .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 +writestr_top: + lodsb + and al, al + jz writestr_end + call writechr + jmp short writestr_top +writestr_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 + +// +// writechr: 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, HEX(0E) + xor bx, bx + int HEX(10) + 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 word ptr ds:[si+4], bx + mov bx, es + mov word ptr ds:[si+6], bx + mov dword ptr ds:[si+8], eax +.loop2: + push bp // Sectors left + cmp bp, word ptr ds:[MaxTransfer] + jbe .bp_ok + mov bp, word ptr ds:[MaxTransfer] +.bp_ok: + mov word ptr ds:[si+2], bp + push si + mov dl, byte ptr ds:[DriveNo] + mov ah, HEX(42) // Extended Read + call xint13 + pop si + pop bp + movzx eax,word ptr ds:[si+2] // Sectors we read + add dword ptr ds:[si+8], eax // Advance sector pointer + sub bp, ax // Sectors left + shl ax, SECTORSIZE_LG2-4 // 2048-byte sectors -> segment + add word ptr ds:[si+6], ax // Advance buffer pointer + and bp, bp + jnz .loop2 + mov eax, dword ptr ds:[si+8] // Next sector + ret + + // INT 13h with retry +xint13: + mov byte ptr ds:[RetryCount], retry_count +.try: + pushad + int 13h + jc .error + add sp, 8*4 // Clean up stack + ret +.error: + mov byte ptr ds:[DiskError], ah // Save error code + popad + dec byte ptr ds:[RetryCount] + jz .real_error + push ax + mov al, byte ptr ds:[RetryCount] + mov ah, byte ptr ds:[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 byte ptr ds:[MaxTransfer],ah + mov byte ptr ds:[dapa+2],ah +.again: + pop ax + jmp .try + +.real_error: + mov si, offset diskerr_msg + call writemsg + mov al, byte ptr ds:[DiskError] + call writehex2 + mov si, offset 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 + xor ax, ax // Wait for keypress + int HEX(16) + cli + mov word ptr ds:[BIOS_magic], 0 // Cold reboot + ljmp16 HEX(0F000), HEX(0FFF0) // Reset vector address + + +// +// pollchar_and_empty: check if we have an input character pending (ZF = 0) and empty the input buffer afterwards +// +pollchar_and_empty: + pushad + mov ah, 1 // Did the user press a key? + int HEX(16) + jz .end // No, then we're done + mov ah, 0 // Otherwise empty the buffer by reading it + int HEX(16) +.end: + popad + ret + + +isolinux_banner: + .asciz "\r\nLoading IsoBoot...\r\n" +copyright_str: + .asciz " (C) 1994-2002 H. Peter Anvin\r\n" +presskey_msg: + .asciz "Press any key to boot from CD" +dot_msg: + .asciz "." + +#ifdef DEBUG_MESSAGES +startup_msg: + .asciz "Startup, DL = '" +spec_ok_msg: + .asciz "packet OK, drive = " +secsize_msg: + .asciz "size appears to be " +rootloc_msg: + .asciz "Root dir loc: " +rootlen_msg: + .asciz "Root dir len: " +rootsect_msg: + .asciz "Root dir len(sect): " +fileloc_msg: + .asciz "SETUPLDR loc: " +filelen_msg: + .asciz "SETUPLDR len: " +filesect_msg: + .asciz "SETUPLDR len(sect): " +findfail_msg: + .asciz "Failed to find file!" +startldr_msg: + .asciz "Starting SETUPLDR.SYS" +#endif + +spec_err_msg: + .asciz "Load spec failed, trying wing ...\r\n" +maybe_msg: + .asciz "Found smth at drive = " +alright_msg: + .asciz "might be ok, continuing...\r\n" +nothing_msg: + .asciz "Failed locate CD-ROM; boot failed.\r\n" + +isolinux_str: + .asciz "IsoBoot: " +crlf_msg: + .asciz "\r\n" +diskerr_msg: + .asciz "Disk error " +ondrive_str: + .asciz ", drive " + +err_bootfailed: + .asciz "\r\nfailed.." +isolinux_dir: + .asciz "\\LOADER" +no_dir_msg: + .asciz "LOADER dir not found.\r\n" +isolinux_bin: + .asciz "SETUPLDR.SYS" +no_isolinux_msg: + .asciz "SETUPLDR not found.\r\n" + + +// +// El Torito spec packet +// +.align 8 +spec_packet: + db HEX(13) // 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 +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: + db 0,0,0,0 // Host bus type +dp_interface: + db 0,0,0,0,0,0,0,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 +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) + +.align 4 +MaxTransfer: + dw 2 //32 // Max sectors per transfer + +.org 2047 // Pad to file offset 2046 +.word 0aa55h // BootSector signature + +.endcode16 + +END