cubelinux: the kernel records its own boot

The second half of "the OS stores itself". The store was already the kernel's; what was missing
was the kernel *saying* something of its own rather than a client doing it. At its first write of
a boot the driver now appends one record describing the boot it is having — its own version
banner, the wall-clock time, and the store device it resolved — to a reserved space, through the
same append path every other mutation uses.

Three things had to be decided, and each had a wrong answer that looked right:

WHERE IT HOOKS. "At store init" does not exist and must not be invented: there is no init-time
open, deliberately, so there is no ordering to get wrong against the block driver that provides
the device. An __initcall appending a record would reintroduce exactly that ordering problem.
The moment is the FIRST WRITE, which needs no ordering at all and is the semantically right one —
the kernel records itself when it becomes the writer. A boot in which the kernel only reads
writes no record, which is honest rather than a gap.

WHICH SPACE. 0xFD was the first choice, following the convention that a reserved space is one
repeated byte. 0xFD is the OS KEYSTORE — the space the kill switch exists to destroy — and
writing boot records into it would have been a serious bug. Only the userspace name table catches
this (format_space in crates/cube-command) because the kernel keeps no table of space names, so
the table is now written down where the constant is: 0x00 root, 0xFF edges, 0xFE portal,
0xFD keystore, 0xFC boot. The record lives at (0,0,0) in 0xFC: one record, the current boot.

WHAT IT SAYS. boot=<epoch seconds> device=<resolved path> kernel=<the version banner>, banner
last and unquoted so everything after the final = is the kernel's own words rather than a field
this code parsed. Raw epoch seconds rather than a date: rendering a calendar date in the kernel
is date arithmetic, and a caller with a clock can do it without a kernel bug being the reason a
timestamp is wrong. The banner comes from linux_banner and the time from ktime_get_real_ts64.

WHY IT IS OFF BY DEFAULT. Not caution, but an invariant. The gates' method is that the store the
kernel produces is comparable, byte for byte, with the store userspace produces from the same
mutations; a record the kernel injects that the caller never asked for would turn those
comparisons into non-comparisons. So it is cube_boot_record=1 on the kernel command line, parsed
in C beside cube_store= for the reason that parameter is in C (this kernel's Rust cannot express
a string parameter), and kernel/verify-boot-record.sh is the gate that turns it on.

A failure to record is logged and never propagated: the record is worth having and is not a
precondition for the caller's write. It is attempted once per boot rather than retried per write,
because a store that will not take it will not take it later, and one warning is information
where a stream of them is noise.
This commit is contained in:
surface-camera-build
2026-09-21 18:05:10 -04:00
parent 78540b5687
commit 087c6b0e60
2 changed files with 221 additions and 0 deletions
+29
View File
@@ -20,6 +20,7 @@
#include <linux/slab.h>
#include <linux/string.h>
#include <linux/syscalls.h>
#include <linux/types.h>
#include <linux/uaccess.h>
#include <linux/cube.h>
@@ -84,6 +85,34 @@ const char *cubelinux_store_device(void)
return store_device_path;
}
/*
* Whether the kernel should record its own boots in the store.
*
* Off unless asked for, and the reason is not caution: the gate method of this tree is that the
* store the kernel produces is comparable, byte for byte, with the store userspace produces from the
* same mutations. A record the kernel injects that the caller never asked for would turn two of
* those comparisons into non-comparisons. So it is a command-line switch, beside `cube_store=`,
* and the gate that proves it is the one that turns it on.
*
* cube_store=/var/lib/cubelinux/store.img cube_boot_record=1
*
* The hook itself is not here: it lives in the Rust driver and fires at the first write of a boot,
* which is named and argued where it is implemented (`BOOT_SPACE` in cubelinux_store.rs).
*/
static bool boot_record_enabled;
static int __init cube_boot_record_setup(char *str)
{
boot_record_enabled = (str[0] == '1');
return 1;
}
__setup("cube_boot_record=", cube_boot_record_setup);
bool cubelinux_boot_record_enabled(void)
{
return boot_record_enabled;
}
/* No value may be larger than this in one call. A coordinate store is not a bulk-file path;
* a caller with more than this to store has more than one record to store. */
#define CUBE_MAX_VALUE (16u * 1024u * 1024u)