|
| 1 | +## Understanding the generic bootscript |
| 2 | +The generic bootscript [template] attempts to [do all the things](http://www.quickmeme.com/img/55/55157deb762c88e8979fe0c515e68802cceaa45f0f35707af310059bae831ecd.jpg) found in the bootscripts of `sunxi`, `mvebu` and `rockchip64`. |
| 3 | + |
| 4 | +There are a number of functional blocks in the generic bootscript: |
| 5 | + |
| 6 | +1. Define U-Boot environment variables. |
| 7 | +1. Load a U-Boot environment (`armbianEnv.txt` in our case). |
| 8 | +1. Prepare kernel commandline parameters based on loaded environment settings. |
| 9 | +1. Process device tree (DT). |
| 10 | +1. Proces the kernel image. |
| 11 | +1. Process the initial ramdisk. |
| 12 | +1. Load the initial ramdisk. |
| 13 | +1. Boot the kernel with locations of the initial ramdisk and device tree. |
| 14 | + |
| 15 | +The DT is now loaded first, followed by the kernel image with the initial ramdisk last. |
| 16 | + |
| 17 | +### Templating |
| 18 | +Differences and deviations in the actions or settings performed by these bootscript have been templated, meaning that the generic bootscript needs input for each board. For example, they all have a serial console so all bootscripts contain actions to prepare the kernel to use the serial console. The actual console device is however not always the same. |
| 19 | + |
| 20 | +The following variables need to be defined on the board configuration to render the generic bootscript template: |
| 21 | + |
| 22 | +|Variable|Usage| |
| 23 | +|-|-| |
| 24 | +|`BOOTSCRIPT_TEMPLATE__ALIGN_TO`|For the calculation of load addresses by the generic bootscript, addresses need to be aligned for most CPU types. For example, for ARM64 CPUs, the start of the `Image` file to be aligned to a 2MiB (`0x00200000`) boundary. For most architectures, aligning these addresses to a 4KiB (`0x1000`) address boundary is good practice.| |
| 25 | +|`BOOTSCRIPT_TEMPLATE__DISPLAY_CONSOLE`|The serial device to use for the 'display' console, e.g. `/dev/tty0`.| |
| 26 | +|`BOOTSCRIPT_TEMPLATE__SERIAL_CONSOLE`|The serial device to use for the 'serial' console, e.g. `/dev/ttyS1`.| |
| 27 | +|`BOOTSCRIPT_TEMPLATE__BOARD_FAMILY`|The CPU family, currently not used by the generic bootscript.| |
| 28 | +|`BOOTSCRIPT_TEMPLATE__ROOTFS_TYPE`|The filesystem type of the root filesystem, e.g. `ext4` or `f2fs`.| |
| 29 | +|`BOOTSCRIPT_TEMPLATE__BOARD_VENDOR`|The vendor of the board, e.g. `allwinner`, `rockchips64`.| |
| 30 | +|`BOOTSCRIPT_TEMPLATE__LOAD_ADDR`|Some architectures/CPUs have a different load address that is used to load scripts or FDT files. Use the `loadaddr` that fits with your architecture, e.g. `0x00300000` for the Helios4 (`mvebu`) or `0x09000000` for the NanoPi R2s.| |
| 31 | + |
| 32 | +The generic bootscript template will be rendered during building. If any of the bootscript template variables are not defined, the build process will error out. |
| 33 | + |
| 34 | +Example of a board configuration file for the Orange Pi Zero: |
| 35 | +``` |
| 36 | +# Allwinner H2+ quad core 256/512MB RAM SoC WiFi SPI |
| 37 | +BOARD_NAME="Orange Pi Zero" |
| 38 | +BOARDFAMILY="sun8i" |
| 39 | +BOARD_MAINTAINER="" |
| 40 | +BOOTCONFIG="orangepi_zero_defconfig" |
| 41 | +MODULES_CURRENT="g_serial" |
| 42 | +MODULES_BLACKLIST="sunxi_cedrus" |
| 43 | +DEFAULT_OVERLAYS="usbhost2 usbhost3 tve" |
| 44 | +DEFAULT_CONSOLE="both" |
| 45 | +HAS_VIDEO_OUTPUT="yes" |
| 46 | +KERNEL_TARGET="legacy,current,edge" |
| 47 | +KERNEL_TEST_TARGET="current" |
| 48 | +CRUSTCONFIG="orangepi_zero_defconfig" |
| 49 | +
|
| 50 | +DISPLAYCON='' |
| 51 | +SERIALCON="ttyS0:115200,ttyGS0" |
| 52 | +
|
| 53 | +BOOTSCRIPT='boot-generic.cmd.template:boot.cmd' |
| 54 | +BOOTSCRIPT_TEMPLATE__ALIGN_TO='0x00001000' |
| 55 | +BOOTSCRIPT_TEMPLATE__BOARD_FAMILY="${BOARDFAMILY:-sun8i}" |
| 56 | +BOOTSCRIPT_TEMPLATE__BOARD_VENDOR='allwinner' |
| 57 | +BOOTSCRIPT_TEMPLATE__DISPLAY_CONSOLE='' # determine later on |
| 58 | +BOOTSCRIPT_TEMPLATE__LOAD_ADDR='0x45000000' |
| 59 | +BOOTSCRIPT_TEMPLATE__ROOTFS_TYPE="${ROOTFS_TYPE:-ext4}" |
| 60 | +BOOTSCRIPT_TEMPLATE__SERIAL_CONSOLE='' # determine later on |
| 61 | +
|
| 62 | +function orange_pi_zero_enable_xradio_workarounds() { |
| 63 | + /usr/bin/systemctl enable xradio_unload.service |
| 64 | +... |
| 65 | +``` |
| 66 | + |
| 67 | +### Rendering of the template |
| 68 | +The bootscript template is rendered in `lib/functions/rootfs/distro-agnostic.sh` by the function `render_bootscript_template`. As the display and serial console devices can be defined throughout the build process, the following functions will gather them all and process them accordingly: |
| 69 | +- `bootscript_export_display_console` for `DISPLAYCON` |
| 70 | +- `bootscript_export_serial_console` for `SERIALCON` |
| 71 | + |
| 72 | +All consoles defined in `SERIALCON`/`DISPLAYCON` and `BOOTSCRIPT_TEMPLATE__SERIAL_CONSOLE`/`BOOTSCRIPT_TEMPLATE__DISPLAY_CONSOLE` will be combined by the generic the bootscript into something that can be passed on to the Linux kernel. |
| 73 | + |
| 74 | +Multiple console devices can be defined by seperating them with a `,` (comma). Standard Linux kernel arguments are allowed: |
| 75 | +``` |
| 76 | +SERIALCON="ttyS0:115200,ttyGS0" |
| 77 | +``` |
| 78 | + |
| 79 | +See [here](https://www.kernel.org/doc/html/latest/admin-guide/serial-console.html) for more information on the arguments and syntax. |
| 80 | + |
| 81 | +### Calculating the size of the device tree |
| 82 | +For the device tree (DT) it depends on the U-Boot version if the bootscript can determine it's size. The `fdt` shell command has a subcommand `header get` that can return the size of the current DT in-memory. In case the size of the in-memory DT cannot be determined, the filesize of the FDT will be used - aligned to `${align_to}`. |
| 83 | + |
| 84 | +### Calculating the size of the linux kernel image |
| 85 | + |
| 86 | +### Calculating the size of the initial ramdisk |
| 87 | + |
| 88 | +# References |
| 89 | + |
| 90 | +- [U-Boot shell commands](https://docs.u-boot.org/en/latest/usage/index.html#shell-commands). |
| 91 | +- [U-Boot environment variables](https://docs.u-boot.org/en/latest/usage/environment.html). |
| 92 | +- [FDT](https://www.kernel.org/doc/html/latest/devicetree/usage-model.html). |
| 93 | +- Initial ramdisk [initrd](https://docs.kernel.org/admin-guide/initrd.html). |
| 94 | +- Kernel image types [[1]](https://www.baeldung.com/linux/kernel-images) [[2]](https://unix.stackexchange.com/a/295142). |
| 95 | +- [Helios4 doesn't boot after upgrading to linux-6.6.71 (linux-image-current-mvebu_25.2.0-trunk.343)](https://forum.armbian.com/topic/49440-helios4-doesnt-boot-after-upgrading-to-linux-6671-linux-image-current-mvebu_2520-trunk343/#findComment-217099). |
| 96 | +- [[Bug]: mvebu/Helios4: Wrong Ramdisk Image Format, Ramdisk image is corrupt or invalid #8165](https://github.com/armbian/build/issues/8165). |
| 97 | +- [[Bug]: U-Boot load address calculation bug and DT overlap oobe #8178](https://github.com/armbian/build/issues/8178). |
0 commit comments