Howto implement bootchooser <-> rauc interaction
Konstantin Kletschke
konstantin.kletschke at inside-m2m.de
Wed Dec 22 06:05:07 PST 2021
I switched from doing the state in the onboard EEPROM (as said, it
is write protected in production use) to save the state in a dead space
in the onboard eMMC chip between MBR and first partition:
/ {
aliases {
state = &state_eeprom;
};
state_eeprom: state_eeprom {
#address-cells = <1>;
#size-cells = <1>;
compatible = "barebox,state";
magic = <0xcafebabe>;
backend-type = "raw";
backend = <&backend_state_mmc2>;
backend-storage-type = "direct";
backend-stridesize = <54>;
last_chosen {
reg = <0x0 0x4>;
type = "uint32";
};
system0 {
#address-cells = <1>;
#size-cells = <1>;
remaining_attempts {
reg = <0x4 0x4>;
type = "uint32";
default = <3>;
};
priority {
reg = <0x8 0x4>;
type = "uint32";
default = <21>;
};
ok {
reg = <0xc 0x4>;
type = "uint32";
default = <0>;
};
};
system1 {
#address-cells = <1>;
#size-cells = <1>;
remaining_attempts {
reg = <0x10 0x4>;
type = "uint32";
default = <3>;
};
priority {
reg = <0x14 0x4>;
type = "uint32";
default = <20>;
};
ok {
reg = <0x18 0x4>;
type = "uint32";
default = <0>;
};
};
};
};
&mmc2 {
backend_state_mmc2: part at 1000 {
label = "state";
reg = <0x1000 0x1000>;
};
};
This looks good so far:
barebox boot-up excerpt:
mmc1: detected MMC card version 5.1
mmc1: registered mmc1
state: New state registered 'state'
state: Using bucket 0 at 0x00000000
devinfo state:
Parameters:
dirty: 0 (type: bool)
init_from_defaults: 0 (type: bool)
last_chosen: 2 (type: uint32)
save_on_shutdown: 1 (type: bool)
system0.ok: 0 (type: uint32)
system0.priority: 21 (type: uint32)
system0.remaining_attempts: 0 (type: uint32)
system1.ok: 0 (type: uint32)
system1.priority: 20 (type: uint32)
system1.remaining_attempts: 1 (type: uint32)
bootchooser -i:
Good targets (first will be booted next):
system1
id: 2
priority: 20
default_priority: 1
remaining attempts: 1
default attempts: 3
boot: 'system1'
Disabled targets:
system0
id: 1
priority: 21
default_priority: 1
remaining attempts: 0
default attempts: 3
boot: 'system0'
disabled due to remaining attempts = 0
last booted target: system1
Compiled in (relevant) variables:
* boot.default: bootchooser insidem2m_1 insidem2m_2
boot.watchdog_timeout: 0
bootchooser.default_attempts: 3
bootchooser.default_priority: 1
bootchooser.disable_on_zero_attempts: 0
bootchooser.reset_attempts: (list: "power-on", "all-zero")
bootchooser.reset_priorities:
bootchooser.retry: 0
* bootchooser.state_prefix: state
* bootchooser.targets: system0 system1
devinfo excerpt:
`-- 481d82fc.target-module at d8000.of
`-- 481d8000.mmc at 0.of
`-- mmc1
`-- 0x00000000-0xe3ffffff ( 3.6 GiB): /dev/mmc1
`-- 0x00100000-0x010fffff ( 16 MiB): /dev/mmc1.0
`-- 0x01100000-0x4ddfffff ( 1.2 GiB): /dev/mmc1.1
`-- 0x4de00000-0x9aafffff ( 1.2 GiB): /dev/mmc1.2
`-- 0x9ab00000-0xe3ffffff ( 1.1 GiB): /dev/mmc1.3
`-- 0x00001000-0x00001fff ( 4 KiB): /dev/mmc1.state
`-- fat0
boot:
Booting entry 'bootchooser'
Booting entry 'system1'
ext4 ext40: EXT2 rev 1, inode_size 256, descriptor size 64
mounted /dev/mmc1.2 on /mnt/mmc1.2
[...]
The userspace is no amused, however:
rauc status output:
(rauc:583): rauc-WARNING **: 18:51:57.389: Failed getting primary slot: Failed getting primary slot: No content to read
=== System Info ===
Compatible: insidem2m-s
Variant:
Booted from: rootfs.1 (system1)
=== Bootloader ===
Activated: (null) ((null))
=== Slot States ===
o [rootfs.1] (/dev/mmcblk0p3, ext4, booted)
bootname: system1
mounted: /
boot status: bad
o [rootfs.0] (/dev/mmcblk0p2, ext4, inactive)
bootname: system0
boot status: bad
/etc/rauc/system.conf:
[system]
compatible=insidem2m-s
bootloader=barebox
[keyring]
path=ca.cert.pem
[slot.rootfs.0]
device=/dev/mmcblk0p2
type=ext4
bootname=system0
[slot.rootfs.1]
device=/dev/mmcblk0p3
type=ext4
bootname=system1
barebox-state:
last_chosen=2
system0.remaining_attempts=0
system0.priority=21
system0.ok=0
system1.remaining_attempts=2
system1.priority=20
system1.ok=0
So rauc is not happy, is somethong wrong with the system.conf?
################ PLAN B ##################
I had a previous state device tree setup, which made userspace happy,
but not barebox. I had a parent bootstate section containing system0 and
system1:
/ {
aliases {
state = &state_eeprom;
};
state_eeprom: state_eeprom {
#address-cells = <1>;
#size-cells = <1>;
compatible = "barebox,state";
magic = <0xcafebabe>;
backend-type = "raw";
backend = <&backend_state_mmc2>;
backend-storage-type = "direct";
backend-stridesize = <54>;
bootstate {
#address-cells = <1>;
#size-cells = <1>;
last_chosen {
reg = <0x0 0x4>;
type = "uint32";
};
system0 {
#address-cells = <1>;
#size-cells = <1>;
remaining_attempts {
reg = <0x4 0x4>;
type = "uint32";
default = <3>;
};
priority {
reg = <0x8 0x4>;
type = "uint32";
default = <21>;
};
ok {
reg = <0xc 0x4>;
type = "uint32";
default = <0>;
};
};
system1 {
#address-cells = <1>;
#size-cells = <1>;
remaining_attempts {
reg = <0x10 0x4>;
type = "uint32";
default = <3>;
};
priority {
reg = <0x14 0x4>;
type = "uint32";
default = <20>;
};
ok {
reg = <0x18 0x4>;
type = "uint32";
default = <0>;
};
};
};
};
};
&mmc2 {
backend_state_mmc2: part at 1000 {
label = "state";
reg = <0x1000 0x1000>;
};
};
With this device tree barebox bootschooser is unhappy:
barebox at TI AM335x BeagleBone black:/ devinfo state
Parameters:
bootstate.last_chosen: 2 (type: uint32)
bootstate.system0.ok: 0 (type: uint32)
bootstate.system0.priority: 21 (type: uint32)
bootstate.system0.remaining_attempts: 0 (type: uint32)
bootstate.system1.ok: 0 (type: uint32)
bootstate.system1.priority: 20 (type: uint32)
bootstate.system1.remaining_attempts: 2 (type: uint32)
dirty: 0 (type: bool)
init_from_defaults: 0 (type: bool)
save_on_shutdown: 1 (type: bool)
barebox at TI AM335x BeagleBone black:/ boot
WARNING: bootchooser: Cannot read priority for target system0, using default 1
WARNING: bootchooser: Cannot read remaining attempts for target system0, using default 3
WARNING: bootchooser: Cannot read priority for target system1, using default 1
WARNING: bootchooser: Cannot read remaining attempts for target system1, using default 3
Cannot set parameter state.system0.remaining_attempts: No such device
ERROR: bootchooser: Failed to save bootchooser state: No such device
Booting entry 'bootchooser'
WARNING: bootchooser: Cannot read priority for target system0, using default 1
WARNING: bootchooser: Cannot read remaining attempts for target system0, using default 3
WARNING: bootchooser: Cannot read priority for target system1, using default 1
WARNING: bootchooser: Cannot read remaining attempts for target system1, using default 3
Cannot set parameter state.last_chosen: No such device
Cannot set parameter state.system0.remaining_attempts: No such device
Booting entry 'system0'
ext4 ext40: EXT2 rev 1, inode_size 256, descriptor size 64
mounted /dev/mmc1.1 on /mnt/mmc1.1
[...]
But userspace is fine:
rauc-Message: 18:58:50.111: rauc status: marked slot rootfs.0 as good
rauc status:
=== System Info ===
Compatible: insidem2m
Variant:
Booted from: rootfs.0 (system0)
=== Bootloader ===
Activated: rootfs.0 (system0)
=== Slot States ===
[bootloader.0] (/dev/mmcblk0p1, vfat, inactive)
o [rootfs.1] (/dev/mmcblk0p3, ext4, inactive)
bootname: system1
boot status: good
x [rootfs.0] (/dev/mmcblk0p2, ext4, booted)
bootname: system0
mounted: /
boot status: good
barebox-state -d:
bootstate.last_chosen=2
bootstate.system0.remaining_attempts=3
bootstate.system0.priority=21
bootstate.system0.ok=0
bootstate.system1.remaining_attempts=2
bootstate.system1.priority=20
bootstate.system1.ok=0
I assume this has to do with bootchooser.state_prefix. If I change from
state to bootstate (yes, brute force) I get:
global excerpt:
* bootchooser.state_prefix: bootstate
devinfo state looks the same as previous.
boot:
barebox at TI AM335x BeagleBone black:/ boot
ERROR: bootchooser: Cannot get state 'bootstate'
Nothing bootable found on 'bootchooser'
Booting entry 'insidem2m_1'
ext4 ext40: EXT2 rev 1, inode_size 256, descriptor size 64
mounted /dev/mmc1.1 on /mnt/mmc1.1
[...]
When I set:
* bootchooser.state_prefix: state.bootstate
I get best of both worlds!
"devinfo state" still the same as previous two cases (logical, since DT
setup is the same, only bootchooser.state_prefix changed), "bootchooser
-i" looks sane, booting happens w/o any error, and userspace
(barebox-state -d, rauc status, barebox-state -g bootstate.system0.ok)
too!
Wall of text, two questions:
Is this resulting setup (DT with bootstate parent, state_prefix:
state.bootstate) sane?
Can the variant without the boostate variant work too? If it was the
other way around, userspace working w/o the bootstate variant but bnot
_with_ I would say additional configuration required or something, but
this way... I would like to understand this fully.
Kind Regards
Konstantin
--
INSIDE M2M GmbH
Konstantin Kletschke
Berenbosteler Straße 76 B
30823 Garbsen
Telefon: +49 (0) 5137 90950136
Mobil: +49 (0) 151 15256238
Fax: +49 (0) 5137 9095010
konstantin.kletschke at inside-m2m.de
http://www.inside-m2m.de
Geschäftsführung: Michael Emmert, Ingo Haase, Dr. Fred Könemann, Derek Uhlig
HRB: 111204, AG Hannover
More information about the barebox
mailing list