Experimental boot code patch (was Re: lost with booting)

看板DFBSD_bugs作者時間21年前 (2004/09/10 08:32), 編輯推噓0(000)
留言0則, 0人參與, 最新討論串1/4 (看更多)
This patch causes the boot1/boot2 code to always try packet mode first (if the BIOS supports it), and fall back to CHS mode if it doesn't. Previously CHS mode would always be used for requests with cylinder numbers below 1024 and packet mode would only be tried for cylinder numbers >= 1024. Packet mode for boot0 is still controlled by boot0cfg. This is basically an end-run around CHS. For any BIOS supporting packet mode, packet mode is used no matter what the BIOS setting for the disk is. The real question here is whether this boot code works with very old machines whos BIOS'es do not have any clue about packet mode. -Matt Index: i386/boot2/boot1.S =================================================================== RCS file: /cvs/src/sys/boot/i386/boot2/boot1.S,v retrieving revision 1.8 diff -u -r1.8 boot1.S --- i386/boot2/boot1.S 27 Jul 2004 19:37:17 -0000 1.8 +++ i386/boot2/boot1.S 9 Sep 2004 23:09:38 -0000 @@ -314,8 +314,43 @@ // // %dl - byte - drive number // stack - 10 bytes - EDD Packet -// -read: push %dx // Save + +read: + /* + * Try EDD mode first. If not enabled or no BIOS support + * exists, fall back to CHS mode. + */ + testb $FL_PACKET,%cs:BOOT1_ORIGIN+flags-start + jz read.1 + + /* + * BIOS: check extensions present + */ + mov $0x55aa,%bx + push %dx + movb $0x41,%ah + int $0x13 + pop %dx + jc read.1 /* BIOS error return */ + cmp $0xaa55,%bx /* check for proper magic */ + jne read.1 + testb $0x1,%cl /* packet interface support? */ + jz read.1 + + /* + * Issue packet command. + * BIOS: Extended read command + */ + mov %bp,%si + movb $0x42,%ah + int $0x13 + retw + + /* + * Fallback to CHS mode + */ +read.1: + push %dx // Save movb $0x8,%ah // BIOS: Get drive int $0x13 // parameters movb %dh,%ch // Max head number @@ -338,7 +373,7 @@ pop %dx // Restore cmpl $0x3ff,%eax // Cylinder number supportable? sti // Enable interrupts - ja read.7 // No, try EDD + ja ereturn // No, failed xchgb %al,%ah // Set up cylinder rorb $0x2,%al // number orb %ch,%al // Merge @@ -374,24 +409,8 @@ read.5: shlb %bl // buffer add %bl,0x5(%bp) // pointer, sub %al,0x2(%bp) // block count - ja read // If not done + ja read.1 // If not done read.6: retw // To caller -read.7: testb $FL_PACKET,%cs:BOOT1_ORIGIN+flags-start // LBA support enabled? - jz ereturn // No, so return an error - mov $0x55aa,%bx // Magic - push %dx // Save - movb $0x41,%ah // BIOS: Check - int $0x13 // extensions present - pop %dx // Restore - jc return // If error, return an error - cmp $0xaa55,%bx // Magic? - jne ereturn // No, so return an error - testb $0x1,%cl // Packet interface? - jz ereturn // No, so return an error - mov %bp,%si // Disk packet - movb $0x42,%ah // BIOS: Extended - int $0x13 // read - retw // To caller // Messages Index: i386/libi386/biosdisk.c =================================================================== RCS file: /cvs/src/sys/boot/i386/libi386/biosdisk.c,v retrieving revision 1.6 diff -u -r1.6 biosdisk.c --- i386/libi386/biosdisk.c 21 Jun 2004 03:38:52 -0000 1.6 +++ i386/libi386/biosdisk.c 9 Sep 2004 23:34:58 -0000 @@ -891,9 +891,14 @@ /* correct sector number for 1-based BIOS numbering */ sec++; - /* Loop retrying the operation a couple of times. The BIOS may also retry. */ + /* + * Loop retrying the operation a couple of times. The BIOS may also + * retry. + */ for (retry = 0; retry < 3; retry++) { - /* if retrying, reset the drive */ + /* + * If retrying, reset the drive. + */ if (retry > 0) { v86.ctl = V86_FLAGS; v86.addr = 0x13; @@ -902,34 +907,33 @@ v86int(); } - if(cyl > 1023) { - /* use EDD if the disk supports it, otherwise, return error */ - if(od->od_flags & BD_MODEEDD1) { - static unsigned short packet[8]; - - packet[0] = 0x10; - packet[1] = x; - packet[2] = VTOPOFF(xp); - packet[3] = VTOPSEG(xp); - packet[4] = dblk & 0xffff; - packet[5] = dblk >> 16; - packet[6] = 0; - packet[7] = 0; - v86.ctl = V86_FLAGS; - v86.addr = 0x13; - v86.eax = 0x4200; - v86.edx = od->od_unit; - v86.ds = VTOPSEG(packet); - v86.esi = VTOPOFF(packet); - v86int(); - result = (v86.efl & 0x1); - if(result == 0) - break; - } else { - result = 1; + /* + * Always use EDD if the disk supports it, otherwise fall back + * to CHS mode (returning an error if the cylinder number is + * too large). + */ + if (od->od_flags & BD_MODEEDD1) { + static unsigned short packet[8]; + + packet[0] = 0x10; + packet[1] = x; + packet[2] = VTOPOFF(xp); + packet[3] = VTOPSEG(xp); + packet[4] = dblk & 0xffff; + packet[5] = dblk >> 16; + packet[6] = 0; + packet[7] = 0; + v86.ctl = V86_FLAGS; + v86.addr = 0x13; + v86.eax = 0x4200; + v86.edx = od->od_unit; + v86.ds = VTOPSEG(packet); + v86.esi = VTOPOFF(packet); + v86int(); + result = (v86.efl & 0x1); + if (result == 0) break; - } - } else { + } else if (cyl < 1024) { /* Use normal CHS addressing */ v86.ctl = V86_FLAGS; v86.addr = 0x13; @@ -941,7 +945,10 @@ v86int(); result = (v86.efl & 0x1); if (result == 0) - break; + break; + } else { + result = 1; + break; } } @@ -1034,9 +1041,14 @@ dblk += x; resid -= x; - /* Loop retrying the operation a couple of times. The BIOS may also retry. */ + /* + * Loop retrying the operation a couple of times. The BIOS may also + * retry. + */ for (retry = 0; retry < 3; retry++) { - /* if retrying, reset the drive */ + /* + * If retrying, reset the drive. + */ if (retry > 0) { v86.ctl = V86_FLAGS; v86.addr = 0x13; @@ -1044,36 +1056,35 @@ v86.edx = od->od_unit; v86int(); } - - if(cyl > 1023) { - /* use EDD if the disk supports it, otherwise, return error */ - if(od->od_flags & BD_MODEEDD1) { - static unsigned short packet[8]; - - packet[0] = 0x10; - packet[1] = x; - packet[2] = VTOPOFF(xp); - packet[3] = VTOPSEG(xp); - packet[4] = dblk & 0xffff; - packet[5] = dblk >> 16; - packet[6] = 0; - packet[7] = 0; - v86.ctl = V86_FLAGS; - v86.addr = 0x13; - /* Should we Write with verify ?? 0x4302 ? */ - v86.eax = 0x4300; - v86.edx = od->od_unit; - v86.ds = VTOPSEG(packet); - v86.esi = VTOPOFF(packet); - v86int(); - result = (v86.efl & 0x1); - if(result == 0) - break; - } else { - result = 1; + + /* + * Always use EDD if the disk supports it, otherwise fall back + * to CHS mode (returning an error if the cylinder number is + * too large). + */ + if (od->od_flags & BD_MODEEDD1) { + static unsigned short packet[8]; + + packet[0] = 0x10; + packet[1] = x; + packet[2] = VTOPOFF(xp); + packet[3] = VTOPSEG(xp); + packet[4] = dblk & 0xffff; + packet[5] = dblk >> 16; + packet[6] = 0; + packet[7] = 0; + v86.ctl = V86_FLAGS; + v86.addr = 0x13; + /* Should we Write with verify ?? 0x4302 ? */ + v86.eax = 0x4300; + v86.edx = od->od_unit; + v86.ds = VTOPSEG(packet); + v86.esi = VTOPOFF(packet); + v86int(); + result = (v86.efl & 0x1); + if (result == 0) break; - } - } else { + } else if (cyl < 1024) { /* Use normal CHS addressing */ v86.ctl = V86_FLAGS; v86.addr = 0x13; @@ -1085,7 +1096,10 @@ v86int(); result = (v86.efl & 0x1); if (result == 0) - break; + break; + } else { + result = 1; + break; } }
文章代碼(AID): #11GFO700 (DFBSD_bugs)
文章代碼(AID): #11GFO700 (DFBSD_bugs)