ZFS boot inside on the second partition inside a slice

John Baldwin jhb at freebsd.org
Tue Jun 21 19:25:37 UTC 2011


On Tuesday, June 21, 2011 3:02:28 pm Henri Hennebert wrote:
> On 06/21/2011 19:51, John Baldwin wrote:
> > On Tuesday, June 21, 2011 12:15:58 pm Henri Hennebert wrote:
> >> On 06/21/2011 17:55, John Baldwin wrote:
> >>> On Tuesday, June 21, 2011 10:50:14 am Henri Hennebert wrote:
> >>>> On 06/21/2011 15:01, John Baldwin wrote:
> >>>>> Index: zfsldr.S
> >>>>> ===================================================================
> >>>>> --- zfsldr.S	(revision 223339)
> >>>>> +++ zfsldr.S	(working copy)
> >>>>> @@ -234,9 +234,12 @@ nread.1:	xor %ecx,%ecx			# Get
> >>>>>     		callw read			# Read from disk
> >>>>>     		lea 0x10(%bp),%sp		# Clear stack
> >>>>>     		jnc return			# If success, return
> >>>>> -		mov $msg_read,%si		# Otherwise, set the error
> >>>>> -						#  message and fall through to
> >>>>> -						#  the error routine
> >>>>> +		mov %ah,%al			# Format
> >>>>> +		mov $read_err,%di		#  error
> >>>>> +		call hex8			#  code
> >>>>> +		mov $msg_read,%si		# 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.
> >>>>> @@ -296,12 +299,28 @@ read.1:		mov $msg_chs,%si
> >>>>>     		jmp error
> >>>>>     msg_chs:	.asciz "CHS not supported"
> >>>>>
> >>>>> +/*
> >>>>> + * Convert AL to hex, saving the result to [EDI].
> >>>>> + */
> >>>>> +hex8:		push %ax			# Save
> >>>>> +		shrb $0x4,%al			# Do upper
> >>>>> +		call hex8.1			#  4
> >>>>> +		pop %ax				# Restore
> >>>>> +hex8.1: 	andb $0xf,%al			# Get lower 4
> >>>>> +		cmpb $0xa,%al			# Convert
> >>>>> +		sbbb $0x69,%al			#  to hex
> >>>>> +		das				#  digit
> >>>>> +		orb $0x20,%al			# To lower case
> >>>>> +		stosb				# Save char
> >>>>> +		ret				# (Recursive)
> >>>>> +
> >>>>>     /* Messages */
> >>>>>
> >>>>> -msg_read:	.asciz "Read"
> >>>>> -msg_part:	.asciz "Boot"
> >>>>> +msg_read:	.ascii "Read error: "
> >>>>> +read_err:	.asciz "XX"
> >>>>> +msg_part:	.asciz "Boot error"
> >>>>>
> >>>>> -prompt: 	.asciz " error\r\n"
> >>>>> +prompt: 	.asciz "\r\n"
> >>>>>
> >>>>>     		.org PRT_OFF,0x90
> >>>>>
> >>>> I get
> >>>>
> >>>> Read error: 01
> >>>
> >>> Hmm, that would be 'invalid parameter'.
> >>>
> >>> Can you add a 'foo: jmp foo' infinite loop and move it around to figure
> > out
> >>> which read call is failing?
> >>>
> >> main.5:         mov %dx,MEM_ARG                 # Save args
> >>                   movb $NSECT,%dh                 # Sector count
> >>                   movl $1024,%eax                 # Offset to boot2
> >>                   callw nread.1                   # Read disk
> >>
> >> foo:            jmp foo
> >>
> >> After this one I get
> >>
> >> 'Read error: 01'
> >
> > Hmm, ok.  NSECT changed in the MFC (it is now larger).  Try this patch.  
It
> > changes the code to read zfsboot in one sector at a time:
> >
> 
> I encounter 2 problems - see in you patch
> 
> Henri
> 
> 
> > Index: zfsldr.S
> > ===================================================================
> > --- zfsldr.S	(revision 223365)
> > +++ zfsldr.S	(working copy)
> > @@ -16,7 +16,6 @@
> >    */
> >
> >   /* Memory Locations */
> > -		.set MEM_REL,0x700		# Relocation address
> >   		.set MEM_ARG,0x900		# Arguments
> >   		.set MEM_ORG,0x7c00		# Origin
> >   		.set MEM_BUF,0x8000		# Load area
> > @@ -91,26 +90,19 @@ main:		cld				# String ops inc
> >   		mov %cx,%ss			# Set up
> >   		mov $start,%sp			#  stack
> >   /*
> > - * Relocate ourself to MEM_REL.  Since %cx == 0, the inc %ch sets
> > - * %cx == 0x100.
> > - */
> > -		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
> > +		mov $part4,%si			# Dummy partition
> >   		cmpb $0x80,%dl			# Hard drive?
> >   		jb main.4			# No
> > -		movb $0x1,%dh			# Block count
> > -		callw nread			# Read MBR
> > +		xor %eax,%eax			# Read MBR from
> > +		movw $MEM_BUF,%bx		#  first sector
> > +		movb $0x1,%dh			#  on disk into
> > +		callw nread			#  $MEM_BUF
> >   		mov $0x1,%cx	 		# Two passes
> >   main.1: 	mov $MEM_BUF+PRT_OFF,%si	# Partition table
> >   		movb $0x1,%dh			# Partition
> > @@ -161,10 +153,18 @@ main.4: 	xor %dx,%dx			# Partition:drive
> >    * area and target area do not overlap.
> >    */
> >   main.5: 	mov %dx,MEM_ARG			# Save args
> > -		movb $NSECT,%dh			# Sector count
> > +		movb $NSECT,%cl			# Sector count
> >   		movl $1024,%eax			# Offset to boot2
> > -		callw nread.1			# Read disk
> > -main.6:		mov $MEM_BUF,%si		# BTX (before reloc)
> > +		mov $MEM_BUF,%bx		# Destination buffer
> > +main.6:		pushal				# Save params
> > +		movb $1,$dh			# One sector
>                          %dh
>                          |
> ------------------------+
> 
> > +		callw nread			# Read disk
> > +		popal				# Restore
> > +		incl %eax			# Update for
> > +		add $SIZ_SEC,%bx		#  next sector
> > +		dec %cx				# Last sector?
> > +		jncxz main.6			# If not, read another.
> 
> Error: no such instruction: `jncxz main.6'

Ah, jcxnz instead (jump if cx is non-zero)


-- 
John Baldwin


More information about the freebsd-stable mailing list