ZFS boot inside on the second partition inside a slice

Henri Hennebert hlh at restart.be
Wed Jun 22 14:43:08 UTC 2011


On 06/22/2011 16:23, Henri Hennebert wrote:
> On 06/22/2011 16:19, Henri Hennebert wrote:
>> On 06/22/2011 15:57, John Baldwin wrote:
>>> On Wednesday, June 22, 2011 7:34:05 am Henri Hennebert wrote:
>>>> I get
>>>>
>>>> LBA: 00008200
>>>> Read error: 04
>>>
>>> Odd. Oh, I fubar'd and read the wrong thing for the sector. Also, we
>>> should leave the EDD packet on the stack so it doesn't get trashed by
>>> calling hex8, etc. Please try this:
>>>
>>> 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,18 @@ 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
>>> + movw $MEM_BUF,%bx # from first
>>> + callw nread # sector
>>> mov $0x1,%cx # Two passes
>>> main.1: mov $MEM_BUF+PRT_OFF,%si # Partition table
>>> movb $0x1,%dh # Partition
>>> @@ -161,10 +152,16 @@ 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
>>> + mov $NSECT,%cx # 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
>>> + callw nread # Read disk
>>> + popal # Restore
>>> + incl %eax # Update for
>>> + add $SIZ_SEC,%bx # next sector
>>> + loop main.6 # If not last, 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,29 +211,35 @@ 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
>>> pushl %eax # block number
>>> push %es # Address of
>>> - push $MEM_BUF # transfer buffer
>>> - xor %ax,%ax # Number of
>>> - movb %dh,%al # blocks to
>>> - push %ax # transfer
>>> + push %bx # transfer buffer
>>> + push $0x1 # Read 1 sector
>>> push $0x10 # Size of packet
>>> mov %sp,%bp # Packet pointer
>>> callw read # Read from disk
>>> + jc nread.1 # If error, fail
>>> 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
>>> + ret # If success, return
>>> +nread.1: mov %ah,%al # Format
>>> + mov $read_err,%di # error
>>> + call hex8 # code
>>> + movl 0x8(%bp),%eax # Format
>>> + mov $lba,%di # LBA
>>> + call hex32
>>> + mov $msg_lba,%si # Display
>>> + call putstr # LBA
>>> + 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.
>>> @@ -259,14 +262,6 @@ putstr: lodsb # Get char
>>> 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
>>> @@ -294,14 +289,38 @@ read: cmpb $0x80,%dl # Hard drive?
>>> retw # To caller
>>> read.1: mov $msg_chs,%si
>>> jmp error
>>> -msg_chs: .asciz "CHS not supported"
>>>
>>> +/*
>>> + * Convert EAX, AX, or AL to hex, saving the result to [EDI].
>>> + */
>>> +hex32: pushl %eax # Save
>>> + shrl $0x10,%eax # Do upper
>>> + call hex16 # 16
>>> + popl %eax # Restore
>>> +hex16: call hex16.1 # Do upper 8
>>> +hex16.1: xchgb %ah,%al # Save/restore
>>> +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_chs: .asciz "CHS not supported"
>>> +msg_read: .ascii "Read error: "
>>> +read_err: .asciz "XX"
>>> +msg_lba: .ascii "LBA: "
>>> +lba: .asciz "XXXXXXXX\r\n"
>>> +msg_part: .asciz "Boot error"
>>>
>>> -prompt: .asciz " error\r\n"
>>> +prompt: .asciz "\r\n"
>>>
>>> .org PRT_OFF,0x90
>>>
>>>
>>>
>> This time:
>>
>> LBA: 3c802308
>> Read error: 04
>>
>> This morning I was reading the code (I'm in Belgium) and find that the
>> previous LBA output was DAP+4 and so was the addr of the buffer. 0x8200
>> = $MEM_BUF+512, and so we must be in the second read.
>>
>
> OK I think I see, the first read mangle the partition table previously
> read at $MEM_BUF and so the next one is wrong.

That's it. I read `hd zfsboot' and at 0x200+0x1be+0x10+0x08 I get

07 1f  80 3c

as LBA: 0x3C801F07

+ 0x401 = 3c802308


>
>
>> Henri
>>
>>
>
> _______________________________________________
> freebsd-stable at freebsd.org mailing list
> http://lists.freebsd.org/mailman/listinfo/freebsd-stable
> To unsubscribe, send any mail to "freebsd-stable-unsubscribe at freebsd.org"
>



More information about the freebsd-stable mailing list