1.\" 2.\" SPDX-License-Identifier: BSD-2-Clause 3.\" 4.\" Copyright (c) 2019-2022 Netflix, Inc 5.\" Copyright (c) 2022-2026 Mateusz Piotrowski <0mp@FreeBSD.org> 6.\" Copyright 2022 The FreeBSD Foundation 7.\" 8.\" Part of this documentation was written by 9.\" Konstantin Belousov <kib@FreeBSD.org> under sponsorship 10.\" from the FreeBSD Foundation. 11.\" 12.\" Redistribution and use in source and binary forms, with or without 13.\" modification, are permitted provided that the following conditions 14.\" are met: 15.\" 1. Redistributions of source code must retain the above copyright 16.\" notice, this list of conditions and the following disclaimer. 17.\" 2. Redistributions in binary form must reproduce the above copyright 18.\" notice, this list of conditions and the following disclaimer in the 19.\" documentation and/or other materials provided with the distribution. 20.\" 21.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 22.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 25.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31.\" SUCH DAMAGE. 32.\" 33.Dd June 14, 2026 34.Dt LOADER.EFI 8 35.Os 36.Sh NAME 37.Nm loader.efi 38.Nd UEFI kernel loader 39.Sh DESCRIPTION 40On UEFI systems, 41.Nm 42loads the kernel. 43.Pp 44.Nm 45is invoked directly from the EFI System Partition (ESP) 46on systems installed using 47.Xr bsdinstall 8 , 48when installed as the default EFI boot program as described in 49.Xr uefi 8 50or when configured as an EFI boot entry with 51.Xr efibootmgr 8 . 52.Pp 53On systems upgraded from 54.Fx 10 55or earlier, the EFI System Partition (ESP) 56can be too small to accommodate 57.Nm . 58In such cases, 59.Xr boot1.efi 8 60may be retained as the firmware boot program. 61It will chain-load the current 62.Pa /boot/loader.efi , 63which is updated during the 64.Cm installworld 65process. 66.Xr boot1.efi 8 67is deprecated for new installations. 68.Ss Console Considerations 69The UEFI firmware provides a generic console. 70In 71.Nm 72this is selected by specifying 73.Dq efi 74using the 75.Dv console 76variable. 77.Nm 78examines the 79.Dv 8be4df61-93ca-11d2-aa0d-00e098032b8c-ConOut 80UEFI environment variable to guess what the 81.Dq efi 82console points to. 83.Nm 84will output its prompts and menus to all the places specified by ConOut. 85However, the 86.Fx 87kernel has a limitation when more than one console is present. 88The kernel outputs to all configured consoles. 89Only the primary console will get the log messages from the 90.Xr rc 8 91system, and prompts for things like 92.Xr geli 8 93passwords. 94If 95.Nm 96finds a video device first, then 97.Nm 98tells the kernel to use the video console as primary. 99Likewise, if a serial device is first in the 100.Dv ConOut 101list, the serial port will be the primary console. 102.Pp 103If there is no 104.Dv ConOut 105variable, both serial and video are attempted. 106.Nm 107uses the 108.Dq efi 109console for the video (which may or may not work) and 110.Dq comconsole 111for the serial on 112.Dv COM1 113at the default baud rate. 114The kernel will use a dual console, with the video console 115primary if a UEFI graphics device is detected, or the serial console 116as primary if not. 117.Pp 118On x86 platforms, if you wish to redirect the loader's output to a serial port 119when the UEFI firmware doesn't support it, or to a serial port that isn't the 120one the UEFI firmware redirects its output to, set 121.Dv console 122to 123.Dq comconsole . 124The default port is 125.Dv COM1 126with an I/O address of 0x3f8. 127.Dv comconsole_port 128is used to set this to a different port address. 129.Dv comconsole_speed 130is used to set the of the serial port (the default is 9600). 131If you have 132.Dv console 133set to 134.Dq efi,comconsole 135you will get output on both the EFI console and the serial port. 136If this causes a doubling of characters, set 137.Dv console 138to 139.Dq efi , 140since your UEFI firmware is redirecting to the serial port already. 141.Pp 142If your UEFI firmware redirects the serial port, you may need to tell the kernel 143which address to use. 144EFI uses ACPI's UID to identify the serial port, but 145.Nm 146does not have an ACPI parser, so it cannot convert that to an I/O port. 147The 148.Fx 149kernel initializes its consoles before it can decode ACPI resources. 150The 151.Fx 152kernel will look at the 153.Dv hw.uart.console 154variable to set its serial console. 155Its format is described in 156.Xr uart 4 . 157Set it to 158.Dq io:0x3f8,br:115200 159with the proper port address. 160PCI or memory mapped ports are beyond the scope of this man page. 161.Pp 162The serial ports are assigned as follows on IBM PC compatible systems: 163.Bl -column -offset indent "Windows Name" "I/O Port Address" "Typical FreeBSD device" 164.It Sy Windows Name Ta Sy I/O Port Address Ta Sy Typical FreeBSD device 165.It COM1 Ta 0x3f8 Ta Pa /dev/uart0 166.It COM2 Ta 0x2f8 Ta Pa /dev/uart1 167.It COM3 Ta 0x3e8 Ta Pa /dev/uart2 168.It COM4 Ta 0x2e8 Ta Pa /dev/uart3 169.El 170.Pp 171Though 172.Dv COM3 173and 174.Dv COM4 175can vary. 176.Ss Primary Console 177The primary console is set using the boot flags. 178These command line arguments set corresponding flags for the kernel. 179These flags can be controlled by setting loader environment variables 180to 181.Dq yes 182or 183.Dq no . 184Boot flags may be set on the command line to the boot command. 185Inside the kernel, the RB_ flags are used to control behavior, sometimes 186in architecturally specific ways and are included to aid in discovery 187of any behavior not covered in this document. 188.Bl -column -offset indent "boot flag" "loader variable" "Kernel RB_ flag" 189.It Sy Boot Flag Ta Sy Loader Variable Ta Sy Kernel RB_ Flag 190.It Fl a Ta Dv boot_askme Ta Va RB_ASKNAME 191.It Fl c Ta Dv boot_cdrom Ta Va RB_CDROM 192.It Fl d Ta Dv boot_ddb Ta Va RB_KDB 193.It Fl r Ta Dv boot_dfltroot Ta Va RB_DFLTROOT 194.It Fl D Ta Dv boot_multiple Ta Va RB_MULTIPLE 195.It Fl m Ta Dv boot_mute Ta Va RB_MUTE 196.It Fl g Ta Dv boot_gdb Ta Va RB_GDB 197.It Fl h Ta Dv boot_serial Ta Va RB_SERIAL 198.It Fl p Ta Dv boot_pause Ta Va RB_PAUSE 199.It Fl P Ta Dv boot_probe Ta Va RB_PROBE 200.It Fl s Ta Dv boot_single Ta Va RB_SINGLE 201.It Fl v Ta Dv boot_verbose Ta Va RB_VERBOSE 202.El 203.Pp 204And the following flags determine the primary console: 205.Bl -column -offset indent "Flags" "RB_SERIAL | RB_MULTIPLE" "Kernel Consoles" "Primary Console" 206.It Sy Flags Ta Sy Kernel Flags Ta Sy Kernel Consoles Ta Sy Primary Console 207.It none Ta 0 Ta Video Ta Video 208.It Fl h Ta RB_SERIAL Ta Serial Ta Serial 209.It Fl D Ta RB_MULTIPLE Ta Serial, Video Ta Video 210.It Fl Dh Ta RB_SERIAL | RB_MULTIPLE Ta Serial, Video Ta Serial 211.El 212.Pp 213.Nm 214does not implement the probe 215.Fl P 216functionality where we use the video console if a keyboard is connected and a 217serial console otherwise. 218.Ss Additional Environment Variables 219.Nm 220can set variables early in startup from a file on the EFI partition. 221By default, that file is 222.Pa /efi/freebsd/loader.env . 223It can be changed by setting the 224.Fx 225EFI variable 226.Va LoaderEnv , 227as in: 228.Bd -literal -offset indent 229echo -n /efi/freebsd/alt.env | efivar -w -t 7 \\ 230 -n cfee69ad-a0de-47a9-93a8-f63106f8ae99-LoaderEnv 231.Ed 232.Pp 233After that is executed, the file 234.Pa /efi/freebsd/alt.env 235is used instead of 236.Pa /efi/freebsd/loader.env . 237See 238.Xr efivar 8 239for more information on setting EFI variables. 240.Pp 241The EFI variable 242.Va NextLoaderEnv 243can be set to the pathname of a second startup file. 244That variable is deleted immediately after its value is retrieved, 245so setting it will affect only the next boot attempt. 246For either variable, a missing file is silently ignored. 247.Pp 248Only simple variables can be set in the startup file. 249It can be useful to specify the root filesystem: 250.Bd -literal -offset indent 251rootdev=disk0s1a 252.Ed 253.Pp 254The startup file contains a series of assignments separated by spaces, 255tabs, or newlines. 256Quotes are not given any special treatment. 257If no 258.Li =value 259is given, the value 260.Li 1 261is used. 262Invalid syntax and the like are silently ignored. 263.Ss Staging Slop 264The kernel must parse the firmware memory map tables to know what memory 265it can use. 266It also needs to allocate memory for the kernel page tables. 267Since it must allocate memory to do this, 268without overwriting important structures, 269for instance the trampoline page table, 270.Nm 271ensures there's extra memory available, called 272.Dq slop , 273after everything it loads 274.Po 275the kernel, modules and metadata 276.Pc 277for the kernel to bootstrap the memory allocator. 278.Pp 279By default, amd64 reserves 8MB. 280The 281.Ic staging_slop 282command allows for tuning the slop size. 283It takes a single argument, the size of the slop in bytes. 284.Ss amd64 Nocopy 285.Nm 286will load the kernel into memory that is 2MB aligned below 4GB. 287It cannot load to a fixed address because the UEFI firmware may reserve 288arbitrary memory for its use at runtime. 289Prior to 290.Fx 13.1 , 291kernels retained the old BIOS-boot protocol of loading at exactly 2MB. 292Such kernels must be copied from their loaded location to 2MB prior 293starting them up. 294The 295.Ic copy_staging 296command is used to enable this copying for older kernels. 297It takes a single argument 298which can be one of 299.Bl -tag -width disable 300.It Ar disable 301Force-disable copying staging area to 302.Ad 2M . 303.It Ar enable 304Force-enable copying staging area to 305.Ad 2M . 306.It Ar auto 307Selects the behaviour based on the kernel's capability of boostraping 308from non-2M physical base. 309The kernel reports this capability by exporting the symbol 310.Va kernphys . 311.El 312.Pp 313Arm64 loaders have operated in the 314.Sq nocopy 315mode from their inception, so there is no 316.Ic copy_staging 317command on that platform. 318Riscv, 32-bit arm and arm64 have always loaded at any 319.Ad 2MB 320aligned location, so do not provide 321.Ic copy_staging . 322.Bd -ragged -offset indent 323.Sy Note . 324BIOS loaders on i386 and amd64 put the staging area starting 325at the physical address 326.Ad 2M , 327then enable paging with identical mapping for the low 328.Ad 1G . 329The initial port of 330.Nm 331followed the same scheme for handing control to the kernel, 332since it avoided modifications for the loader/kernel hand-off protocol, 333and for the kernel page table bootstrap. 334.Pp 335This approach is incompatible with the UEFI specification, 336and as a practical matter, caused troubles on many boards, 337because UEFI firmware is free to use any memory for its own needs. 338Applications like 339.Nm 340must only use memory explicitly allocated using boot interfaces. 341The original way also potentially destroyed UEFI runtime interfaces data. 342.Pp 343Eventually, 344.Nm 345and the kernel were improved to avoid this problem. 346.Ed 347.Ss amd64 Faults 348Because it executes in 64-bit long mode, the amd64 version of 349.Nm 350is susceptible to CPU faults due to programmer mistakes and 351memory corruption. 352To make debugging such faults easier, amd64 353.Nm 354can provide detailed reporting of the CPU state at the time 355of the fault. 356.Pp 357The 358.Ic grab_faults 359command installs a handler for faults directly in the IDT, 360avoiding the use of the UEFI debugging interface 361.Fn EFI_DEBUG_SUPPORT_PROTOCOL.RegisterExceptionCallback . 362That interface is left available for advanced debuggers in 363the UEFI environment. 364The 365.Ic ungrab_faults 366command tries to deinstall the fault handler, returning TSS and IDT 367CPU tables to their pre-installation state. 368The 369.Ic fault 370command produces a fault in the 371.Nm 372environment for testing purposes, by executing the 373.Ic ud2 374processor instruction. 375.Ss i386 firmware on amd64 machines 376Some devices have 64-bit (long mode) capable CPUs, but come with a 37732-bit (protected mode) UEFI implementation. 378.Pa /boot/loader_ia32.efi 379is provided for such devices. 380It switches to long mode right before executing the kernel. 381Note that since the firmware expects its runtime EFI functions to be 382executed in 32-bit protected mode, EFI runtime services are not 383available to the kernel. 384Which means that programs like 385.Xr efibootmgr 8 386will not work. 387.Sh FILES 388.Bl -tag -width "/boot/loader.efi" 389.It Pa /boot/loader.efi 390The location of the UEFI kernel loader within the system. 391.El 392.Ss EFI System Partition 393.Nm 394is installed on the ESP (EFI System Partition) 395in one of the following locations: 396.Bl -tag -width "efi/freebsd/loader.efi" 397.It Pa efi/boot/bootXXX.efi 398The default location for any EFI loader 399.Po see 400.Xr uefi 8 401for values to replace 402.Ql XXX 403with 404.Pc . 405.It Pa efi/freebsd/loader.efi 406The location reserved specifically for the 407.Fx 408EFI loader. 409.El 410.Pp 411The default location for the ESP mount point is documented in 412.Xr hier 7 . 413.Sh EXAMPLES 414.Ss Updating loader.efi on the ESP 415The following example shows how to install a new 416.Nm 417on the ESP. 418The exact placement is complicated due to the diversity of 419installations, setups and situations. 420In this section, paths that are all lower case are Unix paths. 421Paths that are all upper case are relative to the ESP mount point, 422though they may appear as lower case on your system because the 423FAT filesystem of the ESP is case insensitive. 424.Pp 425Locate the ESP, which has its own partition type of 426.Dq efi : 427.Bd -literal -offset indent 428# gpart show nda0 429=> 40 7501476448 nda0 GPT (3.5T) 430 40 614400 1 efi (300M) 431 614440 7500862048 2 freebsd-zfs (3.5T) 432.Ed 433.Pp 434The name of the ESP on this system is 435.Pa nda0p1 . 436By default, this will be mounted on 437.Pa /boot/efi . 438To check: 439.Bd -literal -offset indent 440# mount | grep nda0p1 441/dev/nda0p1 on /boot/efi (msdosfs, local) 442.Ed 443.Pp 444If it's not mounted, you will need to mount it: 445.Bd -literal -offset indent 446# mount -t msdosfs /dev/nda0p1 /boot/efi 447.Ed 448.Pp 449.Xr efibootmgr 8 450reports what we booted from. 451.Bd -literal -offset indent 452# efibootmgr -v 453Boot to FW : false 454BootCurrent: 0001 455Timeout : 2 seconds 456BootOrder : 0000, 0001, 0003, 0004, 0005, 0006, 0001, 0008, 000A, 000B, 000C, 000E, 0007 457\&... 458+Boot0001* FreeBSD ZPOOL HD(1,GPT,b5d0f86b-265d-1e1b-18aa-0ed55e1e73bd,0x28,0x96000)/File(\eEFI\eFREEBSD\eLOADER.EFI) 459 nda0p1:/EFI/FREEBSD/LOADER.EFI /boot/efi//EFI/FREEBSD/LOADER.EFI 460\&... 461.Ed 462.Pp 463Often there are several options, depending on the BIOS. 464The entry that we booted with is marked with a 465.Sq + 466at the start of the line, as shown above. 467So in this case, this firmware is using 468.Pa /EFI/FREEBSD/LOADER.EFI 469from the ESP. 470Often times it will be the UEFI 471.Dq default 472loader, which varies by architecture. 473.Bl -column -offset indent "Architecture" "Default Path" 474.It Sy Architecture Ta Sy Default Path 475.It amd64 Ta Pa /EFI/BOOT/BOOTX64.EFI 476.It arm Ta Pa /EFI/BOOT/BOOTARM.EFI 477.It arm64 Ta Pa /EFI/BOOT/BOOTAA64.EFI 478.It i386 Ta Pa /EFI/BOOT/BOOTIA32.EFI 479.It riscv Ta Pa /EFI/BOOT/BOOTRISCV64.EFI 480.El 481.Pp 482However, care must be taken: some multiple-boot environments rely on a special 483.Pa bootXXX.efi 484to function. 485Before updating a 486.Pa bootXXX.efi 487file, make sure it is the 488.Fx 489boot loader before updating it: 490.Bd -literal -offset indent 491# strings /boot/efi/EFI/BOOT/BOOTX64.EFI | grep FreeBSD | grep EFI 492FreeBSD/amd64 EFI loader, Revision 3.0 493.Ed 494.Pp 495.Xr bsdinstall 8 496copies 497.Pa loader.efi 498to the default name if there wasn't one there before. 499Check to see if they are copies before updating (with X64 substituted using the 500above table): 501.Bd -literal -offset indent 502# cmp /boot/efi/EFI/FREEBSD/LOADER.EFI /boot/efi/EFI/BOOT/BOOTX64.EFI 503.Ed 504.Pp 505Copy the loader: 506.Bd -literal -offset indent 507# cp /boot/loader.efi /boot/efi/EFI/FREEBSD/LOADER.EFI 508.Ed 509.Pp 510replacing the all caps part of the example with the proper path. 511.Pp 512If ESP path was 513.Pa /FREEBSD/LOADER.EFI 514and LOADER.EFI and BOOTX64.EFI were identical in the cmp step, 515copy the loader to the default location: 516.Bd -literal -offset indent 517# cp /boot/loader.efi /boot/efi/EFI/BOOT/BOOTX64.EFI 518.Ed 519.Pp 520Finally, if you mounted the ESP, you may wish to unmount it. 521.Bd -literal -offset indent 522# umount /boot/efi 523.Ed 524.Sh SEE ALSO 525.Xr loader 8 , 526.Xr uefi 8 527.Sh BUGS 528Non-x86 serial console handling is even more confusing and less well documented. 529.Pp 530Sometimes when the serial port speed isn't set, 9600 is used. 531Other times the result is typically 115200 since the speed remains unchanged 532from the default. 533.Pp 534U-Boot implements a subset of the UEFI standard. 535Some versions do not support fetching loader variables, so 536.Pa efibootmgr 537may not work. 538In addition, 539.Pa efibootmgr 540is not supported on armv7 or riscv. 541In these instances, the user has to understand what was booted to update 542it properly (and in most cases, it will be the 543.Fx 544path and the UEFI default 545so just copy loader.efi there if there are loaders there). 546Typically in these embedded situations, there is only one 547.Pa .efi 548file ( 549.Pa loader.efi 550or a copy of 551.Pa loader.efi ) . 552The path to this file is typically the default removable path above. 553.Pp 554Managing booting multiple OSes on UEFI varies greatly, 555so extra caution is required 556when updating the UEFI default loader. 557