Index: sys/boot/i386/Makefile =================================================================== --- sys/boot/i386/Makefile +++ sys/boot/i386/Makefile @@ -2,8 +2,8 @@ .include -SUBDIR= mbr pmbr boot0 boot0sio btx boot2 cdboot gptboot kgzldr \ - libi386 libfirewire loader +SUBDIR= mbr pmbr pmbrsio boot0 boot0sio btx boot2 cdboot gptboot \ + kgzldr libi386 libfirewire loader # special boot programs, 'self-extracting boot2+loader' SUBDIR+= pxeldr Index: sys/boot/i386/Makefile.mbr =================================================================== --- sys/boot/i386/Makefile.mbr +++ sys/boot/i386/Makefile.mbr @@ -1,84 +1,44 @@ # $FreeBSD: head/sys/boot/i386/boot0/Makefile 264400 2014-04-13 05:21:56Z imp $ -PROG?= boot0 -STRIP= -BINMODE=${NOBINMODE} -MAN= -SRCS= ${PROG}.S - -# Additional options that you can specify with make OPTS="..." -# (these only apply to boot0.S) -# -# -DVOLUME_SERIAL support volume serial number (NT, XP, Vista) -# -DSIO do I/O using COM1: -# -DPXE fallback to INT18/PXE with F6 -# -DCHECK_DRIVE enable checking drive number -# -DONLY_F_KEYS accept only Fx keys in console -# -DTEST print drive number on entry -# -OPTS ?= -DVOLUME_SERIAL -DPXE -CFLAGS += ${OPTS} - -# Flags used in the boot0.S code: -# 0x0f all valid partitions enabled. -# 0x80 'packet', use BIOS EDD (LBA) extensions instead of CHS -# to read from disk. boot0.S does not check that the extensions -# are supported, but all modern BIOSes should have them. -# 0x40 'noupdate', disable writing boot0 back to disk so that -# the current selection is not preserved across reboots. -# 0x20 'setdrv', override the drive number supplied by the bios -# with the one in the boot sector. - -# Default boot flags: -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 -# 0xb6 (182d) corresponds to 10 seconds. -BOOT_BOOT0_TICKS?= 0xb6 +# Shared bits for various i386 master boot records -# The base address that we the boot0 code to to run it. Don't change this -# unless you are glutton for punishment. +# The base address that we relocate the boot0 code to prior to running it. +# Don't change this unless you are glutton for punishment. BOOT_BOOT0_ORG?= 0x600 -# Comm settings for boot0sio. +# Comm settings for boot0sio/pmbrsio. # Bit(s) Description # 7-5 data rate (110,150,300,600,1200,2400,4800,9600 bps) # 4-3 parity (00 or 10 = none, 01 = odd, 11 = even) # 2 stop bits (set = 2, clear = 1) # 1-0 data bits (00 = 5, 01 = 6, 10 = 7, 11 = 8) -.if !defined(BOOT_BOOT0_COMCONSOLE_SPEED) +.if !defined(BOOT_BIOS_COMSONSOLE_SPEED) BOOT_COMCONSOLE_SPEED?= 9600 .if ${BOOT_COMCONSOLE_SPEED} == 9600 -BOOT_BOOT0_COMCONSOLE_SPEED= "7 << 5 + 3" +BOOT_BIOS_COMSONSOLE_SPEED= "7 << 5 + 3" .elif ${BOOT_COMCONSOLE_SPEED} == 4800 -BOOT_BOOT0_COMCONSOLE_SPEED= "6 << 5 + 3" +BOOT_BIOS_COMSONSOLE_SPEED= "6 << 5 + 3" .elif ${BOOT_COMCONSOLE_SPEED} == 2400 -BOOT_BOOT0_COMCONSOLE_SPEED= "5 << 5 + 3" +BOOT_BIOS_COMSONSOLE_SPEED= "5 << 5 + 3" .elif ${BOOT_COMCONSOLE_SPEED} == 1200 -BOOT_BOOT0_COMCONSOLE_SPEED= "4 << 5 + 3" +BOOT_BIOS_COMSONSOLE_SPEED= "4 << 5 + 3" .elif ${BOOT_COMCONSOLE_SPEED} == 600 -BOOT_BOOT0_COMCONSOLE_SPEED= "3 << 5 + 3" +BOOT_BIOS_COMSONSOLE_SPEED= "3 << 5 + 3" .elif ${BOOT_COMCONSOLE_SPEED} == 300 -BOOT_BOOT0_COMCONSOLE_SPEED= "2 << 5 + 3" +BOOT_BIOS_COMSONSOLE_SPEED= "2 << 5 + 3" .elif ${BOOT_COMCONSOLE_SPEED} == 150 -BOOT_BOOT0_COMCONSOLE_SPEED= "1 << 5 + 3" +BOOT_BIOS_COMSONSOLE_SPEED= "1 << 5 + 3" .elif ${BOOT_COMCONSOLE_SPEED} == 110 -BOOT_BOOT0_COMCONSOLE_SPEED= "0 << 5 + 3" +BOOT_BIOS_COMSONSOLE_SPEED= "0 << 5 + 3" .else -BOOT_BOOT0_COMCONSOLE_SPEED= "7 << 5 + 3" +BOOT_BIOS_COMSONSOLE_SPEED= "7 << 5 + 3" .endif .endif -CFLAGS+=-DFLAGS=${BOOT_BOOT0_FLAGS} \ - -DTICKS=${BOOT_BOOT0_TICKS} \ - -DCOMSPEED=${BOOT_BOOT0_COMCONSOLE_SPEED} +CFLAGS+=-DCOMSPEED=${BOOT_BIOS_COMSONSOLE_SPEED} LDFLAGS=-e start -Ttext ${BOOT_BOOT0_ORG} -Wl,-N,-S,--oformat,binary -.include +CFLAGS+= ${CFLAGS.${.IMPSRC:T}} -# XXX: clang integrated-as doesn't grok .codeNN directives yet -CFLAGS.boot0.S= ${CLANG_NO_IAS} -CFLAGS.boot0ext.S= ${CLANG_NO_IAS} -CFLAGS+= ${CFLAGS.${.IMPSRC:T}} +.include Index: sys/boot/i386/boot0/Makefile =================================================================== --- sys/boot/i386/boot0/Makefile +++ sys/boot/i386/boot0/Makefile @@ -37,48 +37,12 @@ # 0xb6 (182d) corresponds to 10 seconds. BOOT_BOOT0_TICKS?= 0xb6 -# The base address that we the boot0 code to to run it. Don't change this -# unless you are glutton for punishment. -BOOT_BOOT0_ORG?= 0x600 - -# Comm settings for boot0sio. -# Bit(s) Description -# 7-5 data rate (110,150,300,600,1200,2400,4800,9600 bps) -# 4-3 parity (00 or 10 = none, 01 = odd, 11 = even) -# 2 stop bits (set = 2, clear = 1) -# 1-0 data bits (00 = 5, 01 = 6, 10 = 7, 11 = 8) -.if !defined(BOOT_BOOT0_COMCONSOLE_SPEED) -BOOT_COMCONSOLE_SPEED?= 9600 -.if ${BOOT_COMCONSOLE_SPEED} == 9600 -BOOT_BOOT0_COMCONSOLE_SPEED= "7 << 5 + 3" -.elif ${BOOT_COMCONSOLE_SPEED} == 4800 -BOOT_BOOT0_COMCONSOLE_SPEED= "6 << 5 + 3" -.elif ${BOOT_COMCONSOLE_SPEED} == 2400 -BOOT_BOOT0_COMCONSOLE_SPEED= "5 << 5 + 3" -.elif ${BOOT_COMCONSOLE_SPEED} == 1200 -BOOT_BOOT0_COMCONSOLE_SPEED= "4 << 5 + 3" -.elif ${BOOT_COMCONSOLE_SPEED} == 600 -BOOT_BOOT0_COMCONSOLE_SPEED= "3 << 5 + 3" -.elif ${BOOT_COMCONSOLE_SPEED} == 300 -BOOT_BOOT0_COMCONSOLE_SPEED= "2 << 5 + 3" -.elif ${BOOT_COMCONSOLE_SPEED} == 150 -BOOT_BOOT0_COMCONSOLE_SPEED= "1 << 5 + 3" -.elif ${BOOT_COMCONSOLE_SPEED} == 110 -BOOT_BOOT0_COMCONSOLE_SPEED= "0 << 5 + 3" -.else -BOOT_BOOT0_COMCONSOLE_SPEED= "7 << 5 + 3" -.endif -.endif - CFLAGS+=-DFLAGS=${BOOT_BOOT0_FLAGS} \ - -DTICKS=${BOOT_BOOT0_TICKS} \ - -DCOMSPEED=${BOOT_BOOT0_COMCONSOLE_SPEED} - -LDFLAGS=-e start -Ttext ${BOOT_BOOT0_ORG} -Wl,-N,-S,--oformat,binary + -DTICKS=${BOOT_BOOT0_TICKS} -.include # XXX: clang integrated-as doesn't grok .codeNN directives yet CFLAGS.boot0.S= ${CLANG_NO_IAS} CFLAGS.boot0ext.S= ${CLANG_NO_IAS} -CFLAGS+= ${CFLAGS.${.IMPSRC:T}} + +.include "${.CURDIR}/../Makefile.mbr" Index: sys/boot/i386/boot2/boot2.c =================================================================== --- sys/boot/i386/boot2/boot2.c +++ sys/boot/i386/boot2/boot2.c @@ -436,7 +436,10 @@ ioctrl = OPT_CHECK(RBX_DUAL) ? (IO_SERIAL|IO_KEYBOARD) : OPT_CHECK(RBX_SERIAL) ? IO_SERIAL : IO_KEYBOARD; if (DO_SIO) { - if (sio_init(115200 / comspeed) != 0) + /* If comspeed is set to 0, assume serial port has already + * been initialized in a previous boot stage. + */ + if (comspeed != 0 && sio_init(115200 / comspeed) != 0) ioctrl &= ~IO_SERIAL; } #endif Index: sys/boot/i386/mbr/Makefile =================================================================== --- sys/boot/i386/mbr/Makefile +++ sys/boot/i386/mbr/Makefile @@ -9,9 +9,6 @@ # MBR flags: 0x80 -- try packet interface (also known as EDD or LBA) BOOT_MBR_FLAGS?= 0x80 -ORG= 0x600 - AFLAGS+=--defsym FLAGS=${BOOT_MBR_FLAGS} -LDFLAGS=-e start -Ttext ${ORG} -Wl,-N,-S,--oformat,binary -.include +.include "${.CURDIR}/../Makefile.mbr" Index: sys/boot/i386/pmbr/Makefile =================================================================== --- sys/boot/i386/pmbr/Makefile +++ sys/boot/i386/pmbr/Makefile @@ -1,14 +1,12 @@ # $FreeBSD$ -PROG= pmbr +PROG?= pmbr STRIP= BINMODE=${NOBINMODE} MAN= -SRCS= ${PROG}.s +SRCS= ${PROG}.S -ORG= 0x600 +# XXX: clang integrated-as doesn't grok .codeNN directives yet +CFLAGS.pmbr.S= ${CLANG_NO_IAS} -AFLAGS+=--defsym FLAGS=${BOOT_MBR_FLAGS} -LDFLAGS=-e start -Ttext ${ORG} -Wl,-N,-S,--oformat,binary - -.include +.include "${.CURDIR}/../Makefile.mbr" Index: sys/boot/i386/pmbr/pmbr.S =================================================================== --- sys/boot/i386/pmbr/pmbr.S +++ sys/boot/i386/pmbr/pmbr.S @@ -212,18 +212,29 @@ err_rd: movw $msg_rd,%si # "I/O error loading jmp putstr # boot loader" -err_noboot: movw $msg_noboot,%si # "Missing boot - jmp putstr # loader" +err_noboot: movw $msg_noboot,%si # "Missing boot loader" + # fall through to putstr # # Output an ASCIZ string to the console via the BIOS. # -putstr.0: movw $0x7,%bx # Page:attribute +putstr: +#if defined(SIO) && COMSPEED != 0 + xorw %dx,%dx # Use COM1 + movw $COMSPEED,%ax # defined by Makefile + int $0x14 # BIOS: Serial init +#endif + lodsb # Get character + testb %al,%al # End of string? +putstr.0: jz putstr.0 # Yes: await reset +#ifndef SIO + movw $0x7,%bx # Page: attribute movb $0xe,%ah # BIOS: Display int $0x10 # character -putstr: lodsb # Get character - testb %al,%al # End of string? - jnz putstr.0 # No -putstr.1: jmp putstr.1 # Await reset +#else + movb $0x01,%ah # BIOS: Send + int $0x14 # character +#endif + jmp putstr # Next character msg_big: .asciz "Boot loader too large" msg_pt: .asciz "Invalid partition table" Index: sys/boot/i386/pmbr/pmbr.s =================================================================== --- sys/boot/i386/pmbr/pmbr.s +++ sys/boot/i386/pmbr/pmbr.s @@ -1,252 +0,0 @@ -#- -# Copyright (c) 2007 Yahoo!, Inc. -# All rights reserved. -# Written by: John Baldwin -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions -# are met: -# 1. Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# 2. Redistributions in binary form must reproduce the above copyright -# notice, this list of conditions and the following disclaimer in the -# documentation and/or other materials provided with the distribution. -# 3. Neither the name of the author nor the names of any co-contributors -# may be used to endorse or promote products derived from this software -# without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND -# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE -# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -# SUCH DAMAGE. -# -# $FreeBSD$ -# -# Partly from: src/sys/boot/i386/mbr/mbr.s 1.7 - -# A 512 byte PMBR boot manager that looks for a FreeBSD boot GPT partition -# and boots it. - - .set LOAD,0x7c00 # Load address - .set EXEC,0x600 # Execution address - .set MAGIC,0xaa55 # Magic: bootable - .set SECSIZE,0x200 # Size of a single disk sector - .set DISKSIG,440 # Disk signature offset - .set STACK,EXEC+SECSIZE*4 # Stack address - .set GPT_ADDR,STACK # GPT header address - .set GPT_SIG,0 - .set GPT_SIG_0,0x20494645 # "EFI " - .set GPT_SIG_1,0x54524150 # "PART" - .set GPT_MYLBA,24 - .set GPT_PART_LBA,72 - .set GPT_NPART,80 - .set GPT_PART_SIZE,84 - .set PART_ADDR,GPT_ADDR+SECSIZE # GPT partition array address - .set PART_TYPE,0 - .set PART_START_LBA,32 - .set PART_END_LBA,40 - .set DPBUF,PART_ADDR+SECSIZE - .set DPBUF_SEC,0x10 # Number of sectors - - .set NHRDRV,0x475 # Number of hard drives - - .globl start # Entry point - .code16 - -# -# Setup the segment registers for flat addressing and setup the stack. -# -start: cld # String ops inc - xorw %ax,%ax # Zero - movw %ax,%es # Address - movw %ax,%ds # data - movw %ax,%ss # Set up - movw $STACK,%sp # stack -# -# Relocate ourself to a lower address so that we have more room to load -# other sectors. -# - movw $main-EXEC+LOAD,%si # Source - movw $main,%di # Destination - movw $SECSIZE-(main-start),%cx # Byte count - rep # Relocate - movsb # code -# -# Jump to the relocated code. -# - jmp main-LOAD+EXEC # To relocated code -# -# Validate drive number in %dl. -# -main: cmpb $0x80,%dl # Drive valid? - jb main.1 # No - movb NHRDRV,%dh # Calculate the highest - addb $0x80,%dh # drive number available - cmpb %dh,%dl # Within range? - jb main.2 # Yes -main.1: movb $0x80,%dl # Assume drive 0x80 -# -# Load the GPT header and verify signature. Try LBA 1 for the primary one and -# the last LBA for the backup if it is broken. -# -main.2: call getdrvparams # Read drive parameters - movb $1,%dh # %dh := 1 (reading primary) -main.2a: movw $GPT_ADDR,%bx - movw $lba,%si - call read # Read header and check GPT sig - cmpl $GPT_SIG_0,GPT_ADDR+GPT_SIG - jnz main.2b - cmpl $GPT_SIG_1,GPT_ADDR+GPT_SIG+4 - jnz main.2b - jmp load_part -main.2b: cmpb $1,%dh # Reading primary? - jne err_pt # If no - invalid table found -# -# Try alternative LBAs from the last sector for the GPT header. -# -main.3: movb $0,%dh # %dh := 0 (reading backup) - movw $DPBUF+DPBUF_SEC,%si # %si = last sector + 1 - movw $lba,%di # %di = $lba -main.3a: decl (%si) # 0x0(%si) = last sec (0-31) - movw $2,%cx - rep - movsw # $lastsec--, copy it to $lba - jmp main.2a # Read the next sector -# -# Load a partition table sector from disk and look for a FreeBSD boot -# partition. -# -load_part: movw $GPT_ADDR+GPT_PART_LBA,%si - movw $PART_ADDR,%bx - call read -scan: movw %bx,%si # Compare partition UUID - movw $boot_uuid,%di # with FreeBSD boot UUID - movb $0x10,%cl - repe cmpsb - jnz next_part # Didn't match, next partition -# -# We found a boot partition. Load it into RAM starting at 0x7c00. -# - movw %bx,%di # Save partition pointer in %di - leaw PART_START_LBA(%di),%si - movw $LOAD/16,%bx - movw %bx,%es - xorw %bx,%bx -load_boot: push %si # Save %si - call read - pop %si # Restore - movl PART_END_LBA(%di),%eax # See if this was the last LBA - cmpl (%si),%eax - jnz next_boot - movl PART_END_LBA+4(%di),%eax - cmpl 4(%si),%eax - jnz next_boot - mov %bx,%es # Reset %es to zero - jmp LOAD # Jump to boot code -next_boot: incl (%si) # Next LBA - adcl $0,4(%si) - mov %es,%ax # Adjust segment for next - addw $SECSIZE/16,%ax # sector - cmp $0x9000,%ax # Don't load past 0x90000, - jae err_big # 545k should be enough for - mov %ax,%es # any boot code. :) - jmp load_boot -# -# Move to the next partition. If we walk off the end of the sector, load -# the next sector. We assume that partition entries are smaller than 64k -# and that they won't span a sector boundary. -# -# XXX: Should we int 0x18 instead of err_noboot if we hit the end of the table? -# -next_part: decl GPT_ADDR+GPT_NPART # Was this the last partition? - jz err_noboot - movw GPT_ADDR+GPT_PART_SIZE,%ax - addw %ax,%bx # Next partition - cmpw $PART_ADDR+0x200,%bx # Still in sector? - jb scan - incl GPT_ADDR+GPT_PART_LBA # Next sector - adcl $0,GPT_ADDR+GPT_PART_LBA+4 - jmp load_part -# -# Load a sector (64-bit LBA at %si) from disk %dl into %es:%bx by creating -# a EDD packet on the stack and passing it to the BIOS. Trashes %ax and %si. -# -read: pushl 0x4(%si) # Set the LBA - pushl 0x0(%si) # address - pushw %es # Set the address of - pushw %bx # the transfer buffer - pushw $0x1 # Read 1 sector - pushw $0x10 # Packet length - movw %sp,%si # Packer pointer - movw $0x4200,%ax # BIOS: LBA Read from disk - int $0x13 # Call the BIOS - add $0x10,%sp # Restore stack - jc err_rd # If error - ret -# -# Check the number of LBAs on the drive index %dx. Trashes %ax and %si. -# -getdrvparams: - movw $DPBUF,%si # Set the address of result buf - movw $0x001e,(%si) # len - movw $0x4800,%ax # BIOS: Read Drive Parameters - int $0x13 # Call the BIOS - jc err_rd # "I/O error" if error - ret -# -# Various error message entry points. -# -err_big: movw $msg_big,%si # "Boot loader too - jmp putstr # large" - -err_pt: movw $msg_pt,%si # "Invalid partition - jmp putstr # table" - -err_rd: movw $msg_rd,%si # "I/O error loading - jmp putstr # boot loader" - -err_noboot: movw $msg_noboot,%si # "Missing boot - jmp putstr # loader" -# -# Output an ASCIZ string to the console via the BIOS. -# -putstr.0: movw $0x7,%bx # Page:attribute - movb $0xe,%ah # BIOS: Display - int $0x10 # character -putstr: lodsb # Get character - testb %al,%al # End of string? - jnz putstr.0 # No -putstr.1: jmp putstr.1 # Await reset - -msg_big: .asciz "Boot loader too large" -msg_pt: .asciz "Invalid partition table" -msg_rd: .asciz "I/O error loading boot loader" -msg_noboot: .asciz "Missing boot loader" - -lba: .quad 1 # LBA of GPT header - -boot_uuid: .long 0x83bd6b9d - .word 0x7f41 - .word 0x11dc - .byte 0xbe - .byte 0x0b - .byte 0x00 - .byte 0x15 - .byte 0x60 - .byte 0xb8 - .byte 0x4f - .byte 0x0f - - .org DISKSIG,0x90 -sig: .long 0 # OS Disk Signature - .word 0 # "Unknown" in PMBR - -partbl: .fill 0x10,0x4,0x0 # Partition table - .word MAGIC # Magic number Index: sys/boot/i386/pmbrsio/Makefile =================================================================== --- sys/boot/i386/pmbrsio/Makefile +++ sys/boot/i386/pmbrsio/Makefile @@ -1,8 +1,8 @@ # $FreeBSD$ -.PATH: ${.CURDIR}/../boot0 +.PATH: ${.CURDIR}/../pmbr -PROGNAME= boot0sio +PROGNAME= pmbrsio CFLAGS+= -DSIO -.include "${.CURDIR}/../boot0/Makefile" +.include "${.CURDIR}/../pmbr/Makefile"