ZFS boot inside on the second partition inside a slice

Henri Hennebert hlh at restart.be
Tue Jun 21 20:13:23 UTC 2011


On 06/21/2011 21:25, John Baldwin wrote:
> 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)
>
>
I have to use:

                 jcxz main.7                     # If not, read another.
                 jmp main.6
main.7:         mov $MEM_BUF,%si                # BTX (before reloc)


and I get:

Read error: 04

Henri


More information about the freebsd-stable mailing list