Dennis Gilmore | ffb4f6f | 2015-01-22 11:34:20 -0700 | [diff] [blame] | 1 | /* |
| 2 | * (C) Copyright 2014 Red Hat Inc. |
| 3 | * Copyright (c) 2014-2015, NVIDIA CORPORATION. All rights reserved. |
Karsten Merker | 8c24929 | 2015-03-21 14:15:38 +0100 | [diff] [blame] | 4 | * Copyright (C) 2015 K. Merker <merker@debian.org> |
Dennis Gilmore | ffb4f6f | 2015-01-22 11:34:20 -0700 | [diff] [blame] | 5 | * |
| 6 | * SPDX-License-Identifier: GPL-2.0+ |
| 7 | */ |
| 8 | |
| 9 | Generic Distro Configuration Concept |
| 10 | ==================================== |
| 11 | |
| 12 | Linux distributions are faced with supporting a variety of boot mechanisms, |
| 13 | environments or bootloaders (PC BIOS, EFI, U-Boot, Barebox, ...). This makes |
| 14 | life complicated. Worse, bootloaders such as U-Boot have a configurable set |
| 15 | of features, and each board chooses to enable a different set of features. |
| 16 | Hence, distros typically need to have board-specific knowledge in order to |
| 17 | set up a bootable system. |
| 18 | |
| 19 | This document defines a common set of U-Boot features that are required for |
| 20 | a distro to support the board in a generic fashion. Any board wishing to |
| 21 | allow distros to install and boot in an out-of-the-box fashion should enable |
| 22 | all these features. Linux distros can then create a single set of boot |
| 23 | support/install logic that targets these features. This will allow distros |
| 24 | to install on many boards without the need for board-specific logic. |
| 25 | |
| 26 | In fact, some of these features can be implemented by any bootloader, thus |
| 27 | decoupling distro install/boot logic from any knowledge of the bootloader. |
| 28 | |
| 29 | This model assumes that boards will load boot configuration files from a |
| 30 | regular storage mechanism (eMMC, SD card, USB Disk, SATA disk, etc.) with |
Masahiro Yamada | 28fd00b | 2015-07-07 18:47:17 +0900 | [diff] [blame] | 31 | a standard partitioning scheme (MBR, GPT). Boards that cannot support this |
Dennis Gilmore | ffb4f6f | 2015-01-22 11:34:20 -0700 | [diff] [blame] | 32 | storage model are outside the scope of this document, and may still need |
| 33 | board-specific installer/boot-configuration support in a distro. |
| 34 | |
| 35 | To some extent, this model assumes that a board has a separate boot flash |
| 36 | that contains U-Boot, and that the user has somehow installed U-Boot to this |
| 37 | flash before running the distro installer. Even on boards that do not conform |
| 38 | to this aspect of the model, the extent of the board-specific support in the |
| 39 | distro installer logic would be to install a board-specific U-Boot package to |
Masahiro Yamada | 28fd00b | 2015-07-07 18:47:17 +0900 | [diff] [blame] | 40 | the boot partition during installation. This distro-supplied U-Boot can still |
| 41 | implement the same features as on any other board, and hence the distro's boot |
| 42 | configuration file generation logic can still be board-agnostic. |
Dennis Gilmore | ffb4f6f | 2015-01-22 11:34:20 -0700 | [diff] [blame] | 43 | |
| 44 | Locating Bootable Disks |
| 45 | ----------------------- |
| 46 | |
| 47 | Typical desktop/server PCs search all (or a user-defined subset of) attached |
| 48 | storage devices for a bootable partition, then load the bootloader or boot |
| 49 | configuration files from there. A U-Boot board port that enables the features |
| 50 | mentioned in this document will search for boot configuration files in the |
| 51 | same way. |
| 52 | |
| 53 | Thus, distros do not need to manipulate any kind of bootloader-specific |
| 54 | configuration data to indicate which storage device the system should boot |
| 55 | from. |
| 56 | |
| 57 | Distros simply need to install the boot configuration files (see next |
| 58 | section) in an ext2/3/4 or FAT partition, mark the partition bootable (via |
| 59 | the MBR bootable flag, or GPT legacy_bios_bootable attribute), and U-Boot (or |
| 60 | any other bootloader) will find those boot files and execute them. This is |
| 61 | conceptually identical to creating a grub2 configuration file on a desktop |
| 62 | PC. |
| 63 | |
Masahiro Yamada | 28fd00b | 2015-07-07 18:47:17 +0900 | [diff] [blame] | 64 | Note that in the absence of any partition that is explicitly marked bootable, |
Dennis Gilmore | ffb4f6f | 2015-01-22 11:34:20 -0700 | [diff] [blame] | 65 | U-Boot falls back to searching the first valid partition of a disk for boot |
| 66 | configuration files. Other bootloaders are recommended to do the same, since |
| 67 | I believe that partition table bootable flags aren't so commonly used outside |
| 68 | the realm of x86 PCs. |
| 69 | |
| 70 | U-Boot can also search for boot configuration files from a TFTP server. |
| 71 | |
| 72 | Boot Configuration Files |
| 73 | ------------------------ |
| 74 | |
| 75 | The standard format for boot configuration files is that of extlinux.conf, as |
| 76 | handled by U-Boot's "syslinux" (disk) or "pxe boot" (network). This is roughly |
| 77 | as specified at: |
| 78 | |
| 79 | http://www.freedesktop.org/wiki/Specifications/BootLoaderSpec/ |
| 80 | |
| 81 | ... with the exceptions that the BootLoaderSpec document: |
| 82 | |
| 83 | * Prescribes a separate configuration per boot menu option, whereas U-Boot |
| 84 | lumps all options into a single extlinux.conf file. Hence, U-Boot searches |
| 85 | for /extlinux/extlinux.conf then /boot/extlinux/extlinux.conf on disk, or |
| 86 | pxelinux.cfg/default over the network. |
| 87 | |
| 88 | * Does not document the fdtdir option, which automatically selects the DTB to |
| 89 | pass to the kernel. |
| 90 | |
| 91 | One example extlinux.conf generated by the Fedora installer is: |
| 92 | |
| 93 | ------------------------------------------------------------ |
| 94 | # extlinux.conf generated by anaconda |
| 95 | |
| 96 | ui menu.c32 |
| 97 | |
| 98 | menu autoboot Welcome to Fedora. Automatic boot in # second{,s}. Press a key for options. |
| 99 | menu title Fedora Boot Options. |
| 100 | menu hidden |
| 101 | |
| 102 | timeout 50 |
| 103 | #totaltimeout 9000 |
| 104 | |
| 105 | default Fedora (3.17.0-0.rc4.git2.1.fc22.armv7hl+lpae) 22 (Rawhide) |
| 106 | |
| 107 | label Fedora (3.17.0-0.rc4.git2.1.fc22.armv7hl) 22 (Rawhide) |
| 108 | kernel /boot/vmlinuz-3.17.0-0.rc4.git2.1.fc22.armv7hl |
| 109 | append ro root=UUID=8eac677f-8ea8-4270-8479-d5ddbb797450 console=ttyS0,115200n8 LANG=en_US.UTF-8 drm.debug=0xf |
| 110 | fdtdir /boot/dtb-3.17.0-0.rc4.git2.1.fc22.armv7hl |
| 111 | initrd /boot/initramfs-3.17.0-0.rc4.git2.1.fc22.armv7hl.img |
| 112 | |
| 113 | label Fedora (3.17.0-0.rc4.git2.1.fc22.armv7hl+lpae) 22 (Rawhide) |
| 114 | kernel /boot/vmlinuz-3.17.0-0.rc4.git2.1.fc22.armv7hl+lpae |
| 115 | append ro root=UUID=8eac677f-8ea8-4270-8479-d5ddbb797450 console=ttyS0,115200n8 LANG=en_US.UTF-8 drm.debug=0xf |
| 116 | fdtdir /boot/dtb-3.17.0-0.rc4.git2.1.fc22.armv7hl+lpae |
| 117 | initrd /boot/initramfs-3.17.0-0.rc4.git2.1.fc22.armv7hl+lpae.img |
| 118 | |
| 119 | label Fedora-0-rescue-8f6ba7b039524e0eb957d2c9203f04bc (0-rescue-8f6ba7b039524e0eb957d2c9203f04bc) |
| 120 | kernel /boot/vmlinuz-0-rescue-8f6ba7b039524e0eb957d2c9203f04bc |
| 121 | initrd /boot/initramfs-0-rescue-8f6ba7b039524e0eb957d2c9203f04bc.img |
| 122 | append ro root=UUID=8eac677f-8ea8-4270-8479-d5ddbb797450 console=ttyS0,115200n8 |
| 123 | fdtdir /boot/dtb-3.16.0-0.rc6.git1.1.fc22.armv7hl+lpae |
| 124 | ------------------------------------------------------------ |
| 125 | |
| 126 | Another hand-crafted network boot configuration file is: |
| 127 | |
| 128 | ------------------------------------------------------------ |
| 129 | TIMEOUT 100 |
| 130 | |
| 131 | MENU TITLE TFTP boot options |
| 132 | |
| 133 | LABEL jetson-tk1-emmc |
| 134 | MENU LABEL ../zImage root on Jetson TK1 eMMC |
| 135 | LINUX ../zImage |
| 136 | FDTDIR ../ |
| 137 | APPEND console=ttyS0,115200n8 console=tty1 loglevel=8 rootwait rw earlyprintk root=PARTUUID=80a5a8e9-c744-491a-93c1-4f4194fd690b |
| 138 | |
| 139 | LABEL venice2-emmc |
| 140 | MENU LABEL ../zImage root on Venice2 eMMC |
| 141 | LINUX ../zImage |
| 142 | FDTDIR ../ |
| 143 | APPEND console=ttyS0,115200n8 console=tty1 loglevel=8 rootwait rw earlyprintk root=PARTUUID=5f71e06f-be08-48ed-b1ef-ee4800cc860f |
| 144 | |
| 145 | LABEL sdcard |
| 146 | MENU LABEL ../zImage, root on 2GB sdcard |
| 147 | LINUX ../zImage |
| 148 | FDTDIR ../ |
| 149 | APPEND console=ttyS0,115200n8 console=tty1 loglevel=8 rootwait rw earlyprintk root=PARTUUID=b2f82cda-2535-4779-b467-094a210fbae7 |
| 150 | |
| 151 | LABEL fedora-installer-fk |
| 152 | MENU LABEL Fedora installer w/ Fedora kernel |
| 153 | LINUX fedora-installer/vmlinuz |
| 154 | INITRD fedora-installer/initrd.img.orig |
| 155 | FDTDIR fedora-installer/dtb |
| 156 | APPEND loglevel=8 ip=dhcp inst.repo=http://10.0.0.2/mirrors/fedora/linux/development/rawhide/armhfp/os/ rd.shell cma=64M |
| 157 | ------------------------------------------------------------ |
| 158 | |
| 159 | U-Boot Implementation |
| 160 | ===================== |
| 161 | |
| 162 | Enabling the distro options |
| 163 | --------------------------- |
| 164 | |
| 165 | In your board configuration file, include the following: |
| 166 | |
| 167 | ------------------------------------------------------------ |
| 168 | #ifndef CONFIG_SPL_BUILD |
| 169 | #include <config_distro_defaults.h> |
| 170 | #include <config_distro_bootcmd.h> |
| 171 | #endif |
| 172 | ------------------------------------------------------------ |
| 173 | |
| 174 | The first of those headers primarily enables a core set of U-Boot features, |
| 175 | such as support for MBR and GPT partitions, ext* and FAT filesystems, booting |
| 176 | raw zImage and initrd (rather than FIT- or uImage-wrapped files), etc. Network |
| 177 | boot support is also enabled here, which is useful in order to boot distro |
| 178 | installers given that distros do not commonly distribute bootable install |
| 179 | media for non-PC targets at present. |
| 180 | |
| 181 | Finally, a few options that are mostly relevant only when using U-Boot- |
| 182 | specific boot.scr scripts are enabled. This enables distros to generate a |
| 183 | U-Boot-specific boot.scr script rather than extlinux.conf as the boot |
| 184 | configuration file. While doing so is fully supported, and |
| 185 | <config_distro_defaults.h> exposes enough parameterization to boot.scr to |
| 186 | allow for board-agnostic boot.scr content, this document recommends that |
| 187 | distros generate extlinux.conf rather than boot.scr. extlinux.conf is intended |
| 188 | to work across multiple bootloaders, whereas boot.scr will only work with |
| 189 | U-Boot. TODO: document the contract between U-Boot and boot.scr re: which |
| 190 | environment variables a generic boot.scr may rely upon. |
| 191 | |
| 192 | The second of those headers sets up the default environment so that $bootcmd |
| 193 | is defined in a way that searches attached disks for boot configuration files, |
| 194 | and executes them if found. |
| 195 | |
| 196 | Required Environment Variables |
| 197 | ------------------------------ |
| 198 | |
| 199 | The U-Boot "syslinux" and "pxe boot" commands require a number of environment |
| 200 | variables be set. Default values for these variables are often hard-coded into |
| 201 | CONFIG_EXTRA_ENV_SETTINGS in the board's U-Boot configuration file, so that |
| 202 | the user doesn't have to configure them. |
| 203 | |
| 204 | fdt_addr: |
| 205 | |
| 206 | Mandatory for any system that provides the DTB in HW (e.g. ROM) and wishes |
| 207 | to pass that DTB to Linux, rather than loading a DTB from the boot |
| 208 | filesystem. Prohibited for any other system. |
| 209 | |
| 210 | If specified a DTB to boot the system must be available at the given |
| 211 | address. |
| 212 | |
| 213 | fdt_addr_r: |
| 214 | |
| 215 | Mandatory. The location in RAM where the DTB will be loaded or copied to when |
| 216 | processing the fdtdir/devicetreedir or fdt/devicetree options in |
| 217 | extlinux.conf. |
| 218 | |
| 219 | This is mandatory even when fdt_addr is provided, since extlinux.conf must |
| 220 | always be able to provide a DTB which overrides any copy provided by the HW. |
| 221 | |
| 222 | A size of 1MB for the FDT/DTB seems reasonable. |
| 223 | |
| 224 | ramdisk_addr_r: |
| 225 | |
| 226 | Mandatory. The location in RAM where the initial ramdisk will be loaded to |
| 227 | when processing the initrd option in extlinux.conf. |
| 228 | |
| 229 | It is recommended that this location be highest in RAM out of fdt_addr_, |
| 230 | kernel_addr_r, and ramdisk_addr_r, so that the RAM disk can vary in size |
| 231 | and use any available RAM. |
| 232 | |
| 233 | kernel_addr_r: |
| 234 | |
| 235 | Mandatory. The location in RAM where the kernel will be loaded to when |
| 236 | processing the kernel option in the extlinux.conf. |
| 237 | |
| 238 | The kernel should be located within the first 128M of RAM in order for the |
| 239 | kernel CONFIG_AUTO_ZRELADDR option to work, which is likely enabled on any |
| 240 | distro kernel. Since the kernel will decompress itself to 0x8000 after the |
Masahiro Yamada | 28fd00b | 2015-07-07 18:47:17 +0900 | [diff] [blame] | 241 | start of RAM, kernel_addr_r should not overlap that area, or the kernel will |
Dennis Gilmore | ffb4f6f | 2015-01-22 11:34:20 -0700 | [diff] [blame] | 242 | have to copy itself somewhere else first before decompression. |
| 243 | |
| 244 | A size of 16MB for the kernel is likely adequate. |
| 245 | |
| 246 | pxe_addr_r: |
| 247 | |
| 248 | Mandatory. The location in RAM where extlinux.conf will be loaded to prior |
| 249 | to processing. |
| 250 | |
| 251 | A size of 1MB for extlinux.conf is more than adequate. |
| 252 | |
| 253 | scriptaddr: |
| 254 | |
| 255 | Mandatory, if the boot script is boot.scr rather than extlinux.conf. The |
| 256 | location in RAM where boot.scr will be loaded to prior to execution. |
| 257 | |
| 258 | A size of 1MB for extlinux.conf is more than adequate. |
| 259 | |
| 260 | For suggestions on memory locations for ARM systems, you must follow the |
| 261 | guidelines specified in Documentation/arm/Booting in the Linux kernel tree. |
| 262 | |
| 263 | For a commented example of setting these values, please see the definition of |
| 264 | MEM_LAYOUT_ENV_SETTINGS in include/configs/tegra124-common.h. |
| 265 | |
| 266 | Boot Target Configuration |
| 267 | ------------------------- |
| 268 | |
| 269 | <config_distro_bootcmd.h> defines $bootcmd and many helper command variables |
| 270 | that automatically search attached disks for boot configuration files and |
| 271 | execute them. Boards must provide configure <config_distro_bootcmd.h> so that |
| 272 | it supports the correct set of possible boot device types. To provide this |
| 273 | configuration, simply define macro BOOT_TARGET_DEVICES prior to including |
| 274 | <config_distro_bootcmd.h>. For example: |
| 275 | |
| 276 | ------------------------------------------------------------ |
| 277 | #ifndef CONFIG_SPL_BUILD |
| 278 | #define BOOT_TARGET_DEVICES(func) \ |
| 279 | func(MMC, mmc, 1) \ |
| 280 | func(MMC, mmc, 0) \ |
| 281 | func(USB, usb, 0) \ |
| 282 | func(PXE, pxe, na) \ |
| 283 | func(DHCP, dhcp, na) |
| 284 | #include <config_distro_bootcmd.h> |
| 285 | #endif |
| 286 | ------------------------------------------------------------ |
| 287 | |
| 288 | Each entry in the macro defines a single boot device (e.g. a specific eMMC |
| 289 | device or SD card) or type of boot device (e.g. USB disk). The parameters to |
| 290 | the func macro (passed in by the internal implementation of the header) are: |
| 291 | |
| 292 | - Upper-case disk type (MMC, SATA, SCSI, IDE, USB, DHCP, PXE). |
| 293 | - Lower-case disk type (same options as above). |
| 294 | - ID of the specific disk (MMC only) or ignored for other types. |
| 295 | |
| 296 | User Configuration |
| 297 | ================== |
| 298 | |
| 299 | Once the user has installed U-Boot, it is expected that the environment will |
| 300 | be reset to the default values in order to enable $bootcmd and friends, as set |
| 301 | up by <config_distro_bootcmd.h>. After this, various environment variables may |
| 302 | be altered to influence the boot process: |
| 303 | |
| 304 | boot_targets: |
| 305 | |
| 306 | The list of boot locations searched. |
| 307 | |
| 308 | Example: mmc0, mmc1, usb, pxe |
| 309 | |
| 310 | Entries may be removed or re-ordered in this list to affect the boot order. |
| 311 | |
| 312 | boot_prefixes: |
| 313 | |
| 314 | For disk-based booting, the list of directories within a partition that are |
| 315 | searched for boot configuration files (extlinux.conf, boot.scr). |
| 316 | |
| 317 | Example: / /boot/ |
| 318 | |
| 319 | Entries may be removed or re-ordered in this list to affect the set of |
| 320 | directories which are searched. |
| 321 | |
| 322 | boot_scripts: |
| 323 | |
| 324 | The name of U-Boot style boot.scr files that $bootcmd searches for. |
| 325 | |
| 326 | Example: boot.scr.uimg boot.scr |
| 327 | |
| 328 | (Typically we expect extlinux.conf to be used, but execution of boot.scr is |
| 329 | maintained for backwards-compatibility.) |
| 330 | |
| 331 | Entries may be removed or re-ordered in this list to affect the set of |
| 332 | filenames which are supported. |
| 333 | |
| 334 | scan_dev_for_extlinux: |
| 335 | |
| 336 | If you want to disable extlinux.conf on all disks, set the value to something |
| 337 | innocuous, e.g. setenv scan_dev_for_extlinux true. |
| 338 | |
| 339 | scan_dev_for_scripts: |
| 340 | |
| 341 | If you want to disable boot.scr on all disks, set the value to something |
| 342 | innocuous, e.g. setenv scan_dev_for_scripts true. |
Karsten Merker | 8c24929 | 2015-03-21 14:15:38 +0100 | [diff] [blame] | 343 | |
| 344 | |
| 345 | Interactively booting from a specific device at the u-boot prompt |
| 346 | ================================================================= |
| 347 | |
| 348 | For interactively booting from a user-selected device at the u-boot command |
| 349 | prompt, the environment provides predefined bootcmd_<target> variables for |
| 350 | every target defined in boot_targets, which can be run be the user. |
| 351 | |
| 352 | If the target is a storage device, the format of the target is always |
| 353 | <device type><device number>, e.g. mmc0. Specifying the device number is |
| 354 | mandatory for storage devices, even if only support for a single instance |
| 355 | of the storage device is actually implemented. |
| 356 | |
| 357 | For network targets (dhcp, pxe), only the device type gets specified; |
| 358 | they do not have a device number. |
| 359 | |
| 360 | Examples: |
| 361 | |
| 362 | - run bootcmd_usb0 |
| 363 | boots from the first USB mass storage device |
| 364 | |
| 365 | - run bootcmd_mmc1 |
| 366 | boots from the second MMC device |
| 367 | |
| 368 | - run bootcmd_pxe |
| 369 | boots by tftp using a pxelinux.cfg |
| 370 | |
| 371 | The list of possible targets consists of: |
| 372 | |
| 373 | - network targets |
| 374 | * dhcp |
| 375 | * pxe |
| 376 | |
| 377 | - storage targets (to which a device number must be appended) |
| 378 | * mmc |
| 379 | * sata |
| 380 | * scsi |
| 381 | * ide |
| 382 | * usb |
| 383 | |
| 384 | Other *boot* variables than the ones defined above are only for internal use |
| 385 | of the boot environment and are not guaranteed to exist or work in the same |
| 386 | way in future u-boot versions. In particular the <device type>_boot |
| 387 | variables (e.g. mmc_boot, usb_boot) are a strictly internal implementation |
| 388 | detail and must not be used as a public interface. |