Skip site navigation (1)Skip section navigation (2)

FreeBSD Manual Pages

  
 
  

home | help
LOADER.EFI(8)		     System Manager's Manual		   LOADER.EFI(8)

NAME
     loader.efi -- UEFI kernel loader

DESCRIPTION
     On UEFI systems, loader.efi loads the kernel.

     loader.efi  is invoked directly from the EFI System Partition (ESP) on sys-
     tems installed using bsdinstall(8), when installed as the default EFI  boot
     program  as  described  in  uefi(8) or when configured as an EFI boot entry
     with efibootmgr(8).

     On systems upgraded from FreeBSD 10 or earlier, the  EFI  System  Partition
     (ESP)  can  be  too  small  to  accommodate  loader.efi.	In  such  cases,
     boot1.efi(8) may be retained as the firmware boot program. It  will  chain-
     load the current /boot/loader.efi, which is updated during the installworld
     process.  boot1.efi(8) is deprecated for new installations.

   Console Considerations
     The  UEFI	firmware  provides a generic console.  In loader.efi this is se-
     lected by specifying "efi" using the console variable.  loader.efi examines
     the 8be4df61-93ca-11d2-aa0d-00e098032b8c-ConOut UEFI  environment	variable
     to  guess	what  the  "efi"  console points to.  loader.efi will output its
     prompts and menus to all the places  specified  by  ConOut.   However,  the
     FreeBSD kernel has a limitation when more than one console is present.  The
     kernel  outputs  to all configured consoles.  Only the primary console will
     get the log messages from the rc(8) system, and  prompts  for  things  like
     geli(8)  passwords.   If  loader.efi  finds  a  video  device  first,  then
     loader.efi tells the kernel to use the video console as primary.  Likewise,
     if a serial device is first in the ConOut list, the serial port will be the
     primary console.

     If there is no ConOut  variable,  both  serial  and  video  are  attempted.
     loader.efi uses the "efi" console for the video (which may or may not work)
     and "comconsole" for the serial on COM1 at the default baud rate.	The ker-
     nel  will	use  a	dual  console,	with the video console primary if a UEFI
     graphics device is detected, or the serial console as primary if not.

     On x86 platforms, if you wish to redirect the loader's output to  a  serial
     port  when  the  UEFI firmware doesn't support it, or to a serial port that
     isn't the one the UEFI firmware redirects its output  to,	set  console  to
     "comconsole".   The  default  port  is  COM1  with an I/O address of 0x3f8.
     comconsole_port  is  used	to  set  this  to  a  different  port	address.
     comconsole_speed  is  used  to  set  the of the serial port (the default is
     9600).  If you have console set to "efi,comconsole" you will get output  on
     both  the	EFI  console  and the serial port.  If this causes a doubling of
     characters, set console to "efi", since your UEFI firmware  is  redirecting
     to the serial port already.

     If  your  UEFI firmware redirects the serial port, you may need to tell the
     kernel which address to use.  EFI uses ACPI's UID to  identify  the  serial
     port,  but  loader.efi  does  not have an ACPI parser, so it cannot convert
     that to an I/O port.  The FreeBSD kernel initializes its consoles before it
     can  decode  ACPI	resources.   The  FreeBSD  kernel  will  look	at   the
     hw.uart.console  variable	to set its serial console.  Its format should be
     described in uart(4) but is not.  Set it to "io:0x3f8,br:115200"  with  the
     proper  port  address.   PCI or memory mapped ports are beyond the scope of
     this man page.

     The serial ports are assigned as follows on IBM PC compatible systems:

	   Windows Name    I/O Port Address    Typical FreeBSD device
	   COM1 	   0x3f8	       /dev/uart0
	   COM2 	   0x2f8	       /dev/uart1
	   COM3 	   0x3e8	       /dev/uart2
	   COM4 	   0x2e8	       /dev/uart3

     Though COM3 and COM4 can vary.

   Primary Console
     The primary console is set using the boot flags.  These command line  argu-
     ments  set  corresponding	flags  for  the kernel.  These flags can be con-
     trolled by setting loader environment variables to  "yes"	or  "no".   Boot
     flags  may be set on the command line to the boot command.  Inside the ker-
     nel, the RB_ flags are used to control  behavior,	sometimes  in  architec-
     turally  specific ways and are included to aid in discovery of any behavior
     not covered in this document.

	   boot flag	loader variable    Kernel RB_ flag
	   -a		boot_askme	   RB_ASKNAME
	   -c		boot_cdrom	   RB_CDROM
	   -d		boot_ddb	   RB_KDB
	   -r		boot_dfltroot	   RB_DFLTROOT
	   -D		boot_multiple	   RB_MULTIPLE
	   -m		boot_mute	   RB_MUTE
	   -g		boot_gdb	   RB_GDB
	   -h		boot_serial	   RB_SERIAL
	   -p		boot_pause	   RB_PAUSE
	   -P		boot_probe	   RB_PROBE
	   -s		boot_single	   RB_SINGLE
	   -v		boot_verbose	   RB_VERBOSE

     And the following flags determine the primary console:

	Flags	 Kernel Flags		    Kernel Consoles    Primary Console
	none	 0			    Video	       Video
	-h	 RB_SERIAL		    Serial	       Serial
	-D	 RB_MULTIPLE		    Serial, Video      Video
	-Dh	 RB_SERIAL | RB_MULTIPLE    Serial, Video      Serial

     loader.efi does not implement the probe -P functionality where we	use  the
     video console if a keyboard is connected and a serial console otherwise.

   Additional Environment Variables
     loader.efi   loads   some	 extra	 variables   early   in   startup   from
     /efi/freebsd/loader.env from the EFI partition.  Only simple variables  can
     be set here.  It can be useful to specify the root filesystem:

	   rootdev=disk0s1a

   Staging Slop
     The kernel must parse the firmware memory map tables to know what memory it
     can  use.	 Since	it  must  allocate memory to do this, loader.efi ensures
     there's extra memory available, called "slop", after  everything  it  loads
     (the  kernel,  modules and metadata) for the kernel to bootstrap the memory
     allocator.

     By default, amd64 reserves 8MB.  The staging_slop command allows for tuning
     the slop size.  It takes a single argument, the size of the slop in bytes.

   amd64 Nocopy
     loader.efi will load the kernel into memory that is 2MB aligned below  4GB.
     It cannot load to a fixed address because the UEFI firmware may reserve ar-
     bitrary  memory for its use at runtime.  Prior to FreeBSD 13.1, kernels re-
     tained the old BIOS-boot protocol of loading at exactly 2MB.  Such  kernels
     must  be  copied  from their loaded location to 2MB prior starting them up.
     The copy_staging command is used to enable this copying for older	kernels.
     It takes a single argument which can be one of

     disable  Force-disable copying staging area to 2M.

     enable   Force-enable copying staging area to 2M.

     auto     Selects  the  behaviour based on the kernel's capability of boost-
	      raping from non-2M physical base.  The kernel reports  this  capa-
	      bility by exporting the symbol kernphys.

     Arm64  loaders  have operated in the `nocopy' mode from their inception, so
     there is no copy_staging command on that platform.  Riscv, 32-bit	arm  and
     arm64  have  always  loaded  at any 2MB aligned location, so do not provide
     copy_staging.

	   Note. BIOS loaders on i386 and amd64 put the staging area starting at
	   the physical address 2M, then enable paging with identical mapping
	   for the low 1G.  The initial port of loader.efi followed the same
	   scheme for handing control to the kernel, since it avoided modifica-
	   tions for the loader/kernel hand-off protocol, and for the kernel
	   page table bootstrap.

	   This approach is incompatible with the UEFI specification, and as a
	   practical matter, caused troubles on many boards, because UEFI
	   firmware is free to use any memory for its own needs.  Applications
	   like loader.efi must only use memory explicitly allocated using boot
	   interfaces.	The original way also potentially destroyed UEFI runtime
	   interfaces data.

	   Eventually, loader.efi and the kernel were improved to avoid this
	   problem.

   amd64 Faults
     Because it executes in x86 protected mode, the amd64 version of  loader.efi
     is  susceptible to CPU faults due to programmer mistakes and memory corrup-
     tion.  To make debugging such faults easier, amd64 loader.efi  can  provide
     detailed reporting of the CPU state at the time of the fault.

     The  grab_faults command installs a handler for faults directly in the IDT,
     avoiding the use of the UEFI debugging  interface	EFI_DEBUG_SUPPORT_PROTO-
     COL.RegisterExceptionCallback().	That interface is left available for ad-
     vanced debuggers in the UEFI environment.	The ungrab_faults command  tries
     to  deinstall  the fault handler, returning TSS and IDT CPU tables to their
     pre-installation  state.	The  fault  command  produces  a  fault  in  the
     loader.efi environment for testing purposes, by executing the ud2 processor
     instruction.

FILES
     /boot/loader.efi  The location of the UEFI kernel loader within the system.

   EFI System Partition
     loader.efi  is  installed	on  the ESP (EFI System Partition) in one of the
     following locations:

     efi/boot/bootXXX.efi    The  default  location  for  any  EFI  loader  (see
			     uefi(8) for values to replace `XXX' with).

     efi/freebsd/loader.efi  The  location reserved specifically for the FreeBSD
			     EFI loader.

     The default location for the ESP mount point is documented in hier(7).

EXAMPLES
   Updating loader.efi on the ESP
     The following example shows how to install a new  loader.efi  on  the  ESP.
     The  exact  placement is complicated due to the diversity of installations,
     setups and situations.  In this section, paths that are all lower case  are
     Unix  paths.   Paths  that are all upper case are relative to the ESP mount
     point, though they may appear as lower case on your system because the  FAT
     filesystem of the ESP is case insensitive.

     Locate the ESP, which has its own partition type of "efi":

	   # gpart show nda0
	   =>	     40  7501476448  nda0  GPT	(3.5T)
		     40      614400	1  efi	(300M)
		 614440  7500862048	2  freebsd-zfs	(3.5T)

     The  name	of  the  ESP on this system is nda0p1.	By default, this will be
     mounted on /boot/efi.  To check:

	   # mount | grep nda0p1
	   /dev/nda0p1 on /boot/efi (msdosfs, local)

     If it's not mounted, you will need to mount it:

	   # mount -t msdosfs /dev/nda0p1 /boot/efi

     efibootmgr(8) reports what we booted from.

	   # efibootmgr -v
	   Boot to FW : false
	   BootCurrent: 0001
	   Timeout    : 2 seconds
	   BootOrder  : 0000, 0001, 0003, 0004, 0005, 0006, 0001, 0008, 000A, 000B, 000C, 000E, 0007
	   ...
	   +Boot0001* FreeBSD ZPOOL HD(1,GPT,b5d0f86b-265d-1e1b-18aa-0ed55e1e73bd,0x28,0x96000)/File(\EFI\FREEBSD\LOADER.EFI)
				       nda0p1:/EFI/FREEBSD/LOADER.EFI /boot/efi//EFI/FREEBSD/LOADER.EFI
	   ...

     Often there are several options, depending on the BIOS.  The entry that  we
     booted  with is marked with a `+' at the start of the line, as shown above.
     So in this case, this firmware is using  /EFI/FREEBSD/LOADER.EFI  from  the
     ESP.  Often times it will be the UEFI "default" loader, which varies by ar-
     chitecture.

	   Architecture    Default Path
	   amd64	   /EFI/BOOT/BOOTX64.EFI
	   arm		   /EFI/BOOT/BOOTARM.EFI
	   arm64	   /EFI/BOOT/BOOTAA64.EFI
	   i386 	   /EFI/BOOT/BOOTIA32.EFI
	   riscv	   /EFI/BOOT/BOOTRISCV64.EFI

     However, care must be taken: some multiple-boot environments rely on a spe-
     cial  bootXXX.efi	to  function.	Before updating a bootXXX.efi file, make
     sure it is the FreeBSD boot loader before updating it:

	   # strings /boot/efi/EFI/BOOT/BOOTX64.EFI | grep FreeBSD | grep EFI
	   FreeBSD/amd64 EFI loader, Revision 3.0

     bsdinstall(8) copies loader.efi to the default name  if  there  wasn't  one
     there  before.   Check  to see if they are copies before updating (with X64
     substituted using the above table):

	   # cmp /boot/efi/EFI/FREEBSD/LOADER.EFI /boot/efi/EFI/BOOT/BOOTX64.EFI

     Copy the loader:

	   # cp /boot/loader.efi /boot/efi/EFI/FREEBSD/LOADER.EFI

     replacing the all caps part of the example with the proper path.

     If ESP path was /FREEBSD/LOADER.EFI and  LOADER.EFI  and  BOOTX64.EFI  were
     identical in the cmp step, copy the loader to the default location:

	   # cp /boot/loader.efi /boot/efi/EFI/BOOT/BOOTX64.EFI

     Finally, if you mounted the ESP, you may wish to unmount it.

	   # umount /boot/efi

SEE ALSO
     loader(8), uefi(8)

BUGS
     Non-x86  serial console handling is even more confusing and less well docu-
     mented.

     Sometimes when the serial port speed isn't set, 9600 is used.  Other  times
     the  result  is typically 115200 since the speed remains unchanged from the
     default.

     U-Boot implements a subset of the UEFI standard.  Some versions do not sup-
     port fetching loader variables, so efibootmgr may not work.   In  addition,
     efibootmgr  is  not  supported  on armv7 or riscv.  In these instances, the
     user has to understand what was booted to update it properly (and	in  most
     cases,  it  will  be  the	FreeBSD  path  and the UEFI default so just copy
     loader.efi there if there are loaders there).  Typically in these	embedded
     situations,  there  is  only  one	.efi  file  (loader.efi  or  a	copy  of
     loader.efi).  The path to this file is typically the default removable path
     above.

     Managing booting multiple OSes on UEFI varies greatly, so extra caution  is
     required when updating the UEFI default loader.

FreeBSD ports 15.1		 April 11, 2026 		   LOADER.EFI(8)

Want to link to this manual page? Use this URL:
<https://man.freebsd.org/cgi/man.cgi?query=loader.efi&manpath=FreeBSD+15.1-RELEASE+and+Ports>

home | help