ZFS boot inside on the second partition inside a slice

Henri Hennebert hlh at restart.be
Wed Jun 22 14:23:24 UTC 2011


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.


> Henri
>
>



More information about the freebsd-stable mailing list