<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom"><title>It's Pi all the way down... - questing</title><link href="https://waldorf.waveform.org.uk/" rel="alternate"></link><link href="https://waldorf.waveform.org.uk/feeds/questing.atom.xml" rel="self"></link><id>https://waldorf.waveform.org.uk/</id><updated>2025-07-10T21:05:08+01:00</updated><entry><title>Pull yourself up by your bootstraps</title><link href="https://waldorf.waveform.org.uk/2025/pull-yourself-up-by-your-bootstraps.html" rel="alternate"></link><published>2025-07-09T00:00:00+01:00</published><updated>2025-07-10T21:05:08+01:00</updated><author><name>Dave Jones</name></author><id>tag:waldorf.waveform.org.uk,2025-07-09:/2025/pull-yourself-up-by-your-bootstraps.html</id><summary type="html">&lt;p class="first last"&gt;Some fairly radical changes to the way Ubuntu boots on the Raspberry&amp;nbsp;Pi&lt;/p&gt;
</summary><content type="html">&lt;p&gt;&lt;strong&gt;Updated&lt;/strong&gt;: Minor punctuation changes, and a small clarification of why the
current fallback probably isn&amp;#8217;t a fallback at&amp;nbsp;all&lt;/p&gt;
&lt;p&gt;The way Ubuntu boots on the Raspberry is changing in questing. Here&amp;#8217;s the story
behind the changes (along with my usual copious tangents, and finishing up with
some details on how to avoid these changes if you really, &lt;em&gt;really&lt;/em&gt; need&amp;nbsp;to).&lt;/p&gt;
&lt;div class="section" id="boots-an-all"&gt;
&lt;h2&gt;Boots an&amp;#8217;&amp;nbsp;all&lt;/h2&gt;
&lt;p&gt;Our current boot setup is… far from optimal. To understand it we should first
have a look at how the Pi boots, and how Ubuntu uses this (skip this section if
you&amp;#8217;re familiar with the Pi&amp;#8217;s&amp;nbsp;bootloader!).&lt;/p&gt;
&lt;p&gt;The Pi&amp;#8217;s native bootloader is split into three parts which we&amp;#8217;ll simply call
Stages 1, 2, and&amp;nbsp;3.&lt;/p&gt;
&lt;p&gt;Stage 1 is always on the SoC (on all models). It&amp;#8217;s main job (as far as we&amp;#8217;re
concerned) as to find and load stage 2. Its configuration is the
&lt;tt class="docutils literal"&gt;autoboot.txt&lt;/tt&gt; file. If this is present, it must be on the first partition of
the boot media. Due to stage 1&amp;#8217;s very limited resources (there&amp;#8217;s no &lt;span class="caps"&gt;RAM&lt;/span&gt;
available at this stage), this file is limited to 512 bytes, and only
understands a few directives. The most important is &lt;tt class="docutils literal"&gt;boot_partition&lt;/tt&gt; which
tells it which partition contains the rest of the boot&amp;nbsp;media.&lt;/p&gt;
&lt;p&gt;Prior to the Pi 4, stage 2 was the &lt;tt class="docutils literal"&gt;bootcode.bin&lt;/tt&gt; executable. From the Pi 4
onwards, this is part of the boot &lt;span class="caps"&gt;EEPROM&lt;/span&gt;. I&amp;#8217;m not fully clear on all the things
stage 2 does, but I do know this stage handles bringing up some more bits of
hardware to load and execute the (much bigger) third stage. For instance, when
network booting, it&amp;#8217;s this stage that brings the ethernet port up, performs
&lt;span class="caps"&gt;DHCP&lt;/span&gt;, and starts the &lt;span class="caps"&gt;TFTP&lt;/span&gt; process for the other boot&amp;nbsp;assets.&lt;/p&gt;
&lt;p&gt;The second stage also reads at least &lt;em&gt;some&lt;/em&gt; of the &lt;tt class="docutils literal"&gt;config.txt&lt;/tt&gt; configuration
file, as this can be used to customize which binary is loaded for the third&amp;nbsp;stage.&lt;/p&gt;
&lt;p&gt;Stage 3 is the real &amp;#8220;meat&amp;#8221; of the bootloader. On the Pi 3 and earlier it was
named &lt;tt class="docutils literal"&gt;start.elf&lt;/tt&gt;; on the Pi 4 this became &lt;tt class="docutils literal"&gt;start4.elf&lt;/tt&gt; file; on the Pi 5
this is another part of the boot &lt;span class="caps"&gt;EEPROM&lt;/span&gt; &lt;a class="footnote-reference" href="#kernel-only" id="footnote-reference-1"&gt;[1]&lt;/a&gt;. There were 4
historical variants of this&amp;nbsp;stage:&lt;/p&gt;
&lt;dl class="docutils"&gt;
&lt;dt&gt;start.elf /&amp;nbsp;start4.elf&lt;/dt&gt;
&lt;dd&gt;The default third&amp;nbsp;stage&lt;/dd&gt;
&lt;dt&gt;start_cd.elf /&amp;nbsp;start4cd.elf&lt;/dt&gt;
&lt;dd&gt;A &amp;#8220;cut down&amp;#8221; version of the bootloader with minimal facilities &lt;a class="footnote-reference" href="#cut-down" id="footnote-reference-2"&gt;[2]&lt;/a&gt;&lt;/dd&gt;
&lt;dt&gt;start_db.elf /&amp;nbsp;start4db.elf&lt;/dt&gt;
&lt;dd&gt;The &amp;#8220;debug&amp;#8221; build of the&amp;nbsp;bootloader&lt;/dd&gt;
&lt;dt&gt;start_x.elf /&amp;nbsp;start4x.elf&lt;/dt&gt;
&lt;dd&gt;The bootloader incorporating the legacy camera firmware &lt;a class="footnote-reference" href="#gpu" id="footnote-reference-3"&gt;[3]&lt;/a&gt;&lt;/dd&gt;
&lt;/dl&gt;
&lt;p&gt;Each of these binaries has a corresponding &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;fixup*.dat&lt;/span&gt;&lt;/tt&gt; (&lt;tt class="docutils literal"&gt;fixup.dat&lt;/tt&gt;,
&lt;tt class="docutils literal"&gt;fixup4.dat&lt;/tt&gt;, etc.) file which contains the relocation information &lt;a class="footnote-reference" href="#afaik" id="footnote-reference-4"&gt;[5]&lt;/a&gt;
for each&amp;nbsp;binary.&lt;/p&gt;
&lt;p&gt;This stage is responsible for loading &lt;a class="footnote-reference" href="#maybe-dt" id="footnote-reference-5"&gt;[4]&lt;/a&gt; the device-tree and
customizing it for the hardware detected, loading the binaries containing the
Linux kernel, and (optionally) the initramfs. It parses all of &lt;tt class="docutils literal"&gt;config.txt&lt;/tt&gt;
which has many options that can be used to customize the booted state. It also
reads &lt;tt class="docutils literal"&gt;cmdline.txt&lt;/tt&gt; which contains the Linux kernel&amp;#8217;s command line.
Importantly, this also defines the eventual rootfs&amp;nbsp;location.&lt;/p&gt;
&lt;p&gt;Finally, this stage is responsible for bringing the &lt;span class="caps"&gt;ARM&lt;/span&gt; cores online and
starting the kernel (passing it the addresses of the fixed up device-tree, the
optional &lt;a class="reference external" href="https://en.wikipedia.org/wiki/Initial_ramdisk"&gt;initramfs&lt;/a&gt;, and the kernel command&amp;nbsp;line).&lt;/p&gt;
&lt;p&gt;Summarizing, the following table shows the location of the various stages on
the various generations of&amp;nbsp;Pi:&lt;/p&gt;
&lt;table border="1" class="docutils"&gt;
&lt;colgroup&gt;
&lt;col width="42%" /&gt;
&lt;col width="10%" /&gt;
&lt;col width="15%" /&gt;
&lt;col width="33%" /&gt;
&lt;/colgroup&gt;
&lt;thead valign="bottom"&gt;
&lt;tr&gt;&lt;th class="head"&gt;Generation&lt;/th&gt;
&lt;th class="head"&gt;SoC&lt;/th&gt;
&lt;th class="head"&gt;&lt;span class="caps"&gt;EEPROM&lt;/span&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;span class="caps"&gt;SD&lt;/span&gt; / &lt;span class="caps"&gt;USB&lt;/span&gt; / NVMe&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody valign="top"&gt;
&lt;tr&gt;&lt;td&gt;Pi 1, 2, 3, and Zero&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;2, 3&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;Pi 4, 400&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;Pi 5, 500&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;2, 3&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;One other important thing to note is that the various stages can &lt;em&gt;only&lt;/em&gt; read
the &lt;span class="caps"&gt;FAT&lt;/span&gt; file-system &lt;a class="footnote-reference" href="#fat-variants" id="footnote-reference-6"&gt;[6]&lt;/a&gt;, so all the following assets &lt;em&gt;must&lt;/em&gt; be
placed on &lt;span class="caps"&gt;FAT&lt;/span&gt; partition(s)&amp;nbsp;somewhere:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;Any bootloader assets that don&amp;#8217;t live in &lt;span class="caps"&gt;EEPROM&lt;/span&gt; for the generation of Pis you
need to&amp;nbsp;support&lt;/li&gt;
&lt;li&gt;The base device-tree(s) of all models you need to&amp;nbsp;support&lt;/li&gt;
&lt;li&gt;All the device-tree overlays wanted&amp;nbsp;(optional)&lt;/li&gt;
&lt;li&gt;The Linux&amp;nbsp;kernel&lt;/li&gt;
&lt;li&gt;The &lt;a class="reference external" href="https://en.wikipedia.org/wiki/Initial_ramdisk"&gt;initramfs&lt;/a&gt;&amp;nbsp;(optional)&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class="section" id="die-with-your-boots-on"&gt;
&lt;h2&gt;Die with your boots&amp;nbsp;on&lt;/h2&gt;
&lt;p&gt;What does Ubuntu&amp;#8217;s current boot set up look like, particularly with regard to
safety?&amp;nbsp;Erm…&lt;/p&gt;
&lt;p&gt;On the plus side we always keep two sets of boot assets around on the boot
partition. But I&amp;#8217;m afraid that&amp;#8217;s it for the good&amp;nbsp;news:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;There is no fallback facility. If your boot configuration is corrupted, if we
release a bad kernel update, etc. your boot will fail and it&amp;#8217;s up to you to
pick the&amp;nbsp;pieces&lt;/li&gt;
&lt;li&gt;The boot assets are spread across &lt;em&gt;many&lt;/em&gt; files (the aforementioned bootloader
files, the kernel, the initramfs, the base device trees, and a few hundred
overlays). But the backup files aren&amp;#8217;t in easy-to-swap directories: they&amp;#8217;re
simply next to their original files with a &amp;#8220;.bak&amp;#8221;&amp;nbsp;suffix.&lt;/li&gt;
&lt;li&gt;If you know enough shell scripting you &lt;em&gt;might&lt;/em&gt; figure out that &lt;tt class="docutils literal"&gt;for f in
$(find /boot/firmware &lt;span class="pre"&gt;-type&lt;/span&gt; f &lt;span class="pre"&gt;-name&lt;/span&gt; &lt;span class="pre"&gt;&amp;quot;*.bak&amp;quot;);&lt;/span&gt; do cp &amp;quot;$f&amp;quot; &lt;span class="pre"&gt;&amp;quot;${f%.bak}&amp;quot;;&lt;/span&gt; done&lt;/tt&gt;
is what you want &lt;a class="footnote-reference" href="#probably" id="footnote-reference-7"&gt;[7]&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Even if you figure this out, the old boot files &lt;em&gt;probably&lt;/em&gt; aren&amp;#8217;t there. If
flash-kernel has run more than once since your last boot (this is extremely
likely given it runs in response to initramfs rebuilds, kernel updates,
flash-kernel upgrades, and so on) the &amp;#8220;.bak&amp;#8221; files will simply be copies of
the &lt;em&gt;new&lt;/em&gt; boot&amp;nbsp;assets!&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This is Bad with a capital B. No automatic fallback, the manual fallback is
extremely painful, and is not even likely to&amp;nbsp;work.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="puttin-the-boot-in"&gt;
&lt;h2&gt;Puttin&amp;#8217; the boot&amp;nbsp;in&lt;/h2&gt;
&lt;p&gt;A little-known &lt;a class="footnote-reference" href="#little-known" id="footnote-reference-8"&gt;[8]&lt;/a&gt; facility of the Pi&amp;#8217;s bootloader is the
&amp;#8220;tryboot&amp;#8221; facility. This is a rather neat system designed to provide a robust
means to implement A/B booting. Classically, A/B booting involves having two
separate copies of all your critical boot assets, and having some mechanism to
switch between&amp;nbsp;them.&lt;/p&gt;
&lt;p&gt;Let&amp;#8217;s say you booted from set &amp;#8220;A&amp;#8221;. A new kernel is released, and gets installed
into &amp;#8220;B&amp;#8221;, and the bootloader is set to boot from &amp;#8220;B&amp;#8221; instead. The bootloader
then needs some means of noticing if the &amp;#8220;B&amp;#8221; boot fails, falling back to &amp;#8220;A&amp;#8221;.
In some cases this is done by having the bootloader record state itself in some
persistent location, but the Pi&amp;#8217;s mechanism for this is quite ingenious: it
uses &lt;em&gt;ephemeral&lt;/em&gt; state &lt;a class="footnote-reference" href="#pm-rsts" id="footnote-reference-9"&gt;[9]&lt;/a&gt; to track that it should be trying &amp;#8220;B&amp;#8221; so
that any failure results in it falling back to&amp;nbsp;&amp;#8220;A&amp;#8221;.&lt;/p&gt;
&lt;p&gt;How does this work in practice? A typical boot-flow reads the following&amp;nbsp;files:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;Stage 1 reads &lt;tt class="docutils literal"&gt;boot_partition&lt;/tt&gt; from &lt;tt class="docutils literal"&gt;autoboot.txt&lt;/tt&gt; (if it&amp;nbsp;exists)&lt;/li&gt;
&lt;li&gt;Reads stage 2 (&lt;tt class="docutils literal"&gt;bootcode.bin&lt;/tt&gt;) from the aforementioned &lt;tt class="docutils literal"&gt;boot_partition&lt;/tt&gt;
(the first by default, but from &lt;span class="caps"&gt;EEPROM&lt;/span&gt; on the Pi 4 and&amp;nbsp;5)&lt;/li&gt;
&lt;li&gt;Reads stage 3 (&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;start*.elf&lt;/span&gt;&lt;/tt&gt;) from the aforementioned &lt;tt class="docutils literal"&gt;boot_partition&lt;/tt&gt;
(from &lt;span class="caps"&gt;EEPROM&lt;/span&gt; on the Pi&amp;nbsp;5)&lt;/li&gt;
&lt;li&gt;Reads &lt;tt class="docutils literal"&gt;config.txt&lt;/tt&gt; to determine the rest of the configuration, which
specifies the locations of all remaining&amp;nbsp;assets&lt;/li&gt;
&lt;li&gt;Reads the kernel, initramfs, device-trees, overlays, etc. from the
&lt;tt class="docutils literal"&gt;boot_partition&lt;/tt&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;However, if you reboot the Pi in &amp;#8220;tryboot&amp;#8221; mode this changes&amp;nbsp;to:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;Stage 1 reads &lt;tt class="docutils literal"&gt;boot_partition&lt;/tt&gt; from &lt;tt class="docutils literal"&gt;autoboot.txt&lt;/tt&gt; (if it exists), but
optionally reads a &lt;tt class="docutils literal"&gt;[tryboot]&lt;/tt&gt; section that may override
&lt;tt class="docutils literal"&gt;boot_partition&lt;/tt&gt; (potentially directing it to a different&amp;nbsp;partition)&lt;/li&gt;
&lt;li&gt;Reads stage 2 (&lt;tt class="docutils literal"&gt;bootcode.bin&lt;/tt&gt;) from the (potentially overridden)
&lt;tt class="docutils literal"&gt;boot_partition&lt;/tt&gt; (from &lt;span class="caps"&gt;EEPROM&lt;/span&gt; on the Pi 4 and&amp;nbsp;5)&lt;/li&gt;
&lt;li&gt;Reads stage 3 (&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;start*.elf&lt;/span&gt;&lt;/tt&gt;) from the (potentially overridden)
&lt;tt class="docutils literal"&gt;boot_partition&lt;/tt&gt; (from &lt;span class="caps"&gt;EEPROM&lt;/span&gt; on the Pi&amp;nbsp;5)&lt;/li&gt;
&lt;li&gt;Reads &lt;tt class="docutils literal"&gt;tryboot.txt&lt;/tt&gt; (instead of &lt;tt class="docutils literal"&gt;config.txt&lt;/tt&gt;) which specifies the
locations of all remaining&amp;nbsp;assets&lt;/li&gt;
&lt;li&gt;Reads the kernel, initramfs, device-trees, overlays, etc. from the
(potentially overridden) &lt;tt class="docutils literal"&gt;boot_partition&lt;/tt&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The &amp;#8220;tryboot&amp;#8221; mode is initiated using the following command to reboot the&amp;nbsp;Pi:&lt;/p&gt;
&lt;pre class="code console literal-block"&gt;
&lt;span class="gp"&gt;$ &lt;/span&gt;sudo&lt;span class="w"&gt; &lt;/span&gt;reboot&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;'0 tryboot'&lt;/span&gt;
&lt;/pre&gt;
&lt;p&gt;This leads to a couple of typical designs for a tryboot-enabled boot
implementation on the&amp;nbsp;Pi…&lt;/p&gt;
&lt;div class="section" id="full-abs"&gt;
&lt;h3&gt;Full&amp;nbsp;ABs&lt;/h3&gt;
&lt;p&gt;A &amp;#8220;full&amp;#8221; A/B boot implementation consists of the following partition&amp;nbsp;layout:&lt;/p&gt;
&lt;dl class="docutils"&gt;
&lt;dt&gt;Partition 1 (&lt;span class="caps"&gt;FAT&lt;/span&gt;)&lt;/dt&gt;
&lt;dd&gt;&lt;p class="first"&gt;Just contains &lt;tt class="docutils literal"&gt;autoboot.txt&lt;/tt&gt; with the following content &lt;a class="footnote-reference" href="#no-comments" id="footnote-reference-10"&gt;[10]&lt;/a&gt;:&lt;/p&gt;
&lt;div class="last"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span id="line-1"&gt;&lt;span class="k"&gt;[all]&lt;/span&gt;
&lt;/span&gt;&lt;span id="line-2"&gt;&lt;span class="na"&gt;boot_partition&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;2&lt;/span&gt;
&lt;/span&gt;&lt;span id="line-3"&gt;
&lt;/span&gt;&lt;span id="line-4"&gt;&lt;span class="k"&gt;[tryboot]&lt;/span&gt;
&lt;/span&gt;&lt;span id="line-5"&gt;&lt;span class="hll"&gt;&lt;span class="na"&gt;tryboot_a_b&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span id="line-6"&gt;&lt;span class="na"&gt;boot_partition&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;3&lt;/span&gt;
&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;&lt;/dd&gt;
&lt;dt&gt;Partition 2 (&lt;span class="caps"&gt;FAT&lt;/span&gt;)&lt;/dt&gt;
&lt;dd&gt;&lt;p class="first"&gt;Contains the &amp;#8220;A&amp;#8221; set of boot assets. This includes the stage 2 and 3
binaries (if support of older Pi models is required), the kernel,
initramfs, device-trees, overlays, etc. No directories required;
everything&amp;#8217;s in the&amp;nbsp;root.&lt;/p&gt;
&lt;p class="last"&gt;Boot configuration is stored in &lt;tt class="docutils literal"&gt;config.txt&lt;/tt&gt;. The kernel command line in
&lt;tt class="docutils literal"&gt;cmdline.txt&lt;/tt&gt; points to partition 4 as the&amp;nbsp;rootfs.&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;Partition 3 (&lt;span class="caps"&gt;FAT&lt;/span&gt;)&lt;/dt&gt;
&lt;dd&gt;Contains the &amp;#8220;B&amp;#8221; set of boot assets. Identical layout to partition 2, but
&lt;tt class="docutils literal"&gt;cmdline.txt&lt;/tt&gt; points to partition 5 as the&amp;nbsp;rootfs.&lt;/dd&gt;
&lt;dt&gt;Partition&amp;nbsp;4&lt;/dt&gt;
&lt;dd&gt;The &amp;#8220;A&amp;#8221;&amp;nbsp;rootfs&lt;/dd&gt;
&lt;dt&gt;Partition&amp;nbsp;5&lt;/dt&gt;
&lt;dd&gt;The &amp;#8220;B&amp;#8221;&amp;nbsp;rootfs&lt;/dd&gt;
&lt;/dl&gt;
&lt;div class="admonition note"&gt;
&lt;p class="first admonition-title"&gt;Note&lt;/p&gt;
&lt;p class="last"&gt;Note the (highlighted) &lt;tt class="docutils literal"&gt;tryboot_a_b=1&lt;/tt&gt; line in &lt;tt class="docutils literal"&gt;autoboot.txt&lt;/tt&gt;. This
causes the third stage to read &lt;tt class="docutils literal"&gt;config.txt&lt;/tt&gt; instead of &lt;tt class="docutils literal"&gt;tryboot.txt&lt;/tt&gt;
because the assumption is that, in this layout, the boot configuration will
be precisely duplicated (both boot partitions have &lt;tt class="docutils literal"&gt;config.txt&lt;/tt&gt;).&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;To switch between the A and B sets, &lt;tt class="docutils literal"&gt;autoboot.txt&lt;/tt&gt; on the first partition is
updated (preferably atomically &lt;a class="footnote-reference" href="#atomic-fs" id="footnote-reference-11"&gt;[11]&lt;/a&gt;) with swapped values of the
&lt;tt class="docutils literal"&gt;boot_partition=&lt;/tt&gt; lines.&lt;/p&gt;
&lt;p&gt;Typically the first partition is some smaller variant of &lt;span class="caps"&gt;FAT&lt;/span&gt; (&lt;span class="caps"&gt;FAT&lt;/span&gt;-12/16) while
partitions two and three are &lt;span class="caps"&gt;FAT&lt;/span&gt;-32. Partitions 4 and 5 are whatever you use as
a rootfs (commonly ext4, but can be anything your kernel and initramfs
combination can&amp;nbsp;support).&lt;/p&gt;
&lt;p&gt;The benefits of this layout are pretty&amp;nbsp;obvious:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;It switches &lt;em&gt;everything&lt;/em&gt; including &lt;em&gt;all&lt;/em&gt; the bootloader assets (at least on
the Pi models without any &lt;span class="caps"&gt;EEPROM&lt;/span&gt;).&lt;/li&gt;
&lt;li&gt;It&amp;#8217;s also capable of switching the entire rootfs, although this is optional
(the &amp;#8220;B&amp;#8221; &lt;tt class="docutils literal"&gt;cmdline.txt&lt;/tt&gt; could equally point at partition 4 to have a single&amp;nbsp;rootfs).&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The drawbacks&amp;nbsp;are:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;You pretty much have to design this &amp;#8220;up front&amp;#8221; into your image; it&amp;#8217;s great
for fresh installations, but almost impossible to &lt;em&gt;safely&lt;/em&gt; migrate existing
installations with a more basic layout to&amp;nbsp;it.&lt;/li&gt;
&lt;li&gt;This design is also more complex for users who wish to edit the boot
configuration as they now need to figure out which partition is mounted and
edit the boot files on the &lt;em&gt;other&lt;/em&gt; partition &lt;a class="footnote-reference" href="#experiments" id="footnote-reference-12"&gt;[12]&lt;/a&gt;. That said, I
suspect most uses of this layout try and ensure that users have no ability to
mess with the boot configuration at&amp;nbsp;all.&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class="section" id="the-beer-belly-version"&gt;
&lt;h3&gt;The beer belly&amp;nbsp;version&lt;/h3&gt;
&lt;p&gt;A much simpler configuration uses the traditional partition layout but with
some minor tweaks to the files on the boot&amp;nbsp;partition:&lt;/p&gt;
&lt;dl class="docutils"&gt;
&lt;dt&gt;Partition 1 (&lt;span class="caps"&gt;FAT&lt;/span&gt;-32)&lt;/dt&gt;
&lt;dd&gt;&lt;ul class="first last"&gt;
&lt;li&gt;&lt;p class="first"&gt;No &lt;tt class="docutils literal"&gt;autoboot.txt&lt;/tt&gt; (as per&amp;nbsp;usual)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p class="first"&gt;Bootloader assets (&lt;tt class="docutils literal"&gt;bootcode.bin&lt;/tt&gt;, &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;start*.elf&lt;/span&gt;&lt;/tt&gt;) are placed in the
root of this&amp;nbsp;partition.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p class="first"&gt;The &lt;tt class="docutils literal"&gt;a/&lt;/tt&gt; directory contains the remainder of the boot assets:
device-trees, Linux kernel, initramfs, overlays, &lt;tt class="docutils literal"&gt;cmdline.txt&lt;/tt&gt; (which
points at partition 2 as the&amp;nbsp;rootfs).&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p class="first"&gt;Another directory, &lt;tt class="docutils literal"&gt;b/&lt;/tt&gt; contains a second set of these boot&amp;nbsp;assets.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p class="first"&gt;&lt;tt class="docutils literal"&gt;config.txt&lt;/tt&gt; contains something like the&amp;nbsp;following:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span id="line-1"&gt;&lt;span class="k"&gt;[all]&lt;/span&gt;
&lt;/span&gt;&lt;span id="line-2"&gt;&lt;span class="hll"&gt;&lt;span class="na"&gt;os_prefix&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;a/&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span id="line-3"&gt;&lt;span class="na"&gt;kernel&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;vmlinuz&lt;/span&gt;
&lt;/span&gt;&lt;span id="line-4"&gt;&lt;span class="na"&gt;initramfs initrd.img followkernel&lt;/span&gt;
&lt;/span&gt;&lt;span id="line-5"&gt;&lt;span class="na"&gt;...&lt;/span&gt;
&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p class="first"&gt;&lt;tt class="docutils literal"&gt;tryboot.txt&lt;/tt&gt; contains something&amp;nbsp;like:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span id="line-1"&gt;&lt;span class="k"&gt;[all]&lt;/span&gt;
&lt;/span&gt;&lt;span id="line-2"&gt;&lt;span class="hll"&gt;&lt;span class="na"&gt;os_prefix&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;b/&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span id="line-3"&gt;&lt;span class="na"&gt;kernel&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;vmlinuz&lt;/span&gt;
&lt;/span&gt;&lt;span id="line-4"&gt;&lt;span class="na"&gt;initramfs initrd.img followkernel&lt;/span&gt;
&lt;/span&gt;&lt;span id="line-5"&gt;&lt;span class="na"&gt;...&lt;/span&gt;
&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/dd&gt;
&lt;dt&gt;Partition&amp;nbsp;2&lt;/dt&gt;
&lt;dd&gt;The&amp;nbsp;rootfs&lt;/dd&gt;
&lt;/dl&gt;
&lt;p&gt;To switch between A and B, either &lt;tt class="docutils literal"&gt;config.txt&lt;/tt&gt; and &lt;tt class="docutils literal"&gt;tryboot.txt&lt;/tt&gt; are
exchanged, or the &lt;tt class="docutils literal"&gt;a/&lt;/tt&gt; and &lt;tt class="docutils literal"&gt;b/&lt;/tt&gt; directories are switched (preferably
atomically &lt;a class="footnote-reference" href="#atomic-exchg" id="footnote-reference-13"&gt;[13]&lt;/a&gt;).&lt;/p&gt;
&lt;p&gt;The advantages to this layout are primarily&amp;nbsp;simplicity.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;It&amp;#8217;s fairly easy to migrate an existing classical layout to this, and do so
in a &amp;#8220;safe&amp;#8221; manner that guarantees a &amp;#8220;known good&amp;#8221; boot configuration is
present at every&amp;nbsp;step.&lt;/li&gt;
&lt;li&gt;It&amp;#8217;s also easier for users who know all their boot configuration will be
present on a single partition (they don&amp;#8217;t need to go potentially mounting&amp;nbsp;things).&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The disadvantages&amp;nbsp;are:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;The bootloader assets (&lt;tt class="docutils literal"&gt;bootcode.bin&lt;/tt&gt;, &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;start*.elf&lt;/span&gt;&lt;/tt&gt;) cannot be switched
by this method as they cannot be read from sub-directories. However, bear in
mind that these are only used by older models of Pi and thus are unlikely to
change much in the coming years&amp;nbsp;anyway.&lt;/li&gt;
&lt;li&gt;Changing the boot configuration becomes a little more complex. Let&amp;#8217;s say you
want to try a new overlay. You add the &lt;tt class="docutils literal"&gt;dtoverlay=&lt;/tt&gt; line to &lt;tt class="docutils literal"&gt;tryboot.txt&lt;/tt&gt;
and initiate &amp;#8220;tryboot&amp;#8221;. Your &lt;span class="caps"&gt;OS&lt;/span&gt; boots successfully, and some service switches
&lt;tt class="docutils literal"&gt;tryboot.txt&lt;/tt&gt; and &lt;tt class="docutils literal"&gt;config.txt&lt;/tt&gt;. However, now you need to remember to make
the same edit to the &lt;em&gt;new&lt;/em&gt; &lt;tt class="docutils literal"&gt;tryboot.txt&lt;/tt&gt; (your former &lt;tt class="docutils literal"&gt;config.txt&lt;/tt&gt;) or
the next switch will lose the&amp;nbsp;change.&lt;/li&gt;
&lt;li&gt;If you want to edit the kernel command line, you still have to query
&lt;tt class="docutils literal"&gt;config.txt&lt;/tt&gt; to figure out which &lt;tt class="docutils literal"&gt;cmdline.txt&lt;/tt&gt; to fiddle with
(&lt;tt class="docutils literal"&gt;a/cmdline.txt&lt;/tt&gt; or &lt;tt class="docutils literal"&gt;b/cmdline.txt&lt;/tt&gt;).&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="section" id="boot-camp"&gt;
&lt;h2&gt;Boot&amp;nbsp;camp&lt;/h2&gt;
&lt;p&gt;As you can probably tell from the above, I don&amp;#8217;t think either of the two
designs presented is &lt;em&gt;quite&lt;/em&gt; what we want for&amp;nbsp;questing.&lt;/p&gt;
&lt;p&gt;The &amp;#8220;full&amp;#8221; A/B design is far too complex to migrate to, and I don&amp;#8217;t think
there&amp;#8217;s any way of doing it safely. This is especially the case given that we
may have upgraders who have inherited a minimal &lt;span class="caps"&gt;256MB&lt;/span&gt; boot partition from
earlier releases of&amp;nbsp;Ubuntu.&lt;/p&gt;
&lt;p&gt;The &amp;#8220;lite&amp;#8221; version is a good basis, but the whole &amp;#8220;a&amp;#8221; and &amp;#8220;b&amp;#8221; thing strikes me
as a little obscure. I also don&amp;#8217;t particularly like the duplication of
&lt;tt class="docutils literal"&gt;config.txt&lt;/tt&gt; into &lt;tt class="docutils literal"&gt;tryboot.txt&lt;/tt&gt;. There are an absolute ton of scripts out
there that assume they can blindly append configuration to &lt;tt class="docutils literal"&gt;config.txt&lt;/tt&gt;
(which is why it&amp;#8217;s usually important to make sure your configuration ends with
an &lt;tt class="docutils literal"&gt;[all]&lt;/tt&gt; section). While this isn&amp;#8217;t &amp;#8220;good practice&amp;#8221;, the swapping of
&lt;tt class="docutils literal"&gt;tryboot.txt&lt;/tt&gt; and &lt;tt class="docutils literal"&gt;config.txt&lt;/tt&gt; would break people who rely on these&amp;nbsp;scripts.&lt;/p&gt;
&lt;p&gt;After experimenting with a few designs over the last few weeks, here&amp;#8217;s the
design I&amp;#8217;ve come up with, which should be landing in questing as I post&amp;nbsp;this:&lt;/p&gt;
&lt;p&gt;As in the &amp;#8220;lite&amp;#8221; A/B boot design, we still have our regular old &lt;span class="caps"&gt;FAT&lt;/span&gt; boot
partition, and one rootfs partition. The bootloader assets (&lt;tt class="docutils literal"&gt;bootcode.bin&lt;/tt&gt;,
&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;start*.elf&lt;/span&gt;&lt;/tt&gt;, and so on) still live in the root of the boot partition
(because they have to). All other assets move into three&amp;nbsp;directories:&lt;/p&gt;
&lt;dl class="docutils"&gt;
&lt;dt&gt;current&lt;/dt&gt;
&lt;dd&gt;This directory &lt;em&gt;always&lt;/em&gt; exists, and &lt;em&gt;always&lt;/em&gt; contains the &lt;em&gt;current&lt;/em&gt; boot
assets of the booted system &lt;a class="footnote-reference" href="#transitional" id="footnote-reference-14"&gt;[14]&lt;/a&gt;. Thus, by definition, it will
always contain &amp;#8220;known good&amp;#8221; boot&amp;nbsp;assets.&lt;/dd&gt;
&lt;dt&gt;old&lt;/dt&gt;
&lt;dd&gt;If this directory exists, it contains the formerly &amp;#8220;known good&amp;#8221; boot
assets. We keep this around when possible just in case users need it;
consider a boot configuration change that isn&amp;#8217;t fatal (the boot still
succeeds), but which results in some undesirable side effect later at
runtime. The new service should make it trivial to switch &amp;#8220;old&amp;#8221; to
&amp;#8220;current&amp;#8221; when&amp;nbsp;desired.&lt;/dd&gt;
&lt;dt&gt;new&lt;/dt&gt;
&lt;dd&gt;If this directory exists, it either contains new untested boot assets, or
it contains boot assets that were tested, but&amp;nbsp;failed.&lt;/dd&gt;
&lt;/dl&gt;
&lt;p&gt;Why keep failed boot assets around? It may be useful to see the configuration
that failed for debugging purposes, but more importantly we can only assume
that we have space for two sets of boot assets on the boot partition.
Therefore, before &amp;#8220;new&amp;#8221; is created, &amp;#8220;old&amp;#8221; is always deleted first. This is safe
because &amp;#8220;current&amp;#8221; is always &amp;#8220;known&amp;nbsp;good&amp;#8221;.&lt;/p&gt;
&lt;p&gt;So, we have the following &amp;#8220;states&amp;#8221; in our new boot&amp;nbsp;layout:&lt;/p&gt;
&lt;dl class="docutils"&gt;
&lt;dt&gt;stable&lt;/dt&gt;
&lt;dd&gt;&lt;span class="dquo"&gt;&amp;#8220;&lt;/span&gt;current&amp;#8221; exists; &amp;#8220;old&amp;#8221; &lt;em&gt;may&lt;/em&gt; exist (if it does, contains &amp;#8220;known good&amp;#8221;
assets); &amp;#8220;new&amp;#8221; &lt;em&gt;does not&lt;/em&gt;&amp;nbsp;exist&lt;/dd&gt;
&lt;dt&gt;untested&lt;/dt&gt;
&lt;dd&gt;&lt;span class="dquo"&gt;&amp;#8220;&lt;/span&gt;current&amp;#8221; exists; &amp;#8220;old&amp;#8221; &lt;em&gt;does not&lt;/em&gt; exist; &amp;#8220;new&amp;#8221; exists and contains
untested boot&amp;nbsp;assets&lt;/dd&gt;
&lt;dt&gt;trying&lt;/dt&gt;
&lt;dd&gt;&lt;span class="dquo"&gt;&amp;#8220;&lt;/span&gt;current&amp;#8221; exists; &amp;#8220;old&amp;#8221; &lt;em&gt;does not&lt;/em&gt; exist; &amp;#8220;new&amp;#8221; exists and contains
boot assets we&amp;#8217;re about to try (this state is entered immediately before
rebooting into the &amp;#8220;tryboot&amp;#8221;&amp;nbsp;mode)&lt;/dd&gt;
&lt;dt&gt;failed&lt;/dt&gt;
&lt;dd&gt;&lt;span class="dquo"&gt;&amp;#8220;&lt;/span&gt;current&amp;#8221; exists; &amp;#8220;old&amp;#8221; &lt;em&gt;does not&lt;/em&gt; exist; &amp;#8220;new&amp;#8221; exists and contains boot
assets marked as having&amp;nbsp;failed&lt;/dd&gt;
&lt;/dl&gt;
&lt;p&gt;The state transition diagram is as&amp;nbsp;follows:&lt;/p&gt;
&lt;object data="https://waldorf.waveform.org.uk/images/ab_states.svg" type="image/svg+xml"&gt;A simple static transition diagram showing &amp;#8220;stable&amp;#8221; goes to
&amp;#8220;untested&amp;#8221;; &amp;#8220;untested&amp;#8221; can go to &amp;#8220;untested&amp;#8221; or &amp;#8220;trying&amp;#8221;; &amp;#8220;trying&amp;#8221;
goes back to &amp;#8220;stable&amp;#8221; or to &amp;#8220;bad&amp;#8221;; and &amp;#8220;bad&amp;#8221; can only go to
&amp;#8220;untested&amp;#8221;.&lt;/object&gt;
&lt;p&gt;The &amp;#8220;loop&amp;#8221; on &amp;#8220;untested&amp;#8221; exists because (as mentioned earlier) it&amp;#8217;s perfectly
valid to have a long running system where flash-kernel has been called multiple
times (a kernel update, an initramfs rebuild, etc.), overwriting the new boot
assets each time. However, in this scenario the current boot assets are never
touched by&amp;nbsp;this.&lt;/p&gt;
&lt;p&gt;The boot configuration is stored in &lt;tt class="docutils literal"&gt;config.txt&lt;/tt&gt; and looks something like&amp;nbsp;this:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span id="line-1"&gt;&lt;span class="hll"&gt;&lt;span class="k"&gt;[all]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span id="line-2"&gt;&lt;span class="hll"&gt;&lt;span class="na"&gt;os_prefix&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;current/&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span id="line-3"&gt;&lt;span class="hll"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span id="line-4"&gt;&lt;span class="hll"&gt;&lt;span class="k"&gt;[tryboot]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span id="line-5"&gt;&lt;span class="hll"&gt;&lt;span class="na"&gt;os_prefix&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;new/&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span id="line-6"&gt;
&lt;/span&gt;&lt;span id="line-7"&gt;&lt;span class="k"&gt;[all]&lt;/span&gt;
&lt;/span&gt;&lt;span id="line-8"&gt;&lt;span class="na"&gt;kernel&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;vmlinuz&lt;/span&gt;
&lt;/span&gt;&lt;span id="line-9"&gt;&lt;span class="na"&gt;initramfs initrd.img followkernel&lt;/span&gt;
&lt;/span&gt;&lt;span id="line-10"&gt;
&lt;/span&gt;&lt;span id="line-11"&gt;&lt;span class="c1"&gt;# The rest of config.txt&lt;/span&gt;
&lt;/span&gt;&lt;span id="line-12"&gt;&lt;span class="c1"&gt;# ...&lt;/span&gt;
&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Finally, &lt;tt class="docutils literal"&gt;autoboot.txt&lt;/tt&gt; also exists, and just&amp;nbsp;contains:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span id="line-1"&gt;&lt;span class="k"&gt;[all]&lt;/span&gt;
&lt;/span&gt;&lt;span id="line-2"&gt;&lt;span class="na"&gt;tryboot_a_b&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;1&lt;/span&gt;
&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This ensures the bootloader &lt;em&gt;always&lt;/em&gt; reads &lt;tt class="docutils literal"&gt;config.txt&lt;/tt&gt;, and we simply use a
&lt;tt class="docutils literal"&gt;[tryboot]&lt;/tt&gt; filter within that file to redirect our boot to the &amp;#8220;new&amp;#8221;
directory. The advantages of this layout&amp;nbsp;are:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;We get all the advantages of the &amp;#8220;lite&amp;#8221; A/B boot setup: a reliable fallback,
and a configuration that we can migrate to &lt;em&gt;safely&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;The boot configuration lives in a single file (&lt;tt class="docutils literal"&gt;config.txt&lt;/tt&gt;) that doesn&amp;#8217;t
get arbitrarily over-written; existing scripts that append configuration to
&lt;tt class="docutils literal"&gt;config.txt&lt;/tt&gt; continue to work without configuration lines silently&amp;nbsp;disappearing.&lt;/li&gt;
&lt;li&gt;There&amp;#8217;s no confusion over which boot assets are current, which are old, and
which are new: the directory names tell you&amp;nbsp;everything.&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class="section" id="booty-yarrr"&gt;
&lt;h2&gt;Booty!&amp;nbsp;Yarrr!&lt;/h2&gt;
&lt;p&gt;This all sounds a bit too good to be true! What are the&amp;nbsp;drawbacks?&lt;/p&gt;
&lt;p&gt;The most obvious one is the fact that the &amp;#8220;tryboot&amp;#8221; mode can never be entered
from a cold boot. It &lt;em&gt;requires&lt;/em&gt; a reboot. This means some service needs to
notice (during a normal boot) that new untested boot assets are present,
interrupt the boot and restart in &amp;#8220;tryboot&amp;#8221; mode. This will mean that, each
time &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;flash-kernel&lt;/span&gt;&lt;/tt&gt; is run for whatever reason (new kernel, initramfs
rebuild, etc.) the next boot will be a double boot. This will probably be a bit
jarring to people at first (&amp;#8220;why did I see the rainbow screen &lt;em&gt;twice&lt;/em&gt;?!&amp;#8221;), and
also means that boot will take roughly twice as long&amp;nbsp;(obviously).&lt;/p&gt;
&lt;p&gt;However, I don&amp;#8217;t see a way around this and, to be frank, it&amp;#8217;s a small price to
pay for the reliability that this mechanism should&amp;nbsp;bring.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="tough-as-old-boots"&gt;
&lt;h2&gt;Tough as old&amp;nbsp;boots&lt;/h2&gt;
&lt;p&gt;I don&amp;#8217;t mean all this to sound like a fait accompli &lt;a class="footnote-reference" href="#it-is" id="footnote-reference-15"&gt;[15]&lt;/a&gt;. Some people do
weird things with their Pi. Some people may be relying on all their boot assets
being in the root of their boot partition. Some may have &lt;em&gt;weird hardware&lt;/em&gt; that
breaks horribly if reboots occur too close together (or which doesn&amp;#8217;t reset
quickly enough for the second&amp;nbsp;boot).&lt;/p&gt;
&lt;p&gt;In short, there &lt;em&gt;must&lt;/em&gt; be a fallback mechanism. To that end, I&amp;#8217;m introducing
these changes as a new &amp;#8220;method&amp;#8221; in &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;flash-kernel&lt;/span&gt;&lt;/tt&gt;, but keeping the old one in
place for those that &lt;em&gt;really&lt;/em&gt; need&amp;nbsp;it.&lt;/p&gt;
&lt;p&gt;All boards that use &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;flash-kernel&lt;/span&gt;&lt;/tt&gt; to write their boot assets (including the
Raspberry Pi under Ubuntu) have entries in the &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;flash-kernel&lt;/span&gt;&lt;/tt&gt; database
(&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;/usr/share/flash-kernel/db/all.db&lt;/span&gt;&lt;/tt&gt;) which look something like&amp;nbsp;this:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span id="line-1"&gt;Machine: Raspberry Pi 3 Model B+
&lt;/span&gt;&lt;span id="line-2"&gt;Machine: Raspberry Pi 3 Model B Plus
&lt;/span&gt;&lt;span id="line-3"&gt;Machine: Raspberry Pi 3 Model B Plus Rev 1.3
&lt;/span&gt;&lt;span id="line-4"&gt;Machine: Raspberry Pi 3 Model B Plus Rev *
&lt;/span&gt;&lt;span id="line-5"&gt;Kernel-Flavors: raspi
&lt;/span&gt;&lt;span id="line-6"&gt;&lt;span class="hll"&gt;Method: pi-try
&lt;/span&gt;&lt;/span&gt;&lt;span id="line-7"&gt;DTB-Id: bcm2710-rpi-3-b-plus.dtb
&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The important setting for our purposes is the &lt;tt class="docutils literal"&gt;Method:&lt;/tt&gt; line (highlighted).
Prior to questing this reads &lt;tt class="docutils literal"&gt;Method: pi&lt;/tt&gt; on all the (relevant) Raspberry Pi
entries. From questing onwards this will read &lt;tt class="docutils literal"&gt;Method: &lt;span class="pre"&gt;pi-try&lt;/span&gt;&lt;/tt&gt;. When
&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;flash-kernel&lt;/span&gt;&lt;/tt&gt; encounters the &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;pi-try&lt;/span&gt;&lt;/tt&gt; method, and finds the old boot
configuration on the boot partition, it will attempt to migrate it to the new
&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;pi-try&lt;/span&gt;&lt;/tt&gt; layout, and re-write the &lt;tt class="docutils literal"&gt;config.txt&lt;/tt&gt; configuration&amp;nbsp;accordingly.&lt;/p&gt;
&lt;p&gt;However, the older &lt;tt class="docutils literal"&gt;pi&lt;/tt&gt; method (no A/B booting, write everything to the root
of the boot partition) is still present in &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;flash-kernel&lt;/span&gt;&lt;/tt&gt;, and if you
absolutely need to, you can switch back to&amp;nbsp;it.&lt;/p&gt;
&lt;div class="admonition warning"&gt;
&lt;p class="first admonition-title"&gt;Warning&lt;/p&gt;
&lt;p class="last"&gt;Using the old &amp;#8220;pi&amp;#8221; mechanism leaves you in the situation described earlier:
your fallback &amp;#8220;.bak&amp;#8221; files may not really be a fallback at all, and even if
they are, it&amp;#8217;s a major pain to revert to them. Still, if you&amp;#8217;re
&lt;em&gt;absolutely&lt;/em&gt;&amp;nbsp;determined…&lt;/p&gt;
&lt;/div&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;Firstly, override the &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;flash-kernel&lt;/span&gt;&lt;/tt&gt; database entry by copying the
relevant entry to &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;/etc/flash-kernel/db&lt;/span&gt;&lt;/tt&gt; and adjusting the &lt;tt class="docutils literal"&gt;Method:&lt;/tt&gt;
line.&lt;/li&gt;
&lt;li&gt;Then, remove the &lt;tt class="docutils literal"&gt;old/&lt;/tt&gt; or &lt;tt class="docutils literal"&gt;new/&lt;/tt&gt; folders from your boot&amp;nbsp;partition.&lt;/li&gt;
&lt;li&gt;Run &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;flash-kernel&lt;/span&gt;&lt;/tt&gt; to re-copy the boot assets to the root of your boot&amp;nbsp;partition.&lt;/li&gt;
&lt;li&gt;Remove the &lt;tt class="docutils literal"&gt;os_prefix&lt;/tt&gt; lines from your boot&amp;nbsp;configuration.&lt;/li&gt;
&lt;li&gt;Finally remove the &lt;tt class="docutils literal"&gt;current/&lt;/tt&gt; directory and &lt;tt class="docutils literal"&gt;autoboot.txt&lt;/tt&gt;.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Done in this specific order, this procedure &lt;em&gt;should&lt;/em&gt; be reasonably safe and
leave you with a bootable system at all&amp;nbsp;steps.&lt;/p&gt;
&lt;p&gt;By way of an example, in the case of the Pi 3 entry above, the following
&lt;em&gt;should&lt;/em&gt; be sufficient to revert to the old boot method (pay close attention to
the highlighted&amp;nbsp;lines):&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span id="line-1"&gt;&lt;span class="gp"&gt;$ &lt;/span&gt;sudo&lt;span class="w"&gt; &lt;/span&gt;-i
&lt;/span&gt;&lt;span id="line-2"&gt;&lt;span class="go"&gt;Password:&lt;/span&gt;
&lt;/span&gt;&lt;span id="line-3"&gt;&lt;span class="gp"&gt;# &lt;/span&gt;cat&lt;span class="w"&gt; &lt;/span&gt;&amp;lt;&amp;lt;&lt;span class="w"&gt; &lt;/span&gt;EOF&lt;span class="w"&gt; &lt;/span&gt;&amp;gt;&amp;gt;&lt;span class="w"&gt; &lt;/span&gt;/etc/flash-kernel/db
&lt;/span&gt;&lt;span id="line-4"&gt;&lt;span class="go"&gt;Machine: Raspberry Pi 3 Model B+&lt;/span&gt;
&lt;/span&gt;&lt;span id="line-5"&gt;&lt;span class="go"&gt;Machine: Raspberry Pi 3 Model B Plus&lt;/span&gt;
&lt;/span&gt;&lt;span id="line-6"&gt;&lt;span class="go"&gt;Machine: Raspberry Pi 3 Model B Plus Rev 1.3&lt;/span&gt;
&lt;/span&gt;&lt;span id="line-7"&gt;&lt;span class="go"&gt;Machine: Raspberry Pi 3 Model B Plus Rev *&lt;/span&gt;
&lt;/span&gt;&lt;span id="line-8"&gt;&lt;span class="go"&gt;Kernel-Flavors: raspi&lt;/span&gt;
&lt;/span&gt;&lt;span id="line-9"&gt;&lt;span class="hll"&gt;&lt;span class="go"&gt;Method: pi&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span id="line-10"&gt;&lt;span class="go"&gt;DTB-Id: bcm2710-rpi-3-b-plus.dtb&lt;/span&gt;
&lt;/span&gt;&lt;span id="line-11"&gt;&lt;span class="go"&gt;EOF&lt;/span&gt;
&lt;/span&gt;&lt;span id="line-12"&gt;&lt;span class="gp"&gt;# &lt;/span&gt;rm&lt;span class="w"&gt; &lt;/span&gt;/boot/firmware/old
&lt;/span&gt;&lt;span id="line-13"&gt;&lt;span class="gp"&gt;# &lt;/span&gt;rm&lt;span class="w"&gt; &lt;/span&gt;/boot/firmware/new
&lt;/span&gt;&lt;span id="line-14"&gt;&lt;span class="gp"&gt;# &lt;/span&gt;flash-kernel
&lt;/span&gt;&lt;span id="line-15"&gt;&lt;span class="gp"&gt;# &lt;/span&gt;sync
&lt;/span&gt;&lt;span id="line-16"&gt;&lt;span class="gp"&gt;# &lt;/span&gt;sed&lt;span class="w"&gt; &lt;/span&gt;-i&lt;span class="w"&gt; &lt;/span&gt;-e&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;/^os_prefix/d&amp;#39;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;/boot/firmware/config.txt
&lt;/span&gt;&lt;span id="line-17"&gt;&lt;span class="gp"&gt;# &lt;/span&gt;rm&lt;span class="w"&gt; &lt;/span&gt;-rf&lt;span class="w"&gt; &lt;/span&gt;/boot/firmware/current
&lt;/span&gt;&lt;span id="line-18"&gt;&lt;span class="gp"&gt;# &lt;/span&gt;rm&lt;span class="w"&gt; &lt;/span&gt;/boot/firmware/autoboot.txt
&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Anyway, that&amp;#8217;s enough &amp;#8220;boot&amp;#8221; puns from me, for now. If you do &lt;em&gt;anything&lt;/em&gt; even
slightly weird with your boot configuration, I would &lt;em&gt;strongly&lt;/em&gt; encourage you
to try out the questing dailies on a spare &lt;span class="caps"&gt;SD&lt;/span&gt;&amp;nbsp;card:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;a class="reference external" href="https://cdimage.ubuntu.com/ubuntu/daily-preinstalled/current/"&gt;Questing desktop&amp;nbsp;dailies&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="https://cdimage.ubuntu.com/ubuntu-server/daily-preinstalled/current/"&gt;Questing server&amp;nbsp;dailies&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;To test the new implementation from a questing daily, add
&lt;a class="reference external" href="https://launchpad.net/~waveform/+archive/ubuntu/flash-kernel"&gt;ppa:waveform/flash-kernel&lt;/a&gt; and install the &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;flash-kernel-piboot&lt;/span&gt;&lt;/tt&gt; package:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span id="line-1"&gt;&lt;span class="gp"&gt;$ &lt;/span&gt;sudo&lt;span class="w"&gt; &lt;/span&gt;add-apt-repository&lt;span class="w"&gt; &lt;/span&gt;ppa:waveform/flash-kernel
&lt;/span&gt;&lt;span id="line-2"&gt;&lt;span class="gp"&gt;$ &lt;/span&gt;sudo&lt;span class="w"&gt; &lt;/span&gt;apt&lt;span class="w"&gt; &lt;/span&gt;install&lt;span class="w"&gt; &lt;/span&gt;flash-kernel-piboot
&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This will also upgrade &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;flash-kernel&lt;/span&gt;&lt;/tt&gt; and migrate your boot partition to the
new layout. In &lt;em&gt;theory&lt;/em&gt; the migration is entirely safe, i.e. it can fail at any
point and you &lt;em&gt;should&lt;/em&gt; be left with a bootable system (I&amp;#8217;ve tested this a
couple of times by yanking the power-cord in the middle of it!). However, if
you can find a way to break it (from a configuration we&amp;#8217;d actually support),
then please let me&amp;nbsp;know!&lt;/p&gt;
&lt;p&gt;If you find any issues, please &lt;a class="reference external" href="https://bugs.launchpad.net/ubuntu/+source/flash-kernel/+filebug"&gt;file a bug&lt;/a&gt; against the &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;flash-kernel&lt;/span&gt;&lt;/tt&gt;
package in Launchpad, and tag it &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;raspi-image&lt;/span&gt;&lt;/tt&gt; to bring it to my&amp;nbsp;attention.&lt;/p&gt;
&lt;p&gt;If you &lt;em&gt;do&lt;/em&gt; find a genuine need to fall back to the old boot configuration,
again &lt;em&gt;please&lt;/em&gt; let me know! I&amp;#8217;d be really curious to find out what these
circumstances are; I&amp;#8217;m sure they exist, but they&amp;#8217;ll be things I haven&amp;#8217;t thought
of (yet), and if there&amp;#8217;s a way I can tweak the new design to accommodate them,
I&amp;#8217;d prefer to do that rather than have people forcing themselves back into the
old (fundamentally unsafe)&amp;nbsp;configuration.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="boots-of-spanish-leather"&gt;
&lt;h2&gt;Boots of Spanish&amp;nbsp;Leather&lt;/h2&gt;
&lt;p&gt;The alternative to falling back to the old mechanism is to keep the A/B
facility, but manage the tryboot mode somewhat&amp;nbsp;manually…&lt;/p&gt;
&lt;p&gt;The &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;piboot-try&lt;/span&gt;&lt;/tt&gt; command is the new script that manages all the stuff
mentioned above (which will be provided by the new &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;flash-kernel-piboot&lt;/span&gt;&lt;/tt&gt;
package, hopefully in Ubuntu questing by next week. When called with the
&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;--test&lt;/span&gt;&lt;/tt&gt; flag this will exit with status code 0 (&amp;#8220;true&amp;#8221; in shell parlance) in
the event there are new, untested boot assets. Otherwise, it will exit with
status code 1 (&amp;#8220;false&amp;#8221; or &amp;#8220;error&amp;#8221; in&amp;nbsp;shells).&lt;/p&gt;
&lt;p&gt;When called with &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;--reboot&lt;/span&gt;&lt;/tt&gt;, if new untested boot assets are present, it will
immediately re-write their status to &amp;#8220;trying&amp;#8221; and reboot into the &amp;#8220;tryboot&amp;#8221;&amp;nbsp;mode.&lt;/p&gt;
&lt;p&gt;Hence, if you know flash-kernel has run, and new boot assets are present, and
you&amp;#8217;re happy to reboot immediately you can simply run &lt;tt class="docutils literal"&gt;sudo &lt;span class="pre"&gt;piboot-try&lt;/span&gt;
&lt;span class="pre"&gt;--reboot&lt;/span&gt;&lt;/tt&gt; to reboot and immediately try the new boot assets (no double boot
necessary). If you&amp;#8217;re thinking of scripting this and want to query the state of
the boot assets, &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;piboot-try&lt;/span&gt; &lt;span class="pre"&gt;--test&lt;/span&gt;&lt;/tt&gt; (no &lt;tt class="docutils literal"&gt;sudo&lt;/tt&gt; necessary) will tell you
whether &lt;tt class="docutils literal"&gt;sudo &lt;span class="pre"&gt;piboot-try&lt;/span&gt; &lt;span class="pre"&gt;--reboot&lt;/span&gt;&lt;/tt&gt; &lt;em&gt;would&lt;/em&gt; reboot (if the exit code is&amp;nbsp;0).&lt;/p&gt;
&lt;p&gt;If you want to learn more about the command, I&amp;#8217;ll be including a full man-page
for it, &lt;tt class="docutils literal"&gt;man &lt;span class="pre"&gt;piboot-try&lt;/span&gt;&lt;/tt&gt;.&lt;/p&gt;
&lt;hr class="docutils" /&gt;
&lt;table class="docutils footnote" frame="void" id="kernel-only" rules="none"&gt;
&lt;colgroup&gt;&lt;col class="label" /&gt;&lt;col /&gt;&lt;/colgroup&gt;
&lt;tbody valign="top"&gt;
&lt;tr&gt;&lt;td class="label"&gt;&lt;a class="fn-backref" href="#footnote-reference-1"&gt;[1]&lt;/a&gt;&lt;/td&gt;&lt;td&gt;On the Pi 5, none of the bootloader resides on the &lt;span class="caps"&gt;FAT&lt;/span&gt;
partition anymore. In certain configurations, you can even get away with no
configuration file, so just shoving a Linux kernel on the &lt;span class="caps"&gt;FAT&lt;/span&gt; partition is
enough!&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;table class="docutils footnote" frame="void" id="cut-down" rules="none"&gt;
&lt;colgroup&gt;&lt;col class="label" /&gt;&lt;col /&gt;&lt;/colgroup&gt;
&lt;tbody valign="top"&gt;
&lt;tr&gt;&lt;td class="label"&gt;&lt;a class="fn-backref" href="#footnote-reference-2"&gt;[2]&lt;/a&gt;&lt;/td&gt;&lt;td&gt;Intended to maximize the &lt;span class="caps"&gt;RAM&lt;/span&gt; available at runtime (the default
bootloader typically reserved &lt;span class="caps"&gt;64MB&lt;/span&gt; of &lt;span class="caps"&gt;RAM&lt;/span&gt; for facilities it provided at
runtime; the cut down variant only needed &lt;span class="caps"&gt;16MB&lt;/span&gt;).&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;table class="docutils footnote" frame="void" id="gpu" rules="none"&gt;
&lt;colgroup&gt;&lt;col class="label" /&gt;&lt;col /&gt;&lt;/colgroup&gt;
&lt;tbody valign="top"&gt;
&lt;tr&gt;&lt;td class="label"&gt;&lt;a class="fn-backref" href="#footnote-reference-3"&gt;[3]&lt;/a&gt;&lt;/td&gt;&lt;td&gt;One particularly odd aspect of the Pi&amp;#8217;s boot process is that it runs
entirely on the &lt;span class="caps"&gt;GPU&lt;/span&gt; (well … &lt;span class="caps"&gt;VPU&lt;/span&gt;?), rather than the &lt;span class="caps"&gt;ARM&lt;/span&gt; &lt;span class="caps"&gt;CPU&lt;/span&gt;. The legacy
camera firmware basically ran its own &lt;span class="caps"&gt;RTOS&lt;/span&gt; over on the &lt;span class="caps"&gt;GPU&lt;/span&gt;, hence
incorporating it into the bootloader made perfect sense.&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;table class="docutils footnote" frame="void" id="maybe-dt" rules="none"&gt;
&lt;colgroup&gt;&lt;col class="label" /&gt;&lt;col /&gt;&lt;/colgroup&gt;
&lt;tbody valign="top"&gt;
&lt;tr&gt;&lt;td class="label"&gt;&lt;a class="fn-backref" href="#footnote-reference-5"&gt;[4]&lt;/a&gt;&lt;/td&gt;&lt;td&gt;Actually, I&amp;#8217;m not entirely clear if stage 3 loads the &lt;em&gt;base&lt;/em&gt;
device tree. That &lt;em&gt;might&lt;/em&gt; be stage 2, but stage 3 handles some of the
customization of the device-tree, loading overlays, and so forth.&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;table class="docutils footnote" frame="void" id="afaik" rules="none"&gt;
&lt;colgroup&gt;&lt;col class="label" /&gt;&lt;col /&gt;&lt;/colgroup&gt;
&lt;tbody valign="top"&gt;
&lt;tr&gt;&lt;td class="label"&gt;&lt;a class="fn-backref" href="#footnote-reference-4"&gt;[5]&lt;/a&gt;&lt;/td&gt;&lt;td&gt;I&amp;#8217;m not entirely clear on what &lt;tt class="docutils literal"&gt;fixup.dat&lt;/tt&gt; really does either. I
know each fixup file corresponds to each &lt;tt class="docutils literal"&gt;start.elf&lt;/tt&gt; file and that it has
&lt;em&gt;something&lt;/em&gt; to do with the &lt;span class="caps"&gt;CPU&lt;/span&gt;/&lt;span class="caps"&gt;GPU&lt;/span&gt; memory split. The &lt;tt class="docutils literal"&gt;start.elf&lt;/tt&gt; binary
will operate without &lt;tt class="docutils literal"&gt;fixup.dat&lt;/tt&gt; being present, but the wrong amount of
&lt;span class="caps"&gt;RAM&lt;/span&gt; is reported by the mailbox interface in this case. I&amp;#8217;ve also heard fixup
has to do with &amp;#8220;relocation&amp;#8221;, and I do know that the &lt;span class="caps"&gt;CPU&lt;/span&gt;/&lt;span class="caps"&gt;GPU&lt;/span&gt; memory split has
the &lt;span class="caps"&gt;CPU&lt;/span&gt; (&lt;span class="caps"&gt;ARM&lt;/span&gt; portion) at the &amp;#8220;low&amp;#8221; end and the &lt;span class="caps"&gt;GPU&lt;/span&gt; firmware at the &amp;#8220;high&amp;#8221;
end so my vaguely educated guess is that &lt;tt class="docutils literal"&gt;start.elf&lt;/tt&gt; gets loaded at a
too-low, but definitely safe location, then &lt;tt class="docutils literal"&gt;fixup.dat&lt;/tt&gt; is used to
relocate it to the highest possible point it can safely sit in &lt;span class="caps"&gt;RAM&lt;/span&gt; to
maximize the amount available to the &lt;span class="caps"&gt;ARM&lt;/span&gt; cores. But that&amp;#8217;s just my guess.&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;table class="docutils footnote" frame="void" id="fat-variants" rules="none"&gt;
&lt;colgroup&gt;&lt;col class="label" /&gt;&lt;col /&gt;&lt;/colgroup&gt;
&lt;tbody valign="top"&gt;
&lt;tr&gt;&lt;td class="label"&gt;&lt;a class="fn-backref" href="#footnote-reference-6"&gt;[6]&lt;/a&gt;&lt;/td&gt;&lt;td&gt;The stages all understand &lt;span class="caps"&gt;FAT&lt;/span&gt;-12, &lt;span class="caps"&gt;FAT&lt;/span&gt;-16, &lt;span class="caps"&gt;FAT&lt;/span&gt;-32, and the
&lt;span class="caps"&gt;VFAT&lt;/span&gt; long filename extensions.&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;table class="docutils footnote" frame="void" id="probably" rules="none"&gt;
&lt;colgroup&gt;&lt;col class="label" /&gt;&lt;col /&gt;&lt;/colgroup&gt;
&lt;tbody valign="top"&gt;
&lt;tr&gt;&lt;td class="label"&gt;&lt;a class="fn-backref" href="#footnote-reference-7"&gt;[7]&lt;/a&gt;&lt;/td&gt;&lt;td&gt;Maybe… This is just off the top of my head; I haven&amp;#8217;t tested
it and give no warranty that this will (or won&amp;#8217;t!) unbrick your boot!&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;table class="docutils footnote" frame="void" id="little-known" rules="none"&gt;
&lt;colgroup&gt;&lt;col class="label" /&gt;&lt;col /&gt;&lt;/colgroup&gt;
&lt;tbody valign="top"&gt;
&lt;tr&gt;&lt;td class="label"&gt;&lt;a class="fn-backref" href="#footnote-reference-8"&gt;[8]&lt;/a&gt;&lt;/td&gt;&lt;td&gt;Maybe, given some interactions I&amp;#8217;ve had online?&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;table class="docutils footnote" frame="void" id="pm-rsts" rules="none"&gt;
&lt;colgroup&gt;&lt;col class="label" /&gt;&lt;col /&gt;&lt;/colgroup&gt;
&lt;tbody valign="top"&gt;
&lt;tr&gt;&lt;td class="label"&gt;&lt;a class="fn-backref" href="#footnote-reference-9"&gt;[9]&lt;/a&gt;&lt;/td&gt;&lt;td&gt;The state is stored in the PM_RSTS register on the &lt;abbr title="Power Management IC"&gt;&lt;span class="caps"&gt;PMIC&lt;/span&gt;&lt;/abbr&gt;. &lt;span class="caps"&gt;PMIC&lt;/span&gt; registers (generally) survive reset (obviously
not power off though), but this particular one is also reset-on-read so it
is guaranteed subsequent boots will fall back if the tryboot one fails for
any reason.&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;table class="docutils footnote" frame="void" id="no-comments" rules="none"&gt;
&lt;colgroup&gt;&lt;col class="label" /&gt;&lt;col /&gt;&lt;/colgroup&gt;
&lt;tbody valign="top"&gt;
&lt;tr&gt;&lt;td class="label"&gt;&lt;a class="fn-backref" href="#footnote-reference-10"&gt;[10]&lt;/a&gt;&lt;/td&gt;&lt;td&gt;The &lt;tt class="docutils literal"&gt;autoboot.txt&lt;/tt&gt; file has a size limit of 512 bytes
(presumably because stage 1 has to be incredibly basic, and can&amp;#8217;t read
&lt;span class="caps"&gt;FAT&lt;/span&gt; chains, so the file is limited to one sector). In other words don&amp;#8217;t
include extraneous comments or line breaks!&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;table class="docutils footnote" frame="void" id="atomic-fs" rules="none"&gt;
&lt;colgroup&gt;&lt;col class="label" /&gt;&lt;col /&gt;&lt;/colgroup&gt;
&lt;tbody valign="top"&gt;
&lt;tr&gt;&lt;td class="label"&gt;&lt;a class="fn-backref" href="#footnote-reference-11"&gt;[11]&lt;/a&gt;&lt;/td&gt;&lt;td&gt;Bear in mind that &lt;span class="caps"&gt;FAT&lt;/span&gt; is not a journalling file-system. Updates
to any boot configuration should generally be done atomically by writing the
new content to a temporary file on the target &lt;span class="caps"&gt;FAT&lt;/span&gt; partition, then renaming
the temporary file over the original. The rename operation is atomic so
anything reading the file-system should either see the original content or
the new content, but no partially written file.&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;table class="docutils footnote" frame="void" id="experiments" rules="none"&gt;
&lt;colgroup&gt;&lt;col class="label" /&gt;&lt;col /&gt;&lt;/colgroup&gt;
&lt;tbody valign="top"&gt;
&lt;tr&gt;&lt;td class="label"&gt;&lt;a class="fn-backref" href="#footnote-reference-12"&gt;[12]&lt;/a&gt;&lt;/td&gt;&lt;td&gt;Under the assumption that you shouldn&amp;#8217;t ever be fiddling with
your &amp;#8220;known good&amp;#8221; boot configuration. All experiments should be performed in
the &amp;#8220;alternate&amp;#8221; boot assets which are then tested with tryboot before being
made the new &amp;#8220;known good&amp;#8221; set.&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;table class="docutils footnote" frame="void" id="atomic-exchg" rules="none"&gt;
&lt;colgroup&gt;&lt;col class="label" /&gt;&lt;col /&gt;&lt;/colgroup&gt;
&lt;tbody valign="top"&gt;
&lt;tr&gt;&lt;td class="label"&gt;&lt;a class="fn-backref" href="#footnote-reference-13"&gt;[13]&lt;/a&gt;&lt;/td&gt;&lt;td&gt;With &lt;span class="caps"&gt;GNU&lt;/span&gt; coreutils 9.5 and above, simply: &lt;tt class="docutils literal"&gt;mv &lt;span class="pre"&gt;--exchange&lt;/span&gt;
config.txt tryboot.txt&lt;/tt&gt;!&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;table class="docutils footnote" frame="void" id="transitional" rules="none"&gt;
&lt;colgroup&gt;&lt;col class="label" /&gt;&lt;col /&gt;&lt;/colgroup&gt;
&lt;tbody valign="top"&gt;
&lt;tr&gt;&lt;td class="label"&gt;&lt;a class="fn-backref" href="#footnote-reference-14"&gt;[14]&lt;/a&gt;&lt;/td&gt;&lt;td&gt;This is a slight lie. There are some brief transitional
states where &lt;em&gt;current&lt;/em&gt; exists, but contains former assets. These should
always be rapidly corrected, as we&amp;#8217;ll see.&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;table class="docutils footnote" frame="void" id="it-is" rules="none"&gt;
&lt;colgroup&gt;&lt;col class="label" /&gt;&lt;col /&gt;&lt;/colgroup&gt;
&lt;tbody valign="top"&gt;
&lt;tr&gt;&lt;td class="label"&gt;&lt;a class="fn-backref" href="#footnote-reference-15"&gt;[15]&lt;/a&gt;&lt;/td&gt;&lt;td&gt;Though it kinda is… I do control the boot process on your Pi after
all! Mwuhahahaha!&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
</content><category term="misc"></category><category term="ubuntu"></category><category term="questing"></category><category term="pi"></category><category term="boot"></category></entry></feed>