? boot0 ? boot0.out Index: Makefile =================================================================== RCS file: /home/ncvs/src/sys/boot/i386/boot0/Makefile,v retrieving revision 1.16 diff -u -r1.16 Makefile --- Makefile 10 Jan 2002 21:40:33 -0000 1.16 +++ Makefile 10 Jan 2002 22:04:45 -0000 @@ -12,7 +12,7 @@ # the modified boot0 back to disk after running so that the selection made is # saved), packet mode (detect and use the BIOS EDD extensions if we try to # boot past the 1024 cylinder liimt), and booting from all valid slices. -BOOT_BOOT0_FLAGS?= 0xf +BOOT_BOOT0_FLAGS?= 0x8f # The number of timer ticks to wait for a keypress before assuming the default # selection. Since there are 18.2 ticks per second, the default value of Index: boot0.s =================================================================== RCS file: /home/ncvs/src/sys/boot/i386/boot0/boot0.s,v retrieving revision 1.25 diff -u -r1.25 boot0.s --- boot0.s 19 Dec 2000 00:17:36 -0000 1.25 +++ boot0.s 10 Jan 2002 22:04:45 -0000 @@ -15,33 +15,42 @@ # $FreeBSD: src/sys/boot/i386/boot0/boot0.s,v 1.25 2000/12/19 00:17:36 rnordier Exp $ -# 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,0xc # Table 1 size + .set TBL0SZ,table0_end-table0 # Table 0 size + .set TBL1SZ,table1_end-table1 # Table 1 size .set MAGIC,0xaa55 # Magic: bootable - .set B0MAGIC,0xbb66 # Identification .set KEY_ENTER,0x1c # Enter key scan code .set KEY_F1,0x3b # F1 key scan code # +# Flag bits +# + .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 sector (%ebp). +# Accessed with negative offsets from the end of the relocated sectors (%bp). # - .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 _PRT_END,(FAKE-(ORIGIN+SECTOR_SIZE*(NUM_SECTORS-1))) + .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 @@ -53,49 +62,58 @@ # segments start at 0. # The stack is immediately 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 the block, # by using negative offsets. # - movw %di,%bp # Address variables - movb $0x8,%cl # Words to clear + movw $fake,%bp # Address variables + movw %bp,%di # %di used in stosw + movw $0x8,%cx # Words to clear rep # Zero stosw # them + incb -0xe(%di) # Sector number 1 # -# Relocate to the new copy of the code. -# - incb -0xe(%di) # Sector number - jmp main-LOAD+ORIGIN # 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? - jnz main.1 # Yes + testb $FL_SETDRV,LOAD+flags-start # Set number drive? + jnz boot.1 # Yes testb %dl,%dl # Drive number valid? - js main.2 # Possibly (0x80 set) -main.1: movb _SETDRV(%bp),%dl # Drive number to use + js boot.2 # Possibly (0x80 set) +boot.1: movb LOAD+setdrv-start,%dl # Drive number to use +boot.2: +# +# 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. +# + jmp main+ORIGIN-LOAD # To relocated code # # Whatever we decided to use, now store it into the fake # partition entry that lives in the data space above us. # -main.2: movb %dl,_FAKE(%bp) # Save drive number +main: movb %dl,_FAKE(%bp) # Save drive number callw putn # To new line pushw %dx # Save drive number # @@ -134,7 +152,7 @@ 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 @@ -175,7 +193,7 @@ 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 @@ -243,7 +261,7 @@ # 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? @@ -257,10 +275,10 @@ # 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 @@ -275,19 +293,16 @@ # 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 + # # Display routines # @@ -326,28 +341,91 @@ 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 @@ -360,12 +438,14 @@ # # These entries identify invalid or NON BOOT types and partitions. # - .byte 0x0, 0x5, 0xf +table0: .byte 0x0, 0x5, 0xf +table0_end: # # These values indicate bootable types we know the names of # - .byte 0x1, 0x4, 0x6, 0xb, 0xc, 0xe, 0x63, 0x83 +table1: .byte 0x1, 0x4, 0x6, 0x7, 0xb, 0xc, 0xe, 0x63, 0x83 .byte 0x9f, 0xa5, 0xa6, 0xa9 +table1_end: # # These are offsets that match the known names above and point to the strings # that will be printed. @@ -374,44 +454,35 @@ .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_bsd-. # BSD/OS + .byte os_bsdos-. # BSD/OS .byte os_freebsd-. # FreeBSD - .byte os_bsd-. # OpenBSD - .byte os_bsd-. # NetBSD + .byte os_openbsd-. # OpenBSD + .byte os_netbsd-. # NetBSD # # 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 - - .org PRT_OFF-0xe,0x90 - - .word B0MAGIC # Magic number - +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 + +# +# Fake partition entry created at the end of the table used when loading +# boot0 at the very beginning and when loading an MBR from another disk when +# F5 is pressed. # -# 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 - -# -# here is the 64 byte partition table that fdisk would fiddle with. -# -partbl: .fill 0x40,0x1,0x0 # Partition table - .word MAGIC # Magic number + .org SECTOR_SIZE*NUM_SECTORS, 0x0 +fake: