Date: Wed, 22 Jun 2011 18:48:43 +0200 From: Henri Hennebert <hlh@restart.be> To: John Baldwin <jhb@freebsd.org> Cc: freebsd-stable@freebsd.org Subject: Re: ZFS boot inside on the second partition inside a slice Message-ID: <4E021CEB.4080703@restart.be> In-Reply-To: <201106221158.16485.jhb@freebsd.org> References: <BANLkTi=drd8vY84_4jqDZTFK%2Bsq=n0Kx9g@mail.gmail.com> <4E01FA03.9070805@restart.be> <4E01FADA.2070104@restart.be> <201106221158.16485.jhb@freebsd.org>
next in thread | previous in thread | raw e-mail | index | archive | help
On 06/22/2011 17:58, John Baldwin wrote: > 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 > @@ -143,32 +134,35 @@ main.4: xor %dx,%dx # Partition:drive > * (i.e. after the two vdev labels). We don't have do anything fancy > * here to allow for an extra copy of boot1 and a partition table > * (compare to this section of the UFS bootstrap) so we just load it > - * all at 0x8000. The first part of boot2 is BTX, which wants to run > + * all at 0x9000. The first part of boot2 is BTX, which wants to run > * at 0x9000. The boot2.bin binary starts right after the end of BTX, > * so we have to figure out where the start of it is and then move the > - * binary to 0xc000. After we have moved the client, we relocate BTX > - * itself to 0x9000 - doing it in this order means that none of the > - * memcpy regions overlap which would corrupt the copy. Normally, BTX > - * clients start at MEM_USR, or 0xa000, but when we use btxld to > - * create zfsboot2, we use an entry point of 0x2000. That entry point is > - * relative to MEM_USR; thus boot2.bin starts at 0xc000. > + * binary to 0xc000. Normally, BTX clients start at MEM_USR, or 0xa000, > + * but when we use btxld to create zfsboot2, we use an entry point of > + * 0x2000. That entry point is relative to MEM_USR; thus boot2.bin > + * starts at 0xc000. > * > * The load area and the target area for the client overlap so we have > * to use a decrementing string move. We also play segment register > * games with the destination address for the move so that the client > * can be larger than 16k (which would overflow the zero segment since > - * the client starts at 0xc000). Relocating BTX is easy since the load > - * area and target area do not overlap. > + * the client starts at 0xc000). > */ > 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_BTX,%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_BTX,%si # BTX > 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 > - add $MEM_BUF,%si # area > + add $MEM_BTX,%si # area > sub %bx,%di # End of client, 0xc000 rel > mov %di,%cx # Size of > inc %cx # client > @@ -179,12 +173,6 @@ main.5: mov %dx,MEM_ARG # Save args > movsb # client > mov %ds,%dx # Back to > mov %dx,%es # zero segment > - mov $MEM_BUF,%si # BTX (before reloc) > - mov $MEM_BTX,%di # BTX > - mov %bx,%cx # Get BTX length > - cld # Increment this time > - rep # Relocate > - movsb # BTX > > /* > * Enable A20 so we can access memory above 1 meg. > @@ -214,29 +202,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 +253,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 +280,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 > No error message but a reboot... I add: loop main.6 # If not last, read another mov $msg_debug,%si call putstr mov $MEM_BTX,%si # BTX ...... msg_debug: .asciz "@\r\n" I don't get the @ on the console :-( PS - I have to keep a short message otherwise: /usr/src/sys/boot/i386/zfsboot/zfsldr.S:322: Error: attempt to move .org backwards Henri Henri
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?4E021CEB.4080703>