diff --git a/Makefile b/Makefile index 2393faa..c7daebb 100644 --- a/Makefile +++ b/Makefile @@ -68,7 +68,7 @@ INSTALL_SBIN = extlinux/extlinux # Things to install in /usr/lib/syslinux INSTALL_AUX = core/pxelinux.0 gpxe/gpxelinux.0 core/isolinux.bin \ core/isolinux-debug.bin \ - dos/syslinux.com win32/syslinux.exe \ + dos/syslinux.com \ mbr/*.bin $(MODULES) INSTALL_AUX_OPT = win32/syslinux.exe diff --git a/core/Makefile b/core/Makefile index 65418c4..fbb38b5 100644 --- a/core/Makefile +++ b/core/Makefile @@ -66,6 +66,7 @@ kwdhash.gen: keywords genhash.pl iso%.bin: iso%.elf checksumiso.pl $(OBJCOPY) -O binary $< $@ $(PERL) checksumiso.pl $@ + -./add_crc $@ # Standard rule for {ldlinux,pxelinux,extlinux}.bin %.bin: %.elf diff --git a/core/add_crc b/core/add_crc new file mode 100644 index 0000000..0da2307 --- /dev/null +++ b/core/add_crc @@ -0,0 +1,57 @@ +#! /usr/bin/perl + +use integer; + +# for isolinux +# +# Ensure checksum over (first sector - 64 bytes) [internally: FirstSecSum] +# is 0 by adjusting the variable csum_value. +# +# Though isolinux checks the integrity with a separate checksum after all +# data has been loaded this does not help with BIOSes that don't get even +# the first 2k right. Hence this additional check. :-( +# + +$file = shift; +$list = "$file"; +$list =~ s/\.bin$/.lsr/; + +open F, $list; + +while() { + if(/^\s*\d+\s*(\S+)\s*0+\s*(\<\d+\>\s*)?csum_value\s*dd\s*0/) { + $ofs = hex $1; + } +} +close F; + +die "oops 1\n" unless $ofs && !($ofs & 3); + +# print "$ofs\n"; + +open F, $file or die "$file: $!\n"; + +$file_size = -s $file; + +sysread F, $buf, $file_size; + +close F; + +die "oops 1\n" if $file_size != length($buf); + +@x = unpack "V512", $buf; + +for ($sum = 0, $i = 16; $i < 512; $i++) { + $sum += $x[$i]; +} + +# printf "0x%08x\n", $sum; + +$ns = pack "V", -$sum; + +substr($buf, $ofs, 4) = $ns; + +open F, ">$file" or die "$file: $!\n"; + +syswrite F, $buf; + diff --git a/core/isolinux.asm b/core/isolinux.asm index 54f2e19..72be12a 100644 --- a/core/isolinux.asm +++ b/core/isolinux.asm @@ -308,6 +308,22 @@ initial_csum: xor edi,edi mov [FirstSecSum],edi mov [DriveNumber],dl + + ; check whether the BIOS did load us correctly + cmp dl,80h ; some BIOSes try to do floppy emulation... + jb bios_err + cmp dword [FirstSecSum], byte 0 + jmp bios_ok ; ############## + jz bios_ok +bios_err: + mov si,broken_bios_msg + call writemsg + jmp short $ +broken_bios_msg db 13, 10, 'Cannot boot from this CD. Please try a BIOS update.', 13, 10, 0 + align 4 +csum_value dd 0 +bios_ok: + %ifdef DEBUG_MESSAGES mov si,startup_msg call writemsg @@ -336,6 +352,9 @@ initial_csum: xor edi,edi cmp word [BIOSType],bios_cdrom jne found_drive ; If so, no spec packet... +%if 0 + ; Some BIOSes don't like that call. + ; 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 @@ -356,6 +375,8 @@ initial_csum: xor edi,edi call crlf %endif +%endif + found_drive: ; Alright, we have found the drive. Now, try to find the ; boot file itself. If we have a boot info table, life is @@ -480,6 +501,9 @@ integrity_ok: %endif jmp all_read ; Jump to main code +%if 0 + ; doesn't work anyway, see above + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Start of BrokenAwardHack --- 10-nov-2002 Knut_Petersen@t-online.de ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; @@ -671,6 +695,7 @@ spec_query_failed: mov si,trysbm_msg call writemsg jmp .found_drive ; Pray that this works... +%endif fatal_error: mov si,nothing_msg @@ -936,8 +961,18 @@ maxtrans: getlinsec_cdrom: mov si,dapa ; Load up the DAPA mov [si+4],bx - mov [si+6],es mov [si+8],eax + + ; seems that some BIOSes have problems if the target + ; segment is 0 (don't ask); to avoid this, we normalize + ; the buffer address here + ; -> seen on Acer TravelMate C102Ti + and word [si+4],0fh + mov ax,es + shr bx,4 + add ax,bx + mov [si+6],ax + .loop: push bp ; Sectors left cmp bp,[MaxTransferCD] @@ -1770,6 +1805,7 @@ default_str db 'default', 0 default_len equ ($-default_str) boot_dir db '/boot' ; /boot/isolinux isolinux_dir db '/isolinux', 0 +zb 64 config_name db 'isolinux.cfg', 0 err_disk_image db 'Cannot load disk image (invalid file)?', CR, LF, 0