Date: Wed, 22 Jun 2011 16:42:36 +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: <4E01FF5C.1060306@restart.be> In-Reply-To: <4E01FADA.2070104@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> <4E01FADA.2070104@restart.be>
next in thread | previous in thread | raw e-mail | index | archive | help
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@freebsd.org mailing list > http://lists.freebsd.org/mailman/listinfo/freebsd-stable > To unsubscribe, send any mail to "freebsd-stable-unsubscribe@freebsd.org" >
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?4E01FF5C.1060306>