Date: Wed, 22 Jun 2011 16:23:22 +0200 From: Henri Hennebert <hlh@restart.be> To: freebsd-stable@freebsd.org Cc: jhb@freebsd.org Subject: Re: ZFS boot inside on the second partition inside a slice Message-ID: <4E01FADA.2070104@restart.be> In-Reply-To: <4E01FA03.9070805@restart.be> References: <BANLkTi=drd8vY84_4jqDZTFK%2Bsq=n0Kx9g@mail.gmail.com> <201106211727.26413.jhb@freebsd.org> <4E01D32D.5050801@restart.be> <201106220957.09449.jhb@freebsd.org> <4E01FA03.9070805@restart.be>
next in thread | previous in thread | raw e-mail | index | archive | help
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 > >
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?4E01FADA.2070104>