Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 16 Apr 2001 15:35:36 -0500 (CDT)
From:      "Roger P. Johnson" <rpj@fep.hirshfields.com>
To:        dpd@raffles-it.com (David Dooley)
Cc:        freebsd-questions@FreeBSD.ORG
Subject:   Re: Problems booting a Digital 5000 PC
Message-ID:  <200104162035.PAA01541@fep.hirshfields.com>
In-Reply-To: <200104160115.f3G1FwG02498@arrow.lan.raffles-it.com> from David Dooley at "Apr 16, 1 02:15:58 am"

next in thread | previous in thread | raw e-mail | index | archive | help
Hi,

   I run about 15 DEC PC's. I know exactly what you are talking about. 
There appears to be a bug in the Phoenix BIOS that when you use
FreeBSD in dedicated mode, then you get "Read error". This has occured
with FreeBSD since way back in 2.1.5 (when I started FreeBSD). You
won't get the Read error with NetBSD or Linux, or others.

  You have to solutions. One is that you can use it in compatable mode,
or two, use dedicated mode with a patched boot code (enclosed, taken
right from my machines).

  I prefer to use dedicated mode and install my patched boot1 code.

  Here is how you fix the "Read error" with dedicated usage:

     1. cd /usr/src/sys/boot/i386/boot2
     2. cp boot1.s boot1.s.bak
     3. cp this_enclosed_boot1.s to .
     4. cd ../btx
     5. make
     6. cd ../boot2
     7. make
     8. make install
     9. # disklabel -B -b boot1 da0
     10. reboot

Look for my comments "rpj" in boot1.s to see what I changed.

e-mail me if you have any question.
-Roger

------------------- begin patched boot1.s -------------------
#
# 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 patched boot1.s -------------------

> Hi,
> 
> I have a Digital 5000 PC that I have been trying to install FreeBSD 
> 4.2 on to for the last couple of weeks.
> 
> It would appear that I can install FreeBSD no problem, but when I try 
> and boot my nice new clean install I get a 'read error' and that's 
> it. I can boot from the 2nd CD and muck about with the disk disklabel 
> and fdisk to no avail. The system was running Win98 and so I thought 
> that I would try and reinstall that and see if the drive was 
> nackered, but it worked and it booted up into Windows first time. I 
> have now gone back to FreeBSD 4.2 and I once again get this 'read 
> error' error message. I have tried to be 'Dangerously Dedicated' and 
> not with no success.
> 
> I found an option in the BIOS that's under the Advanced option tab of 
> my Phoenix BIOS that is labelled 'Large Disk Access Mode' and has the 
> options 'DOS' and 'OTHER'. In the help panel the text is
> 
> 	UNIX, Novell Netware, or other operating  systems, select 'OTHER'. 
> If
> 	you are installing new software and the drive failes, change this 
> 	selection and try again. Different operating systems require 
> different
> 	representations of drive geometries.
> 
> I have tried every permutation of Other/Dos and Not/Dangerously 
> Dedicated.
> 
> Just this evening I tried to install FreeBSD again, but this time I 
> tried using a small root partition thinking it maybe something to do 
> with old machine and large partitions, so I set the root partition to 
> be 512M and 128M swap and /usr everything else. Previously I had set 
> the root partition to be everything bar 128M for swap. I have done 
> this rebuild tonight with 'Dangerously dedicated' set and the BIOS 
> setting set to both DOS and other.
> 
> Just as an aside the option was set to DOS but when I installed Win98 
> I had mistakenly left it at 'Other' and it still worked.
> 
> Once I have FreeBSD installed, this machines prime function will be 
> to be a print server for a postscript printer, with the occasional 
> duty as a cd burner.
> 
> The system is a Pentium 2 233MHz with 96MB ram and a 3.2 GB IDE Hard 
> Drive (1st channel, Master), 1 CDROM (2nd channel, Master), 1 CD-RW 
> (1st channel, slave). The drive has been partitioned
> 
> Thanks for your time and any assistance.
> 
> David.
> 
> 
> 

[application/pgp-signature is not supported, skipping...]


To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-questions" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200104162035.PAA01541>