Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions os/image/machine-id-setup.service
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
[Unit]
Description=Initialize shared machine-id on first boot
Description=Initialize shared machine-id when /data/ becomes available
DefaultDependencies=no
Before=sysinit.target
After=data.mount
Requires=data.mount
ConditionPathExists=/data
ConditionPathExists=!/data/machine-id

[Service]
Expand Down
26 changes: 26 additions & 0 deletions os/image/make-image.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
#!/usr/bin/env node

import { $ } from "execa"

const device = `/dev/nvme0n1`
const partn = 6
const path = device + "p" + partn

if (import.meta.main) {
if (process.getuid() !== 0) {
throw new Error("Please run as root.")
}

// await $`mount ${path} /mnt`
// await $`fstrim /mnt`
// await $`umount ${path}`

// Resize is not effective, it creates a smaller partition
// await $`e2fsck -f ${path}`
// await $`resize2fs ${path} 8M`
// await $`sgdisk --delete=${partn} --new=${partn}:0:+8M --typecode=${partn}:8300 -A ${partn}:set:0 -A ${partn}:set:1 -A ${partn}:set:62 -A ${partn}:set:63 --change-name=${partn}:DATA --partition-guid=${partn}:ce528120-d0dd-52be-aea3-8225fabd8a00 ${device}`

// systemd-repart will recreate the partition on boot
await $`sgdisk --delete=${partn}`
// await $`partprobe ${device}`
}
38 changes: 29 additions & 9 deletions os/image/planktoscope.js
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ export async function updateMountpoints(device, rpios_partitions) {
await setup_fstab(partitions)
await setup_autoboot(partitions)
await setup_machineid(partitions)
await setup_repart(partitions)
}

async function createPartitionTable(device) {
Expand All @@ -78,23 +79,23 @@ async function createPartitionTable(device) {

// BOOTLOADER
partn++
await $`sgdisk --new=${partn}:0:+8M --typecode=${partn}:0700 -A ${partn}:set:0 -A ${partn}:set:1 -A ${partn}:set:62 -A ${partn}:set:63 --change-name=${partn}:BOOTLOADER --partition-guid=${partn}:${stablePartUuid("BOOTLOADER")} ${device}`
await $`sgdisk --new=${partn}:0:+8M --typecode=${partn}:0700 --change-name=${partn}:BOOTLOADER --partition-guid=${partn}:${stablePartUuid("BOOTLOADER")} ${device}`

// FIRMWARE X
for (const bootname of bootnames) {
partn++
await $`sgdisk --new=${partn}:0:+256M --typecode=${partn}:0700 -A ${partn}:set:0 -A ${partn}:set:1 -A ${partn}:set:62 -A ${partn}:set:63 --change-name=${partn}:${"FIRMWARE_" + bootname} --partition-guid=${partn}:${stablePartUuid("FIRMWARE_" + bootname)} ${device}`
await $`sgdisk --new=${partn}:0:+256M --typecode=${partn}:0700 --change-name=${partn}:${"FIRMWARE_" + bootname} --partition-guid=${partn}:${stablePartUuid("FIRMWARE_" + bootname)} ${device}`
}

// ROOT X
for (const bootname of bootnames) {
partn++
await $`sgdisk --new=${partn}:0:+10G --typecode=${partn}:8300 -A ${partn}:set:0 -A ${partn}:set:1 -A ${partn}:set:62 -A ${partn}:set:63 --change-name=${partn}:${"ROOT_" + bootname} --partition-guid=${partn}:${stablePartUuid("ROOT_" + bootname)} ${device}`
await $`sgdisk --new=${partn}:0:+10G --typecode=${partn}:8300 --change-name=${partn}:${"ROOT_" + bootname} --partition-guid=${partn}:${stablePartUuid("ROOT_" + bootname)} ${device}`
}

// "DATA"
partn++
await $`sgdisk --new=${partn}:0:0 --typecode=${partn}:8300 -A ${partn}:set:0 -A ${partn}:set:1 -A ${partn}:set:62 -A ${partn}:set:63 --change-name=${partn}:DATA --partition-guid=${partn}:${stablePartUuid("DATA")} ${device}`
await $`sgdisk --new=${partn}:0:0 --typecode=${partn}:8300 --change-name=${partn}:DATA --partition-guid=${partn}:${stablePartUuid("DATA")} ${device}`

await $`sgdisk --verify ${device}`

Expand Down Expand Up @@ -163,10 +164,6 @@ async function create_datafs(device, rootfs) {
await $`wipefs -a ${path}`
await $`mkfs.ext4 -q ${path}`

// will be grown by x-systemd.growfs, see fstab
await $`resize2fs -M ${path}`
await $`e2fsck -f -p ${path}`

await $`mount ${path} ${mountpoint}`

// /data/home
Expand Down Expand Up @@ -276,6 +273,7 @@ async function setup_config(rpios_partitions, partitions) {
"utf8",
)

// See https://www.raspberrypi.com/documentation/computers/config_txt.html#boot_partition-2
let config = "[all]\n\n"
for (const bootname of bootnames) {
const part = partitions[`FIRMWARE_${bootname}`]
Expand Down Expand Up @@ -355,7 +353,7 @@ async function setup_fstab(partitions) {
const datafs_partuuid = partitions[`DATA`].partuuid
const fstab = dedent`
PARTUUID=${bootloader_partuuid} /bootloader vfat defaults,noatime,ro 0 2
PARTUUID=${datafs_partuuid} /data ext4 defaults,noatime,x-systemd.growfs 0 2
PARTUUID=${datafs_partuuid} /data ext4 defaults,noatime 0 2
/data/home /home none bind 0 0
`
// TODO: when we go readonly
Expand All @@ -371,6 +369,28 @@ async function setup_fstab(partitions) {
}
}

// repart will create the DATA GPT partition but won't grow the EXT4 filesystem
// we use x-systemd.growfs in fstab for that
// > Note that these definitions may only be used to create and initialize new partitions or to grow existing ones. In the latter case, it will not grow the contained files systems however; separate mechanisms, such as systemd-growfs(8) may be used to grow the file systems inside of these partitions.
// https://www.freedesktop.org/software/systemd/man/latest/repart.d.html#Description
async function setup_repart(partitions) {
const datafs_partuuid = partitions[`DATA`].partuuid
const conf = dedent`
[Partition]
UUID=${datafs_partuuid}
GrowFileSystem=yes
Type=linux-generic
`
for (const bootname of bootnames) {
const path = join(
partitions[`ROOT_${bootname}`].mountpoint,
"usr/lib/repart.d",
)
await mkdir(path, { recursive: true })
await writeFile(join(path, "50-data.conf"), conf)
}
}

export async function getPartitions(device) {
const devices = await getBlockDevices(device)
const partitions = Object.create(null)
Expand Down
5 changes: 5 additions & 0 deletions os/image/repart.d/10-bootloader.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
[Partition]
Label=BOOTLOADER
Type=ebd0a0a2-b9e5-4433-87c0-68b6b72699c7
SizeMinBytes=8M
SizeMaxBytes=8M
5 changes: 5 additions & 0 deletions os/image/repart.d/20-firmware_a.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
[Partition]
Label=FIRMWARE_A
Type=ebd0a0a2-b9e5-4433-87c0-68b6b72699c7
SizeMinBytes=256M
SizeMaxBytes=256M
5 changes: 5 additions & 0 deletions os/image/repart.d/30-firmware_b.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
[Partition]
Label=FIRMWARE_B
Type=ebd0a0a2-b9e5-4433-87c0-68b6b72699c7
SizeMinBytes=256M
SizeMaxBytes=256M
5 changes: 5 additions & 0 deletions os/image/repart.d/40-root_a.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
[Partition]
Label=ROOT_A
Type=linux-generic
SizeMinBytes=10G
SizeMaxBytes=10G
5 changes: 5 additions & 0 deletions os/image/repart.d/50-root_b.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
[Partition]
Label=ROOT_B
Type=linux-generic
SizeMinBytes=10G
SizeMaxBytes=10G
5 changes: 5 additions & 0 deletions os/image/repart.d/60-data.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
[Partition]
Label=DATA
UUID=ce528120-d0dd-52be-aea3-8225fabd8a00
Type=linux-generic
GrowFileSystem=yes
8 changes: 8 additions & 0 deletions os/rauc/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,14 @@ sudo ./rauc.js create-bundle /dev/device B [version]

This will create a bundle from partitions `FIRMWARE_B` and `ROOT_B` on device `/dev/device`.

A bundle can be installed to either slot. So please consider:

* Files on `FIRMWARE_A` and `FIRMWARE_B` should be considered identical.
* Files on `ROOT_A` and `ROOT_B` should be considered identical.
* A bundle must work for any slot

We use the Raspberry Pi firmware and bootloader to dynamically switch between A and B.

## Install a bundle

```sh
Expand Down