In the previous post, we looked at why I’ve been working on pibootctl. But if you just want to use it, look no further! (Or, do go and read the fine manual if you prefer).
Installing it on your pi is pretty simple:
$ sudo add-apt-repository ppa:waveform/pibootctl $ sudo apt install pibootctl
Side note: in future, this should be included by default on Ubuntu images, but for now it lives in my PPA.
Help!
The utility includes several sub-commands, but the first you ought to learn (or even guess) is “help”:
$ pibootctl help usage: pibootctl [-h] [--version] {help,?,status,dump,get,set,save,load,diff,show,cat,list, ls,remove,rm,rename,mv} ... pibootctl is a tool for querying and modifying the boot configuration of the Raspberry Pi. optional arguments: -h, --help show this help message and exit --version show program's version number and exit commands: {help,?,status,dump,get,set,save,load,diff,show,cat,list,ls,remove,rm, rename,mv} help (?) Displays help about the specified command or setting status (dump) Output the current boot time configuration get Query the state of one or more boot settings set Change the state of one or more boot settings save Store the current boot configuration for later use load Replace the boot configuration with a saved one diff Show the differences between boot configurations show (cat) Show the specified stored configuration list (ls) List the stored boot configurations remove (rm) Remove a stored boot configuration rename (mv) Rename a stored boot configuration
You can also ask this sub-command for help on any of the other sub-commands … including itself:
$ pibootctl help help usage: pibootctl help [-h] [command-or-setting] With no arguments, displays the list of pibootctl commands. If a command name is given, displays the description and options for the named command. If a setting name is given, displays the description and default value for that setting. positional arguments: command-or-setting The name of the command or setting to output help for optional arguments: -h, --help show this help message and exit
If you fancy good old man-pages, there’s those too. One for the tool itself, and one for each sub-command. For example:
$ man pibootctl $ man pibootctl help
These include some additional notes and examples which may be worth a look (they’re also included in the online manual).
First Steps
What about actual usage? The first thing you’ll probably want to do is look at the current state of your boot configuration. This is what Ubuntu 20.04’s looks like in pibootctl “out of the box”:
$ pibootctl status ┌─────────────────────────┬──────────────────────┐ │ Name │ Value │ ├─────────────────────────┼──────────────────────┤ │ audio.enabled │ on │ │ boot.devicetree.address │ 50331648 (0x3000000) │ │ boot.kernel.64bit │ on │ │ boot.kernel.cmdline │ 'cmdline.txt' │ │ boot.kernel.filename │ 'uboot_rpi_3.bin' │ │ i2c.enabled │ on │ │ serial.enabled │ on │ │ spi.enabled │ on │ └─────────────────────────┴──────────────────────┘
Several things to note above:
- Oooh, pretty!
- The default output mode is designed to be human-readable and, if your locale includes “UTF-8” then unicode line-drawing characters will be used for tables.
- You’re using arm64 on a Pi3?
- Right now, yes. It was the first card and Pi combination that came to hand!
- There’s not many settings there?
- Yes, only modified settings are listed by default because otherwise there’s … a lot (and most of them you probably don’t care about). You can list all the settings with the --all option, but be warned there’s more than a page’s worth!
- I don’t recognize those setting names!
- Yes. This is probably going to be one of the more contentious decisions in the design of pibootctl. I could’ve stuck with the actual commands used in the Pi’s boot configuration, e.g. “dtparam=spi=on” or “uart_enable=1” or “disable_overscan=1”, but I didn’t. This probably needs justifying as it’s going to confuse anyone familiar with the existing settings (including me!)…
Setting Names
The names for settings in the Pi’s bootloader have grown more or less organically over time and occasionally change as new interfaces emerge (e.g. “display_rotate” being deprecated in favour of “display_lcd_rotate” and “display_hdmi_rotate”). Moreover, the settings are for use in a fairly low-level tool (the bootloader) so there’s a general preference for defaults to be “0”, hence the occasional setting with reverse setting logic (“disable_overscan=1”).
The lack of a common naming standard (while understandable) does make it tricky to query groups of settings common to an area. For example, how would you query all the video related settings (remembering that “disable_overscan” setting)? However, if a naming scheme is imposed on the settings, it becomes easy:
ubuntu@pitest:~$ pibootctl status --all video.* ┌──────────────────────────────┬──────────┬────────────────────────────────┐ │ Name │ Modified │ Value │ ├──────────────────────────────┼──────────┼────────────────────────────────┤ │ video.cec.enabled │ │ on │ │ video.cec.init │ │ on │ │ video.cec.name │ │ 'Raspberry Pi' │ │ video.dispmanx.offline │ │ off │ │ video.dpi.clock │ │ off │ │ video.dpi.enabled │ │ off │ │ video.dpi.format │ │ 1 (9-bit RGB666; unsupported) │ │ video.dpi.group │ │ 0 (auto from EDID) │ │ video.dpi.hsync.disabled │ │ off │ │ video.dpi.hsync.phase │ │ off │ │ video.dpi.hsync.polarity │ │ off │ ...
The usual “*” and “?” wildcards can be used in the setting pattern. In the above output it’s worth noting that explanatory text is included for certain setting values (e.g. “auto from EDID” for “video.dpi.group”). A more minimal example is all the settings for the TV output:
ubuntu@pitest:~$ pibootctl status --all video.tv.* ┌─────────────────────┬──────────┬──────────┐ │ Name │ Modified │ Value │ ├─────────────────────┼──────────┼──────────┤ │ video.tv.aspect │ │ 1 (4:3) │ │ video.tv.colorburst │ │ on │ │ video.tv.enabled │ │ on │ │ video.tv.mode │ │ 0 (NTSC) │ └─────────────────────┴──────────┴──────────┘
This scheme also means that simple sorting by name groups related settings together in the output. However, as mentioned above it is going to confuse anyone who’s familiar with the underlying setting names. To try and mitigate this a bit, the help output for all settings includes the underlying command name (or overlay and parameter name as appropriate), and the “help” command itself will also accept such names:
$ pibootctl help disable_overscan Name: video.overscan.enabled Default: on Command(s): disable_overscan When enabled (the default), if a group 1 (CEA) HDMI mode is selected (automatically or otherwise), the display output will include black borders to align the edges of the output with a typical TV display.
There are cases where an underlying command is represented (or affected by) several settings (and vice versa). In this case, asking for help on such a setting will tell you the names of all settings that can affect it:
$ pibootctl help start_file start_file is affected by the following settings: boot.debug.enabled boot.firmware.filename camera.enabled
Scripting
We’ve seen the pretty-printed output of multiple settings above. What about retrieving an individual setting for scripting purposes? The “get” command is used for this (there’s very little point using this command outside a script):
$ pibootctl get serial.enabled on
While this is simple enough, it’s not very efficient when it comes to obtaining the value of lots of settings. To accommodate usage from scripts, the majority of commands in pibootctl (including “get” and “status”) accept the --json, --yaml, or --shell switches to produce output in JSON, YAML, or a shell-compatible style respectively:
$ pibootctl status --json --all "video.hdmi*" {"video.hdmi.edid.override": false, "video.hdmi.safe": false, "video.hdmi.4kp60": false, "video.hdmi.edid.ignore": false, "video.hdmi.edid.contenttype": 0, "video.hdmi0.edid.filename": "edid.dat", "video.hdmi.edid.parse": true, "video.hdmi0.enabled": null, "video.hdmi.edid.3d": false, "video.hdmi0.audio": null, "video.hdmi0.boost": 5, "video.hdmi0.group": 0, "video.hdmi0.timings": [], "video.hdmi.powersave": false, "video.hdmi0.mode": 0, "video.hdmi0.mode.force": false, "video.hdmi0.encoding": 0, "video.hdmi0.drive": 0, "video.hdmi0.rotate": 0, "video.hdmi0.flip": 0, "video.hdmi1.boost": 5, "video.hdmi1.enabled": null, "video.hdmi1.audio": null, "video.hdmi1.edid.filename": "edid.dat", "video.hdmi1.timings": [], "video.hdmi1.group": 0, "video.hdmi1.mode": 0, "video.hdmi1.mode.force": false, "video.hdmi1.encoding": 0, "video.hdmi1.drive": 0, "video.hdmi1.rotate": 0, "video.hdmi1.flip": 0} $ pibootctl get --json serial.enabled true
Writing?
That’s enough for this post; next time we’ll have a look at how pibootctl modifies the boot configuration, and the steps it takes to try and do so safely!