mirror of
https://github.com/reactos/reactos.git
synced 2024-12-28 10:04:49 +00:00
Added .cvsignore file.
Added cdrom bootsector. svn path=/trunk/; revision=2863
This commit is contained in:
parent
2b6504d6a9
commit
bba0443d8d
3 changed files with 899 additions and 1 deletions
3
freeldr/bootsect/.cvsignore
Normal file
3
freeldr/bootsect/.cvsignore
Normal file
|
@ -0,0 +1,3 @@
|
|||
*.exe
|
||||
*.bin
|
||||
*.h
|
|
@ -26,7 +26,7 @@ export NASM_CMD = nasm
|
|||
|
||||
.PHONY : clean
|
||||
|
||||
all: fat.bin fat32.bin bin2c.exe
|
||||
all: fat.bin fat32.bin isoboot.bin bin2c.exe
|
||||
|
||||
fat.bin: fat.asm bin2c.exe
|
||||
$(NASM_CMD) -o fat.bin -f bin fat.asm
|
||||
|
@ -37,6 +37,9 @@ fat32.bin: fat32.asm bin2c.exe
|
|||
$(NASM_CMD) -o fat32.bin -f bin fat32.asm
|
||||
bin2c fat32.bin fat32.h fat32_data
|
||||
|
||||
isoboot.bin: isoboot.asm
|
||||
$(NASM_CMD) -o isoboot.bin -f bin isoboot.asm
|
||||
|
||||
bin2c.exe: bin2c.c
|
||||
$(CC) -o bin2c.exe bin2c.c
|
||||
|
||||
|
|
892
freeldr/bootsect/isoboot.asm
Normal file
892
freeldr/bootsect/isoboot.asm
Normal file
|
@ -0,0 +1,892 @@
|
|||
|
||||
; 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
|
||||
|
||||
|
||||
|
||||
; Note: The Makefile builds one version with DEBUG_MESSAGES automatically.
|
||||
%define DEBUG_MESSAGES ; Uncomment to get debugging messages
|
||||
|
||||
|
||||
|
||||
|
||||
; ---------------------------------------------------------------------------
|
||||
; 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
|
||||
|
||||
|
||||
|
||||
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
|
||||
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
|
||||
mov si, isolinux_banner ; si points to hello message
|
||||
call writestr ; display the message
|
||||
%ifdef DEBUG_MESSAGES
|
||||
mov si,copyright_str
|
||||
call writestr
|
||||
%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
|
||||
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 "X86" 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:
|
||||
push si ; save file pointer
|
||||
|
||||
%ifdef DEBUG_MESSAGES
|
||||
mov si, filelen_msg
|
||||
call writemsg
|
||||
call writehex8
|
||||
call crlf
|
||||
%endif
|
||||
|
||||
mov bx, 0x8000 ; bx = load address
|
||||
pop si ; si = file pointer
|
||||
mov cx, 0xFFFF ; load the whole file
|
||||
call getfssec ; get the first sector
|
||||
mov dl, [DriveNo] ; dl = boot drive
|
||||
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=<passed in value> 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
|
||||
.loop:
|
||||
push bp ; Sectors left
|
||||
cmp bp,byte 32
|
||||
jbe .bp_ok
|
||||
mov bp,32
|
||||
.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 .loop
|
||||
mov eax,[si+8] ; Next sector
|
||||
ret
|
||||
|
||||
; INT 13h with retry
|
||||
xint13:
|
||||
mov byte [RetryCount], 6
|
||||
.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]
|
||||
jnz .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
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
isolinux_banner db CR, LF, 'Loading IsoBoot...', CR, LF, 0
|
||||
copyright_str db ' Copyright (C) 1994-2002 H. Peter Anvin', CR, LF, 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 'FreeLdr.sys location: ', 0
|
||||
filelen_msg: db 'FreeLdr.sys length: ', 0
|
||||
filesect_msg: db 'FreeLdr.sys length(sectors): ', 0
|
||||
findfail_msg: db 'Failed to find file!', 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 '\bscript', 0
|
||||
isolinux_dir db '\I386', 0
|
||||
;no_dir_msg db 'Could not find the \bscript directory.', CR, LF, 0
|
||||
no_dir_msg db 'Could not find the I386 directory.', CR, LF, 0
|
||||
;isolinux_bin db 'isolinux.bin', 0
|
||||
isolinux_bin db 'FREELDR.SYS', 0
|
||||
;no_isolinux_msg db 'Could not find the file isolinux.bin.', CR, LF, 0
|
||||
no_isolinux_msg db 'Could not find the file FREELDR.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)
|
||||
|
||||
times 2048-($-$$) nop ; Pad to file offset 2048
|
||||
|
||||
|
||||
;section .bss
|
||||
|
||||
;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
|
||||
;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
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
Loading…
Reference in a new issue