Index: sys/boot/Makefile =================================================================== --- sys/boot/Makefile +++ sys/boot/Makefile @@ -9,7 +9,7 @@ SUBDIR+= forth .endif -SUBDIR+= common +SUBDIR+= man .include Index: sys/boot/Makefile.inc =================================================================== --- sys/boot/Makefile.inc +++ sys/boot/Makefile.inc @@ -2,15 +2,11 @@ .include +.include "defs.mk" + .if !defined(__BOOT_MAKEFILE_INC__) __BOOT_MAKEFILE_INC__=${MFILE} -SASRC=${SRCTOP}/sys/boot/libsa -# Normal Standalone library -LIBSA=${OBJTOP}/sys/boot/libsa/libsa.a -# Standalone library compiled for 32-bit version of the processor -LIBSA32=${OBJTOP}/sys/boot/libsa32/libsa32.a - CFLAGS+=-I${SASRC} SSP_CFLAGS= Index: sys/boot/arm/uboot/Makefile =================================================================== --- sys/boot/arm/uboot/Makefile +++ sys/boot/arm/uboot/Makefile @@ -19,60 +19,17 @@ CWARNFLAGS.self_reloc.c+= -Wno-error=maybe-uninitialized .endif -.if !defined(LOADER_NO_DISK_SUPPORT) -LOADER_DISK_SUPPORT?= yes -.else -LOADER_DISK_SUPPORT= no -.endif LOADER_UFS_SUPPORT?= yes LOADER_CD9660_SUPPORT?= no +LOADER_MSDOS_SUPPORT?= no LOADER_EXT2FS_SUPPORT?= no -.if ${MK_NAND} != "no" -LOADER_NANDFS_SUPPORT?= yes -.else -LOADER_NANDFS_SUPPORT?= no -.endif LOADER_NET_SUPPORT?= yes LOADER_NFS_SUPPORT?= yes LOADER_TFTP_SUPPORT?= no LOADER_GZIP_SUPPORT?= no LOADER_BZIP2_SUPPORT?= no -.if ${MK_FDT} != "no" -LOADER_FDT_SUPPORT= yes -.else -LOADER_FDT_SUPPORT= no -.endif +LOADER_FDT_SUPPORT= ${MK_FDT} -.if ${LOADER_DISK_SUPPORT} == "yes" -CFLAGS+= -DLOADER_DISK_SUPPORT -.endif -.if ${LOADER_UFS_SUPPORT} == "yes" -CFLAGS+= -DLOADER_UFS_SUPPORT -.endif -.if ${LOADER_CD9660_SUPPORT} == "yes" -CFLAGS+= -DLOADER_CD9660_SUPPORT -.endif -.if ${LOADER_EXT2FS_SUPPORT} == "yes" -CFLAGS+= -DLOADER_EXT2FS_SUPPORT -.endif -.if ${LOADER_NANDFS_SUPPORT} == "yes" -CFLAGS+= -DLOADER_NANDFS_SUPPORT -.endif -.if ${LOADER_GZIP_SUPPORT} == "yes" -CFLAGS+= -DLOADER_GZIP_SUPPORT -.endif -.if ${LOADER_BZIP2_SUPPORT} == "yes" -CFLAGS+= -DLOADER_BZIP2_SUPPORT -.endif -.if ${LOADER_NET_SUPPORT} == "yes" -CFLAGS+= -DLOADER_NET_SUPPORT -.endif -.if ${LOADER_NFS_SUPPORT} == "yes" -CFLAGS+= -DLOADER_NFS_SUPPORT -.endif -.if ${LOADER_TFTP_SUPPORT} == "yes" -CFLAGS+= -DLOADER_TFTP_SUPPORT -.endif .if ${LOADER_FDT_SUPPORT} == "yes" CFLAGS+= -I${.CURDIR}/../../fdt CFLAGS+= -I${.OBJDIR}/../../fdt @@ -81,18 +38,8 @@ LIBFDT= ${.OBJDIR}/../../fdt/libfdt.a .endif -.if ${MK_FORTH} != "no" -# Enable BootForth -BOOT_FORTH= yes -CFLAGS+= -DBOOT_FORTH -I${.CURDIR}/../../ficl -CFLAGS+= -I${.CURDIR}/../../ficl/arm -LIBFICL= ${.OBJDIR}/../../ficl/libficl.a -.endif - # Always add MI sources -.PATH: ${.CURDIR}/../../common -.include "${.CURDIR}/../../common/Makefile.inc" -CFLAGS+= -I${.CURDIR}/../../common +.include "../../loader.mk" CFLAGS+= -I. CLEANFILES+= loader.help @@ -124,7 +71,7 @@ loader.help: help.common help.uboot ${.CURDIR}/../../fdt/help.fdt cat ${.ALLSRC} | \ - awk -f ${.CURDIR}/../../common/merge_help.awk > ${.TARGET} + awk -f ${LDR_MI}/merge_help.awk > ${.TARGET} ldscript.abs: echo "UBLDR_LOADADDR = ${UBLDR_LOADADDR};" >${.TARGET} Index: sys/boot/common/Makefile =================================================================== --- /dev/null +++ sys/boot/common/Makefile @@ -1,10 +0,0 @@ -# $FreeBSD$ - -.include - -MAN+= loader.8 -.if ${MK_ZFS} != "no" -MAN+= zfsloader.8 -.endif - -.include Index: sys/boot/common/loader.8 =================================================================== --- /dev/null +++ sys/boot/common/loader.8 @@ -1,1101 +0,0 @@ -.\" Copyright (c) 1999 Daniel C. Sobral -.\" All rights reserved. -.\" -.\" 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. -.\" -.\" 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$ -.\" -.Dd November 18, 2015 -.Dt LOADER 8 -.Os -.Sh NAME -.Nm loader -.Nd kernel bootstrapping final stage -.Sh DESCRIPTION -The program called -.Nm -is the final stage of -.Fx Ns 's -kernel bootstrapping process. -On IA32 (i386) architectures, it is a -.Pa BTX -client. -It is linked statically to -.Xr libstand 3 -and usually located in the directory -.Pa /boot . -.Pp -It provides a scripting language that can be used to -automate tasks, do pre-configuration or assist in recovery -procedures. -This scripting language is roughly divided in -two main components. -The smaller one is a set of commands -designed for direct use by the casual user, called "builtin -commands" for historical reasons. -The main drive behind these commands is user-friendliness. -The bigger component is an -.Tn ANS -Forth compatible Forth interpreter based on FICL, by -.An John Sadler . -.Pp -During initialization, -.Nm -will probe for a console and set the -.Va console -variable, or set it to serial console -.Pq Dq Li comconsole -if the previous boot stage used that. -If multiple consoles are selected, they will be listed separated by spaces. -Then, devices are probed, -.Va currdev -and -.Va loaddev -are set, and -.Va LINES -is set to 24. -Next, -.Tn FICL -is initialized, the builtin words are added to its vocabulary, and -.Pa /boot/boot.4th -is processed if it exists. -No disk switching is possible while that file is being read. -The inner interpreter -.Nm -will use with -.Tn FICL -is then set to -.Ic interpret , -which is -.Tn FICL Ns 's -default. -After that, -.Pa /boot/loader.rc -is processed if available. -These files are processed through the -.Ic include -command, which reads all of them into memory before processing them, -making disk changes possible. -.Pp -At this point, if an -.Ic autoboot -has not been tried, and if -.Va autoboot_delay -is not set to -.Dq Li NO -(not case sensitive), then an -.Ic autoboot -will be tried. -If the system gets past this point, -.Va prompt -will be set and -.Nm -will engage interactive mode. -Please note that historically even when -.Va autoboot_delay -is set to -.Dq Li 0 -user will be able to interrupt autoboot process by pressing some key -on the console while kernel and modules are being loaded. -In some -cases such behaviour may be undesirable, to prevent it set -.Va autoboot_delay -to -.Dq Li -1 , -in this case -.Nm -will engage interactive mode only if -.Ic autoboot -has failed. -.Sh BUILTIN COMMANDS -In -.Nm , -builtin commands take parameters from the command line. -Presently, -the only way to call them from a script is by using -.Pa evaluate -on a string. -If an error condition occurs, an exception will be generated, -which can be intercepted using -.Tn ANS -Forth exception handling -words. -If not intercepted, an error message will be displayed and -the interpreter's state will be reset, emptying the stack and restoring -interpreting mode. -.Pp -The builtin commands available are: -.Pp -.Bl -tag -width Ds -compact -.It Ic autoboot Op Ar seconds Op Ar prompt -Proceeds to bootstrap the system after a number of seconds, if not -interrupted by the user. -Displays a countdown prompt -warning the user the system is about to be booted, -unless interrupted by a key press. -The kernel will be loaded first if necessary. -Defaults to 10 seconds. -.Pp -.It Ic bcachestat -Displays statistics about disk cache usage. -For debugging only. -.Pp -.It Ic boot -.It Ic boot Ar kernelname Op Cm ... -.It Ic boot Fl flag Cm ... -Immediately proceeds to bootstrap the system, loading the kernel -if necessary. -Any flags or arguments are passed to the kernel, but they -must precede the kernel name, if a kernel name is provided. -.Pp -.Em WARNING : -The behavior of this builtin is changed if -.Xr loader.4th 8 -is loaded. -.Pp -.It Ic echo Xo -.Op Fl n -.Op Aq message -.Xc -Displays text on the screen. -A new line will be printed unless -.Fl n -is specified. -.Pp -.It Ic heap -Displays memory usage statistics. -For debugging purposes only. -.Pp -.It Ic help Op topic Op subtopic -Shows help messages read from -.Pa /boot/loader.help . -The special topic -.Em index -will list the topics available. -.Pp -.It Ic include Ar file Op Ar -Process script files. -Each file, in turn, is completely read into memory, -and then each of its lines is passed to the command line interpreter. -If any error is returned by the interpreter, the include -command aborts immediately, without reading any other files, and -returns an error itself (see -.Sx ERRORS ) . -.Pp -.It Ic load Xo -.Op Fl t Ar type -.Ar file Cm ... -.Xc -Loads a kernel, kernel loadable module (kld), disk image, -or file of opaque contents tagged as being of the type -.Ar type . -Kernel and modules can be either in a.out or ELF format. -Any arguments passed after the name of the file to be loaded -will be passed as arguments to that file. -Use the -.Li md_image -type to make the kernel create a file-backed -.Xr md 4 -disk. -This is useful for booting from a temporary rootfs. -Currently, argument passing does not work for the kernel. -.Pp -.It Ic load_geli Xo -.Op Fl n Ar keyno -.Ar prov Ar file -.Xc -Loads a -.Xr geli 8 -encryption keyfile for the given provider name. -The key index can be specified via -.Ar keyno -or will default to zero. -.Pp -.It Ic ls Xo -.Op Fl l -.Op Ar path -.Xc -Displays a listing of files in the directory -.Ar path , -or the root directory if -.Ar path -is not specified. -If -.Fl l -is specified, file sizes will be shown too. -.Pp -.It Ic lsdev Op Fl v -Lists all of the devices from which it may be possible to load modules. -If -.Fl v -is specified, more details are printed. -.Pp -.It Ic lsmod Op Fl v -Displays loaded modules. -If -.Fl v -is specified, more details are shown. -.Pp -.It Ic more Ar file Op Ar -Display the files specified, with a pause at each -.Va LINES -displayed. -.Pp -.It Ic pnpscan Op Fl v -Scans for Plug-and-Play devices. -This is not functional at present. -.Pp -.It Ic read Xo -.Op Fl t Ar seconds -.Op Fl p Ar prompt -.Op Va variable -.Xc -Reads a line of input from the terminal, storing it in -.Va variable -if specified. -A timeout can be specified with -.Fl t , -though it will be canceled at the first key pressed. -A prompt may also be displayed through the -.Fl p -flag. -.Pp -.It Ic reboot -Immediately reboots the system. -.Pp -.It Ic set Ar variable -.It Ic set Ar variable Ns = Ns Ar value -Set loader's environment variables. -.Pp -.It Ic show Op Va variable -Displays the specified variable's value, or all variables and their -values if -.Va variable -is not specified. -.Pp -.It Ic unload -Remove all modules from memory. -.Pp -.It Ic unset Va variable -Removes -.Va variable -from the environment. -.Pp -.It Ic \&? -Lists available commands. -.El -.Ss BUILTIN ENVIRONMENT VARIABLES -The -.Nm -has actually two different kinds of -.Sq environment -variables. -There are ANS Forth's -.Em environmental queries , -and a separate space of environment variables used by builtins, which -are not directly available to Forth words. -It is the latter type that this section covers. -.Pp -Environment variables can be set and unset through the -.Ic set -and -.Ic unset -builtins, and can have their values interactively examined through the -use of the -.Ic show -builtin. -Their values can also be accessed as described in -.Sx BUILTIN PARSER . -.Pp -Notice that these environment variables are not inherited by any shell -after the system has been booted. -.Pp -A few variables are set automatically by -.Nm . -Others can affect the behavior of either -.Nm -or the kernel at boot. -Some options may require a value, -while others define behavior just by being set. -Both types of builtin variables are described below. -.Bl -tag -width bootfile -.It Va autoboot_delay -Number of seconds -.Ic autoboot -will wait before booting. -If this variable is not defined, -.Ic autoboot -will default to 10 seconds. -.Pp -If set to -.Dq Li NO , -no -.Ic autoboot -will be automatically attempted after processing -.Pa /boot/loader.rc , -though explicit -.Ic autoboot Ns 's -will be processed normally, defaulting to 10 seconds delay. -.Pp -If set to -.Dq Li 0 , -no delay will be inserted, but user still will be able to interrupt -.Ic autoboot -process and escape into the interactive mode by pressing some key -on the console while kernel and -modules are being loaded. -.Pp -If set to -.Dq Li -1 , -no delay will be inserted and -.Nm -will engage interactive mode only if -.Ic autoboot -has failed for some reason. -.It Va boot_askname -Instructs the kernel to prompt the user for the name of the root device -when the kernel is booted. -.It Va boot_cdrom -Instructs the kernel to try to mount the root file system from CD-ROM. -.It Va boot_ddb -Instructs the kernel to start in the DDB debugger, rather than -proceeding to initialize when booted. -.It Va boot_dfltroot -Instructs the kernel to mount the statically compiled-in root file system. -.It Va boot_gdb -Selects gdb-remote mode for the kernel debugger by default. -.It Va boot_multicons -Enables multiple console support in the kernel early on boot. -In a running system, console configuration can be manipulated -by the -.Xr conscontrol 8 -utility. -.It Va boot_mute -All console output is suppressed when console is muted. -In a running system, the state of console muting can be manipulated by the -.Xr conscontrol 8 -utility. -.It Va boot_pause -During the device probe, pause after each line is printed. -.It Va boot_serial -Force the use of a serial console even when an internal console -is present. -.It Va boot_single -Prevents the kernel from initiating a multi-user startup; instead, -a single-user mode will be entered when the kernel has finished -device probing. -.It Va boot_verbose -Setting this variable causes extra debugging information to be printed -by the kernel during the boot phase. -.It Va bootfile -List of semicolon-separated search path for bootable kernels. -The default is -.Dq Li kernel . -.It Va comconsole_speed -Defines the speed of the serial console (i386 and amd64 only). -If the previous boot stage indicated that a serial console is in use -then this variable is initialized to the current speed of the console -serial port. -Otherwise it is set to 9600 unless this was overridden using the -.Va BOOT_COMCONSOLE_SPEED -variable when -.Nm -was compiled. -Changes to the -.Va comconsole_speed -variable take effect immediately. -.It Va comconsole_port -Defines the base i/o port used to access console UART -(i386 and amd64 only). -If the variable is not set, its assumed value is 0x3F8, which -corresponds to PC port COM1, unless overridden by -.Va BOOT_COMCONSOLE_PORT -variable during the compilation of -.Nm . -Setting the -.Va comconsole_port -variable automatically set -.Va hw.uart.console -environment variable to provide a hint to kernel for location of the console. -Loader console is changed immediately after variable -.Va comconsole_port -is set. -.It Va comconsole_pcidev -Defines the location of a PCI device of the 'simple communication' -class to be used as the serial console UART (i386 and amd64 only). -The syntax of the variable is -.Li 'bus:device:function[:bar]' , -where all members must be numeric, with possible -.Li 0x -prefix to indicate a hexadecimal value. -The -.Va bar -member is optional and assumed to be 0x10 if omitted. -The bar must decode i/o space. -Setting the variable -.Va comconsole_pcidev -automatically sets the variable -.Va comconsole_port -to the base of the selected bar, and hint -.Va hw.uart.console . -Loader console is changed immediately after variable -.Va comconsole_pcidev -is set. -.It Va console -Defines the current console or consoles. -Multiple consoles may be specified. -In that case, the first listed console will become the default console for -userland output (e.g.\& from -.Xr init 8 ) . -.It Va currdev -Selects the default device. -Syntax for devices is odd. -.It Va dumpdev -Sets the device for kernel dumps. -This can be used to ensure that a device is configured before the corresponding -.Va dumpdev -directive from -.Xr rc.conf 5 -has been processed, allowing kernel panics that happen during the early stages -of boot to be captured. -.It Va init_chroot -If set to a valid directory in the root file system, it causes -.Xr init 8 -to perform a -.Xr chroot 2 -operation on that directory, making it the new root directory. -That happens before entering single-user mode or multi-user -mode (but after executing the -.Va init_script -if enabled). -This functionality has generally been eclipsed by rerooting. -See -.Xr reboot 8 -.Fl r -for details. -.It Va init_path -Sets the list of binaries which the kernel will try to run as the initial -process. -The first matching binary is used. -The default list is -.Dq Li /sbin/init:/sbin/oinit:/sbin/init.bak:\:/rescue/init . -.It Va init_script -If set to a valid file name in the root file system, -instructs -.Xr init 8 -to run that script as the very first action, -before doing anything else. -Signal handling and exit code interpretation is similar to -running the -.Pa /etc/rc -script. -In particular, single-user operation is enforced -if the script terminates with a non-zero exit code, -or if a SIGTERM is delivered to the -.Xr init 8 -process (PID 1). -This functionality has generally been eclipsed by rerooting. -See -.Xr reboot 8 -.Fl r -for details. -.It Va init_shell -Defines the shell binary to be used for executing the various shell scripts. -The default is -.Dq Li /bin/sh . -It is used for running the -.Va init_script -if set, as well as for the -.Pa /etc/rc -and -.Pa /etc/rc.shutdown -scripts. -The value of the corresponding -.Xr kenv 2 -variable is evaluated every time -.Xr init 8 -calls a shell script, so it can be changed later on using the -.Xr kenv 1 -utility. -In particular, if a non-default shell is used for running an -.Va init_script , -it might be desirable to have that script reset the value of -.Va init_shell -back to the default, so that the -.Pa /etc/rc -script is executed with the standard shell -.Pa /bin/sh . -.It Va interpret -Has the value -.Dq Li OK -if the Forth's current state is interpreting. -.It Va LINES -Define the number of lines on the screen, to be used by the pager. -.It Va module_path -Sets the list of directories which will be searched for modules -named in a load command or implicitly required by a dependency. -The default value for this variable is -.Dq Li /boot/kernel;/boot/modules . -.It Va num_ide_disks -Sets the number of IDE disks as a workaround for some problems in -finding the root disk at boot. -This has been deprecated in favor of -.Va root_disk_unit . -.It Va prompt -Value of -.Nm Ns 's -prompt. -Defaults to -.Dq Li "${interpret}" . -If variable -.Va prompt -is unset, the default prompt is -.Ql > . -.It Va root_disk_unit -If the code which detects the disk unit number for the root disk is -confused, e.g.\& by a mix of SCSI and IDE disks, or IDE disks with -gaps in the sequence (e.g.\& no primary slave), the unit number can -be forced by setting this variable. -.It Va rootdev -By default the value of -.Va currdev -is used to set the root file system -when the kernel is booted. -This can be overridden by setting -.Va rootdev -explicitly. -.El -.Pp -Other variables are used to override kernel tunable parameters. -The following tunables are available: -.Bl -tag -width Va -.It Va hw.physmem -Limit the amount of physical memory the system will use. -By default the size is in bytes, but the -.Cm k , K , m , M , g -and -.Cm G -suffixes -are also accepted and indicate kilobytes, megabytes and gigabytes -respectively. -An invalid suffix will result in the variable being ignored by the -kernel. -.It Va hw.pci.host_start_mem , hw.acpi.host_start_mem -When not otherwise constrained, this limits the memory start -address. -The default is 0x80000000 and should be set to at least size of the -memory and not conflict with other resources. -Typically, only systems without PCI bridges need to set this variable -since PCI bridges typically constrain the memory starting address -(and the variable is only used when bridges do not constrain this -address). -.It Va hw.pci.enable_io_modes -Enable PCI resources which are left off by some BIOSes or are not -enabled correctly by the device driver. -Tunable value set to ON (1) by default, but this may cause problems -with some peripherals. -.It Va kern.maxusers -Set the size of a number of statically allocated system tables; see -.Xr tuning 7 -for a description of how to select an appropriate value for this -tunable. -When set, this tunable replaces the value declared in the kernel -compile-time configuration file. -.It Va kern.ipc.nmbclusters -Set the number of mbuf clusters to be allocated. -The value cannot be set below the default -determined when the kernel was compiled. -.It Va kern.ipc.nsfbufs -Set the number of -.Xr sendfile 2 -buffers to be allocated. -Overrides -.Dv NSFBUFS . -Not all architectures use such buffers; see -.Xr sendfile 2 -for details. -.It Va kern.maxswzone -Limits the amount of KVM to be used to hold swap -metadata, which directly governs the -maximum amount of swap the system can support, -at the rate of approximately 200 MB of swap space -per 1 MB of metadata. -This value is specified in bytes of KVA space. -If no value is provided, the system allocates -enough memory to handle an amount of swap -that corresponds to eight times the amount of -physical memory present in the system. -.Pp -Note that swap metadata can be fragmented, -which means that the system can run out of -space before it reaches the theoretical limit. -Therefore, care should be taken to not configure -more swap than approximately half of the -theoretical maximum. -.Pp -Running out of space for swap metadata can leave -the system in an unrecoverable state. -Therefore, you should only change -this parameter if you need to greatly extend the -KVM reservation for other resources such as the -buffer cache or -.Va kern.ipc.nmbclusters . -Modifies kernel option -.Dv VM_SWZONE_SIZE_MAX . -.It Va kern.maxbcache -Limits the amount of KVM reserved for use by the -buffer cache, specified in bytes. -The default maximum is 200MB on i386, -and 400MB on amd64 and sparc64. -This parameter is used to -prevent the buffer cache from eating too much -KVM in large-memory machine configurations. -Only mess around with this parameter if you need to -greatly extend the KVM reservation for other resources -such as the swap zone or -.Va kern.ipc.nmbclusters . -Note that -the NBUF parameter will override this limit. -Modifies -.Dv VM_BCACHE_SIZE_MAX . -.It Va kern.msgbufsize -Sets the size of the kernel message buffer. -The default limit of 64KB is usually sufficient unless -large amounts of trace data need to be collected -between opportunities to examine the buffer or -dump it to a file. -Overrides kernel option -.Dv MSGBUF_SIZE . -.It Va machdep.disable_mtrrs -Disable the use of i686 MTRRs (x86 only). -.It Va net.inet.tcp.tcbhashsize -Overrides the compile-time set value of -.Dv TCBHASHSIZE -or the preset default of 512. -Must be a power of 2. -.It Va twiddle_divisor -Throttles the output of the -.Sq twiddle -I/O progress indicator displayed while loading the kernel and modules. -This is useful on slow serial consoles where the time spent waiting for -these characters to be written can add up to many seconds. -The default is 1 (full speed); a value of 2 spins half as fast, and so on. -.It Va vm.kmem_size -Sets the size of kernel memory (bytes). -This overrides the value determined when the kernel was compiled. -Modifies -.Dv VM_KMEM_SIZE . -.It Va vm.kmem_size_min -.It Va vm.kmem_size_max -Sets the minimum and maximum (respectively) amount of kernel memory -that will be automatically allocated by the kernel. -These override the values determined when the kernel was compiled. -Modifies -.Dv VM_KMEM_SIZE_MIN -and -.Dv VM_KMEM_SIZE_MAX . -.El -.Ss BUILTIN PARSER -When a builtin command is executed, the rest of the line is taken -by it as arguments, and it is processed by a special parser which -is not used for regular Forth commands. -.Pp -This special parser applies the following rules to the parsed text: -.Bl -enum -.It -All backslash characters are preprocessed. -.Bl -bullet -.It -\eb , \ef , \er , \en and \et are processed as in C. -.It -\es is converted to a space. -.It -\ev is converted to -.Tn ASCII -11. -.It -\ez is just skipped. -Useful for things like -.Dq \e0xf\ez\e0xf . -.It -\e0xN and \e0xNN are replaced by the hex N or NN. -.It -\eNNN is replaced by the octal NNN -.Tn ASCII -character. -.It -\e" , \e' and \e$ will escape these characters, preventing them from -receiving special treatment in Step 2, described below. -.It -\e\e will be replaced with a single \e . -.It -In any other occurrence, backslash will just be removed. -.El -.It -Every string between non-escaped quotes or double-quotes will be treated -as a single word for the purposes of the remaining steps. -.It -Replace any -.Li $VARIABLE -or -.Li ${VARIABLE} -with the value of the environment variable -.Va VARIABLE . -.It -Space-delimited arguments are passed to the called builtin command. -Spaces can also be escaped through the use of \e\e . -.El -.Pp -An exception to this parsing rule exists, and is described in -.Sx BUILTINS AND FORTH . -.Ss BUILTINS AND FORTH -All builtin words are state-smart, immediate words. -If interpreted, they behave exactly as described previously. -If they are compiled, though, -they extract their arguments from the stack instead of the command line. -.Pp -If compiled, the builtin words expect to find, at execution time, the -following parameters on the stack: -.D1 Ar addrN lenN ... addr2 len2 addr1 len1 N -where -.Ar addrX lenX -are strings which will compose the command line that will be parsed -into the builtin's arguments. -Internally, these strings are concatenated in from 1 to N, -with a space put between each one. -.Pp -If no arguments are passed, a 0 -.Em must -be passed, even if the builtin accepts no arguments. -.Pp -While this behavior has benefits, it has its trade-offs. -If the execution token of a builtin is acquired (through -.Ic ' -or -.Ic ['] ) , -and then passed to -.Ic catch -or -.Ic execute , -the builtin behavior will depend on the system state -.Bf Em -at the time -.Ic catch -or -.Ic execute -is processed! -.Ef -This is particularly annoying for programs that want or need to -handle exceptions. -In this case, the use of a proxy is recommended. -For example: -.Dl : (boot) boot ; -.Sh FICL -.Tn FICL -is a Forth interpreter written in C, in the form of a forth -virtual machine library that can be called by C functions and vice -versa. -.Pp -In -.Nm , -each line read interactively is then fed to -.Tn FICL , -which may call -.Nm -back to execute the builtin words. -The builtin -.Ic include -will also feed -.Tn FICL , -one line at a time. -.Pp -The words available to -.Tn FICL -can be classified into four groups. -The -.Tn ANS -Forth standard words, extra -.Tn FICL -words, extra -.Fx -words, and the builtin commands; -the latter were already described. -The -.Tn ANS -Forth standard words are listed in the -.Sx STANDARDS -section. -The words falling in the two other groups are described in the -following subsections. -.Ss FICL EXTRA WORDS -.Bl -tag -width wid-set-super -.It Ic .env -.It Ic .ver -.It Ic -roll -.It Ic 2constant -.It Ic >name -.It Ic body> -.It Ic compare -This is the STRING word set's -.Ic compare . -.It Ic compile-only -.It Ic endif -.It Ic forget-wid -.It Ic parse-word -.It Ic sliteral -This is the STRING word set's -.Ic sliteral . -.It Ic wid-set-super -.It Ic w@ -.It Ic w! -.It Ic x. -.It Ic empty -.It Ic cell- -.It Ic -rot -.El -.Ss FREEBSD EXTRA WORDS -.Bl -tag -width XXXXXXXX -.It Ic \&$ Pq -- -Evaluates the remainder of the input buffer, after having printed it first. -.It Ic \&% Pq -- -Evaluates the remainder of the input buffer under a -.Ic catch -exception guard. -.It Ic .# -Works like -.Ic "." -but without outputting a trailing space. -.It Ic fclose Pq Ar fd -- -Closes a file. -.It Ic fkey Pq Ar fd -- char -Reads a single character from a file. -.It Ic fload Pq Ar fd -- -Processes a file -.Em fd . -.It Ic fopen Pq Ar addr len mode Li -- Ar fd -Opens a file. -Returns a file descriptor, or \-1 in case of failure. -The -.Ar mode -parameter selects whether the file is to be opened for read access, write -access, or both. -The constants -.Dv O_RDONLY , O_WRONLY , -and -.Dv O_RDWR -are defined in -.Pa /boot/support.4th , -indicating read only, write only, and read-write access, respectively. -.It Xo -.Ic fread -.Pq Ar fd addr len -- len' -.Xc -Tries to read -.Em len -bytes from file -.Em fd -into buffer -.Em addr . -Returns the actual number of bytes read, or -1 in case of error or end of -file. -.It Ic heap? Pq -- Ar cells -Return the space remaining in the dictionary heap, in cells. -This is not related to the heap used by dynamic memory allocation words. -.It Ic inb Pq Ar port -- char -Reads a byte from a port. -.It Ic key Pq -- Ar char -Reads a single character from the console. -.It Ic key? Pq -- Ar flag -Returns -.Ic true -if there is a character available to be read from the console. -.It Ic ms Pq Ar u -- -Waits -.Em u -microseconds. -.It Ic outb Pq Ar port char -- -Writes a byte to a port. -.It Ic seconds Pq -- Ar u -Returns the number of seconds since midnight. -.It Ic tib> Pq -- Ar addr len -Returns the remainder of the input buffer as a string on the stack. -.It Ic trace! Pq Ar flag -- -Activates or deactivates tracing. -Does not work with -.Ic catch . -.El -.Ss FREEBSD DEFINED ENVIRONMENTAL QUERIES -.Bl -tag -width Ds -.It arch-i386 -.Ic TRUE -if the architecture is IA32. -.It FreeBSD_version -.Fx -version at compile time. -.It loader_version -.Nm -version. -.El -.Ss SYSTEM DOCUMENTATION -.Sh FILES -.Bl -tag -width /boot/defaults/loader.conf -compact -.It Pa /boot/loader -.Nm -itself. -.It Pa /boot/boot.4th -Additional -.Tn FICL -initialization. -.It Pa /boot/defaults/loader.conf -.It Pa /boot/loader.conf -.It Pa /boot/loader.conf.local -.Nm -configuration files, as described in -.Xr loader.conf 5 . -.It Pa /boot/loader.rc -.Nm -bootstrapping script. -.It Pa /boot/loader.help -Loaded by -.Ic help . -Contains the help messages. -.El -.Sh EXAMPLES -Boot in single user mode: -.Pp -.Dl boot -s -.Pp -Load the kernel, a splash screen, and then autoboot in five seconds. -Notice that a kernel must be loaded before any other -.Ic load -command is attempted. -.Bd -literal -offset indent -load kernel -load splash_bmp -load -t splash_image_data /boot/chuckrulez.bmp -autoboot 5 -.Ed -.Pp -Set the disk unit of the root device to 2, and then boot. -This would be needed in a system with two IDE disks, -with the second IDE disk hardwired to ada2 instead of ada1. -.Bd -literal -offset indent -set root_disk_unit=2 -boot /boot/kernel/kernel -.Ed -.Pp -See also: -.Bl -tag -width /usr/share/examples/bootforth/X -.It Pa /boot/loader.4th -Extra builtin-like words. -.It Pa /boot/support.4th -.Pa loader.conf -processing words. -.It Pa /usr/share/examples/bootforth/ -Assorted examples. -.El -.Sh ERRORS -The following values are thrown by -.Nm : -.Bl -tag -width XXXXX -offset indent -.It 100 -Any type of error in the processing of a builtin. -.It -1 -.Ic Abort -executed. -.It -2 -.Ic Abort" -executed. -.It -56 -.Ic Quit -executed. -.It -256 -Out of interpreting text. -.It -257 -Need more text to succeed -- will finish on next run. -.It -258 -.Ic Bye -executed. -.It -259 -Unspecified error. -.El -.Sh SEE ALSO -.Xr libstand 3 , -.Xr loader.conf 5 , -.Xr tuning 7 , -.Xr boot 8 , -.Xr btxld 8 -.Sh STANDARDS -For the purposes of ANS Forth compliance, loader is an -.Bf Em -ANS Forth System with Environmental Restrictions, Providing -.Ef -.Bf Li -.No .( , -.No :noname , -.No ?do , -parse, pick, roll, refill, to, value, \e, false, true, -.No <> , -.No 0<> , -compile\&, , erase, nip, tuck -.Ef -.Em and -.Li marker -.Bf Em -from the Core Extensions word set, Providing the Exception Extensions -word set, Providing the Locals Extensions word set, Providing the -Memory-Allocation Extensions word set, Providing -.Ef -.Bf Li -\&.s, -bye, forget, see, words, -\&[if], -\&[else] -.Ef -.Em and -.Li [then] -.Bf Em -from the Programming-Tools extension word set, Providing the -Search-Order extensions word set. -.Ef -.Sh HISTORY -The -.Nm -first appeared in -.Fx 3.1 . -.Sh AUTHORS -.An -nosplit -The -.Nm -was written by -.An Michael Smith Aq msmith@FreeBSD.org . -.Pp -.Tn FICL -was written by -.An John Sadler Aq john_sadler@alum.mit.edu . -.Sh BUGS -The -.Ic expect -and -.Ic accept -words will read from the input buffer instead of the console. -The latter will be fixed, but the former will not. Index: sys/boot/common/zfsloader.8 =================================================================== --- /dev/null +++ sys/boot/common/zfsloader.8 @@ -1,106 +0,0 @@ -.\" Copyright (c) 2014 Andriy Gapon -.\" All rights reserved. -.\" -.\" 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. -.\" -.\" 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$ -.\" -.Dd September 15, 2014 -.Dt ZFSLOADER 8 -.Os -.Sh NAME -.Nm zfsloader -.Nd kernel bootstrapping final stage -.Sh DESCRIPTION -.Nm -is an extended variant of -.Xr loader 8 -with added support for booting from ZFS. -This document describes only differences from -.Xr loader 8 . -.Sh ZFS FEATURES -.Nm -supports the following format for specifying ZFS filesystems which -can be used wherever -.Xr loader 8 -refers to a device specification: -.Pp -.Ar zfs:pool/filesystem: -.Pp -where -.Pa pool/filesystem -is a ZFS filesystem name as described in -.Xr zfs 8 . -.Pp -If -.Pa /etc/fstab -does not have an entry for the root filesystem and -.Va vfs.root.mountfrom -is not set, but -.Va currdev -refers to a ZFS filesystem, then -.Nm -will instruct kernel to use that filesystem as the root filesystem. -.Sh ZFS COMMAND EXTENSIONS -.Bl -tag -width Ds -compact -.It Ic lsdev Op Fl v -Lists ZFS pools in addition to disks and partitions. -Adding -.Fl v -shows more ZFS pool details in a format that resembles -.Nm zpool Cm status -output. -.Pp -.It Ic lszfs Ar filesystem -A ZFS extended command that can be used to explore the ZFS filesystem -hierarchy in a pool. -Lists the immediate children of the -.Ar filesystem . -The filesystem hierarchy is rooted at a filesystem with the same name -as the pool. -.El -.Sh FILES -.Bl -tag -width /boot/zfsloader -compact -.It Pa /boot/zfsloader -.Nm -itself. -.El -.Sh EXAMPLES -Set the default device used for loading a kernel from a ZFS filesystem: -.Bd -literal -offset indent -set currdev=zfs:tank/ROOT/knowngood: -.Ed -.Sh SEE ALSO -.Xr gptzfsboot 8 , -.Xr loader 8 , -.Xr zfs 8 , -.Xr zfsboot 8 , -.Xr zfsloader 8 , -.Xr zpool 8 -.Sh HISTORY -The -.Nm -first appeared in -.Fx 7.3 . -.Sh AUTHORS -This manual page was written by -.An Andriy Gapon Aq avg@FreeBSD.org . Index: sys/boot/defs.mk =================================================================== --- /dev/null +++ sys/boot/defs.mk @@ -0,0 +1,74 @@ +# $FreeBSD$ + +.include + +.if !defined(__BOOT_DEFS_MK__) +__BOOT_DEFS_MK__=${MFILE} + +BOOTDIR= ${SRCTOP}/sys/boot +FICLDIR= ${SRCTOP}/sys/boot/ficl +LDR_MI= ${BOOTDIR}/common +SASRC= ${SRCTOP}/sys/boot/libsa +SYSDIR= ${SRCTOP}/sys + +# NB: The makefiles depend on these being empty when we don't build forth. +.if ${MK_FORTH} != "no" +LIBFICL= ${OBJTOP}/sys/boot/ficl/libficl.a +LIBFICL32= ${OBJTOP}/sys/boot/ficl32/libficl.a +.endif +LIBSA= ${OBJTOP}/sys/boot/libsa/libsa.a +LIBSA32= ${OBJTOP}/sys/boot/libsa32/libsa32.a + +# Standard options: + +# Filesystem support +.if ${LOADER_CD9660_SUPPORT:Uno} == "yes" +CFLAGS+= -DLOADER_CD9660_SUPPORT +.endif +.if ${LOADER_EXT2FS_SUPPORT:Uno} == "yes" +CFLAGS+= -DLOADER_EXT2FS_SUPPORT +.endif +.if ${LOADER_MSDOS_SUPPORT:Uno} == "yes" +CFLAGS+= -DLOADER_MSDOS_SUPPORT +.endif +.if ${LOADER_NANDFS_SUPPORT:U${MK_NAND}} == "yes" +CFLAGS+= -DLOADER_NANDFS_SUPPORT +.endif +.if ${LOADER_UFS_SUPPORT:Uyes} == "yes" +CFLAGS+= -DLOADER_UFS_SUPPORT +.endif + +# Compression +.if ${LOADER_GZIP_SUPPORT:Uno} == "yes" +CFLAGS+= -DLOADER_GZIP_SUPPORT +.endif +.if ${LOADER_BZIP2_SUPPORT:Uno} == "yes" +CFLAGS+= -DLOADER_BZIP2_SUPPORT +.endif + +# Network related things +.if ${LOADER_NET_SUPPORT:Uno} == "yes" +CFLAGS+= -DLOADER_NET_SUPPORT +.endif +.if ${LOADER_NFS_SUPPORT:Uno} == "yes" +CFLAGS+= -DLOADER_NFS_SUPPORT +.endif +.if ${LOADER_TFTP_SUPPORT:Uno} == "yes" +CFLAGS+= -DLOADER_TFTP_SUPPORT +.endif + +# Disk and partition support +.if ${LOADER_DISK_SUPPORT:Uyes} == "yes" +CFLAGS+= -DLOADER_DISK_SUPPORT +.if ${LOADER_GPT_SUPPORT:Uyes} == "yes" +CFLAGS+= -DLOADER_GPT_SUPPORT +.endif +.if ${LOADER_MBR_SUPPORT:Uyes} == "yes" +CFLAGS+= -DLOADER_MBR_SUPPORT +.endif +.if ${LOADER_GELI_SUPPORT:Uyes} == "yes" +CFLAGS+= -DLOADER_GELI_SUPPORT +.endif +.endif + +.endif # __BOOT_DEFS_MK__ Index: sys/boot/efi/boot1/Makefile =================================================================== --- sys/boot/efi/boot1/Makefile +++ sys/boot/efi/boot1/Makefile @@ -5,10 +5,14 @@ .include "../Makefile.inc" MK_SSP= no +MK_FORTH= no PROG= boot1.sym INTERNALPROG= -WARNS?= 6 +WARNS?= 3 + +# Include bcache code. +HAVE_BCACHE= yes # We implement a slightly non-standard %S in that it always takes a # CHAR16 that's common in UEFI-land instead of a wchar_t. This only @@ -18,13 +22,15 @@ CWARNFLAGS.boot1.c+= -Wno-format # Disable warnings that are currently incompatible with the zfs boot code -CWARNFLAGS.zfs_module.c += -Wno-array-bounds -CWARNFLAGS.zfs_module.c += -Wno-cast-align -CWARNFLAGS.zfs_module.c += -Wno-cast-qual -CWARNFLAGS.zfs_module.c += -Wno-missing-prototypes -CWARNFLAGS.zfs_module.c += -Wno-sign-compare -CWARNFLAGS.zfs_module.c += -Wno-unused-parameter -CWARNFLAGS.zfs_module.c += -Wno-unused-function +CWARNFLAGS.zfs.c += -Wno-incompatible-pointer-types-discards-qualifiers +CWARNFLAGS.zfs.c += -Wno-missing-variable-declarations +CWARNFLAGS.zfs.c += -Wno-array-bounds +CWARNFLAGS.zfs.c += -Wno-cast-align +CWARNFLAGS.zfs.c += -Wno-cast-qual +CWARNFLAGS.zfs.c += -Wno-missing-prototypes +CWARNFLAGS.zfs.c += -Wno-sign-compare +CWARNFLAGS.zfs.c += -Wno-unused-parameter +CWARNFLAGS.zfs.c += -Wno-unused-function CWARNFLAGS.skein.c += -Wno-cast-align .if ${COMPILER_TYPE} == "clang" CWARNFLAGS.skein.c += -Wno-missing-variable-declarations @@ -33,19 +39,25 @@ .endif # architecture-specific loader code -SRCS= boot1.c self_reloc.c start.S ufs_module.c +SRCS= boot1.c self_reloc.c start.S .if ${MK_ZFS} != "no" -SRCS+= zfs_module.c +.PATH: ${.CURDIR}/../../../crypto/skein SRCS+= skein.c skein_block.c # Do not unroll skein loops, reduce code size CFLAGS+= -DSKEIN_LOOP=111 -.PATH: ${.CURDIR}/../../../crypto/skein +.PATH: ${.CURDIR}/../../zfs +SRCS+= zfs.c .endif .if ${COMPILER_TYPE} == "gcc" && ${COMPILER_VERSION} > 40201 CWARNFLAGS.self_reloc.c+= -Wno-error=maybe-uninitialized .endif +# Always add MI sources +.include "../../loader.mk" + +.PATH: ${.CURDIR}/arch/${MACHINE} + CFLAGS+= -I. CFLAGS+= -I${.CURDIR}/../include CFLAGS+= -I${.CURDIR}/../include/${MACHINE} @@ -117,7 +129,7 @@ SOURCE_DATE_EPOCH=${SOURCE_DATE_EPOCH} \ ${OBJCOPY} -j .peheader -j .text -j .sdata -j .data \ -j .dynamic -j .dynsym -j .rel.dyn \ - -j .rela.dyn -j .reloc -j .eh_frame \ + -j .rela.dyn -j .reloc -j .eh_frame -j set_Xcommand_set \ --output-target=${EFI_TARGET} ${.ALLSRC} ${.TARGET} boot1.o: ${SASRC}/ufsread.c Index: sys/boot/efi/boot1/boot1.c =================================================================== --- sys/boot/efi/boot1/boot1.c +++ sys/boot/efi/boot1/boot1.c @@ -23,61 +23,179 @@ __FBSDID("$FreeBSD$"); #include +#include #include #include #include +#include #include +#include +#include #include +#ifdef EFI_ZFS_BOOT +#include +#endif typedef CHAR16 efi_char; #include -#include "boot_module.h" +#include + +#include "efi_drivers.h" +#include "efizfs.h" #include "paths.h" static void efi_panic(EFI_STATUS s, const char *fmt, ...) __dead2 __printflike(2, 3); +#ifdef EFI_DEBUG +#define DPRINTF(fmt, args...) printf(fmt, ##args) +#define DSTALL(d) BS->Stall(d) +#else +#define DPRINTF(fmt, ...) {} +#define DSTALL(d) {} +#endif + +struct arch_switch archsw; /* MI/MD interface boundary */ + +static const efi_driver_t *efi_drivers[] = { + NULL +}; + +extern struct console efi_console; +#if defined(__amd64__) || defined(__i386__) +extern struct console comconsole; +extern struct console nullconsole; +#endif -static const boot_module_t *boot_modules[] = -{ #ifdef EFI_ZFS_BOOT - &zfs_module, +uint64_t pool_guid; #endif + +struct fs_ops *file_system[] = { +#ifdef EFI_ZFS_BOOT + &zfs_fsops, +#endif + &dosfs_fsops, #ifdef EFI_UFS_BOOT - &ufs_module + &ufs_fsops, +#endif + &cd9660_fsops, + &nfs_fsops, + &gzipfs_fsops, + &bzipfs_fsops, + NULL +}; + +struct devsw *devsw[] = { + &efipart_hddev, + &efipart_fddev, + &efipart_cddev, +#ifdef EFI_ZFS_BOOT + &zfs_dev, #endif + NULL }; -#define NUM_BOOT_MODULES nitems(boot_modules) +struct console *consoles[] = { + &efi_console, + NULL +}; + +static EFI_LOADED_IMAGE *boot_image; +static EFI_DEVICE_PATH *imgpath; +static EFI_DEVICE_PATH *imgprefix; + +/* Definitions we don't actually need for boot, but we need to define + * to make the linker happy. + */ +struct file_format *file_formats[] = { NULL }; + +struct netif_driver *netif_drivers[] = { NULL }; + +static int +efi_autoload(void) +{ + printf("******** Boot block should not call autoload\n"); + return (-1); +} + +static ssize_t +efi_copyin(const void *src __unused, vm_offset_t dest __unused, + const size_t len __unused) +{ + printf("******** Boot block should not call copyin\n"); + return (-1); +} + +static ssize_t +efi_copyout(vm_offset_t src __unused, void *dest __unused, + const size_t len __unused) +{ + printf("******** Boot block should not call copyout\n"); + return (-1); +} + +static ssize_t +efi_readin(int fd __unused, vm_offset_t dest __unused, + const size_t len __unused) +{ + printf("******** Boot block should not call readin\n"); + return (-1); +} + /* The initial number of handles used to query EFI for partitions. */ #define NUM_HANDLES_INIT 24 -static EFI_GUID BlockIoProtocolGUID = BLOCK_IO_PROTOCOL; static EFI_GUID DevicePathGUID = DEVICE_PATH_PROTOCOL; static EFI_GUID LoadedImageGUID = LOADED_IMAGE_PROTOCOL; -static EFI_GUID ConsoleControlGUID = EFI_CONSOLE_CONTROL_PROTOCOL_GUID; static EFI_GUID FreeBSDBootVarGUID = FREEBSD_BOOT_VAR_GUID; -/* - * Provide Malloc / Free backed by EFIs AllocatePool / FreePool which ensures - * memory is correctly aligned avoiding EFI_INVALID_PARAMETER returns from - * EFI methods. - */ -void * -Malloc(size_t len, const char *file __unused, int line __unused) +static EFI_STATUS +do_load(const char *filepath, void **bufp, size_t *bufsize) { - void *out; + struct stat st; + void *buf = NULL; + int fd, err; + size_t fsize, remaining; + ssize_t readsize; - if (BS->AllocatePool(EfiLoaderData, len, &out) == EFI_SUCCESS) - return (out); + if ((fd = open(filepath, O_RDONLY)) < 0) { + return (ENOTSUP); + } - return (NULL); -} + if ((err = fstat(fd, &st)) != 0) { + goto close_file; + } -void -Free(void *buf, const char *file __unused, int line __unused) -{ - if (buf != NULL) - (void)BS->FreePool(buf); + fsize = st.st_size; + + if ((buf = malloc(fsize)) == NULL) { + err = ENOMEM; + goto close_file; + } + + remaining = fsize; + + do { + if ((readsize = read(fd, buf, fsize)) < 0) { + err = (-readsize); + goto free_buf; + } + + remaining -= readsize; + } while(remaining != 0); + + close(fd); + *bufsize = st.st_size; + *bufp = buf; + + close_file: + close(fd); + + return errno_to_efi_status(err); + + free_buf: + free(buf); + goto close_file; } static EFI_STATUS @@ -97,98 +215,275 @@ return (rv); } -/* - * nodes_match returns TRUE if the imgpath isn't NULL and the nodes match, - * FALSE otherwise. - */ -static BOOLEAN -nodes_match(EFI_DEVICE_PATH *imgpath, EFI_DEVICE_PATH *devpath) +static int +probe_fs(const char *filepath) { - size_t len; + int fd; - if (imgpath == NULL || imgpath->Type != devpath->Type || - imgpath->SubType != devpath->SubType) - return (FALSE); + if ((fd = open(filepath, O_RDONLY)) < 0) { + return (ENOTSUP); + } - len = DevicePathNodeLength(imgpath); - if (len != DevicePathNodeLength(devpath)) - return (FALSE); + close(fd); - return (memcmp(imgpath, devpath, (size_t)len) == 0); + return (0); } -/* - * device_paths_match returns TRUE if the imgpath isn't NULL and all nodes - * in imgpath and devpath match up to their respective occurrences of a - * media node, FALSE otherwise. - */ -static BOOLEAN -device_paths_match(EFI_DEVICE_PATH *imgpath, EFI_DEVICE_PATH *devpath) +static int +probe_dev(struct devsw *dev, int unit, const char *filepath) { + struct devdesc currdev; + char *devname; + int err; - if (imgpath == NULL) - return (FALSE); + currdev.d_dev = dev; + currdev.d_type = currdev.d_dev->dv_type; + currdev.d_unit = unit; + currdev.d_opendata = NULL; + devname = efi_fmtdev(&currdev); - while (!IsDevicePathEnd(imgpath) && !IsDevicePathEnd(devpath)) { - if (IsDevicePathType(imgpath, MEDIA_DEVICE_PATH) && - IsDevicePathType(devpath, MEDIA_DEVICE_PATH)) - return (TRUE); + env_setenv("currdev", EV_VOLATILE, devname, efi_setcurrdev, + env_nounset); - if (!nodes_match(imgpath, devpath)) - return (FALSE); + err = probe_fs(filepath); - imgpath = NextDevicePathNode(imgpath); - devpath = NextDevicePathNode(devpath); - } + return (err); +} - return (FALSE); +static bool +check_preferred(EFI_HANDLE *h) +{ + EFI_DEVICE_PATH *path = efi_lookup_devpath(h); + bool out; + + if ((path = efi_lookup_devpath(h)) == NULL) + return (false); + + out = efi_devpath_is_prefix(imgpath, path) || + efi_devpath_is_prefix(imgprefix, path); + + return (out); } -/* - * devpath_last returns the last non-path end node in devpath. - */ -static EFI_DEVICE_PATH * -devpath_last(EFI_DEVICE_PATH *devpath) +bool +efi_zfs_is_preferred(EFI_HANDLE *h) { + return (check_preferred(h)); +} - while (!IsDevicePathEnd(NextDevicePathNode(devpath))) - devpath = NextDevicePathNode(devpath); +static int +load_preferred(EFI_LOADED_IMAGE *img, const char *filepath, void **bufp, + size_t *bufsize, EFI_HANDLE *handlep) +{ + pdinfo_list_t *pdi_list; + pdinfo_t *dp, *pp; + char *devname; - return (devpath); +#ifdef EFI_ZFS_BOOT + /* Did efi_zfs_probe() detect the boot pool? */ + if (pool_guid != 0) { + struct zfs_devdesc currdev; + + currdev.d_dev = &zfs_dev; + currdev.d_unit = 0; + currdev.d_type = currdev.d_dev->dv_type; + currdev.d_opendata = NULL; + currdev.pool_guid = pool_guid; + currdev.root_guid = 0; + devname = efi_fmtdev(&currdev); + + env_setenv("currdev", EV_VOLATILE, devname, efi_setcurrdev, + env_nounset); + + if (probe_fs(filepath) == 0 && + do_load(filepath, bufp, bufsize) == EFI_SUCCESS) { + *handlep = efizfs_get_handle_by_guid(pool_guid); + return (0); + } + } +#endif /* EFI_ZFS_BOOT */ + + /* We have device lists for hd, cd, fd, walk them all. */ + pdi_list = efiblk_get_pdinfo_list(&efipart_hddev); + STAILQ_FOREACH(dp, pdi_list, pd_link) { + struct disk_devdesc currdev; + + currdev.d_dev = &efipart_hddev; + currdev.d_type = currdev.d_dev->dv_type; + currdev.d_unit = dp->pd_unit; + currdev.d_opendata = NULL; + currdev.d_slice = -1; + currdev.d_partition = -1; + devname = efi_fmtdev(&currdev); + + env_setenv("currdev", EV_VOLATILE, devname, efi_setcurrdev, + env_nounset); + + if (check_preferred(dp->pd_handle) && + probe_fs(filepath) == 0 && + do_load(filepath, bufp, bufsize) == EFI_SUCCESS) { + *handlep = dp->pd_handle; + return (0); + } + + /* Assuming GPT partitioning. */ + STAILQ_FOREACH(pp, &dp->pd_part, pd_link) { + if (check_preferred(pp->pd_handle)) { + currdev.d_slice = pp->pd_unit; + currdev.d_partition = 255; + devname = efi_fmtdev(&currdev); + + env_setenv("currdev", EV_VOLATILE, devname, + efi_setcurrdev, env_nounset); + + if (probe_fs(filepath) == 0 && + do_load(filepath, bufp, bufsize) == + EFI_SUCCESS) { + *handlep = pp->pd_handle; + return (0); + } + } + } + } + + pdi_list = efiblk_get_pdinfo_list(&efipart_cddev); + STAILQ_FOREACH(dp, pdi_list, pd_link) { + if ((dp->pd_handle == img->DeviceHandle || + dp->pd_alias == img->DeviceHandle || + check_preferred(dp->pd_handle)) && + probe_dev(&efipart_cddev, dp->pd_unit, filepath) == 0 && + do_load(filepath, bufp, bufsize) == EFI_SUCCESS) { + *handlep = dp->pd_handle; + return (0); + } + } + + pdi_list = efiblk_get_pdinfo_list(&efipart_fddev); + STAILQ_FOREACH(dp, pdi_list, pd_link) { + if ((dp->pd_handle == img->DeviceHandle || + check_preferred(dp->pd_handle)) && + probe_dev(&efipart_cddev, dp->pd_unit, filepath) == 0 && + do_load(filepath, bufp, bufsize) == EFI_SUCCESS) { + *handlep = dp->pd_handle; + return (0); + } + } + + return (ENOENT); } -/* - * load_loader attempts to load the loader image data. - * - * It tries each module and its respective devices, identified by mod->probe, - * in order until a successful load occurs at which point it returns EFI_SUCCESS - * and EFI_NOT_FOUND otherwise. - * - * Only devices which have preferred matching the preferred parameter are tried. - */ -static EFI_STATUS -load_loader(const boot_module_t **modp, dev_info_t **devinfop, void **bufp, - size_t *bufsize, BOOLEAN preferred) +static int +load_all(const char *filepath, void **bufp, size_t *bufsize, + EFI_HANDLE *handlep) { - UINTN i; - dev_info_t *dev; - const boot_module_t *mod; - - for (i = 0; i < NUM_BOOT_MODULES; i++) { - mod = boot_modules[i]; - for (dev = mod->devices(); dev != NULL; dev = dev->next) { - if (dev->preferred != preferred) - continue; - - if (mod->load(PATH_LOADER_EFI, dev, bufp, bufsize) == - EFI_SUCCESS) { - *devinfop = dev; - *modp = mod; - return (EFI_SUCCESS); + pdinfo_list_t *pdi_list; + pdinfo_t *dp, *pp; + zfsinfo_list_t *zfsi_list; + zfsinfo_t *zi; + char *devname; + +#ifdef EFI_ZFS_BOOT + zfsi_list = efizfs_get_zfsinfo_list(); + STAILQ_FOREACH(zi, zfsi_list, zi_link) { + struct zfs_devdesc currdev; + + currdev.d_dev = &zfs_dev; + currdev.d_unit = 0; + currdev.d_type = currdev.d_dev->dv_type; + currdev.d_opendata = NULL; + currdev.pool_guid = zi->zi_pool_guid; + currdev.root_guid = 0; + devname = efi_fmtdev(&currdev); + + env_setenv("currdev", EV_VOLATILE, devname, efi_setcurrdev, + env_nounset); + + if (probe_fs(filepath) == 0 && + do_load(filepath, bufp, bufsize) == EFI_SUCCESS) { + *handlep = zi->zi_handle; + + return (0); + } + } +#endif /* EFI_ZFS_BOOT */ + + /* We have device lists for hd, cd, fd, walk them all. */ + pdi_list = efiblk_get_pdinfo_list(&efipart_hddev); + STAILQ_FOREACH(dp, pdi_list, pd_link) { + struct disk_devdesc currdev; + + currdev.d_dev = &efipart_hddev; + currdev.d_type = currdev.d_dev->dv_type; + currdev.d_unit = dp->pd_unit; + currdev.d_opendata = NULL; + currdev.d_slice = -1; + currdev.d_partition = -1; + devname = efi_fmtdev(&currdev); + + env_setenv("currdev", EV_VOLATILE, devname, efi_setcurrdev, + env_nounset); + + if (probe_fs(filepath) == 0 && + do_load(filepath, bufp, bufsize) == EFI_SUCCESS) { + *handlep = dp->pd_handle; + + return (0); + } + + /* Assuming GPT partitioning. */ + STAILQ_FOREACH(pp, &dp->pd_part, pd_link) { + currdev.d_slice = pp->pd_unit; + currdev.d_partition = 255; + devname = efi_fmtdev(&currdev); + + env_setenv("currdev", EV_VOLATILE, devname, + efi_setcurrdev, env_nounset); + + if (probe_fs(filepath) == 0 && + do_load(filepath, bufp, bufsize) == EFI_SUCCESS) { + *handlep = pp->pd_handle; + + return (0); } } } + pdi_list = efiblk_get_pdinfo_list(&efipart_cddev); + STAILQ_FOREACH(dp, pdi_list, pd_link) { + if (probe_dev(&efipart_cddev, dp->pd_unit, filepath) == 0 && + do_load(filepath, bufp, bufsize) == EFI_SUCCESS) { + *handlep = dp->pd_handle; + + return (0); + } + } + + pdi_list = efiblk_get_pdinfo_list(&efipart_fddev); + STAILQ_FOREACH(dp, pdi_list, pd_link) { + if (probe_dev(&efipart_fddev, dp->pd_unit, filepath) == 0 && + do_load(filepath, bufp, bufsize) == EFI_SUCCESS) { + *handlep = dp->pd_handle; + + return (0); + } + } + + return (ENOENT); +} + +static EFI_STATUS +load_loader(EFI_HANDLE *handlep, void **bufp, size_t *bufsize) +{ + /* Try the preferred handles first, then all the handles */ + if (load_preferred(boot_image, PATH_LOADER_EFI, bufp, bufsize, + handlep) == 0) { + return (0); + } + + if (load_all(PATH_LOADER_EFI, bufp, bufsize, handlep) == 0) { + return (0); + } + return (EFI_NOT_FOUND); } @@ -202,20 +497,27 @@ size_t bufsize, loadersize, cmdsize; void *buf, *loaderbuf; char *cmd; - dev_info_t *dev; - const boot_module_t *mod; + EFI_HANDLE fshandle; EFI_HANDLE loaderhandle; EFI_LOADED_IMAGE *loaded_image; EFI_STATUS status; + EFI_DEVICE_PATH *fspath; + + status = load_loader(&fshandle, &loaderbuf, &loadersize); + + if (status != EFI_SUCCESS) { + return (status); + } - status = load_loader(&mod, &dev, &loaderbuf, &loadersize, TRUE); - if (status != EFI_SUCCESS) { - status = load_loader(&mod, &dev, &loaderbuf, &loadersize, - FALSE); + fspath = NULL; + if (status == EFI_SUCCESS) { + status = BS->OpenProtocol(fshandle, &DevicePathGUID, + (void **)&fspath, IH, NULL, EFI_OPEN_PROTOCOL_GET_PROTOCOL); if (status != EFI_SUCCESS) { - printf("Failed to load '%s'\n", PATH_LOADER_EFI); - return (status); - } + DPRINTF("Failed to get image DevicePath (%lu)\n", + EFI_ERROR_CODE(status)); + } + DPRINTF("filesystem device path: %s\n", devpath_str(fspath)); } /* @@ -230,9 +532,9 @@ */ cmd = NULL; cmdsize = 0; - status = mod->load(PATH_DOTCONFIG, dev, &buf, &bufsize); + status = do_load(PATH_DOTCONFIG, &buf, &bufsize); if (status == EFI_NOT_FOUND) - status = mod->load(PATH_CONFIG, dev, &buf, &bufsize); + status = do_load(PATH_CONFIG, &buf, &bufsize); if (status == EFI_SUCCESS) { cmdsize = bufsize + 1; cmd = malloc(cmdsize); @@ -244,24 +546,25 @@ buf = NULL; } - if ((status = BS->LoadImage(TRUE, IH, devpath_last(dev->devpath), + if ((status = BS->LoadImage(TRUE, IH, efi_devpath_last_node(fspath), loaderbuf, loadersize, &loaderhandle)) != EFI_SUCCESS) { - printf("Failed to load image provided by %s, size: %zu, (%lu)\n", - mod->name, loadersize, EFI_ERROR_CODE(status)); + printf("Failed to load image, size: %zu, (%lu)\n", + loadersize, EFI_ERROR_CODE(status)); goto errout; } - if ((status = BS->HandleProtocol(loaderhandle, &LoadedImageGUID, - (VOID**)&loaded_image)) != EFI_SUCCESS) { - printf("Failed to query LoadedImage provided by %s (%lu)\n", - mod->name, EFI_ERROR_CODE(status)); + if ((status = BS->OpenProtocol(loaderhandle, &LoadedImageGUID, + (VOID**)&loaded_image, IH, NULL, + EFI_OPEN_PROTOCOL_GET_PROTOCOL)) != EFI_SUCCESS) { + printf("Failed to query LoadedImage (%lu)\n", + EFI_ERROR_CODE(status)); goto errout; } if (cmd != NULL) printf(" command args: %s\n", cmd); - loaded_image->DeviceHandle = dev->devhandle; + loaded_image->DeviceHandle = fshandle; loaded_image->LoadOptionsSize = cmdsize; loaded_image->LoadOptions = cmd; @@ -279,8 +582,8 @@ if ((status = BS->StartImage(loaderhandle, NULL, NULL)) != EFI_SUCCESS) { - printf("Failed to start image provided by %s (%lu)\n", - mod->name, EFI_ERROR_CODE(status)); + printf("Failed to start image (%lu)\n", + EFI_ERROR_CODE(status)); loaded_image->LoadOptionsSize = 0; loaded_image->LoadOptions = NULL; } @@ -296,142 +599,37 @@ return (status); } -/* - * probe_handle determines if the passed handle represents a logical partition - * if it does it uses each module in order to probe it and if successful it - * returns EFI_SUCCESS. - */ -static EFI_STATUS -probe_handle(EFI_HANDLE h, EFI_DEVICE_PATH *imgpath, BOOLEAN *preferred) +EFI_STATUS +main(int argc __unused, CHAR16 *argv[] __unused) { - dev_info_t *devinfo; - EFI_BLOCK_IO *blkio; - EFI_DEVICE_PATH *devpath; - EFI_STATUS status; - UINTN i; + EFI_STATUS status; - /* Figure out if we're dealing with an actual partition. */ - status = BS->HandleProtocol(h, &DevicePathGUID, (void **)&devpath); - if (status == EFI_UNSUPPORTED) - return (status); + SIMPLE_TEXT_OUTPUT_INTERFACE *conout = NULL; + UINTN i, max_dim, best_mode, cols, rows; + CHAR16 *text; - if (status != EFI_SUCCESS) { - DPRINTF("\nFailed to query DevicePath (%lu)\n", - EFI_ERROR_CODE(status)); - return (status); - } -#ifdef EFI_DEBUG - { - CHAR16 *text = efi_devpath_name(devpath); - DPRINTF("probing: %S\n", text); - efi_free_devpath_name(text); - } + archsw.arch_autoload = efi_autoload; + archsw.arch_getdev = efi_getdev; + archsw.arch_copyin = efi_copyin; + archsw.arch_copyout = efi_copyout; + archsw.arch_readin = efi_readin; +#ifdef EFI_ZFS_BOOT + /* Note this needs to be set before ZFS init. */ + archsw.arch_zfs_probe = efi_zfs_probe; #endif - status = BS->HandleProtocol(h, &BlockIoProtocolGUID, (void **)&blkio); - if (status == EFI_UNSUPPORTED) - return (status); - - if (status != EFI_SUCCESS) { - DPRINTF("\nFailed to query BlockIoProtocol (%lu)\n", - EFI_ERROR_CODE(status)); - return (status); - } - - if (!blkio->Media->LogicalPartition) - return (EFI_UNSUPPORTED); - - *preferred = device_paths_match(imgpath, devpath); - /* Run through each module, see if it can load this partition */ - for (i = 0; i < NUM_BOOT_MODULES; i++) { - devinfo = malloc(sizeof(*devinfo)); - if (devinfo == NULL) { - DPRINTF("\nFailed to allocate devinfo\n"); - continue; - } - devinfo->dev = blkio; - devinfo->devpath = devpath; - devinfo->devhandle = h; - devinfo->devdata = NULL; - devinfo->preferred = *preferred; - devinfo->next = NULL; - - status = boot_modules[i]->probe(devinfo); - if (status == EFI_SUCCESS) - return (EFI_SUCCESS); - free(devinfo); - } - - return (EFI_UNSUPPORTED); -} + /* Init the time source */ + efi_time_init(); + cons_probe(); -/* - * probe_handle_status calls probe_handle and outputs the returned status - * of the call. - */ -static void -probe_handle_status(EFI_HANDLE h, EFI_DEVICE_PATH *imgpath) -{ - EFI_STATUS status; - BOOLEAN preferred; - - preferred = FALSE; - status = probe_handle(h, imgpath, &preferred); - - DPRINTF("probe: "); - switch (status) { - case EFI_UNSUPPORTED: - printf("."); - DPRINTF(" not supported\n"); - break; - case EFI_SUCCESS: - if (preferred) { - printf("%c", '*'); - DPRINTF(" supported (preferred)\n"); - } else { - printf("%c", '+'); - DPRINTF(" supported\n"); - } - break; - default: - printf("x"); - DPRINTF(" error (%lu)\n", EFI_ERROR_CODE(status)); - break; - } - DSTALL(500000); -} - -EFI_STATUS -efi_main(EFI_HANDLE Ximage, EFI_SYSTEM_TABLE *Xsystab) -{ - EFI_HANDLE *handles; - EFI_LOADED_IMAGE *img; - EFI_DEVICE_PATH *imgpath; - EFI_STATUS status; - EFI_CONSOLE_CONTROL_PROTOCOL *ConsoleControl = NULL; - SIMPLE_TEXT_OUTPUT_INTERFACE *conout = NULL; - UINTN i, max_dim, best_mode, cols, rows, hsize, nhandles; - CHAR16 *text; - - /* Basic initialization*/ - ST = Xsystab; - IH = Ximage; - BS = ST->BootServices; - RS = ST->RuntimeServices; - - /* Set up the console, so printf works. */ - status = BS->LocateProtocol(&ConsoleControlGUID, NULL, - (VOID **)&ConsoleControl); - if (status == EFI_SUCCESS) - (void)ConsoleControl->SetMode(ConsoleControl, - EfiConsoleControlScreenText); /* * Reset the console and find the best text mode. */ conout = ST->ConOut; conout->Reset(conout, TRUE); max_dim = best_mode = 0; - for (i = 0; ; i++) { + + for (i = 0; ; i++) { status = conout->QueryMode(conout, i, &cols, &rows); if (EFI_ERROR(status)) break; @@ -440,31 +638,37 @@ best_mode = i; } } - if (max_dim > 0) + + if (max_dim > 0) conout->SetMode(conout, best_mode); + conout->EnableCursor(conout, TRUE); conout->ClearScreen(conout); + /* Print this here, so people know it's at least starting. */ printf("\n>> FreeBSD EFI boot block\n"); printf(" Loader path: %s\n\n", PATH_LOADER_EFI); - printf(" Initializing modules:"); - for (i = 0; i < NUM_BOOT_MODULES; i++) { - printf(" %s", boot_modules[i]->name); - if (boot_modules[i]->init != NULL) - boot_modules[i]->init(); + + /* Get the image path and trim it to get the disk on which we + * found this loader. + */ + if ((status = BS->OpenProtocol(IH, &LoadedImageGUID, + (VOID**)&boot_image, IH, NULL, + EFI_OPEN_PROTOCOL_GET_PROTOCOL)) != EFI_SUCCESS) { + panic("Failed to query LoadedImage (%lu)\n", + EFI_ERROR_CODE(status)); } - putchar('\n'); /* Determine the devpath of our image so we can prefer it. */ - status = BS->HandleProtocol(IH, &LoadedImageGUID, (VOID**)&img); + status = BS->HandleProtocol(IH, &LoadedImageGUID, (VOID**)&boot_image); imgpath = NULL; if (status == EFI_SUCCESS) { - text = efi_devpath_name(img->FilePath); + text = efi_devpath_name(boot_image->FilePath); printf(" Load Path: %S\n", text); efi_setenv_freebsd_wcs("Boot1Path", text); efi_free_devpath_name(text); - status = BS->HandleProtocol(img->DeviceHandle, &DevicePathGUID, + status = BS->HandleProtocol(boot_image->DeviceHandle, &DevicePathGUID, (void **)&imgpath); if (status != EFI_SUCCESS) { DPRINTF("Failed to get image DevicePath (%lu)\n", @@ -478,74 +682,42 @@ } - /* Get all the device handles */ - hsize = (UINTN)NUM_HANDLES_INIT * sizeof(EFI_HANDLE); - handles = malloc(hsize); - if (handles == NULL) { - printf("Failed to allocate %d handles\n", NUM_HANDLES_INIT); - } - - status = BS->LocateHandle(ByProtocol, &BlockIoProtocolGUID, NULL, - &hsize, handles); - switch (status) { - case EFI_SUCCESS: - break; - case EFI_BUFFER_TOO_SMALL: - free(handles); - handles = malloc(hsize); - if (handles == NULL) - efi_panic(EFI_OUT_OF_RESOURCES, "Failed to allocate %d handles\n", - NUM_HANDLES_INIT); - status = BS->LocateHandle(ByProtocol, &BlockIoProtocolGUID, - NULL, &hsize, handles); - if (status != EFI_SUCCESS) - efi_panic(status, "Failed to get device handles\n"); - break; - default: - efi_panic(status, "Failed to get device handles\n"); - break; - } + /* The loaded image device path ends with a partition, then a + * file path. Trim them both to get the actual disk. + */ + if ((imgprefix = efi_devpath_trim(imgpath)) == NULL || + (imgprefix = efi_devpath_trim(imgprefix)) == NULL) { + panic("Couldn't trim device path"); + } - /* Scan all partitions, probing with all modules. */ - nhandles = hsize / sizeof(*handles); - printf(" Probing %zu block devices...", nhandles); - DPRINTF("\n"); + /* + * Initialize the block cache. Set the upper limit. + */ + bcache_init(32768, 512); - for (i = 0; i < nhandles; i++) - probe_handle_status(handles[i], imgpath); - printf(" done\n"); + printf("\n Initializing modules:"); - /* Status summary. */ - for (i = 0; i < NUM_BOOT_MODULES; i++) { - printf(" "); - boot_modules[i]->status(); + for (i = 0; efi_drivers[i] != NULL; i++) { + printf(" %s", efi_drivers[i]->name); + if (efi_drivers[i]->init != NULL) + efi_drivers[i]->init(); } + for (i = 0; devsw[i] != NULL; i++) { + if (devsw[i]->dv_init != NULL) { + printf(" %s", devsw[i]->dv_name); + (devsw[i]->dv_init)(); + } + } + + putchar('\n'); + try_boot(); /* If we get here, we're out of luck... */ efi_panic(EFI_LOAD_ERROR, "No bootable partitions found!"); } -/* - * add_device adds a device to the passed devinfo list. - */ -void -add_device(dev_info_t **devinfop, dev_info_t *devinfo) -{ - dev_info_t *dev; - - if (*devinfop == NULL) { - *devinfop = devinfo; - return; - } - - for (dev = *devinfop; dev->next != NULL; dev = dev->next) - ; - - dev->next = devinfo; -} - /* * OK. We totally give up. Exit back to EFI with a sensible status so * it can try the next option on the list. @@ -553,28 +725,13 @@ static void efi_panic(EFI_STATUS s, const char *fmt, ...) { - va_list ap; + va_list ap; - printf("panic: "); - va_start(ap, fmt); - vprintf(fmt, ap); - va_end(ap); - printf("\n"); + printf("panic: "); + va_start(ap, fmt); + vprintf(fmt, ap); + va_end(ap); + printf("\n"); - BS->Exit(IH, s, 0, NULL); -} - -void -putchar(int c) -{ - CHAR16 buf[2]; - - if (c == '\n') { - buf[0] = '\r'; - buf[1] = 0; - ST->ConOut->OutputString(ST->ConOut, buf); - } - buf[0] = c; - buf[1] = 0; - ST->ConOut->OutputString(ST->ConOut, buf); + BS->Exit(IH, s, 0, NULL); } Index: sys/boot/efi/boot1/boot_module.h =================================================================== --- sys/boot/efi/boot1/boot_module.h +++ sys/boot/efi/boot1/boot_module.h @@ -1,109 +0,0 @@ -/*- - * Copyright (c) 2015 Eric McCorkle - * All rights reserved. - * - * 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. - * - * 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$ - */ - -#ifndef _BOOT_MODULE_H_ -#define _BOOT_MODULE_H_ - -#include - -#include -#include -#include - -#ifdef EFI_DEBUG -#define DPRINTF(fmt, args...) printf(fmt, ##args) -#define DSTALL(d) BS->Stall(d) -#else -#define DPRINTF(fmt, ...) {} -#define DSTALL(d) {} -#endif - -/* EFI device info */ -typedef struct dev_info -{ - EFI_BLOCK_IO *dev; - EFI_DEVICE_PATH *devpath; - EFI_HANDLE *devhandle; - void *devdata; - BOOLEAN preferred; - struct dev_info *next; -} dev_info_t; - -/* - * A boot loader module. - * - * This is a standard interface for filesystem modules in the EFI system. - */ -typedef struct boot_module_t -{ - const char *name; - - /* init is the optional initialiser for the module. */ - void (*init)(void); - - /* - * probe checks to see if the module can handle dev. - * - * Return codes: - * EFI_SUCCESS = The module can handle the device. - * EFI_NOT_FOUND = The module can not handle the device. - * Other = The module encountered an error. - */ - EFI_STATUS (*probe)(dev_info_t* dev); - - /* - * load should select the best out of a set of devices that probe - * indicated were loadable and load the specified file. - * - * Return codes: - * EFI_SUCCESS = The module can handle the device. - * EFI_NOT_FOUND = The module can not handle the device. - * Other = The module encountered an error. - */ - EFI_STATUS (*load)(const char *filepath, dev_info_t *devinfo, - void **buf, size_t *bufsize); - - /* status outputs information about the probed devices. */ - void (*status)(void); - - /* valid devices as found by probe. */ - dev_info_t *(*devices)(void); -} boot_module_t; - -/* Standard boot modules. */ -#ifdef EFI_UFS_BOOT -extern const boot_module_t ufs_module; -#endif -#ifdef EFI_ZFS_BOOT -extern const boot_module_t zfs_module; -#endif - -/* Functions available to modules. */ -extern void add_device(dev_info_t **devinfop, dev_info_t *devinfo); -extern int vsnprintf(char *str, size_t sz, const char *fmt, va_list ap); -#endif Index: sys/boot/efi/boot1/ufs_module.c =================================================================== --- sys/boot/efi/boot1/ufs_module.c +++ sys/boot/efi/boot1/ufs_module.c @@ -1,185 +0,0 @@ -/*- - * Copyright (c) 1998 Robert Nordier - * All rights reserved. - * Copyright (c) 2001 Robert Drehmel - * All rights reserved. - * Copyright (c) 2014 Nathan Whitehorn - * All rights reserved. - * Copyright (c) 2015 Eric McCorkle - * All rights reverved. - * - * 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. - * - * 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$ - */ - -#include -#include -#include -#include -#include - -#include "boot_module.h" - -static dev_info_t *devinfo; -static dev_info_t *devices; - -static int -dskread(void *buf, u_int64_t lba, int nblk) -{ - int size; - EFI_STATUS status; - - lba = lba / (devinfo->dev->Media->BlockSize / DEV_BSIZE); - size = nblk * DEV_BSIZE; - - status = devinfo->dev->ReadBlocks(devinfo->dev, - devinfo->dev->Media->MediaId, lba, size, buf); - - if (status != EFI_SUCCESS) { - DPRINTF("dskread: failed dev: %p, id: %u, lba: %ju, size: %d, " - "status: %lu\n", devinfo->dev, - devinfo->dev->Media->MediaId, (uintmax_t)lba, size, - EFI_ERROR_CODE(status)); - return (-1); - } - - return (0); -} - -#include "ufsread.c" - -static struct dmadat __dmadat; - -static int -init_dev(dev_info_t* dev) -{ - - devinfo = dev; - dmadat = &__dmadat; - - return fsread(0, NULL, 0); -} - -static EFI_STATUS -probe(dev_info_t* dev) -{ - - if (init_dev(dev) < 0) - return (EFI_UNSUPPORTED); - - add_device(&devices, dev); - - return (EFI_SUCCESS); -} - -static EFI_STATUS -load(const char *filepath, dev_info_t *dev, void **bufp, size_t *bufsize) -{ - ufs_ino_t ino; - EFI_STATUS status; - size_t size; - ssize_t read; - void *buf; - -#ifdef EFI_DEBUG - { - CHAR16 *text = efi_devpath_name(dev->devpath); - DPRINTF("Loading '%s' from %S\n", filepath, text); - efi_free_devpath_name(text); - } -#endif - if (init_dev(dev) < 0) { - DPRINTF("Failed to init device\n"); - return (EFI_UNSUPPORTED); - } - - if ((ino = lookup(filepath)) == 0) { - DPRINTF("Failed to lookup '%s' (file not found?)\n", filepath); - return (EFI_NOT_FOUND); - } - - if (fsread_size(ino, NULL, 0, &size) < 0 || size <= 0) { - printf("Failed to read size of '%s' ino: %d\n", filepath, ino); - return (EFI_INVALID_PARAMETER); - } - - if ((status = BS->AllocatePool(EfiLoaderData, size, &buf)) != - EFI_SUCCESS) { - printf("Failed to allocate read buffer %zu for '%s' (%lu)\n", - size, filepath, EFI_ERROR_CODE(status)); - return (status); - } - - read = fsread(ino, buf, size); - if ((size_t)read != size) { - printf("Failed to read '%s' (%zd != %zu)\n", filepath, read, - size); - (void)BS->FreePool(buf); - return (EFI_INVALID_PARAMETER); - } - - DPRINTF("Load complete\n"); - - *bufp = buf; - *bufsize = size; - - return (EFI_SUCCESS); -} - -static void -status(void) -{ - int i; - dev_info_t *dev; - - for (dev = devices, i = 0; dev != NULL; dev = dev->next, i++) - ; - - printf("%s found ", ufs_module.name); - switch (i) { - case 0: - printf("no partitions\n"); - break; - case 1: - printf("%d partition\n", i); - break; - default: - printf("%d partitions\n", i); - } -} - -static dev_info_t * -_devices(void) -{ - - return (devices); -} - -const boot_module_t ufs_module = -{ - .name = "UFS", - .probe = probe, - .load = load, - .status = status, - .devices = _devices -}; Index: sys/boot/efi/boot1/zfs_module.c =================================================================== --- sys/boot/efi/boot1/zfs_module.c +++ sys/boot/efi/boot1/zfs_module.c @@ -1,248 +0,0 @@ -/*- - * Copyright (c) 2015 Eric McCorkle - * All rights reserved. - * - * 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. - * - * 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$ - */ -#include -#include -#include -#include -#include -#include -#include - -#include "boot_module.h" - -#include "libzfs.h" -#include "zfsimpl.c" - -static dev_info_t *devices; - -uint64_t -ldi_get_size(void *priv) -{ - dev_info_t *devinfo = priv; - - return (devinfo->dev->Media->BlockSize * - (devinfo->dev->Media->LastBlock + 1)); -} - -static int -vdev_read(vdev_t *vdev, void *priv, off_t off, void *buf, size_t bytes) -{ - dev_info_t *devinfo; - uint64_t lba; - size_t size, remainder, rb_size, blksz; - char *bouncebuf = NULL, *rb_buf; - EFI_STATUS status; - - devinfo = (dev_info_t *)priv; - lba = off / devinfo->dev->Media->BlockSize; - remainder = off % devinfo->dev->Media->BlockSize; - - rb_buf = buf; - rb_size = bytes; - - /* - * If we have remainder from off, we need to add remainder part. - * Since buffer must be multiple of the BlockSize, round it all up. - */ - size = roundup2(bytes + remainder, devinfo->dev->Media->BlockSize); - blksz = size; - if (remainder != 0 || size != bytes) { - rb_size = devinfo->dev->Media->BlockSize; - bouncebuf = malloc(rb_size); - if (bouncebuf == NULL) { - printf("vdev_read: out of memory\n"); - return (-1); - } - rb_buf = bouncebuf; - blksz = rb_size - remainder; - } - - while (bytes > 0) { - status = devinfo->dev->ReadBlocks(devinfo->dev, - devinfo->dev->Media->MediaId, lba, rb_size, rb_buf); - if (EFI_ERROR(status)) - goto error; - if (bytes < blksz) - blksz = bytes; - if (bouncebuf != NULL) - memcpy(buf, rb_buf + remainder, blksz); - buf = (void *)((uintptr_t)buf + blksz); - bytes -= blksz; - lba++; - remainder = 0; - blksz = rb_size; - } - - free(bouncebuf); - return (0); - -error: - free(bouncebuf); - DPRINTF("vdev_read: failed dev: %p, id: %u, lba: %ju, size: %zu," - " rb_size: %zu, status: %lu\n", devinfo->dev, - devinfo->dev->Media->MediaId, (uintmax_t)lba, bytes, rb_size, - EFI_ERROR_CODE(status)); - return (-1); -} - -static EFI_STATUS -probe(dev_info_t *dev) -{ - spa_t *spa; - dev_info_t *tdev; - EFI_STATUS status; - - /* ZFS consumes the dev on success so we need a copy. */ - if ((status = BS->AllocatePool(EfiLoaderData, sizeof(*dev), - (void**)&tdev)) != EFI_SUCCESS) { - DPRINTF("Failed to allocate tdev (%lu)\n", - EFI_ERROR_CODE(status)); - return (status); - } - memcpy(tdev, dev, sizeof(*dev)); - - if (vdev_probe(vdev_read, tdev, &spa) != 0) { - (void)BS->FreePool(tdev); - return (EFI_UNSUPPORTED); - } - - dev->devdata = spa; - add_device(&devices, dev); - - return (EFI_SUCCESS); -} - -static EFI_STATUS -load(const char *filepath, dev_info_t *devinfo, void **bufp, size_t *bufsize) -{ - spa_t *spa; - struct zfsmount zfsmount; - dnode_phys_t dn; - struct stat st; - int err; - void *buf; - EFI_STATUS status; - - spa = devinfo->devdata; - -#ifdef EFI_DEBUG - { - CHAR16 *text = efi_devpath_name(devinfo->devpath); - DPRINTF("load: '%s' spa: '%s', devpath: %S\n", filepath, - spa->spa_name, text); - efi_free_devpath_name(text); - } -#endif - if ((err = zfs_spa_init(spa)) != 0) { - DPRINTF("Failed to load pool '%s' (%d)\n", spa->spa_name, err); - return (EFI_NOT_FOUND); - } - - if ((err = zfs_mount(spa, 0, &zfsmount)) != 0) { - DPRINTF("Failed to mount pool '%s' (%d)\n", spa->spa_name, err); - return (EFI_NOT_FOUND); - } - - if ((err = zfs_lookup(&zfsmount, filepath, &dn)) != 0) { - if (err == ENOENT) { - DPRINTF("Failed to find '%s' on pool '%s' (%d)\n", - filepath, spa->spa_name, err); - return (EFI_NOT_FOUND); - } - printf("Failed to lookup '%s' on pool '%s' (%d)\n", filepath, - spa->spa_name, err); - return (EFI_INVALID_PARAMETER); - } - - if ((err = zfs_dnode_stat(spa, &dn, &st)) != 0) { - printf("Failed to stat '%s' on pool '%s' (%d)\n", filepath, - spa->spa_name, err); - return (EFI_INVALID_PARAMETER); - } - - if ((status = BS->AllocatePool(EfiLoaderData, (UINTN)st.st_size, &buf)) - != EFI_SUCCESS) { - printf("Failed to allocate load buffer %jd for pool '%s' for '%s' " - "(%lu)\n", (intmax_t)st.st_size, spa->spa_name, filepath, EFI_ERROR_CODE(status)); - return (EFI_INVALID_PARAMETER); - } - - if ((err = dnode_read(spa, &dn, 0, buf, st.st_size)) != 0) { - printf("Failed to read node from %s (%d)\n", spa->spa_name, - err); - (void)BS->FreePool(buf); - return (EFI_INVALID_PARAMETER); - } - - *bufsize = st.st_size; - *bufp = buf; - - return (EFI_SUCCESS); -} - -static void -status(void) -{ - spa_t *spa; - - spa = STAILQ_FIRST(&zfs_pools); - if (spa == NULL) { - printf("%s found no pools\n", zfs_module.name); - return; - } - - printf("%s found the following pools:", zfs_module.name); - STAILQ_FOREACH(spa, &zfs_pools, spa_link) - printf(" %s", spa->spa_name); - - printf("\n"); -} - -static void -init(void) -{ - - zfs_init(); -} - -static dev_info_t * -_devices(void) -{ - - return (devices); -} - -const boot_module_t zfs_module = -{ - .name = "ZFS", - .init = init, - .probe = probe, - .load = load, - .status = status, - .devices = _devices -}; Index: sys/boot/efi/libefi/Makefile =================================================================== --- sys/boot/efi/libefi/Makefile +++ sys/boot/efi/libefi/Makefile @@ -3,16 +3,16 @@ .include .if ${MK_FORTH} != "no" -CFLAGS+= -DBOOT_FORTH -.include "${.CURDIR}/../../Makefile.ficl" +.include "../../ficl.mk" .endif LIB= efi INTERNALLIB= WARNS?= 2 -SRCS= delay.c devpath.c efi_console.c efichar.c efinet.c efipart.c env.c errno.c \ - handles.c wchar.c libefi.c efi_driver_utils.c efizfs.c devicename.c +SRCS= delay.c devpath.c efi_console.c efichar.c efinet.c efipart.c env.c \ + errno.c handles.c wchar.c libefi.c efi_driver_utils.c efizfs.c \ + devicename.c efi_main.c .if ${MACHINE_CPUARCH} == "amd64" || ${MACHINE_CPUARCH} == "i386" SRCS+= time.c @@ -35,6 +35,7 @@ .if ${MACHINE_ARCH} == "amd64" CFLAGS+= -fPIC -mno-red-zone .endif +CFLAGS+= -I${SYSDIR} CFLAGS+= -I${.CURDIR}/../include CFLAGS+= -I${.CURDIR}/../include/${MACHINE} .if ${MK_ZFS} != "no" Index: sys/boot/efi/loader/Makefile =================================================================== --- sys/boot/efi/loader/Makefile +++ sys/boot/efi/loader/Makefile @@ -11,12 +11,16 @@ WARNS?= 3 LOADER_NET_SUPPORT?= yes +LOADER_MSDOS_SUPPORT?= yes +LOADER_UFS_SUPPORT?= yes +LOADER_CD9660_SUPPORT?= no +LOADER_EXT2FS_SUPPORT?= no + # architecture-specific loader code SRCS= autoload.c \ bootinfo.c \ conf.c \ copy.c \ - efi_main.c \ main.c \ self_reloc.c \ smbios.c \ @@ -79,14 +83,6 @@ .endif .endif -.if ${MK_FORTH} != "no" -BOOT_FORTH= yes -CFLAGS+= -DBOOT_FORTH -CFLAGS+= -I${.CURDIR}/../../ficl -CFLAGS+= -I${.CURDIR}/../../ficl/${MACHINE_CPUARCH} -LIBFICL= ${.OBJDIR}/../../ficl/libficl.a -.endif - LOADER_FDT_SUPPORT?= no .if ${MK_FDT} != "no" && ${LOADER_FDT_SUPPORT} != "no" CFLAGS+= -I${.CURDIR}/../../fdt @@ -104,9 +100,7 @@ .endif # Always add MI sources -.PATH: ${.CURDIR}/../../common -.include "${.CURDIR}/../../common/Makefile.inc" -CFLAGS+= -I${.CURDIR}/../../common +.include "../../loader.mk" FILES+= loader.efi FILESMODE_loader.efi= ${BINMODE} Index: sys/boot/efi/loader/efi_main.c =================================================================== --- /dev/null +++ sys/boot/efi/loader/efi_main.c @@ -1,188 +0,0 @@ -/*- - * Copyright (c) 2000 Doug Rabson - * All rights reserved. - * - * 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. - * - * 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. - */ - -#include -__FBSDID("$FreeBSD$"); - -#include -#include -#include -#include - -static EFI_PHYSICAL_ADDRESS heap; -static UINTN heapsize; - -void -efi_exit(EFI_STATUS exit_code) -{ - - BS->FreePages(heap, EFI_SIZE_TO_PAGES(heapsize)); - BS->Exit(IH, exit_code, 0, NULL); -} - -void -exit(int status) -{ - - efi_exit(EFI_LOAD_ERROR); -} - -static CHAR16 * -arg_skipsep(CHAR16 *argp) -{ - - while (*argp == ' ' || *argp == '\t' || *argp == '\n') - argp++; - return (argp); -} - -static CHAR16 * -arg_skipword(CHAR16 *argp) -{ - - while (*argp && *argp != ' ' && *argp != '\t' && *argp != '\n') - argp++; - return (argp); -} - -EFI_STATUS -efi_main(EFI_HANDLE image_handle, EFI_SYSTEM_TABLE *system_table) -{ - static EFI_GUID image_protocol = LOADED_IMAGE_PROTOCOL; - static EFI_GUID console_control_protocol = - EFI_CONSOLE_CONTROL_PROTOCOL_GUID; - EFI_CONSOLE_CONTROL_PROTOCOL *console_control = NULL; - EFI_LOADED_IMAGE *img; - CHAR16 *argp, *args, **argv; - EFI_STATUS status; - int argc, addprog; - - IH = image_handle; - ST = system_table; - BS = ST->BootServices; - RS = ST->RuntimeServices; - - status = BS->LocateProtocol(&console_control_protocol, NULL, - (VOID **)&console_control); - if (status == EFI_SUCCESS) - (void)console_control->SetMode(console_control, - EfiConsoleControlScreenText); - - heapsize = 64 * 1024 * 1024; - status = BS->AllocatePages(AllocateAnyPages, EfiLoaderData, - EFI_SIZE_TO_PAGES(heapsize), &heap); - if (status != EFI_SUCCESS) - BS->Exit(IH, status, 0, NULL); - - setheap((void *)(uintptr_t)heap, (void *)(uintptr_t)(heap + heapsize)); - - /* Use efi_exit() from here on... */ - - status = BS->HandleProtocol(IH, &image_protocol, (VOID**)&img); - if (status != EFI_SUCCESS) - efi_exit(status); - - /* - * Pre-process the (optional) load options. If the option string - * is given as an ASCII string, we use a poor man's ASCII to - * Unicode-16 translation. The size of the option string as given - * to us includes the terminating null character. We assume the - * string is an ASCII string if strlen() plus the terminating - * '\0' is less than LoadOptionsSize. Even if all Unicode-16 - * characters have the upper 8 bits non-zero, the terminating - * null character will cause a one-off. - * If the string is already in Unicode-16, we make a copy so that - * we know we can always modify the string. - */ - if (img->LoadOptionsSize > 0 && img->LoadOptions != NULL) { - if (img->LoadOptionsSize == strlen(img->LoadOptions) + 1) { - args = malloc(img->LoadOptionsSize << 1); - for (argc = 0; argc < (int)img->LoadOptionsSize; argc++) - args[argc] = ((char*)img->LoadOptions)[argc]; - } else { - args = malloc(img->LoadOptionsSize); - memcpy(args, img->LoadOptions, img->LoadOptionsSize); - } - } else - args = NULL; - - /* - * Use a quick and dirty algorithm to build the argv vector. We - * first count the number of words. Then, after allocating the - * vector, we split the string up. We don't deal with quotes or - * other more advanced shell features. - * The EFI shell will pass the name of the image as the first - * word in the argument list. This does not happen if we're - * loaded by the boot manager. This is not so easy to figure - * out though. The ParentHandle is not always NULL, because - * there can be a function (=image) that will perform the task - * for the boot manager. - */ - /* Part 1: Figure out if we need to add our program name. */ - addprog = (args == NULL || img->ParentHandle == NULL || - img->FilePath == NULL) ? 1 : 0; - if (!addprog) { - addprog = - (DevicePathType(img->FilePath) != MEDIA_DEVICE_PATH || - DevicePathSubType(img->FilePath) != MEDIA_FILEPATH_DP || - DevicePathNodeLength(img->FilePath) <= - sizeof(FILEPATH_DEVICE_PATH)) ? 1 : 0; - if (!addprog) { - /* XXX todo. */ - } - } - /* Part 2: count words. */ - argc = (addprog) ? 1 : 0; - argp = args; - while (argp != NULL && *argp != 0) { - argp = arg_skipsep(argp); - if (*argp == 0) - break; - argc++; - argp = arg_skipword(argp); - } - /* Part 3: build vector. */ - argv = malloc((argc + 1) * sizeof(CHAR16*)); - argc = 0; - if (addprog) - argv[argc++] = (CHAR16 *)L"loader.efi"; - argp = args; - while (argp != NULL && *argp != 0) { - argp = arg_skipsep(argp); - if (*argp == 0) - break; - argv[argc++] = argp; - argp = arg_skipword(argp); - /* Terminate the words. */ - if (*argp != 0) - *argp++ = 0; - } - argv[argc] = NULL; - - status = main(argc, argv); - efi_exit(status); - return (status); -} Index: sys/boot/ficl.mk =================================================================== --- sys/boot/ficl.mk +++ sys/boot/ficl.mk @@ -2,7 +2,7 @@ # Common flags to build FICL related files -FICLDIR?= ${SRCTOP}/sys/boot/ficl +.include "defs.mk" .if ${MACHINE_CPUARCH} == "amd64" && defined(FICL32) FICL_CPUARCH= i386 @@ -26,8 +26,9 @@ CFLAGS+= -m32 -mcpu=powerpc -I. .endif -CFLAGS+= -I${FICLDIR} -I${FICLDIR}/${FICL_CPUARCH} \ - -I${FICLDIR}/../common +CFLAGS+= -I${FICLDIR} -I${FICLDIR}/${FICL_CPUARCH} -I${LDR_MI} +CFLAGS+= -DBOOT_FORTH +CFLAGS+= -DBF_DICTSIZE=15000 .if ${MACHINE_CPUARCH} == "amd64" && defined(FICL32) .if !exists(machine) Index: sys/boot/ficl/Makefile =================================================================== --- sys/boot/ficl/Makefile +++ sys/boot/ficl/Makefile @@ -1,7 +1,7 @@ # $FreeBSD$ # -.include "${.CURDIR}/../Makefile.ficl" +.include "../ficl.mk" BASE_SRCS= dict.c ficl.c fileaccess.c float.c loader.c math64.c \ prefix.c search.c stack.c tools.c vm.c words.c Index: sys/boot/i386/libi386/Makefile =================================================================== --- sys/boot/i386/libi386/Makefile +++ sys/boot/i386/libi386/Makefile @@ -1,5 +1,7 @@ # $FreeBSD$ # +.include "../../defs.mk" + LIB= i386 INTERNALLIB= @@ -12,13 +14,6 @@ .PATH: ${.CURDIR}/../../zfs SRCS+= devicename_stubs.c -.if defined(LOADER_TFTP_SUPPORT) -CFLAGS+= -DLOADER_TFTP_SUPPORT -.endif -.if defined(LOADER_NFS_SUPPORT) -CFLAGS+= -DLOADER_NFS_SUPPORT -.endif - BOOT_COMCONSOLE_PORT?= 0x3f8 CFLAGS+= -DCOMPORT=${BOOT_COMCONSOLE_PORT} Index: sys/boot/i386/loader/Makefile =================================================================== --- sys/boot/i386/loader/Makefile +++ sys/boot/i386/loader/Makefile @@ -13,6 +13,11 @@ LOADER_NFS_SUPPORT?= yes LOADER_TFTP_SUPPORT?= yes +LOADER_CD9660_SUPPORT?= no +LOADER_EXT2FS_SUPPORT?= no +LOADER_MSDOS_SUPPORT?= no +LOADER_UFS_SUPPORT?= yes + # architecture-specific loader code SRCS= main.c conf.c vers.c chain.c @@ -28,13 +33,6 @@ LIBZFSBOOT= ${.OBJDIR}/../../zfs/libzfsboot.a .endif -.if defined(LOADER_TFTP_SUPPORT) -CFLAGS+= -DLOADER_TFTP_SUPPORT -.endif -.if defined(LOADER_NFS_SUPPORT) -CFLAGS+= -DLOADER_NFS_SUPPORT -.endif - # Include bcache code. HAVE_BCACHE= yes @@ -42,27 +40,7 @@ HAVE_PNP= yes HAVE_ISABUS= yes -.if ${MK_FORTH} != "no" -# Enable BootForth -BOOT_FORTH= yes -CFLAGS+= -DBOOT_FORTH -I${.CURDIR}/../../ficl -I${.CURDIR}/../../ficl/i386 -.if ${MACHINE_CPUARCH} == "amd64" -LIBFICL= ${.OBJDIR}/../../ficl32/libficl.a -.else -LIBFICL= ${.OBJDIR}/../../ficl/libficl.a -.endif -.endif - -.if defined(LOADER_BZIP2_SUPPORT) -CFLAGS+= -DLOADER_BZIP2_SUPPORT -.endif -.if !defined(LOADER_NO_GZIP_SUPPORT) -CFLAGS+= -DLOADER_GZIP_SUPPORT -.endif -.if defined(LOADER_NANDFS_SUPPORT) -CFLAGS+= -DLOADER_NANDFS_SUPPORT -.endif -.if !defined(LOADER_NO_GELI_SUPPORT) +.if ${LOADER_GELI_SUPPORT:Uyes} == "yes" CFLAGS+= -DLOADER_GELI_SUPPORT CFLAGS+= -I${.CURDIR}/../../geli LIBGELIBOOT= ${.OBJDIR}/../../geli/libgeliboot.a @@ -72,9 +50,7 @@ .endif # Always add MI sources -.PATH: ${.CURDIR}/../../common -.include "${.CURDIR}/../../common/Makefile.inc" -CFLAGS+= -I${.CURDIR}/../../common +.include "../../loader.mk" CFLAGS+= -I. CLEANFILES= ${LOADER} ${LOADER}.bin loader.help @@ -104,7 +80,7 @@ strip -R .comment -R .note -o ${.TARGET} ${.ALLSRC} loader.help: help.common help.i386 - cat ${.ALLSRC} | awk -f ${.CURDIR}/../../common/merge_help.awk > ${.TARGET} + cat ${.ALLSRC} | awk -f ${LDR_MI}/merge_help.awk > ${.TARGET} FILES= ${LOADER} # XXX INSTALLFLAGS_loader= -b @@ -121,8 +97,15 @@ # XXX crt0.o needs to be first for pxeboot(8) to work OBJS= ${BTXCRT} -DPADD= ${LIBFICL} ${LIBFIREWIRE} ${LIBZFSBOOT} ${LIBI386} ${LIBGELIBOOT} ${LIBSA32} -LDADD= ${LIBFICL} ${LIBFIREWIRE} ${LIBZFSBOOT} ${LIBI386} ${LIBGELIBOOT} ${LIBSA32} +# XXX not happy with this construct, revisit +.if ${MACHINE_CPUARCH} == "amd64" +FICL= ${LIBFICL32} +.else +FICL= ${LIBFICL} +.endif + +DPADD= ${FICL} ${LIBFIREWIRE} ${LIBZFSBOOT} ${LIBI386} ${LIBGELIBOOT} ${LIBSA32} +LDADD= ${FICL} ${LIBFIREWIRE} ${LIBZFSBOOT} ${LIBI386} ${LIBGELIBOOT} ${LIBSA32} .include Index: sys/boot/i386/zfsboot/Makefile =================================================================== --- sys/boot/i386/zfsboot/Makefile +++ sys/boot/i386/zfsboot/Makefile @@ -1,5 +1,7 @@ # $FreeBSD$ +LOADER_GELI_SUPPORT=no + .include "../Makefile.inc" .PATH: ${.CURDIR}/../boot2 ${.CURDIR}/../common \ Index: sys/boot/libsa/Makefile =================================================================== --- sys/boot/libsa/Makefile +++ sys/boot/libsa/Makefile @@ -21,7 +21,7 @@ NO_PIC= WARNS?= 0 -CFLAGS+= -I${SASRC} +CFLAGS+= -I${SASRC} -I${SYSDIR} # standalone components and stuff we have modified locally SRCS+= gzguts.h zutil.h __main.c assert.c bcd.c environment.c getopt.c gets.c \ Index: sys/boot/loader.mk =================================================================== --- sys/boot/loader.mk +++ sys/boot/loader.mk @@ -1,6 +1,10 @@ # $FreeBSD$ -.PATH: ${SRCTOP}/sys/boot/common ${SRCTOP}/sys/boot/libsa +.include "defs.mk" + +.PATH: ${LDR_MI} ${BOOTDIR}/libsa + +CFLAGS+=-I${LDR_MI} SRCS+= boot.c commands.c console.c devopen.c interp.c SRCS+= interp_backslash.c interp_parse.c ls.c misc.c @@ -24,22 +28,12 @@ SRCS+= load_elf32.c reloc_elf32.c .endif -.if defined(LOADER_NET_SUPPORT) -SRCS+= dev_net.c -.endif - -.if !defined(LOADER_NO_DISK_SUPPORT) +.if ${LOADER_DISK_SUPPORT:Uyes} == "yes" SRCS+= disk.c part.c -CFLAGS+= -DLOADER_DISK_SUPPORT -.if !defined(LOADER_NO_GPT_SUPPORT) -CFLAGS+= -DLOADER_GPT_SUPPORT .endif -.if !defined(LOADER_NO_MBR_SUPPORT) -CFLAGS+= -DLOADER_MBR_SUPPORT -.endif -.endif -.if !defined(LOADER_NO_GELI_SUPPORT) -CFLAGS+= -DLOADER_GELI_SUPPORT + +.if ${LOADER_NET_SUPPORT:Uno} == "yes" +SRCS+= dev_net.c .endif .if defined(HAVE_BCACHE) @@ -60,9 +54,9 @@ .endif # Forth interpreter -.if defined(BOOT_FORTH) +.if ${MK_FORTH} != "no" SRCS+= interp_forth.c -.include "${SRCTOP}/sys/boot/Makefile.ficl" +.include "${BOOTDIR}/ficl.mk" .endif .if defined(BOOT_PROMPT_123) @@ -78,6 +72,6 @@ .if ${MK_REPRODUCIBLE_BUILD} != no REPRO_FLAG= -r .endif -vers.c: ${SRCTOP}/sys/boot/common/newvers.sh ${VERSION_FILE} - sh ${SRCTOP}/sys/boot/common/newvers.sh ${REPRO_FLAG} ${VERSION_FILE} \ +vers.c: ${LDR_MI}/newvers.sh ${VERSION_FILE} + sh ${LDR_MI}/newvers.sh ${REPRO_FLAG} ${VERSION_FILE} \ ${NEWVERSWHAT} Index: sys/boot/mips/beri/loader/Makefile =================================================================== --- sys/boot/mips/beri/loader/Makefile +++ sys/boot/mips/beri/loader/Makefile @@ -59,31 +59,15 @@ # Since we don't have a backward compatibility issue, default to this on BERI. CFLAGS+= -DBOOT_PROMPT_123 -CFLAGS+= -DLOADER_DISK_SUPPORT -CFLAGS+= -DLOADER_UFS_SUPPORT -CFLAGS+= -DLOADER_GZIP_SUPPORT -CFLAGS+= -DLOADER_BZIP2_SUPPORT - -#CFLAGS+= -DLOADER_NET_SUPPORT -#CFLAGS+= -DLOADER_NFS_SUPPORT -#CFLAGS+= -DLOADER_TFTP_SUPPORT - -.if ${MK_FORTH} != "no" -# Enable BootForth -BOOT_FORTH= yes -CFLAGS+= -DBOOT_FORTH -I${.CURDIR}/../../../ficl -CFLAGS+= -I${.CURDIR}/../../../ficl/mips64 -LIBFICL= ${.OBJDIR}/../../../ficl/libficl.a -.endif - -# Common code across BERI boot loader parts -.PATH: ${.CURDIR}/../common -CFLAGS+= -I${.CURDIR}/../common +LOADER_MSDOS_SUPPORT?= yes +LOADER_UFS_SUPPORT?= yes +LOADER_CD9660_SUPPORT?= no +LOADER_EXT2FS_SUPPORT?= no +LOADER_GZIP_SUPPORT?= yes +LOADER_BZIP2_SUPPORT?= yes # Always add MI sources -.PATH: ${.CURDIR}/../../../common -.include "${.CURDIR}/../../../common/Makefile.inc" -CFLAGS+= -I${.CURDIR}/../../../common +.include "../../../loader.mk" # BERI files common to boot2 and loader .PATH: ${.CURDIR}/../common @@ -112,7 +96,7 @@ loader.help: help.common help.mips cat ${.ALLSRC} | \ - awk -f ${.CURDIR}/../../../common/merge_help.awk > ${.TARGET} + awk -f ${LDR_MI}/merge_help.awk > ${.TARGET} .PATH: ${.CURDIR}/../../../forth .include "${.CURDIR}/../../../forth/Makefile.inc" Index: sys/boot/mips/uboot/Makefile =================================================================== --- sys/boot/mips/uboot/Makefile +++ sys/boot/mips/uboot/Makefile @@ -15,64 +15,17 @@ # Architecture-specific loader code SRCS= start.S conf.c vers.c -.if !defined(LOADER_NO_DISK_SUPPORT) -LOADER_DISK_SUPPORT?= yes -.else -LOADER_DISK_SUPPORT= no -.endif -LOADER_MSDOS_SUPPORT?= yes -LOADER_UFS_SUPPORT?= yes LOADER_CD9660_SUPPORT?= no LOADER_EXT2FS_SUPPORT?= no -.if ${MK_NAND} != "no" -LOADER_NANDFS_SUPPORT?= yes -.else -LOADER_NANDFS_SUPPORT?= no -.endif +LOADER_MSDOS_SUPPORT?= yes +LOADER_UFS_SUPPORT?= yes LOADER_NET_SUPPORT?= yes LOADER_NFS_SUPPORT?= yes LOADER_TFTP_SUPPORT?= no LOADER_GZIP_SUPPORT?= no LOADER_BZIP2_SUPPORT?= no -.if ${MK_FDT} != "no" -LOADER_FDT_SUPPORT= yes -.else -LOADER_FDT_SUPPORT= no -.endif +LOADER_FDT_SUPPORT= ${MK_FDT} -.if ${LOADER_DISK_SUPPORT} == "yes" -CFLAGS+= -DLOADER_DISK_SUPPORT -.endif -.if ${LOADER_MSDOS_SUPPORT} == "yes" -CFLAGS+= -DLOADER_MSDOS_SUPPORT -.endif -.if ${LOADER_UFS_SUPPORT} == "yes" -CFLAGS+= -DLOADER_UFS_SUPPORT -.endif -.if ${LOADER_CD9660_SUPPORT} == "yes" -CFLAGS+= -DLOADER_CD9660_SUPPORT -.endif -.if ${LOADER_EXT2FS_SUPPORT} == "yes" -CFLAGS+= -DLOADER_EXT2FS_SUPPORT -.endif -.if ${LOADER_NANDFS_SUPPORT} == "yes" -CFLAGS+= -DLOADER_NANDFS_SUPPORT -.endif -.if ${LOADER_GZIP_SUPPORT} == "yes" -CFLAGS+= -DLOADER_GZIP_SUPPORT -.endif -.if ${LOADER_BZIP2_SUPPORT} == "yes" -CFLAGS+= -DLOADER_BZIP2_SUPPORT -.endif -.if ${LOADER_NET_SUPPORT} == "yes" -CFLAGS+= -DLOADER_NET_SUPPORT -.endif -.if ${LOADER_NFS_SUPPORT} == "yes" -CFLAGS+= -DLOADER_NFS_SUPPORT -.endif -.if ${LOADER_TFTP_SUPPORT} == "yes" -CFLAGS+= -DLOADER_TFTP_SUPPORT -.endif .if ${LOADER_FDT_SUPPORT} == "yes" CFLAGS+= -I${.CURDIR}/../../fdt CFLAGS+= -I${.OBJDIR}/../../fdt @@ -81,22 +34,8 @@ LIBFDT= ${.OBJDIR}/../../fdt/libfdt.a .endif -.if ${MK_FORTH} != "no" -# Enable BootForth -BOOT_FORTH= yes -CFLAGS+= -DBOOT_FORTH -I${.CURDIR}/../../ficl -.if ${MACHINE_ARCH:Mmips64*} != "" -CFLAGS+= -I${.CURDIR}/../../ficl/mips64 -.else -CFLAGS+= -I${.CURDIR}/../../ficl/mips -.endif -LIBFICL= ${.OBJDIR}/../../ficl/libficl.a -.endif - # Always add MI sources -.PATH: ${.CURDIR}/../../common -.include "${.CURDIR}/../../common/Makefile.inc" -CFLAGS+= -I${.CURDIR}/../../common +.include "../../loader.mk" CFLAGS+= -I. CLEANFILES+= loader.help @@ -126,7 +65,7 @@ loader.help: help.common help.uboot ${.CURDIR}/../../fdt/help.fdt cat ${.ALLSRC} | \ - awk -f ${.CURDIR}/../../common/merge_help.awk > ${.TARGET} + awk -f ${LDR_MI}/merge_help.awk > ${.TARGET} ldscript.abs: echo "UBLDR_LOADADDR = ${UBLDR_LOADADDR};" >${.TARGET} Index: sys/boot/powerpc/kboot/Makefile =================================================================== --- sys/boot/powerpc/kboot/Makefile +++ sys/boot/powerpc/kboot/Makefile @@ -14,10 +14,10 @@ SRCS+= host_syscall.S hostcons.c hostdisk.c kerneltramp.S kbootfdt.c SRCS+= ucmpdi2.c -LOADER_DISK_SUPPORT?= yes -LOADER_UFS_SUPPORT?= yes LOADER_CD9660_SUPPORT?= yes +LOADER_MSDOS_SUPPORT?= no LOADER_EXT2FS_SUPPORT?= yes +LOADER_UFS_SUPPORT?= yes LOADER_NET_SUPPORT?= yes LOADER_NFS_SUPPORT?= yes LOADER_TFTP_SUPPORT?= no @@ -25,33 +25,6 @@ LOADER_FDT_SUPPORT= yes LOADER_BZIP2_SUPPORT?= no -.if ${LOADER_DISK_SUPPORT} == "yes" -CFLAGS+= -DLOADER_DISK_SUPPORT -.endif -.if ${LOADER_UFS_SUPPORT} == "yes" -CFLAGS+= -DLOADER_UFS_SUPPORT -.endif -.if ${LOADER_CD9660_SUPPORT} == "yes" -CFLAGS+= -DLOADER_CD9660_SUPPORT -.endif -.if ${LOADER_EXT2FS_SUPPORT} == "yes" -CFLAGS+= -DLOADER_EXT2FS_SUPPORT -.endif -.if ${LOADER_GZIP_SUPPORT} == "yes" -CFLAGS+= -DLOADER_GZIP_SUPPORT -.endif -.if ${LOADER_BZIP2_SUPPORT} == "yes" -CFLAGS+= -DLOADER_BZIP2_SUPPORT -.endif -.if ${LOADER_NET_SUPPORT} == "yes" -CFLAGS+= -DLOADER_NET_SUPPORT -.endif -.if ${LOADER_NFS_SUPPORT} == "yes" -CFLAGS+= -DLOADER_NFS_SUPPORT -.endif -.if ${LOADER_TFTP_SUPPORT} == "yes" -CFLAGS+= -DLOADER_TFTP_SUPPORT -.endif .if ${LOADER_FDT_SUPPORT} == "yes" CFLAGS+= -I${.CURDIR}/../../fdt CFLAGS+= -I${.OBJDIR}/../../fdt @@ -60,21 +33,12 @@ LIBFDT= ${.OBJDIR}/../../fdt/libfdt.a .endif - -.if ${MK_FORTH} != "no" -# Enable BootForth -BOOT_FORTH= yes -CFLAGS+= -DBOOT_FORTH -I${.CURDIR}/../../ficl -CFLAGS+= -I${.CURDIR}/../../ficl/powerpc -LIBFICL= ${.OBJDIR}/../../ficl/libficl.a -.endif - CFLAGS+= -mcpu=powerpc64 # Always add MI sources -.PATH: ${.CURDIR}/../../common ${.CURDIR}/../../../libkern -.include "${.CURDIR}/../../common/Makefile.inc" -CFLAGS+= -I${.CURDIR}/../../common -I${.CURDIR}/../../.. +.include "../../loader.mk" +.PATH: ${.CURDIR}/../../../libkern +CFLAGS+= -I${.CURDIR}/../../.. CFLAGS+= -I. CLEANFILES+= loader.help @@ -98,7 +62,7 @@ loader.help: help.common help.kboot ${.CURDIR}/../../fdt/help.fdt cat ${.ALLSRC} | \ - awk -f ${.CURDIR}/../../common/merge_help.awk > ${.TARGET} + awk -f ${LDR_MI}/merge_help.awk > ${.TARGET} .PATH: ${.CURDIR}/../../forth .include "${.CURDIR}/../../forth/Makefile.inc" Index: sys/boot/powerpc/ofw/Makefile =================================================================== --- sys/boot/powerpc/ofw/Makefile +++ sys/boot/powerpc/ofw/Makefile @@ -13,10 +13,10 @@ SRCS= conf.c metadata.c vers.c start.c SRCS+= ucmpdi2.c -LOADER_DISK_SUPPORT?= yes -LOADER_UFS_SUPPORT?= yes LOADER_CD9660_SUPPORT?= yes LOADER_EXT2FS_SUPPORT?= no +LOADER_MSDOS_SUPPORT?= no +LOADER_UFS_SUPPORT?= yes LOADER_NET_SUPPORT?= yes LOADER_NFS_SUPPORT?= yes LOADER_TFTP_SUPPORT?= no @@ -24,33 +24,6 @@ LOADER_BZIP2_SUPPORT?= no LOADER_FDT_SUPPORT?= yes -.if ${LOADER_DISK_SUPPORT} == "yes" -CFLAGS+= -DLOADER_DISK_SUPPORT -.endif -.if ${LOADER_UFS_SUPPORT} == "yes" -CFLAGS+= -DLOADER_UFS_SUPPORT -.endif -.if ${LOADER_CD9660_SUPPORT} == "yes" -CFLAGS+= -DLOADER_CD9660_SUPPORT -.endif -.if ${LOADER_EXT2FS_SUPPORT} == "yes" -CFLAGS+= -DLOADER_EXT2FS_SUPPORT -.endif -.if ${LOADER_GZIP_SUPPORT} == "yes" -CFLAGS+= -DLOADER_GZIP_SUPPORT -.endif -.if ${LOADER_BZIP2_SUPPORT} == "yes" -CFLAGS+= -DLOADER_BZIP2_SUPPORT -.endif -.if ${LOADER_NET_SUPPORT} == "yes" -CFLAGS+= -DLOADER_NET_SUPPORT -.endif -.if ${LOADER_NFS_SUPPORT} == "yes" -CFLAGS+= -DLOADER_NFS_SUPPORT -.endif -.if ${LOADER_TFTP_SUPPORT} == "yes" -CFLAGS+= -DLOADER_TFTP_SUPPORT -.endif .if ${LOADER_FDT_SUPPORT} == "yes" SRCS+= ofwfdt.c CFLAGS+= -I${.CURDIR}/../../fdt @@ -60,18 +33,11 @@ LIBFDT= ${.OBJDIR}/../../fdt/libfdt.a .endif -.if ${MK_FORTH} != "no" -# Enable BootForth -BOOT_FORTH= yes -CFLAGS+= -DBOOT_FORTH -I${.CURDIR}/../../ficl -CFLAGS+= -I${.CURDIR}/../../ficl/powerpc -LIBFICL= ${.OBJDIR}/../../ficl/libficl.a -.endif - # Always add MI sources -.PATH: ${.CURDIR}/../../common ${.CURDIR}/../../../libkern -.include "${.CURDIR}/../../common/Makefile.inc" -CFLAGS+= -I${.CURDIR}/../../common -I${.CURDIR}/../../.. +.include "../../loader.mk" + +.PATH: ${.CURDIR}/../../../libkern +CFLAGS+= -I${.CURDIR}/../../.. CFLAGS+= -I. CLEANFILES+= loader.help @@ -96,7 +62,7 @@ loader.help: help.common help.ofw ${.CURDIR}/../../fdt/help.fdt cat ${.ALLSRC} | \ - awk -f ${.CURDIR}/../../common/merge_help.awk > ${.TARGET} + awk -f ${LDR_MI}/merge_help.awk > ${.TARGET} .PATH: ${.CURDIR}/../../forth .include "${.CURDIR}/../../forth/Makefile.inc" Index: sys/boot/powerpc/ps3/Makefile =================================================================== --- sys/boot/powerpc/ps3/Makefile +++ sys/boot/powerpc/ps3/Makefile @@ -15,7 +15,6 @@ ps3stor.c ps3disk.c ps3cdrom.c SRCS+= ucmpdi2.c -LOADER_DISK_SUPPORT?= yes LOADER_UFS_SUPPORT?= yes LOADER_CD9660_SUPPORT?= yes LOADER_EXT2FS_SUPPORT?= yes @@ -26,33 +25,6 @@ LOADER_FDT_SUPPORT?= no LOADER_BZIP2_SUPPORT?= no -.if ${LOADER_DISK_SUPPORT} == "yes" -CFLAGS+= -DLOADER_DISK_SUPPORT -.endif -.if ${LOADER_UFS_SUPPORT} == "yes" -CFLAGS+= -DLOADER_UFS_SUPPORT -.endif -.if ${LOADER_CD9660_SUPPORT} == "yes" -CFLAGS+= -DLOADER_CD9660_SUPPORT -.endif -.if ${LOADER_EXT2FS_SUPPORT} == "yes" -CFLAGS+= -DLOADER_EXT2FS_SUPPORT -.endif -.if ${LOADER_GZIP_SUPPORT} == "yes" -CFLAGS+= -DLOADER_GZIP_SUPPORT -.endif -.if ${LOADER_BZIP2_SUPPORT} == "yes" -CFLAGS+= -DLOADER_BZIP2_SUPPORT -.endif -.if ${LOADER_NET_SUPPORT} == "yes" -CFLAGS+= -DLOADER_NET_SUPPORT -.endif -.if ${LOADER_NFS_SUPPORT} == "yes" -CFLAGS+= -DLOADER_NFS_SUPPORT -.endif -.if ${LOADER_TFTP_SUPPORT} == "yes" -CFLAGS+= -DLOADER_TFTP_SUPPORT -.endif .if ${LOADER_FDT_SUPPORT} == "yes" CFLAGS+= -I${.CURDIR}/../../fdt CFLAGS+= -I${.OBJDIR}/../../fdt @@ -60,21 +32,12 @@ LIBFDT= ${.OBJDIR}/../../fdt/libfdt.a .endif - -.if ${MK_FORTH} != "no" -# Enable BootForth -BOOT_FORTH= yes -CFLAGS+= -DBOOT_FORTH -I${.CURDIR}/../../ficl -CFLAGS+= -I${.CURDIR}/../../ficl/powerpc -LIBFICL= ${.OBJDIR}/../../ficl/libficl.a -.endif - CFLAGS+= -mcpu=powerpc64 # Always add MI sources -.PATH: ${.CURDIR}/../../common ${.CURDIR}/../../../libkern -.include "${.CURDIR}/../../common/Makefile.inc" -CFLAGS+= -I${.CURDIR}/../../common -I${.CURDIR}/../../.. +.include "../../loader.mk" +.PATH: ${.CURDIR}/../../../libkern +CFLAGS+= -I${.CURDIR}/../../.. CFLAGS+= -I. CLEANFILES+= loader.help @@ -100,7 +63,7 @@ loader.help: help.common help.ps3 ${.CURDIR}/../../fdt/help.fdt cat ${.ALLSRC} | \ - awk -f ${.CURDIR}/../../common/merge_help.awk > ${.TARGET} + awk -f ${LDR_MI}/merge_help.awk > ${.TARGET} .PATH: ${.CURDIR}/../../forth .include "${.CURDIR}/../../forth/Makefile.inc" Index: sys/boot/powerpc/uboot/Makefile =================================================================== --- sys/boot/powerpc/uboot/Makefile +++ sys/boot/powerpc/uboot/Makefile @@ -12,11 +12,6 @@ SRCS= start.S conf.c vers.c SRCS+= ucmpdi2.c -.if !defined(LOADER_NO_DISK_SUPPORT) -LOADER_DISK_SUPPORT?= yes -.else -LOADER_DISK_SUPPORT= no -.endif LOADER_UFS_SUPPORT?= yes LOADER_CD9660_SUPPORT?= no LOADER_EXT2FS_SUPPORT?= no @@ -25,39 +20,8 @@ LOADER_TFTP_SUPPORT?= no LOADER_GZIP_SUPPORT?= no LOADER_BZIP2_SUPPORT?= no -.if ${MK_FDT} != "no" -LOADER_FDT_SUPPORT= yes -.else -LOADER_FDT_SUPPORT= no -.endif +LOADER_FDT_SUPPORT= ${MK_FDT} -.if ${LOADER_DISK_SUPPORT} == "yes" -CFLAGS+= -DLOADER_DISK_SUPPORT -.endif -.if ${LOADER_UFS_SUPPORT} == "yes" -CFLAGS+= -DLOADER_UFS_SUPPORT -.endif -.if ${LOADER_CD9660_SUPPORT} == "yes" -CFLAGS+= -DLOADER_CD9660_SUPPORT -.endif -.if ${LOADER_EXT2FS_SUPPORT} == "yes" -CFLAGS+= -DLOADER_EXT2FS_SUPPORT -.endif -.if ${LOADER_GZIP_SUPPORT} == "yes" -CFLAGS+= -DLOADER_GZIP_SUPPORT -.endif -.if ${LOADER_BZIP2_SUPPORT} == "yes" -CFLAGS+= -DLOADER_BZIP2_SUPPORT -.endif -.if ${LOADER_NET_SUPPORT} == "yes" -CFLAGS+= -DLOADER_NET_SUPPORT -.endif -.if ${LOADER_NFS_SUPPORT} == "yes" -CFLAGS+= -DLOADER_NFS_SUPPORT -.endif -.if ${LOADER_TFTP_SUPPORT} == "yes" -CFLAGS+= -DLOADER_TFTP_SUPPORT -.endif .if ${LOADER_FDT_SUPPORT} == "yes" CFLAGS+= -I${.CURDIR}/../../fdt CFLAGS+= -I${.OBJDIR}/../../fdt @@ -66,18 +30,10 @@ LIBFDT= ${.OBJDIR}/../../fdt/libfdt.a .endif -.if ${MK_FORTH} != "no" -# Enable BootForth -BOOT_FORTH= yes -CFLAGS+= -DBOOT_FORTH -I${.CURDIR}/../../ficl -CFLAGS+= -I${.CURDIR}/../../ficl/powerpc -LIBFICL= ${.OBJDIR}/../../ficl/libficl.a -.endif - # Always add MI sources -.PATH: ${.CURDIR}/../../common ${.CURDIR}/../../../libkern -.include "${.CURDIR}/../../common/Makefile.inc" -CFLAGS+= -I${.CURDIR}/../../common -I${.CURDIR}/../../.. +.include "../../loader.mk" +.PATH: ${.CURDIR}/../../../libkern +CFLAGS+= -I${.CURDIR}/../../.. CFLAGS+= -I. CLEANFILES+= ${PROG}.help @@ -101,7 +57,7 @@ loader.help: help.common help.uboot ${.CURDIR}/../../fdt/help.fdt cat ${.ALLSRC} | \ - awk -f ${.CURDIR}/../../common/merge_help.awk > ${.TARGET} + awk -f ${LDR_MI}/merge_help.awk > ${.TARGET} .PATH: ${.CURDIR}/../../forth FILES= loader.help Index: sys/boot/sparc64/loader/Makefile =================================================================== --- sys/boot/sparc64/loader/Makefile +++ sys/boot/sparc64/loader/Makefile @@ -15,6 +15,8 @@ LOADER_DISK_SUPPORT?= yes LOADER_UFS_SUPPORT?= yes LOADER_CD9660_SUPPORT?= yes +LOADER_EXT2FS_SUPPORT?= no +LOADER_MSDOS_SUPPORT?= no LOADER_ZFS_SUPPORT?= no LOADER_NET_SUPPORT?= yes LOADER_NFS_SUPPORT?= yes @@ -26,49 +28,15 @@ .if ${LOADER_DEBUG} == "yes" CFLAGS+= -DLOADER_DEBUG .endif -.if ${LOADER_DISK_SUPPORT} == "yes" -CFLAGS+= -DLOADER_DISK_SUPPORT -.endif -.if ${LOADER_UFS_SUPPORT} == "yes" -CFLAGS+= -DLOADER_UFS_SUPPORT -.endif -.if ${LOADER_CD9660_SUPPORT} == "yes" -CFLAGS+= -DLOADER_CD9660_SUPPORT -.endif .if ${LOADER_ZFS_SUPPORT} == "yes" CFLAGS+= -DLOADER_ZFS_SUPPORT CFLAGS+= -I${.CURDIR}/../../zfs CFLAGS+= -I${.CURDIR}/../../../cddl/boot/zfs LIBZFSBOOT= ${.OBJDIR}/../../zfs/libzfsboot.a .endif -.if ${LOADER_GZIP_SUPPORT} == "yes" -CFLAGS+= -DLOADER_GZIP_SUPPORT -.endif -.if ${LOADER_BZIP2_SUPPORT} == "yes" -CFLAGS+= -DLOADER_BZIP2_SUPPORT -.endif -.if ${LOADER_NET_SUPPORT} == "yes" -CFLAGS+= -DLOADER_NET_SUPPORT -.endif -.if ${LOADER_NFS_SUPPORT} == "yes" -CFLAGS+= -DLOADER_NFS_SUPPORT -.endif -.if ${LOADER_TFTP_SUPPORT} == "yes" -CFLAGS+= -DLOADER_TFTP_SUPPORT -.endif - -.if ${MK_FORTH} != "no" -# Enable BootForth -BOOT_FORTH= yes -CFLAGS+= -DBOOT_FORTH -I${.CURDIR}/../../ficl -CFLAGS+= -I${.CURDIR}/../../ficl/sparc64 -LIBFICL= ${.OBJDIR}/../../ficl/libficl.a -.endif # Always add MI sources -.PATH: ${.CURDIR}/../../common -.include "${.CURDIR}/../../common/Makefile.inc" -CFLAGS+= -I${.CURDIR}/../../common +.include "../../loader.mk" CFLAGS+= -I. CLEANFILES+= loader.help @@ -87,7 +55,7 @@ loader.help: help.common help.sparc64 cat ${.ALLSRC} | \ - awk -f ${.CURDIR}/../../common/merge_help.awk > ${.TARGET} + awk -f ${LDR_MI}/merge_help.awk > ${.TARGET} .PATH: ${.CURDIR}/../../forth .include "${.CURDIR}/../../forth/Makefile.inc" Index: sys/boot/uboot/lib/Makefile =================================================================== --- sys/boot/uboot/lib/Makefile +++ sys/boot/uboot/lib/Makefile @@ -13,11 +13,6 @@ CFLAGS+= -ffreestanding -msoft-float -.if !defined(LOADER_NO_DISK_SUPPORT) -SRCS+= disk.c -CFLAGS+= -DLOADER_DISK_SUPPORT -.endif - .if ${MK_FDT} != "no" LOADER_FDT_SUPPORT= yes .else Index: sys/boot/userboot/userboot/Makefile =================================================================== --- sys/boot/userboot/userboot/Makefile +++ sys/boot/userboot/userboot/Makefile @@ -5,6 +5,11 @@ .include MK_SSP= no +LOADER_MSDOS_SUPPORT?= yes +LOADER_UFS_SUPPORT?= yes +LOADER_CD9660_SUPPORT?= no +LOADER_EXT2FS_SUPPORT?= no + SHLIB_NAME= userboot.so MK_CTF= no STRIP= @@ -30,7 +35,6 @@ CFLAGS+= -Wall CFLAGS+= -I${.CURDIR}/.. -CFLAGS+= -I${.CURDIR}/../../common CFLAGS+= -I${.CURDIR}/../../.. CFLAGS+= -ffreestanding -I. @@ -40,23 +44,13 @@ NEWVERSWHAT= "User boot" ${MACHINE_CPUARCH} -.if ${MK_FORTH} != "no" -BOOT_FORTH= yes -CFLAGS+= -DBOOT_FORTH -I${.CURDIR}/../../ficl -CFLAGS+= -I${.CURDIR}/../../ficl/i386 -CFLAGS+= -DBF_DICTSIZE=15000 -LIBFICL= ${.OBJDIR}/../ficl/libficl.a -.endif - .if ${MK_ZFS} != "no" CFLAGS+= -DUSERBOOT_ZFS_SUPPORT LIBZFSBOOT= ${.OBJDIR}/../zfs/libzfsboot.a .endif # Always add MI sources -.PATH: ${.CURDIR}/../../common -.include "${.CURDIR}/../../common/Makefile.inc" -CFLAGS+= -I${.CURDIR}/../../common +.include "../../loader.mk" CFLAGS+= -I. DPADD+= ${LIBFICL} ${LIBZFSBOOT} ${LIBSA} LDADD+= ${LIBFICL} ${LIBZFSBOOT} ${LIBSA}