ZFS boot inside on the second partition inside a slice

John Baldwin jhb at freebsd.org
Tue Jun 21 17:51:47 UTC 2011


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:

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
+		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.
+		mov $MEM_BUF,%si		# BTX (before reloc)
 		mov 0xa(%si),%bx		# Get BTX length and set
 		mov $NSECT*SIZ_SEC-1,%di	# Size of load area (less one)
 		mov %di,%si			# End of load
@@ -214,12 +214,12 @@ seta20.3:	sti				# Enable interrupts
  * packet on the stack and passes it to read.
  *
  * %eax		- int     - LBA to read in relative to partition start
+ * %es:%bx	- ptr	  - destination address
  * %dl		- byte    - drive to read from
  * %dh		- byte    - num sectors to read
  * %si		- ptr     - MBR partition entry
  */
-nread:		xor %eax,%eax			# Sector offset in partition
-nread.1:	xor %ecx,%ecx			# Get
+nread:		xor %ecx,%ecx			# Get
 		addl 0x8(%si),%eax		#  LBA
 		adc $0,%ecx
 		pushl %ecx			# Starting absolute block
@@ -234,9 +234,12 @@ seta20.3:	sti				# Enable interrupts
 		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
 

-- 
John Baldwin


More information about the freebsd-stable mailing list