aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorhpa <hpa>2004-05-18 04:10:58 +0000
committerhpa <hpa>2004-05-18 04:10:58 +0000
commit810a573722bc8972ac0aa820d591f5c13123488d (patch)
tree020fc50f3adc3d37601bc42e2a64e468689be875
parent719e4dd2a2731a1849dc5444870850882b05e8b1 (diff)
downloadsyslinux.git-syslinux-2.10-pre2.tar.gz
syslinux.git-syslinux-2.10-pre2.tar.xz
syslinux.git-syslinux-2.10-pre2.zip
Knut Petersen's hack for Award BIOS bugssyslinux-2.10-pre2
-rw-r--r--NEWS2
-rw-r--r--isolinux.asm130
2 files changed, 129 insertions, 3 deletions
diff --git a/NEWS b/NEWS
index 59f0bcf5..2895e7c6 100644
--- a/NEWS
+++ b/NEWS
@@ -8,6 +8,8 @@ Changes in 2.10:
these kinds of images by default. Patch by Patrick
LoPresti.
* Major menu improvement from Murali Ganapathy.
+ * ISOLINUX: Wonderfully sick and brilliant workaround for
+ severe bugs in certain Award BIOSes; from Knut Petersen.
Changes in 2.09:
* SYSLINUX: Remove residual setuid crap from
diff --git a/isolinux.asm b/isolinux.asm
index 33d22314..aebc6d4a 100644
--- a/isolinux.asm
+++ b/isolinux.asm
@@ -301,7 +301,7 @@ initial_csum: xor edi,edi
mov dl,[DriveNo]
mov si,spec_packet
int 13h
- jc spec_query_failed ; Shouldn't happen (BIOS bug)
+ jc award_hack ; changed for BrokenAwardHack
mov dl,[DriveNo]
cmp [sp_drive],dl ; Should contain the drive number
jne spec_query_failed
@@ -386,11 +386,135 @@ integrity_ok:
%endif
jmp all_read ; Jump to main code
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; Start of BrokenAwardHack --- 10-nov-2002 Knut_Petersen@t-online.de
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;; There is a problem with certain versions of the AWARD BIOS ...
+;; the boot sector will be loaded and executed correctly, but, because the
+;; int 13 vector points to the wrong code in the BIOS, every attempt to
+;; load the spec packet will fail. We scan for the equivalent of
+;;
+;; mov ax,0201h
+;; mov bx,7c00h
+;; mov cx,0006h
+;; mov dx,0180h
+;; pushf
+;; call <direct far>
+;;
+;; and use <direct far> as the new vector for int 13. The code above is
+;; used to load the boot code into ram, and there should be no reason
+;; for anybody to change it now or in the future. There are no opcodes
+;; that use encodings relativ to IP, so scanning is easy. If we find the
+;; code above in the BIOS code we can be pretty sure to run on a machine
+;; with an broken AWARD BIOS ...
+;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+ ;;
+%ifdef DEBUG_MESSAGES ;;
+ ;;
+award_notice db "Trying BrokenAwardHack first ...",CR,LF,0 ;;
+award_not_orig db "BAH: Original Int 13 vector : ",0 ;;
+award_not_new db "BAH: Int 13 vector changed to : ",0 ;;
+award_not_succ db "BAH: SUCCESS",CR,LF,0 ;;
+award_not_fail db "BAH: FAILURE" ;;
+award_not_crlf db CR,LF,0 ;;
+ ;;
+%endif ;;
+ ;;
+award_oldint13 dd 0 ;;
+award_string db 0b8h,1,2,0bbh,0,7ch,0b9h,6,0,0bah,80h,1,09ch,09ah ;;
+ ;;
+ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+award_hack: mov si,spec_err_msg ; Moved to this place from
+ call writemsg ; spec_query_faild
+ ;
+%ifdef DEBUG_MESSAGES ;
+ ;
+ mov si,award_notice ; display our plan
+ call writemsg ;
+ mov si,award_not_orig ; display original int 13
+ call writemsg ; vector
+%endif ;
+ mov eax,[13h*4] ;
+ mov [award_oldint13],eax ;
+ ;
+%ifdef DEBUG_MESSAGES ;
+ ;
+ call writehex8 ;
+ mov si,award_not_crlf ;
+ call writestr ;
+%endif ;
+ push es ; save ES
+ mov ax,0f000h ; ES = BIOS Seg
+ mov es,ax ;
+ cld ;
+ xor di,di ; start at ES:DI = f000:0
+award_loop: push di ; save DI
+ mov si,award_string ; scan for award_string
+ mov cx,7 ; length of award_string = 7dw
+ repz cmpsw ; compare
+ pop di ; restore DI
+ jcxz award_found ; jmp if found
+ inc di ; not found, inc di
+ jno award_loop ;
+ ;
+award_failed: pop es ; No, not this way :-((
+award_fail2: ;
+ ;
+%ifdef DEBUG_MESSAGES ;
+ ;
+ mov si,award_not_fail ; display failure ...
+ call writemsg ;
+%endif ;
+ mov eax,[award_oldint13] ; restore the original int
+ or eax,eax ; 13 vector if there is one
+ jz spec_query_failed ; and try other workarounds
+ mov [13h*4],eax ;
+ jmp spec_query_failed ;
+ ;
+award_found: mov eax,[es:di+0eh] ; load possible int 13 addr
+ pop es ; restore ES
+ ;
+ cmp eax,[award_oldint13] ; give up if this is the
+ jz award_failed ; active int 13 vector,
+ mov [13h*4],eax ; otherwise change 0:13h*4
+ ;
+ ;
+%ifdef DEBUG_MESSAGES ;
+ ;
+ push eax ; display message and
+ mov si,award_not_new ; new vector address
+ call writemsg ;
+ pop eax ;
+ call writehex8 ;
+ mov si,award_not_crlf ;
+ call writestr ;
+%endif ;
+ mov ax,4B01h ; try to read the spec packet
+ mov dl,[DriveNo] ; now ... it should not fail
+ mov si,spec_packet ; any longer
+ int 13h ;
+ jc award_fail2 ;
+ ;
+%ifdef DEBUG_MESSAGES ;
+ ;
+ mov si,award_not_succ ; display our SUCCESS
+ call writemsg ;
+%endif ;
+ jmp found_drive ; and leave error recovery code
+ ;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; End of BrokenAwardHack ---- 10-nov-2002 Knut_Petersen@t-online.de
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+
; 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
+
+ ; some code moved to BrokenAwardHack
mov dl,0FFh
.test_loop: pusha