ZFS boot inside on the second partition inside a slice
John Baldwin
jhb at freebsd.org
Tue Jun 21 19:25:37 UTC 2011
On Tuesday, June 21, 2011 3:02:28 pm Henri Hennebert wrote:
> On 06/21/2011 19:51, John Baldwin wrote:
> > On Tuesday, June 21, 2011 12:15:58 pm Henri Hennebert wrote:
> >> On 06/21/2011 17:55, John Baldwin wrote:
> >>> On Tuesday, June 21, 2011 10:50:14 am Henri Hennebert wrote:
> >>>> On 06/21/2011 15:01, John Baldwin wrote:
> >>>>> Index: zfsldr.S
> >>>>> ===================================================================
> >>>>> --- zfsldr.S (revision 223339)
> >>>>> +++ zfsldr.S (working copy)
> >>>>> @@ -234,9 +234,12 @@ nread.1: xor %ecx,%ecx # Get
> >>>>> callw read # Read from disk
> >>>>> 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
> >>>>> + mov %ah,%al # Format
> >>>>> + mov $read_err,%di # error
> >>>>> + call hex8 # code
> >>>>> + 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.
> >>>>> @@ -296,12 +299,28 @@ read.1: mov $msg_chs,%si
> >>>>> jmp error
> >>>>> msg_chs: .asciz "CHS not supported"
> >>>>>
> >>>>> +/*
> >>>>> + * Convert AL to hex, saving the result to [EDI].
> >>>>> + */
> >>>>> +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_read: .ascii "Read error: "
> >>>>> +read_err: .asciz "XX"
> >>>>> +msg_part: .asciz "Boot error"
> >>>>>
> >>>>> -prompt: .asciz " error\r\n"
> >>>>> +prompt: .asciz "\r\n"
> >>>>>
> >>>>> .org PRT_OFF,0x90
> >>>>>
> >>>> I get
> >>>>
> >>>> Read error: 01
> >>>
> >>> Hmm, that would be 'invalid parameter'.
> >>>
> >>> Can you add a 'foo: jmp foo' infinite loop and move it around to figure
> > out
> >>> which read call is failing?
> >>>
> >> main.5: mov %dx,MEM_ARG # Save args
> >> movb $NSECT,%dh # Sector count
> >> movl $1024,%eax # Offset to boot2
> >> callw nread.1 # Read disk
> >>
> >> foo: jmp foo
> >>
> >> After this one I get
> >>
> >> 'Read error: 01'
> >
> > Hmm, ok. NSECT changed in the MFC (it is now larger). Try this patch.
It
> > changes the code to read zfsboot in one sector at a time:
> >
>
> I encounter 2 problems - see in you patch
>
> Henri
>
>
> > 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,19 @@ 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 from
> > + movw $MEM_BUF,%bx # first sector
> > + movb $0x1,%dh # on disk into
> > + callw nread # $MEM_BUF
> > mov $0x1,%cx # Two passes
> > main.1: mov $MEM_BUF+PRT_OFF,%si # Partition table
> > movb $0x1,%dh # Partition
> > @@ -161,10 +153,18 @@ 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
> > + movb $NSECT,%cl # 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
> > + movb $1,$dh # One sector
> %dh
> |
> ------------------------+
>
> > + callw nread # Read disk
> > + popal # Restore
> > + incl %eax # Update for
> > + add $SIZ_SEC,%bx # next sector
> > + dec %cx # Last sector?
> > + jncxz main.6 # If not, read another.
>
> Error: no such instruction: `jncxz main.6'
Ah, jcxnz instead (jump if cx is non-zero)
--
John Baldwin
More information about the freebsd-stable
mailing list