FDS/OS 1.0
This commit is contained in:
@@ -0,0 +1,117 @@
|
||||
# Software cartridge format 1
|
||||
|
||||
[Build and use a cartridge](workstation.md) · [Original cartridge classes](cartridges.md)
|
||||
|
||||
A software cartridge is a complete GPT disk image with **1 + m** partitions,
|
||||
where `m` is 1–32. Partition 1 describes every software package in all payload
|
||||
partitions. All partitions use read-only EROFS. This format is the current
|
||||
PROGRAM creation format; existing single-partition PROGRAM media remain readable.
|
||||
SYSTEM, DATA and ENVIRONMENT layouts retain their existing meanings.
|
||||
|
||||
## Disk and filesystem layout
|
||||
|
||||
```text
|
||||
GPT protective MBR + primary GPT
|
||||
1 FDS_METADATA
|
||||
FDS/CARTRIDGE.TOML
|
||||
FDS/SOFTWARE.TOML
|
||||
2 FDS_PAYLOAD02
|
||||
bundles/demo.hello.tar.xz
|
||||
bundles/demo.editor.tar.xz
|
||||
3 FDS_PAYLOAD03
|
||||
bundles/demo.report.tar.xz
|
||||
...
|
||||
backup GPT
|
||||
```
|
||||
|
||||
Partition entries are consecutive, use Linux filesystem type GUIDs, unique
|
||||
nonzero partition UUIDs, no GPT attributes, and nonoverlapping MiB-aligned
|
||||
extents. Partition 1 starts at LBA 2048. Both GPT copies, their headers and CRCs
|
||||
must agree. A full-drive write to a larger USB device relocates the backup table
|
||||
and header. The existing on-target image parser and the workstation writer
|
||||
share these checks.
|
||||
|
||||
`FDS/CARTRIDGE.TOML` uses the existing format-1 identity with `class = "program"`
|
||||
and `media.writable = false`. It contains no startup command. A sample catalogue:
|
||||
|
||||
```toml
|
||||
format = 1
|
||||
|
||||
[[software]]
|
||||
id = "demo.hello"
|
||||
name = "AArch64 hello"
|
||||
version = "1.0"
|
||||
architecture = "aarch64"
|
||||
partition = 2
|
||||
archive_bytes = 2308
|
||||
unpacked_bytes = 70504
|
||||
entries = 2
|
||||
sha256 = "REPLACE_WITH_THE_64_CHARACTER_LOWERCASE_SHA256"
|
||||
[software.commands]
|
||||
hello = "bin/hello"
|
||||
```
|
||||
|
||||
Those lengths and the digest are illustrative. The builder generates actual
|
||||
values. IDs and command names use the existing restricted FDS identifier syntax.
|
||||
IDs are unique per cartridge. Every declared payload partition must contain
|
||||
exactly the catalogue's `bundles/<id>.tar.xz` archive names, and every payload
|
||||
partition must be represented. Multiple software entries may share a partition.
|
||||
The catalogue contains 1–128 software entries and at most 64 KiB of TOML.
|
||||
|
||||
## Archive contract
|
||||
|
||||
Bundles are deterministic USTAR archives compressed with single-threaded xz.
|
||||
Entries are sorted, timestamps/UID/GID are zero, and permissions normalize to
|
||||
0755 for directories/executables or 0644 for ordinary data. Host source symlinks
|
||||
to regular files inside the root are flattened into regular files. Directory or
|
||||
escaping symlinks are rejected; the archive itself never contains links.
|
||||
|
||||
The reader rejects:
|
||||
|
||||
- Absolute, parent-traversing, repeated-separator, non-UTF-8 or control-character paths.
|
||||
- Duplicate entries, file-as-parent conflicts, links, devices, sockets, FIFOs,
|
||||
privileged permissions, and GNU/PAX extension entries.
|
||||
- Incorrect SHA-256, compressed length, unpacked length, entry count, or command
|
||||
paths that do not name executable regular files.
|
||||
- ELF files that are not little-endian 64-bit AArch64, or any ELF in a bundle
|
||||
declared `architecture = "any"`.
|
||||
- Invalid xz data, nonzero material after the tar end marker, and resource-limit
|
||||
violations. Each archive is at most 512 MiB compressed, 1 GiB unpacked and
|
||||
65,536 entries. Xz decompression has a 256 MiB memory limit.
|
||||
|
||||
A source path must fit USTAR's path fields. Packaging reports paths that cannot
|
||||
be represented rather than emitting an unsupported extension header.
|
||||
|
||||
## Guest lifecycle
|
||||
|
||||
On insertion the daemon validates the complete GPT against kernel partition
|
||||
geometry and the current USB disk identity. It reads metadata without following
|
||||
symlinks, mounts every payload read-only/noexec/nosuid/nodev, and checks the
|
||||
archive inventory and lengths. `fds bay BAY` reports the full catalogue;
|
||||
`fds bays` stays compact. No archive command runs automatically on insertion.
|
||||
|
||||
`fds run BAY -- SOFTWARE-ID:COMMAND [ARGUMENT...]` verifies and extracts that
|
||||
package on first use. It creates a private temporary filesystem, applies the
|
||||
archive contract, then makes the finished tree read-only and accessible for
|
||||
execution. The runtime cache has a stricter **256 MiB per software tree** limit,
|
||||
including reserved inode overhead; a host-valid larger bundle may therefore
|
||||
need splitting before running. Caches live under `/run/fds/software/<bay>/` and
|
||||
vanish after eject, unplug, restart cleanup, or shutdown.
|
||||
|
||||
Managed consumers run as UID/GID 1000 with no new privileges in the bay's cgroup.
|
||||
`FDS_APP`, `PATH`, `LD_LIBRARY_PATH` and `XDG_DATA_DIRS` point to that software
|
||||
root. DISPLAY/XAUTHORITY retain the established optional desktop integration.
|
||||
The xz utility is already an explicit dependency of the mandatory `fds-base`
|
||||
package; runtime extraction adds no target package.
|
||||
|
||||
Build recipes, compilers, installation hooks and privileged archive scripts are
|
||||
never part of this runtime path.
|
||||
|
||||
Safe eject stops consumers, rejects unexpected mount aliases, unmounts caches,
|
||||
payloads and metadata, then reports SAFE. Confirmed surprise removal permits
|
||||
lazy detachment after stopping consumers. Service restart removes stale mounts
|
||||
before rescanning. SYSTEM stays immutable throughout.
|
||||
|
||||
SHA-256 detects corruption and binds an archive to its catalogue; it does not
|
||||
establish a publisher's identity. Only run software you trust. Release signature
|
||||
verification remains the separate [release workflow](releases.md).
|
||||
Reference in New Issue
Block a user