Changeset View
Changeset View
Standalone View
Standalone View
head/sys/boot/i386/zfsboot/zfsldr.S
Show All 26 Lines | |||||
/* Partition Constants */ | /* Partition Constants */ | ||||
.set PRT_OFF,0x1be # Partition offset | .set PRT_OFF,0x1be # Partition offset | ||||
.set PRT_NUM,0x4 # Partitions | .set PRT_NUM,0x4 # Partitions | ||||
.set PRT_BSD,0xa5 # Partition type | .set PRT_BSD,0xa5 # Partition type | ||||
/* Misc. Constants */ | /* Misc. Constants */ | ||||
.set SIZ_PAG,0x1000 # Page size | .set SIZ_PAG,0x1000 # Page size | ||||
.set SIZ_SEC,0x200 # Sector size | .set SIZ_SEC,0x200 # Sector size | ||||
.set COPY_BLKS,0x8 # Number of blocks | |||||
.set NSECT,0x80 | # to copy for boot2 | ||||
.set COPY_BLK_SZ,0x8000 # Copy in 32k blocks; must be | |||||
# a multiple of 16 bytes | |||||
.set NSECT,(COPY_BLK_SZ / SIZ_SEC * COPY_BLKS) | |||||
.globl start | .globl start | ||||
.code16 | .code16 | ||||
/* | /* | ||||
* Load the rest of zfsboot2 and BTX up, copy the parts to the right locations, | * Load the rest of zfsboot2 and BTX up, copy the parts to the right locations, | ||||
* and start it all up. | * and start it all up. | ||||
*/ | */ | ||||
Show All 38 Lines | |||||
* error message and die. | * error message and die. | ||||
*/ | */ | ||||
mov $msg_part,%si # Message | mov $msg_part,%si # Message | ||||
jmp error # Error | jmp error # Error | ||||
/* | /* | ||||
* Ok, we have a slice and drive in %dx now, so use that to locate and | * Ok, we have a slice and drive in %dx now, so use that to locate and | ||||
* load boot2. %si references the start of the slice we are looking | * load boot2. %si references the start of the slice we are looking | ||||
* for, so go ahead and load up the 128 sectors starting at sector 1024 | * for, so go ahead and load up the COPY_BLKS*COPY_BLK_SZ/SIZ_SEC sectors | ||||
* (i.e. after the two vdev labels). We don't have do anything fancy | * starting at sector 1024 (i.e. after the two vdev labels). We don't | ||||
* here to allow for an extra copy of boot1 and a partition table | * have do anything fancy here to allow for an extra copy of boot1 and | ||||
* (compare to this section of the UFS bootstrap) so we just load it | * a partition table (compare to this section of the UFS bootstrap) so we | ||||
* all at 0x9000. The first part of boot2 is BTX, which wants to run | * just load it all at 0x9000. The first part of boot2 is BTX, which wants | ||||
* at 0x9000. The boot2.bin binary starts right after the end of BTX, | * 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 | * so we have to figure out where the start of it is and then move the | ||||
* binary to 0xc000. Normally, BTX clients start at MEM_USR, or 0xa000, | * 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 | * 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 | * 0x2000. That entry point is relative to MEM_USR; thus boot2.bin | ||||
* starts at 0xc000. | * starts at 0xc000. | ||||
* | * | ||||
* The load area and the target area for the client overlap so we have | * 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 | * to use a decrementing string move. We also play segment register | ||||
* games with the destination address for the move so that the client | * games with the destination address for the move so that the client | ||||
* can be larger than 16k (which would overflow the zero segment since | * can be larger than 16k (which would overflow the zero segment since | ||||
* the client starts at 0xc000). | * the client starts at 0xc000). | ||||
*/ | */ | ||||
main.5: mov %dx,MEM_ARG # Save args | main.5: mov %dx,MEM_ARG # Save args | ||||
mov $NSECT,%cx # Sector count | mov $NSECT,%cx # Sector count | ||||
movl $1024,%eax # Offset to boot2 | movl $1024,%eax # Offset to boot2 | ||||
mov $MEM_BTX,%ebx # Destination buffer | mov $MEM_BTX,%ebx # Destination buffer | ||||
main.6: pushal # Save params | main.6: pushal # Save params | ||||
call read # Read disk | call read # Read disk | ||||
popal # Restore | popal # Restore | ||||
incl %eax # Advance to | incl %eax # Advance to | ||||
add $SIZ_SEC,%ebx # next sector | add $SIZ_SEC,%ebx # next sector | ||||
loop main.6 # If not last, read another | loop main.6 # If not last, read another | ||||
mov MEM_BTX+0xa,%bx # Get BTX length | |||||
mov $NSECT*SIZ_SEC-1,%di # Size of load area (less one) | mov $MEM_BTX,%bx # BTX | ||||
mov %di,%si # End of load area, 0x9000 rel | mov 0xa(%bx),%si # Get BTX length and set | ||||
sub %bx,%di # End of client, 0xc000 rel | add %bx,%si # %si to start of boot2 | ||||
mov %di,%cx # Size of | dec %si # Set %ds:%si to point at the | ||||
inc %cx # client | mov %si,%ax # last byte we want to copy | ||||
mov $(MEM_BTX)>>4,%dx # Segment | shr $4,%ax # from boot2, with %si made as | ||||
mov %dx,%ds # addressing 0x9000 | add $(COPY_BLKS*COPY_BLK_SZ/16),%ax # small as possible. | ||||
mov $(MEM_USR+2*SIZ_PAG)>>4,%dx # Segment | and $0xf,%si # | ||||
mov %dx,%es # addressing 0xc000 | mov %ax,%ds # | ||||
std # Move with decrement | mov $(MEM_USR+2*SIZ_PAG)/16,%ax # Set %es:(-1) to point at | ||||
rep # Relocate | add $(COPY_BLKS*COPY_BLK_SZ/16),%ax # the last byte we | ||||
movsb # client | mov %ax,%es # want to copy boot2 into. | ||||
mov $COPY_BLKS,%bx # Copy COPY_BLKS 32k blocks | |||||
copyloop: | |||||
add $COPY_BLK_SZ,%si # Adjust %ds:%si to point at | |||||
mov %ds,%ax # the end of the next 32k to | |||||
sub $COPY_BLK_SZ/16,%ax # copy from boot2 | |||||
mov %ax,%ds | |||||
mov $COPY_BLK_SZ-1,%di # Adjust %es:%di to point at | |||||
mov %es,%ax # the end of the next 32k into | |||||
sub $COPY_BLK_SZ/16,%ax # which we want boot2 copied | |||||
mov %ax,%es | |||||
mov $COPY_BLK_SZ,%cx # Copy 32k | |||||
std | |||||
rep movsb | |||||
dec %bx | |||||
jnz copyloop | |||||
mov %cx,%ds # Reset %ds and %es | |||||
mov %cx,%es | |||||
cld # Back to increment | cld # Back to increment | ||||
xor %dx,%dx # Back | |||||
mov %ds,%dx # to zero | |||||
mov %dx,%es # segment | |||||
/* | /* | ||||
* Enable A20 so we can access memory above 1 meg. | * Enable A20 so we can access memory above 1 meg. | ||||
* Use the zero-valued %cx as a timeout for embedded hardware which do not | * Use the zero-valued %cx as a timeout for embedded hardware which do not | ||||
* have a keyboard controller. | * have a keyboard controller. | ||||
*/ | */ | ||||
seta20: cli # Disable interrupts | seta20: cli # Disable interrupts | ||||
seta20.1: dec %cx # Timeout? | seta20.1: dec %cx # Timeout? | ||||
▲ Show 20 Lines • Show All 123 Lines • Show Last 20 Lines |