diff options
author | jhb <jhb@FreeBSD.org> | 2000-07-12 18:11:54 +0000 |
---|---|---|
committer | jhb <jhb@FreeBSD.org> | 2000-07-12 18:11:54 +0000 |
commit | 3f4475e6f5248c282b7b4637dcf96b2ebbadb9b5 (patch) | |
tree | 17b3a349984e508faa8cd93a08a52b6e1f4512e7 /sys/boot/i386/boot0 | |
parent | 2913657a9794149a1d43420d2ee7df734392da82 (diff) | |
download | FreeBSD-src-3f4475e6f5248c282b7b4637dcf96b2ebbadb9b5.zip FreeBSD-src-3f4475e6f5248c282b7b4637dcf96b2ebbadb9b5.tar.gz |
The new and improved boot0, v1.1. This version adds the following:
- Autodetection and support of the BIOS EDD extensions to work around the
1024 cylinder limit on all but really ancient BIOS's.
- To work around some BIOS's which break when EDD is used with older drives,
we only attempt to use EDD if the cylinder is > 1023.
- Since this new code required more space than we had left, expand boot0 to
2 sectors (1024 bytes) in length.
- Add support for boot0 being multiple sectors using predefined constants.
If boot0 needs to be extended in the future, all that is required is
bumping the NUM_SECTORS constant.
- Now that we have more room to work with, add a few more fs type
descriptions while making others more verbose.
Diffstat (limited to 'sys/boot/i386/boot0')
-rw-r--r-- | sys/boot/i386/boot0/Makefile | 3 | ||||
-rw-r--r-- | sys/boot/i386/boot0/boot0.s | 284 |
2 files changed, 213 insertions, 74 deletions
diff --git a/sys/boot/i386/boot0/Makefile b/sys/boot/i386/boot0/Makefile index 015a5e8..a40e780 100644 --- a/sys/boot/i386/boot0/Makefile +++ b/sys/boot/i386/boot0/Makefile @@ -8,7 +8,8 @@ BINMODE= 444 M4?= m4 -B0FLAGS=0xf +# update, packet mode, and all slices enabled by default +B0FLAGS=0x8f B0TICKS=0xb6 ORG= 0x600 diff --git a/sys/boot/i386/boot0/boot0.s b/sys/boot/i386/boot0/boot0.s index 4d186ac..7b2e130 100644 --- a/sys/boot/i386/boot0/boot0.s +++ b/sys/boot/i386/boot0/boot0.s @@ -15,17 +15,20 @@ # $FreeBSD$ -# A 512-byte boot manager. +# A 1024-byte boot manager. .set NHRDRV,0x475 # Number of hard drives .set ORIGIN,0x600 # Execution address - .set FAKE,0x800 # Partition entry + .set SECTOR_SIZE,0x200 # Length of a sector + .set NUM_SECTORS,2 # Total length in sectors + + .set FAKE,ORIGIN+(SECTOR_SIZE*NUM_SECTORS) # Partition entry .set LOAD,0x7c00 # Load address .set PRT_OFF,0x1be # Partition table - .set TBL0SZ,0x3 # Table 0 size - .set TBL1SZ,0xb # Table 1 size + .set TBL0SZ,table0_end-table0 # Table 0 size + .set TBL1SZ,table1_end-table1 # Table 1 size .set MAGIC,0xaa55 # Magic: bootable @@ -33,14 +36,21 @@ .set KEY_F1,0x3b # F1 key scan code # -# Addresses in the sector of embedded data values. -# Accessed with negative offsets from the end of the relocated sector (%ebp). +# Flag bits # - .set _NXTDRV,-0x48 # Next drive - .set _OPT,-0x47 # Default option - .set _SETDRV,-0x46 # Drive to force - .set _FLAGS,-0x45 # Flags - .set _TICKS,-0x44 # Timeout ticks + .set FL_PACKET,0x80 # Packet mode + .set FL_NOUPDATE,0x40 # Don't save selection + .set FL_SETDRV,0x20 # Override drive number +# +# Addresses in the sector of embedded data values. +# Accessed with negative offsets from the end of the relocated sectors (%bp). +# + .set _PRT_END,(FAKE-(ORIGIN+SECTOR_SIZE)) + .set _NXTDRV,-(_PRT_END+0x48) # Next drive + .set _OPT,-(_PRT_END+0x47) # Default option + .set _SETDRV,-(_PRT_END+0x46) # Drive to force + .set _FLAGS,-(_PRT_END+0x45) # Flags + .set _TICKS,-(_PRT_END+0x44) # Timeout ticks .set _FAKE,0x0 # Fake partition entry .set _MNUOPT,0xc # Menu options @@ -52,40 +62,48 @@ # segments start at 0. # The stack is immediatly below the address we were loaded to. # +# Note that this section of code is used as the first signature check in +# boot0cfg(8). +# start: cld # String ops inc xorw %ax,%ax # Zero movw %ax,%es # Address movw %ax,%ds # data movw %ax,%ss # Set up movw $LOAD,%sp # stack - -# -# Copy this code to the address it was linked for -# - movw %sp,%si # Source - movw $start,%di # Destination - movw $0x100,%cx # Word count - rep # Relocate - movsw # code +# +# End signature code +# # # Set address for variable space beyond code, and clear it. # Notice that this is also used to point to the values embedded in in the block, # by using negative offsets. # - movw %di,%bp # Address variables + movw $fake,%bp # Address variables + movw %bp,%di # %di used in stosw movb $0x8,%cl # Words to clear rep # Zero stosw # them + incb -0xe(%di) # Sector number 1 +# +# Reload all of boot0 (including the extra sectors) into memory at the +# relocation address. +# + push %dx # Save drive number + movw $start,%bx # Origin we were linked for + movw %bp,%si # Fake PTE + movw $0x200+NUM_SECTORS,%ax # Read in all + callw intx13 # of boot0 + pop %dx # Restore # # Relocate to the new copy of the code. # - incb -0xe(%di) # Sector number - jmp main-LOAD+ORIGIN # To relocated code + jmp main+ORIGIN-LOAD # To relocated code # -# Check what flags were loaded with us, specifically, Use a predefined Drive. +# Check what flags were loaded with us; specifically, use a predefined Drive. # If what the bios gives us is bad, use the '0' in the block instead, as well. # -main: testb $0x20,_FLAGS(%bp) # Set number drive? +main: testb $FL_SETDRV,_FLAGS(%bp) # Set number drive? jnz main.1 # Yes testb %dl,%dl # Drive number valid? js main.2 # Possibly (0x80 set) @@ -133,7 +151,7 @@ main.3: movb %ch,-0x4(%bx) # Zero active flag (ch == 0) jne main.4 # No # # If it matches get the matching element in the -# next array. if it doesn't, we are already +# next array. If it doesn't, we are already # pointing at its first element which points to a "?". # addw $TBL1SZ,%di # Adjust @@ -174,7 +192,7 @@ main.6: addb $'0'|0x80,%al # Save next callw putx # item # # Now that we've printed the drive (if we needed to), display a prompt. -# Get ready for the input byt noting the time. +# Get ready for the input by noting the time. # main.7: movw $prompt,%si # Display callw putstr # prompt @@ -242,7 +260,7 @@ main.12: cbtw # Option # for rewriting to the disk. # movb %al,_OPT(%bp) # Save option - movw $FAKE,%si # Partition for write + movw $fake,%si # Partition for write movb (%si),%dl # Drive number movw %si,%bx # Partition for read cmpb $0x4,%al # F5 pressed? @@ -256,10 +274,10 @@ main.12: cbtw # Option # If not asked to do a write-back (flags 0x40) don't do one. # main.13: pushw %bx # Save - testb $0x40,_FLAGS(%bp) # No updates? + testb $FL_NOUPDATE,_FLAGS(%bp) # Skip update? jnz main.14 # Yes movw $start,%bx # Data to write - movb $0x3,%ah # Write sector + movw $0x301,%ax # Write 1 sector callw intx13 # to disk main.14: popw %si # Restore popf # Restore @@ -274,19 +292,22 @@ main.14: popw %si # Restore # load selected bootsector to the LOAD location in RAM. # If it fails to read or isn't marked bootable, treat it # as a bad selection. -# XXX what does %si carry? # main.15: movw $LOAD,%bx # Address for read - movb $0x2,%ah # Read sector + movw $0x201,%ax # Read 1 sector callw intx13 # from disk jc main.10 # If error cmpw $MAGIC,0x1fe(%bx) # Bootable? jne main.10 # No - pushw %si # Save - movw $crlf,%si # Leave some - callw puts # space - popw %si # Restore + callw putn # Leave some space jmp *%bx # Invoke bootstrap +/* + movw %bx,%si # Memory to dump + movw $SECTOR_SIZE/16,%dx # Lines to display + callw memdump # Dump memory +hang: jmp hang # Spin +*/ + # # Display routines # @@ -325,28 +346,91 @@ putchr: pushw %bx # Save retw # To caller # One-sector disk I/O routine +# +# Calling conventions: (assumes %si -> partition table entry) +# +# 0x1(%si) - byte - head +# 0x2(%si) - word - cylinder/sector +# 0x8(%si) - long - LBA to use if needed +# %ah - byte - operation, 2 = read, 3 = write +# %al - byte - sector count +# %dl - byte - drive number +# %es:(%bx) - void - buffer to use for transfer +# +# If the head == 0xff, and cylinder/sector == 0xffff, then try +# to use the EDD stuff with the LBA offset instead of CHS. However, +# use CHS if at all possible. intx13: movb 0x1(%si),%dh # Load head movw 0x2(%si),%cx # Load cylinder:sector - movb $0x1,%al # Sector count pushw %si # Save movw %sp,%di # Save - testb $0x80,_FLAGS(%bp) # Use packet interface? - jz intx13.1 # No + cmpb $0xff,%dh # Might we need LBA? + jne intx13.2 # No, just use CHS + cmpw $0xffff,%cx # Do we need LBA? + jne intx13.2 # No + testb $FL_PACKET,_FLAGS(%bp) # Try the packet interface? + jz intx13.2 # No + pushw %cx # Save + pushw %bx # Save + movw $0x55aa,%bx # Magic + pushw %ax # Save + movb $0x41,%ah # BIOS: EDD extensions + int $0x13 # present? + popw %ax # Restore + jc intx13.1 # Not present, use CHS + cmpw $0xaa55,%bx # Magic? + jne intx13.1 # Not present, use CHS + testb $0x1,%cl # Packet mode available? + jz intx13.1 # No, use CHS + orb $0x40,%ah # Use disk packet +intx13.1: popw %bx # Restore + popw %cx # Restore + testb $0x40,%ah # Using packet mode? + jz intx13.2 # No, so skip the rest pushl $0x0 # Set the pushl 0x8(%si) # LBA address pushw %es # Set the transfer pushw %bx # buffer address - push $0x1 # Block count - push $0x10 # Packet size + push $0x0 # Punch a hole in the stack + push $0x10 # Packet size movw %sp,%si # Packet pointer - decw %ax # Verify off - orb $0x40,%ah # Use disk packet -intx13.1: int $0x13 # BIOS: Disk I/O + xchgb %al,0x2(%si) # Set the block count in the + # packet and zero %al, + # turning verify off for writes +intx13.2: int $0x13 # BIOS: Disk I/O movw %di,%sp # Restore popw %si # Restore retw # To caller + .org PRT_OFF-0xe,0x90 +# +# These values are sometimes changed before writing back to the drive +# Be especially careful that nxtdrv: must come after drive:, as it +# is part of the same string. +# +# Note that the 'drive' string variable is used as the second signature +# check in boot0cfg(8). +# +version_minor: .byte 0x1 # minor version +version_major: .byte 0x1 # major version +drive: .ascii "Drive " +nxtdrv: .byte 0x0 # Next drive number +opt: .byte 0x0 # Option +setdrv: .byte 0x80 # Drive to force +flags: .byte FLAGS # Flags +ticks: .word TICKS # Delay + +# +# here is the 64 byte partition table that fdisk would fiddle with. +# +partbl: .fill 0x40,0x1,0x0 # Partition table + .word MAGIC # Magic number + +# +# start of sector two.. ugh +# + .org SECTOR_SIZE,0x90 # Menu strings item: .ascii " "; .byte ' '|0x80 @@ -359,12 +443,14 @@ tables: # # These entries identify invalid or NON BOOT types and partitions. # - .byte 0x0, 0x5, 0xf +table0: .byte 0x0, 0x5, 0xf +table0_end: # # These valuse indicate botable types we know the names of # - .byte 0x1, 0x4, 0x6, 0xb, 0xc, 0xe, 0x63, 0x83 - .byte 0xa5, 0xa6, 0xa9 +table1: .byte 0x1, 0x4, 0x6, 0x7, 0xb, 0xc, 0xe, 0x63, 0x83 + .byte 0xa5, 0xa6, 0xa9, 0xb7 +table1_end: # # These are offsets that match the known names above and point to the strings # that will be printed. @@ -373,40 +459,92 @@ tables: .byte os_dos-. # DOS .byte os_dos-. # DOS .byte os_dos-. # DOS - .byte os_dos-. # Windows - .byte os_dos-. # Windows - .byte os_dos-. # Windows + .byte os_nt-. # NT or OS/2 + .byte os_windows-. # Windows + .byte os_windows-. # Windows + .byte os_windows-. # Windows .byte os_unix-. # UNIX .byte os_linux-. # Linux .byte os_freebsd-. # FreeBSD - .byte os_bsd-. # OpenBSD - .byte os_bsd-. # NetBSD + .byte os_openbsd-. # OpenBSD + .byte os_netbsd-. # NetBSD + .byte os_bsdos-. # BSD/OS # # And here are the strings themselves. 0x80 or'd into a byte indicates # the end of the string. (not so great for Russians but...) # -os_misc: .ascii "?"; .byte '?'|0x80 -os_dos: .ascii "DO"; .byte 'S'|0x80 -os_unix: .ascii "UNI"; .byte 'X'|0x80 -os_linux: .ascii "Linu"; .byte 'x'|0x80 -os_freebsd: .ascii "Free" -os_bsd: .ascii "BS"; .byte 'D'|0x80 +os_misc: .ascii "Unknow"; .byte 'n'|0x80 +os_dos: .ascii "DO"; .byte 'S'|0x80 +os_nt: .ascii "Windows N"; .byte 'T'|0x80 +os_windows: .ascii "Window"; .byte 's'|0x80 +os_unix: .ascii "UNI"; .byte 'X'|0x80 +os_linux: .ascii "Linu"; .byte 'x'|0x80 +os_freebsd: .ascii "FreeBS"; .byte 'D'|0x80 +os_openbsd: .ascii "OpenBS"; .byte 'D'|0x80 +os_netbsd: .ascii "NetBS"; .byte 'D'|0x80 +os_bsdos: .ascii "BSD/O"; .byte 'S'|0x80 - .org PRT_OFF-0xc,0x90 # -# These values are sometimes changed before writing back to the drive -# Be especially careful that nxtdrv: must come after drive:, as it -# is part of the same string. -# -drive: .ascii "Drive " -nxtdrv: .byte 0x0 # Next drive number -opt: .byte 0x0 # Option -setdrv: .byte 0x80 # Drive to force -flags: .byte FLAGS # Flags -ticks: .word TICKS # Delay +# A set of functions to print out various parts of %ax in hex +# +hex16: callw hex16.1 # Do upper 8 +hex16.1: xchgb %ah,%al # Save/restore +hex8: push %ax # Save + shrb $0x4,%al # Do upper + callw 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 + push %ax # Save + callw putchr # Print char + pop %ax # Restore + retw # (Recursive) # -# here is the 64 byte partition table that fdisk would fiddle with. -# -partbl: .fill 0x40,0x1,0x0 # Partition table - .word MAGIC # Magic number +# Function to display a hexdump of memory. Call with: +# +# %dx - word - number of lines to display, each line is 16 bytes +# %ds:(%si) - caddr_t - memory to display +# +memdump: movw %si,%ax # Display the + callw hex16 # memory offset + movb $':',%al # Output a seperator + callw putchr # between the + movb $' ',%al # offset and + callw putchr # the data + push %si # Save %si + movw $16,%cx # Bytes per line +memdump.1: lodsb # Get next byte + callw hex8 # and display it + movb $' ',%al # Determine which + cmpb $9,%cl # seperator + jne memdump.2 # to use + movb $'-',%al # and then +memdump.2: callw putchr # display it + loop memdump.1 # Next byte + movb $'|',%al # Start of character + callw putchr # display + pop %si # Restore %si + movb $16,%cl # Bytes per line +memdump.3: lodsb # Get next byte + cmpb $32,%al # Control character? + jb memdump.4 # Yes, so modify + cmpb $0x80,%al # Upper ASCII? + jb memdump.5 # No, use raw characer +memdump.4: movb $'.',%al # Use '.' instead of bad char +memdump.5: callw putchr # Output character + loop memdump.3 # Do whole line + movb $'|',%al # Start of character + callw putchr # display + push %si # Save %si + callw putn # New line + pop %si # Restore %si + dec %dx # Done yet? + jnz memdump # No, keep going + retw # Yes, return + + .org SECTOR_SIZE*NUM_SECTORS, 0x0 +fake: |