From owner-freebsd-questions Tue Jan 9 7:28:38 2001 Delivered-To: freebsd-questions@freebsd.org Received: from abby.skypoint.net (abby.skypoint.net [199.86.32.252]) by hub.freebsd.org (Postfix) with ESMTP id A272D37B401 for ; Tue, 9 Jan 2001 07:28:08 -0800 (PST) Received: (from uucp@localhost) by abby.skypoint.net (8.8.7/jl 1.3) with UUCP id JAA26241; Tue, 9 Jan 2001 09:27:21 -0600 (CST) Received: (from rpj@localhost) by fep.hirshfields.com (8.8.8/8.8.8) id PAA22982; Mon, 8 Jan 2001 15:41:05 -0600 (CST) (envelope-from rpj) From: "Roger P. Johnson" Message-Id: <200101082141.PAA22982@fep.hirshfields.com> Subject: Re: 4.2R Installation problem -- Read Error In-Reply-To: from GB/DEV - Doug Poland at "Jan 5, 1 02:55:37 pm" To: doug.poland@omniresources.com (GB/DEV - Doug Poland) Date: Mon, 8 Jan 2001 15:41:05 -0600 (CST) Cc: freebsd-questions@FreeBSD.ORG X-Mailer: ELM [version 2.4ME+ PL38 (25)] MIME-Version: 1.0 Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: 7bit Sender: owner-freebsd-questions@FreeBSD.ORG Precedence: bulk X-Loop: FreeBSD.ORG Hi, I have been through this exact same problem since FreeBSD 2.2.2 to many times to count! It's not a problem for me anymore ... The problem lies in that your BIOS is not passing the boot device in the register that boot1.s is expecting. Can I take it that you are using the "dangerously dedicated" partion mode? If you want to fix the "Read error" on boot, so you don't have to use that yucky fdisk type layout, you have to patch, build, and install /usr/src/sys/boot/i386/boot/boot1.s. This is easy to do. Here are the diffs I made to boot1.s (assuming you are using the dedicated partion method): > # 2000/08/30 rpj: belch something to screen about this fix ... > mov $msg_dflt,%si # Display > callw putstr # prompt > 106a111 > 107a113,117 > > # 2000/08/30 rpj: explicitly make the system boot from the first hard drive in > # the system. > mov $0x80, %dl > 309a320,322 > # 2000/08/rpj: this next message is a tip off about the Read error fix > # during the boot process > msg_dflt: .asciz "rpj: Loading ...\r\n" After patching: (I believe you have to build the btxlib first which is why I show it) # cd /usr/src/sys/boot/i386/boot2 # cp boot1.s boot1.s.dist # cd ../btx # make all # cd ../boot2 # make all # make install # installed patched boot code to /boot # disklabel -B -b boot1 da0 # this writes the patched /boot/boot1 to the disk # reboot # should boot now. If you don't want to get fancy in the patching, you only really need just the one line: mov $0x80, %dl and you will never know there was a boot problem. This assumes that you will *always* boot off of the first hard disk. Check out the old mailing list archives at FreeBSD.org. It should have mention of this also. Good luck, e-mail me if you need more info. -Roger P.S Here is my complete attached "boot1.s" I use: ----------------------------begin snip-------------------------------------- # # Copyright (c) 1998 Robert Nordier # All rights reserved. # # Redistribution and use in source and binary forms are freely # permitted provided that the above copyright notice and this # paragraph and the following disclaimer are duplicated in all # such forms. # # This software is provided "AS IS" and without any express or # implied warranties, including, without limitation, the implied # warranties of merchantability and fitness for a particular # purpose. # # $FreeBSD: src/sys/boot/i386/boot2/boot1.s,v 1.10.2.2 2000/07/07 21:12:32 jhb Exp $ # Memory Locations .set MEM_REL,0x700 # Relocation address .set MEM_ARG,0x900 # Arguments .set MEM_ORG,0x7c00 # Origin .set MEM_BUF,0x8c00 # Load area .set MEM_BTX,0x9000 # BTX start .set MEM_JMP,0x9010 # BTX entry point .set MEM_USR,0xa000 # Client start .set BDA_BOOT,0x472 # Boot howto flag # Partition Constants .set PRT_OFF,0x1be # Partition offset .set PRT_NUM,0x4 # Partitions .set PRT_BSD,0xa5 # Partition type # Flag Bits .set FL_PACKET,0x80 # Packet mode # Misc. Constants .set SIZ_PAG,0x1000 # Page size .set SIZ_SEC,0x200 # Sector size .globl start .globl xread .code16 start: jmp main # Start recognizably .org 0x4,0x90 # # Trampoline used by boot2 to call read to read data from the disk via # the BIOS. Call with: # # %cx:%ax - long - LBA to read in # %es:(%bx) - caddr_t - buffer to read data into # %dl - byte - drive to read from # %dh - byte - num sectors to read # xread: push %ss # Address pop %ds # data # # Setup an EDD disk packet and pass it to read # xread.1: # Starting pushl $0x0 # absolute push %cx # block push %ax # number push %es # Address of push %bx # transfer buffer xor %ax,%ax # Number of movb %dh,%al # blocks to push %ax # transfer push $0x10 # Size of packet mov %sp,%bp # Packet pointer callw read # Read from disk lea 0x10(%bp),%sp # Clear stack lret # To far caller # # Load the rest of boot2 and BTX up, copy the parts to the right locations, # and start it all up. # # # Setup the segment registers to flat addressing (segment 0) and setup the # stack to end just below the start of our code. # main: cld # String ops inc xor %cx,%cx # Zero mov %cx,%es # Address mov %cx,%ds # data mov %cx,%ss # Set up mov $start,%sp # stack # # Relocate ourself to MEM_REL. Since %cx == 0, the inc %ch sets # %cx == 0x100. # # 2000/08/30 rpj: belch something to screen about this fix ... mov $msg_dflt,%si # Display callw putstr # prompt mov %sp,%si # Source mov $MEM_REL,%di # Destination incb %ch # Word count rep # Copy movsw # code # # If we are on a hard drive, then load the MBR and look for the first # FreeBSD slice. We use the fake partition entry below that points to # the MBR when we call nread. The first pass looks for the first active # FreeBSD slice. The second pass looks for the first non-active FreeBSD # slice if the first one fails. # mov $part4,%si # Partition # 2000/08/30 rpj: explicitly make the system boot from the first hard drive in # the system. mov $0x80, %dl cmpb $0x80,%dl # Hard drive? jb main.4 # No movb $0x1,%dh # Block count callw nread # Read MBR mov $0x1,%cx # Two passes main.1: mov $MEM_BUF+PRT_OFF,%si # Partition table movb $0x1,%dh # Partition main.2: cmpb $PRT_BSD,0x4(%si) # Our partition type? jne main.3 # No jcxz main.5 # If second pass testb $0x80,(%si) # Active? jnz main.5 # Yes main.3: add $0x10,%si # Next entry incb %dh # Partition cmpb $0x1+PRT_NUM,%dh # In table? jb main.2 # Yes dec %cx # Do two jcxz main.1 # passes # # If we get here, we didn't find any FreeBSD slices at all, so print an # error message and die. # mov $msg_part,%si # Message jmp error # Error # # Floppies use partition 0 of drive 0. # main.4: xor %dx,%dx # Partition:drive # # Ok, we have a slice and drive in %dx now, so use that to locate and load # boot2. %si references the start of the slice we are looking for, so go # ahead and load up the first 16 sectors (boot1 + boot2) from that. When # we read it in, we conveniently use 0x8c00 as our transfer buffer. Thus, # boot1 ends up at 0x8c00, and boot2 starts at 0x8c00 + 0x200 = 0x8e00. # The first part of boot2 is the disklabel, which is 0x200 bytes long. # The second part is BTX, which is thus loaded into 0x9000, which is where # it also runs from. The boot2.bin binary starts right after the end of # BTX, so we have to figure out where the start of it is and then move the # binary to 0xb000. Normally, BTX clients start at MEM_USR, or 0xa000, but # when we use btxld create boot2, we use an entry point of 0x1000. That # entry point is relative to MEM_USR; thus boot2.bin starts at 0xb000. # main.5: mov %dx,MEM_ARG # Save args movb $0x10,%dh # Sector count callw nread # Read disk mov $MEM_BTX,%bx # BTX mov 0xa(%bx),%si # Get BTX length and set add %bx,%si # %si to start of boot2.bin mov $MEM_USR+SIZ_PAG,%di # Client page 1 mov $MEM_BTX+0xe*SIZ_SEC,%cx # Byte sub %si,%cx # count rep # Relocate movsb # client sub %di,%cx # Byte count xorb %al,%al # Zero assumed bss from rep # the end of boot2.bin stosb # up to 0x10000 callw seta20 # Enable A20 jmp start+MEM_JMP-MEM_ORG # Start BTX # # Enable A20 so we can access memory above 1 meg. # seta20: cli # Disable interrupts seta20.1: inb $0x64,%al # Get status testb $0x2,%al # Busy? jnz seta20.1 # Yes movb $0xd1,%al # Command: Write outb %al,$0x64 # output port seta20.2: inb $0x64,%al # Get status testb $0x2,%al # Busy? jnz seta20.2 # Yes movb $0xdf,%al # Enable outb %al,$0x60 # A20 sti # Enable interrupts retw # To caller # # Trampoline used to call read from within boot1. # nread: mov $MEM_BUF,%bx # Transfer buffer mov 0x8(%si),%ax # Get mov 0xa(%si),%cx # LBA push %cs # Read from callw xread.1 # disk jnc return # If success, return mov $msg_read,%si # Otherwise, set the error # message and fall through to # the error routine # # Print out the error message pointed to by %ds:(%si) followed # by a prompt, wait for a keypress, and then reboot the machine. # error: callw putstr # Display message mov $prompt,%si # Display callw putstr # prompt xorb %ah,%ah # BIOS: Get int $0x16 # keypress movw $0x1234, BDA_BOOT # Do a warm boot ljmp $0xffff,$0x0 # reboot the machine # # Display a null-terminated string using the BIOS output. # putstr.0: mov $0x7,%bx # Page:attribute movb $0xe,%ah # BIOS: Display int $0x10 # character putstr: lodsb # Get char testb %al,%al # End of string? jne putstr.0 # No # # Overused return code. ereturn is used to return an error from the # read function. Since we assume putstr succeeds, we (ab)use the # same code when we return from putstr. # ereturn: movb $0x1,%ah # Invalid stc # argument return: retw # To caller # # Reads sectors from the disk. If EDD is enabled, then check if it is # installed and use it if it is. If it is not installed or not enabled, then # fall back to using CHS. Since we use a LBA, if we are using CHS, we have to # fetch the drive parameters from the BIOS and divide it out ourselves. # Call with: # # %dl - byte - drive number # stack - 10 bytes - EDD Packet # read: push %dx # Save movb $0x8,%ah # BIOS: Get drive int $0x13 # parameters movb %dh,%ch # Max head number pop %dx # Restore jc return # If error andb $0x3f,%cl # Sectors per track jz ereturn # If zero cli # Disable interrupts mov 0x8(%bp),%eax # Get LBA push %dx # Save movzbl %cl,%ebx # Divide by xor %edx,%edx # sectors div %ebx # per track movb %ch,%bl # Max head number movb %dl,%ch # Sector number inc %bx # Divide by xorb %dl,%dl # number div %ebx # of heads movb %dl,%bh # Head number pop %dx # Restore cmpl $0x3ff,%eax # Cylinder number supportable? sti # Enable interrupts ja read.7 # No, try EDD xchgb %al,%ah # Set up cylinder rorb $0x2,%al # number orb %ch,%al # Merge inc %ax # sector xchg %ax,%cx # number movb %bh,%dh # Head number subb %ah,%al # Sectors this track mov 0x2(%bp),%ah # Blocks to read cmpb %ah,%al # To read jb read.2 # this movb %ah,%al # track read.2: mov $0x5,%di # Try count read.3: les 0x4(%bp),%bx # Transfer buffer push %ax # Save movb $0x2,%ah # BIOS: Read int $0x13 # from disk pop %bx # Restore jnc read.4 # If success dec %di # Retry? jz read.6 # No xorb %ah,%ah # BIOS: Reset int $0x13 # disk system xchg %bx,%ax # Block count jmp read.3 # Continue read.4: movzbw %bl,%ax # Sectors read add %ax,0x8(%bp) # Adjust jnc read.5 # LBA, incw 0xa(%bp) # transfer read.5: shlb %bl # buffer add %bl,0x5(%bp) # pointer, sub %al,0x2(%bp) # block count ja read # If not done read.6: retw # To caller read.7: testb $FL_PACKET,%cs:MEM_REL+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 # 2000/08/rpj: this next message is a tip off about the Read error fix # during the boot process msg_dflt: .asciz "rpj: Loading ...\r\n" msg_read: .asciz "Read" msg_part: .asciz "Boot" prompt: .asciz " error\r\n" flags: .byte FLAGS # Flags .org PRT_OFF,0x90 # Partition table .fill 0x30,0x1,0x0 part4: .byte 0x80, 0x00, 0x01, 0x00 .byte 0xa5, 0xff, 0xff, 0xff .byte 0x00, 0x00, 0x00, 0x00 .byte 0x50, 0xc3, 0x00, 0x00 # 50000 sectors long, bleh .word 0xaa55 # Magic number --------------------------------end snip---------------------------------------------- > Hi everyone, > > I just completed an install of 4.2-RELEASE on a Gateway 266 PII. I went > through the entire config and install without a problem until it was > time to remove the install CD and reboot. > > After the bios and vga boot info appears, I get a screen refresh > and > > Read error > > as the only message. Sounds like a MBR problem? Anyone have a > solution other than re-install? > > I'm on an extremely tight timeframe with this box > > > Regards, > Doug > > > To Unsubscribe: send mail to majordomo@FreeBSD.org > with "unsubscribe freebsd-questions" in the body of the message > > To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-questions" in the body of the message