Repository navigation
Releases: vkuttyp/CosmoOS
Release list
CosmoOS 1.0.11
CosmoOS 1.0.11
Mirrors that survive a disk
The installer can put the root on two disks.
cosmo$ cosmo-install vdc --mirror vdd
...
cosmo-install: the root is mirrored on vdc2 and vdd2 (vdd's root partition, partuuid ...)
Both disks get the same layout and their own EFI System Partition, so
either can boot. The root is one pool kept as two copies.
When a disk fails or is pulled, the system keeps running.
-
The kernel says so once:
pool: cosmo-root: member 0 copy 1 (vda2) MISSING (-19): the member is degraded -
/proc/mountsshowsrw,degraded. -
cosmo-pool statussaysDEGRADEDand how much the missing copy
missed. -
A boot with a copy missing still boots, and init says so.
-
I/O that no copy can satisfy fails with
EIO; it is not a panic.
cosmo-pool replaces a disk, and a spare takes over by itself.
cosmo-pool replace 0:1 vdbputs a new disk in a missing copy's
place.- The new copy is resilvered while the system runs. Every block the
pool uses is copied to it at mostfs.resilver_rateblocks a second
(8192, 32 MiB/s, unless set). Every write goes to it meanwhile, and a
reboot resumes where the resilver stopped. - A disk that was pulled and comes back while the pool stays mounted is
caught up from the pool's record of what it missed, rather than
rebuilt. One that was missing when the pool was mounted is rebuilt
whole. - The other subcommands:
status,offline,online,attach(make a
single disk a mirror),detach,add-spareandremove-spare. - A spare takes the place of a copy that fails or whose disk goes, with
no command. - A copy that fails more than
fs.fault_errorstimes (16) is taken out
asFAULTED.
Disks can be pulled and added while the system runs. PCIe native
hotplug works on both architectures: removal through the slot's
attention button, and insertion with the disk's partitions read. This
covers virtio-blk and NVMe behind PCIe root ports.
See the guide's new page, Mirrors.
Fixes
- Every copy of a mounted mirror counts as in use.
/dev/blkctl
andmkfsrefuse a device that another copy of a mounted pool
stands on, not just the device the pool was mounted from. - Devices behind a PCIe root port get their DMA mapping. This
applies to VT-d's bridge scopes and to SMMUv3 stream ids above 255.
The pool's format
A pool is raised to format 13 the first time it has a copy to record,
which is when a mirror is degraded. Releases up to v1.0.10 cannot
mount a pool at format 13. A pool that is never degraded keeps its
format.
Upgrading from v1.0.10
cosmo-upgrade --fetch v1.0.11, reboot, then pkg update && pkg upgrade. The upgrade takes a boot environment, so cosmo-upgrade --rollback returns the root and the boot set as they were. A root pool
that has been degraded under 1.0.11 is at format 13, and the rolled-back
1.0.10 kernel cannot mount it.
cosmo-upgrade writes the new release to the ESP of the disk the
system booted from only. On a mirrored root, the other disk's ESP keeps
the release it was installed with.
Tested:
- On every change, on both architectures, beside the release tests:
make test-mirror: install onto two disks; pull one under a writer;
replace and resilver it; scrub; reboot from the new pair; let a
spare take over; boot with a copy missing, and resilver it on its
return.make test-pci-hotplug.
- On a Parallels virtual machine, upgraded from v1.0.10 to v1.0.11-rc1
before this release was tagged. What its mirror did there is in
Tested platforms.
About CosmoOS
CosmoOS 1.0.11: the 1.0 roadmap completed. CosmoOS installs to a disk, reboots into it, is used through BusyBox ash, keeps files across reboots, reaches the network by name, accepts an ssh login, and has a verified boot chain and sound randomness, on x86-64 and AArch64 under QEMU.
Start with the user guide. Each architecture's files: cosmoos-ARCH.img (the signed live image), its UEFI loader, kernel.elf, boot.tar, cmdline, the signed manifest, cosmo-upgrade and its signed package. SHA256SUMS.sig is SHA256SUMS's detached signature with the release key below (scripts/modsign.py verify-detached, or cosmo-verify on an installed system); check the files with sha256sum --ignore-missing -c SHA256SUMS.
Release signing key
The loader in these images verifies the kernel, boot archive and command line against this Ed25519 key (and the kernel trusts it for modules and packages):
- public key:
d2c778bcb38775790b6b6e843631bd2e76d6a29ec52296ece6e2d67c1bef41f8 - key id:
36ae7bb4947896ab(the first 8 bytes of SHA-512 of the key; the boot log prints it:verified boot, key 36ae7bb4947896ab) - in the repository:
tools/keys/release-2026.pub
Toolchain
Built and tested in the project's CI images (ci/Dockerfile), pinned by digest:
- toolchain:
ghcr.io/vkuttyp/cosmoos-ci@sha256:f6aee1470b952bdb426b8d55cfcccb734c9c1f4dac50c89edefba4e8be3be385 - litmus:
ghcr.io/vkuttyp/cosmoos-ci@sha256:c8b16f9c652cd99e4a557c08adc451528cc9cd36ba0e9e37b2973feffb15a5a9 - clang 1:19.0-63
- lld 1:19.0-63
- llvm 1:19.0-63
- qemu-system-x86 1:10.0.13+ds-0+deb13u1
- qemu-system-arm 1:10.0.13+ds-0+deb13u1
- ovmf 2025.02-8+deb13u1
- qemu-efi-aarch64 2025.02-8+deb13u1
- mtools 4.0.48-1
- python3 3.13.5-1
- clang-19 1:19.1.7-3+b1
- lld-19 1:19.1.7-3+b1
- llvm-19 1:19.1.7-3+b1
Third-party sources
Fetched and checked against these SHA-256 digests (ports/busybox/busybox.mk, ports/dropbear/dropbear.mk, ports/openssh/openssh.mk, ports/mbedtls/mbedtls.mk):
| Source | Version | SHA-256 |
|---|---|---|
| BusyBox | 1.37.0 | 3311dff32e746499f4df0d5df04d7eb396382d7e108bb9250e7b519b837043a4 |
| musl | 1.2.5 | a9a118bbe84d8764da0ea0d28b3ab3fae8477fc7e4085d90102b8596fc7c75e4 |
| compiler-rt | 19.1.7 | c12b6e764202c615c1a3af9a13d477846878757ae0e29e5f8979215a6958fffc |
| dropbear | 2026.94 | e098034a843699200c8c977a991fff73159735bf795d5f72ef672c41a6b1ae81 |
| OpenSSH portable (sftp-server only) | 10.6p1 | a9dc9565dffe8640f64d863cd29a32bc4a3dbdec0566a7fc44c5d6ee767d5f39 |
| mbedTLS | 3.6.7 | a7e8bcbec0e6f761b4af24f25677626b35f762f68eef79c08677a363212d11f6 |
| CA certificates (curl's extract of Mozilla's) | 2026-09-25 | a41b5d356aea97a529fe27e0f7316d2f9d946d75927476cf9cf1b90637d00505 |
Reproducibility
Each architecture was built twice from the tag v1.0.11, in two fresh containers of the toolchain image above, with the release key; every file below was identical in both:
- x86_64: two builds, 10 files each, identical; cosmoos-x86_64.img sha256 585acac619da1273718fbdf73f37446d2488f4d0c1233918417ff4e8aeb31cb4
- aarch64: two builds, 10 files each, identical; cosmoos-aarch64.img sha256 bd523b1797eb3eee003c38c0c3547c58924fa8ed80f5996867c9b518aa03b77c
To rebuild: check out the tag, run the toolchain image above, and make ARCH=<arch> SIGNING=release MODSIGN_KEY=<key> KEYRING_PUBS=tools/keys/release-2026.pub release. Without the private key, a build with your own key differs in what the key reaches: the key ring compiled into the kernel and loader, the signatures on modules, packages and the manifest, and the archive and image that hold them.
SHA256SUMS
585acac619da1273718fbdf73f37446d2488f4d0c1233918417ff4e8aeb31cb4 cosmoos-x86_64.img
115ef94c7916d2ba01ed3127701506beb2cc8199f6835a4e4489966fa34ffb67 cosmoos-x86_64-BOOTX64.EFI
a4e02b784d344b30de5980632fc58553de74930419c8a0f6f38f38c5f57afc01 cosmoos-x86_64-kernel.elf
f4ca8fdbf1e1ef8d8a7e92f1877ff4c80b8393793401e9b68ab5c5969e7d6a6a cosmoos-x86_64-boot.tar
7a77470be4312a22db40932c6cd8ddcd6d42a29b07101cbbe135cbfa1fc1aa14 cosmoos-x86_64-cmdline
b15fcdd85e640745aa862705b2d9f1e2ddbcb5a13411cc5694caf74a509b510e cosmoos-x86_64-manifest
e8d3475826bfd1d013cc078a6ebaedb1142518949fab105c005a8890b2b11960 cosmoos-x86_64-cosmo-upgrade
e6b9a0b4f8d6ab0d9bde7fc7567585d813ae2dcba22874c98e5cf58a7fb4e28b cosmoos-x86_64-cosmo-upgrade.cpk
bd523b1797eb3eee003c38c0c3547c58924fa8ed80f5996867c9b518aa03b77c cosmoos-aarch64.img
0d00053d85654789deaf9fa0edc5cb8231d8d142140c1198bcb38cfedc8ff87e cosmoos-aarch64-BOOTAA64.EFI
d1f75dbe0ef90c925c71de81141665f71796c9bb67c555e6c2546ff36fcee045 cosmoos-aarch64-kernel.elf
a5119fc33f81ba28f581c84b492dbebb5f76e01d84487f958457838bc287bdf8 cosmoos-aarch64-boot.tar
7a77470be4312a22db40932c6cd8ddcd6d42a29b07101cbbe135cbfa1fc1aa14 cosmoos-aarch64-cmdline
02d8702bd4c21d6bfb0d66c94d0d5df451d25eb638f01cd733d69bea16aed7cd cosmoos-aarch64-manifest
8d25dc5353238833fb56e7d2f1673a08d0094f0e6dfa20268a02011373ba8444 cosmoos-aarch64-cosmo-upgrade
4b8f6c0445747f4e1eed66686446d79177f4406b5c6d33edcc7e76f118e8f4af cosmoos-aarch64-cosmo-upgrade.cpk
Known limitations
What CosmoOS 1.0 does not do, or does differently from what you may
expect. Each item names where it is recorded; the work that remains
after 1.0 is in docs/plan.md, and the full list of known
gaps in the deferred-work inventory.
Machines
- QEMU is the tested platform. x86-64 on
q35and AArch64 onvirt
are tested by CI; there is no physical hardware matrix. Since v1.0.1
the AArch64 image boots on Parallels Desktop 27 on Apple Silicon, and
since v1.0.3 installs on its NVMe disks and has a network there; its
SATA disks are not seen (Tested platforms). Out of scope for 1.0
(roadmap): GPU and display beyond a text console (on
the firmware's framebuffer, or a virtio-gpu adapter at the display's
own size:...
CosmoOS 1.0.11-rc2
CosmoOS 1.0.11-rc2: the 1.0 roadmap completed. CosmoOS installs to a disk, reboots into it, is used through BusyBox ash, keeps files across reboots, reaches the network by name, accepts an ssh login, and has a verified boot chain and sound randomness, on x86-64 and AArch64 under QEMU.
Start with the user guide. Each architecture's files: cosmoos-ARCH.img (the signed live image), its UEFI loader, kernel.elf, boot.tar, cmdline, the signed manifest, cosmo-upgrade and its signed package. SHA256SUMS.sig is SHA256SUMS's detached signature with the release key below (scripts/modsign.py verify-detached, or cosmo-verify on an installed system); check the files with sha256sum --ignore-missing -c SHA256SUMS.
Release signing key
The loader in these images verifies the kernel, boot archive and command line against this Ed25519 key (and the kernel trusts it for modules and packages):
- public key:
d2c778bcb38775790b6b6e843631bd2e76d6a29ec52296ece6e2d67c1bef41f8 - key id:
36ae7bb4947896ab(the first 8 bytes of SHA-512 of the key; the boot log prints it:verified boot, key 36ae7bb4947896ab) - in the repository:
tools/keys/release-2026.pub
Toolchain
Built and tested in the project's CI images (ci/Dockerfile), pinned by digest:
- toolchain:
ghcr.io/vkuttyp/cosmoos-ci@sha256:f6aee1470b952bdb426b8d55cfcccb734c9c1f4dac50c89edefba4e8be3be385 - litmus:
ghcr.io/vkuttyp/cosmoos-ci@sha256:c8b16f9c652cd99e4a557c08adc451528cc9cd36ba0e9e37b2973feffb15a5a9 - clang 1:19.0-63
- lld 1:19.0-63
- llvm 1:19.0-63
- qemu-system-x86 1:10.0.13+ds-0+deb13u1
- qemu-system-arm 1:10.0.13+ds-0+deb13u1
- ovmf 2025.02-8+deb13u1
- qemu-efi-aarch64 2025.02-8+deb13u1
- mtools 4.0.48-1
- python3 3.13.5-1
- clang-19 1:19.1.7-3+b1
- lld-19 1:19.1.7-3+b1
- llvm-19 1:19.1.7-3+b1
Third-party sources
Fetched and checked against these SHA-256 digests (ports/busybox/busybox.mk, ports/dropbear/dropbear.mk, ports/openssh/openssh.mk, ports/mbedtls/mbedtls.mk):
| Source | Version | SHA-256 |
|---|---|---|
| BusyBox | 1.37.0 | 3311dff32e746499f4df0d5df04d7eb396382d7e108bb9250e7b519b837043a4 |
| musl | 1.2.5 | a9a118bbe84d8764da0ea0d28b3ab3fae8477fc7e4085d90102b8596fc7c75e4 |
| compiler-rt | 19.1.7 | c12b6e764202c615c1a3af9a13d477846878757ae0e29e5f8979215a6958fffc |
| dropbear | 2026.94 | e098034a843699200c8c977a991fff73159735bf795d5f72ef672c41a6b1ae81 |
| OpenSSH portable (sftp-server only) | 10.6p1 | a9dc9565dffe8640f64d863cd29a32bc4a3dbdec0566a7fc44c5d6ee767d5f39 |
| mbedTLS | 3.6.7 | a7e8bcbec0e6f761b4af24f25677626b35f762f68eef79c08677a363212d11f6 |
| CA certificates (curl's extract of Mozilla's) | 2026-09-25 | a41b5d356aea97a529fe27e0f7316d2f9d946d75927476cf9cf1b90637d00505 |
Reproducibility
Each architecture was built twice from the tag v1.0.11-rc2, in two fresh containers of the toolchain image above, with the release key; every file below was identical in both:
- x86_64: two builds, 10 files each, identical; cosmoos-x86_64.img sha256 8d6177bdc9c1d9a8b11298960eea3f4542ffae25700e76508abdd5cce3fea555
- aarch64: two builds, 10 files each, identical; cosmoos-aarch64.img sha256 d44c6fbf728e2094edc8ff47fe31e1658474b0790cc8069e07cef4a161273e0d
To rebuild: check out the tag, run the toolchain image above, and make ARCH=<arch> SIGNING=release MODSIGN_KEY=<key> KEYRING_PUBS=tools/keys/release-2026.pub release. Without the private key, a build with your own key differs in what the key reaches: the key ring compiled into the kernel and loader, the signatures on modules, packages and the manifest, and the archive and image that hold them.
SHA256SUMS
8d6177bdc9c1d9a8b11298960eea3f4542ffae25700e76508abdd5cce3fea555 cosmoos-x86_64.img
115ef94c7916d2ba01ed3127701506beb2cc8199f6835a4e4489966fa34ffb67 cosmoos-x86_64-BOOTX64.EFI
fa5ec9b41c6161337f5a17b9b19410f3d89f0cce60b0b3271f87e3475ec28bbe cosmoos-x86_64-kernel.elf
f4ca8fdbf1e1ef8d8a7e92f1877ff4c80b8393793401e9b68ab5c5969e7d6a6a cosmoos-x86_64-boot.tar
7a77470be4312a22db40932c6cd8ddcd6d42a29b07101cbbe135cbfa1fc1aa14 cosmoos-x86_64-cmdline
5e96196d25ff653c46452e4079e3e715f066a27f096dbc7ee0e542a64135d684 cosmoos-x86_64-manifest
e8d3475826bfd1d013cc078a6ebaedb1142518949fab105c005a8890b2b11960 cosmoos-x86_64-cosmo-upgrade
4cf2f7ce417883c1c5ff38e246f0ba9b06a049d548cc13de728bae2c2242a750 cosmoos-x86_64-cosmo-upgrade.cpk
d44c6fbf728e2094edc8ff47fe31e1658474b0790cc8069e07cef4a161273e0d cosmoos-aarch64.img
0d00053d85654789deaf9fa0edc5cb8231d8d142140c1198bcb38cfedc8ff87e cosmoos-aarch64-BOOTAA64.EFI
61c3b0435164d86cbf1881c32b31fe8142012265c756b0e5cd0128ea377494f9 cosmoos-aarch64-kernel.elf
a5119fc33f81ba28f581c84b492dbebb5f76e01d84487f958457838bc287bdf8 cosmoos-aarch64-boot.tar
7a77470be4312a22db40932c6cd8ddcd6d42a29b07101cbbe135cbfa1fc1aa14 cosmoos-aarch64-cmdline
a1c87b674344faa0eddb34373812953be75e586031588c96164a49fdc60170be cosmoos-aarch64-manifest
8d25dc5353238833fb56e7d2f1673a08d0094f0e6dfa20268a02011373ba8444 cosmoos-aarch64-cosmo-upgrade
871b1df87c4227198b7bd9034f1ed060869fff094b231c93d9baf211cd72a58c cosmoos-aarch64-cosmo-upgrade.cpk
Known limitations
What CosmoOS 1.0 does not do, or does differently from what you may
expect. Each item names where it is recorded; the work that remains
after 1.0 is in docs/plan.md, and the full list of known
gaps in the deferred-work inventory.
Machines
- QEMU is the tested platform. x86-64 on
q35and AArch64 onvirt
are tested by CI; there is no physical hardware matrix. Since v1.0.1
the AArch64 image boots on Parallels Desktop 27 on Apple Silicon, and
since v1.0.3 installs on its NVMe disks and has a network there; its
SATA disks are not seen (Tested platforms). Out of scope for 1.0
(roadmap): GPU and display beyond a text console (on
the firmware's framebuffer, or a virtio-gpu adapter at the display's
own size: no 3D, cursor or display interface for programs), CPU and memory
hotplug (PCIe disks can be added and removed since v1.0.11), NUMA, more than 64 CPUs, huge pages, live migration,
RAID-Z, eBPF, and the Intel VMX backend on hardware. - Randomness from the weakest source last. The pool seeds from the
CPU's random instructions, the firmware'sEFI_RNG_PROTOCOLor a
virtio-rng; with none of them (Parallels Desktop) a timing-jitter source
seeds it, credited conservatively (docs/kernel/security/design.md §6).
random.jitter=offon the command line turns that off, and the pool
then never seeds there. The commands in this guide add-device virtio-rng-pci. - The clock is stepped, not slewed. The wall clock is set at boot
from the RTC or, with none (Parallels), the firmware's time. Since
v1.0.4 root can set it (date -s,hwclock -wwhere there is an RTC)
andntpd -qsteps it once from a server; there is no NTP daemon,
becauseadjtimexis not implemented, and no time zone. - No Wi-Fi, Bluetooth or sound.
Boot and security
- Verified boot covers the loader's three files (kernel, boot archive,
command line). The root filesystem is not verified; the loader is
not signed for UEFI Secure Boot; there is no TPM measurement
and no rollback protection for manifests or modules (inventory
2.9). - No KASLR: the kernel is at a fixed address. User-space ASLR covers
the stack, heap,mmapand PIE executables; a non-PIE (ET_EXEC)
program loads at its fixed address. - One user, root. Privileges, not uids, separate what processes may
do (Privileges). A root session holding fewer
privileges can still rewrite files in/etcthat a later boot runs
with all of them (M5 report, inventory 2.9).
Shell and commands
- The commands are the BusyBox applets listed in the shell
page: noping6; no hard links; no/sys. /prochas the process directories and a fixed set of system files
(meminfo,stat,loadavg,uptime,mounts,version,
cpuinfo). A process has no nice value and no user/system split of its
CPU time;ps'sTTcolumn is a pair of Linux device numbers (5,1
for the console), since devices here have none of their own; and a
process'senvironis what exec gave it, not what it has since written
over (inventory §13).- The terminal driver honours the common modes (canonical input, echo,
signals, raw mode, window size); most other termios flags and control
characters are accepted and ignored (inventory 1.4). - No swap.
Networking
wget's certificate authorities are fixed in the image
(/etc/ssl/certs/ca-certificates.crt, as built); nothing updates them,
and there is no certificate revocation check
(Networking).- The address comes from DHCP. There is no runtime tool to set one by
hand;/etc/resolv.confis written once per boot, not on lease
renewal; the DHCP client does no ARP probe or DECLINE, no INIT-REBOOT,
no RELEASE, and ignores classless routes (option 121) (inventory 2.5). - IPv6 is link-local; there is no IPv6 routing beyond the link, no IP
fragmentation, and no TCP SACK, window scaling or timestamps
(inventory 2.5). - ssh is dropbear with key login only (Ed25519 or RSA), root only;
no port forwarding (ssh).
Storage
...
CosmoOS 1.0.11-rc1
CosmoOS 1.0.11-rc1: the 1.0 roadmap completed. CosmoOS installs to a disk, reboots into it, is used through BusyBox ash, keeps files across reboots, reaches the network by name, accepts an ssh login, and has a verified boot chain and sound randomness, on x86-64 and AArch64 under QEMU.
Start with the user guide. Each architecture's files: cosmoos-ARCH.img (the signed live image), its UEFI loader, kernel.elf, boot.tar, cmdline, the signed manifest, cosmo-upgrade and its signed package. SHA256SUMS.sig is SHA256SUMS's detached signature with the release key below (scripts/modsign.py verify-detached, or cosmo-verify on an installed system); check the files with sha256sum --ignore-missing -c SHA256SUMS.
Release signing key
The loader in these images verifies the kernel, boot archive and command line against this Ed25519 key (and the kernel trusts it for modules and packages):
- public key:
d2c778bcb38775790b6b6e843631bd2e76d6a29ec52296ece6e2d67c1bef41f8 - key id:
36ae7bb4947896ab(the first 8 bytes of SHA-512 of the key; the boot log prints it:verified boot, key 36ae7bb4947896ab) - in the repository:
tools/keys/release-2026.pub
Toolchain
Built and tested in the project's CI images (ci/Dockerfile), pinned by digest:
- toolchain:
ghcr.io/vkuttyp/cosmoos-ci@sha256:f6aee1470b952bdb426b8d55cfcccb734c9c1f4dac50c89edefba4e8be3be385 - litmus:
ghcr.io/vkuttyp/cosmoos-ci@sha256:c8b16f9c652cd99e4a557c08adc451528cc9cd36ba0e9e37b2973feffb15a5a9 - clang 1:19.0-63
- lld 1:19.0-63
- llvm 1:19.0-63
- qemu-system-x86 1:10.0.13+ds-0+deb13u1
- qemu-system-arm 1:10.0.13+ds-0+deb13u1
- ovmf 2025.02-8+deb13u1
- qemu-efi-aarch64 2025.02-8+deb13u1
- mtools 4.0.48-1
- python3 3.13.5-1
- clang-19 1:19.1.7-3+b1
- lld-19 1:19.1.7-3+b1
- llvm-19 1:19.1.7-3+b1
Third-party sources
Fetched and checked against these SHA-256 digests (ports/busybox/busybox.mk, ports/dropbear/dropbear.mk, ports/openssh/openssh.mk, ports/mbedtls/mbedtls.mk):
| Source | Version | SHA-256 |
|---|---|---|
| BusyBox | 1.37.0 | 3311dff32e746499f4df0d5df04d7eb396382d7e108bb9250e7b519b837043a4 |
| musl | 1.2.5 | a9a118bbe84d8764da0ea0d28b3ab3fae8477fc7e4085d90102b8596fc7c75e4 |
| compiler-rt | 19.1.7 | c12b6e764202c615c1a3af9a13d477846878757ae0e29e5f8979215a6958fffc |
| dropbear | 2026.94 | e098034a843699200c8c977a991fff73159735bf795d5f72ef672c41a6b1ae81 |
| OpenSSH portable (sftp-server only) | 10.6p1 | a9dc9565dffe8640f64d863cd29a32bc4a3dbdec0566a7fc44c5d6ee767d5f39 |
| mbedTLS | 3.6.7 | a7e8bcbec0e6f761b4af24f25677626b35f762f68eef79c08677a363212d11f6 |
| CA certificates (curl's extract of Mozilla's) | 2026-09-25 | a41b5d356aea97a529fe27e0f7316d2f9d946d75927476cf9cf1b90637d00505 |
Reproducibility
Each architecture was built twice from the tag v1.0.11-rc1, in two fresh containers of the toolchain image above, with the release key; every file below was identical in both:
- x86_64: two builds, 10 files each, identical; cosmoos-x86_64.img sha256 1043cdc3f40eb0e35e25fa78d7dac8eb6e270c52a24a5ed819afe245280814dc
- aarch64: two builds, 10 files each, identical; cosmoos-aarch64.img sha256 ad8725a38e3efdbe62e7291abb887ca6d8301c2f5f8104905d5821a7d081b22c
To rebuild: check out the tag, run the toolchain image above, and make ARCH=<arch> SIGNING=release MODSIGN_KEY=<key> KEYRING_PUBS=tools/keys/release-2026.pub release. Without the private key, a build with your own key differs in what the key reaches: the key ring compiled into the kernel and loader, the signatures on modules, packages and the manifest, and the archive and image that hold them.
SHA256SUMS
1043cdc3f40eb0e35e25fa78d7dac8eb6e270c52a24a5ed819afe245280814dc cosmoos-x86_64.img
115ef94c7916d2ba01ed3127701506beb2cc8199f6835a4e4489966fa34ffb67 cosmoos-x86_64-BOOTX64.EFI
137e049bee1431b02606f6ad81ca4a502c2e7c8dc55161b7254c3b834a8d891f cosmoos-x86_64-kernel.elf
f4ca8fdbf1e1ef8d8a7e92f1877ff4c80b8393793401e9b68ab5c5969e7d6a6a cosmoos-x86_64-boot.tar
7a77470be4312a22db40932c6cd8ddcd6d42a29b07101cbbe135cbfa1fc1aa14 cosmoos-x86_64-cmdline
2227adfd539e311352cbfa413949aca07fa596d2065f569c23b1fb724084d97c cosmoos-x86_64-manifest
e8d3475826bfd1d013cc078a6ebaedb1142518949fab105c005a8890b2b11960 cosmoos-x86_64-cosmo-upgrade
4cf2f7ce417883c1c5ff38e246f0ba9b06a049d548cc13de728bae2c2242a750 cosmoos-x86_64-cosmo-upgrade.cpk
ad8725a38e3efdbe62e7291abb887ca6d8301c2f5f8104905d5821a7d081b22c cosmoos-aarch64.img
0d00053d85654789deaf9fa0edc5cb8231d8d142140c1198bcb38cfedc8ff87e cosmoos-aarch64-BOOTAA64.EFI
005758de4434f12d9c5a957bd39724b6d140d2178846d0c0d461bf7e8a420ddd cosmoos-aarch64-kernel.elf
a5119fc33f81ba28f581c84b492dbebb5f76e01d84487f958457838bc287bdf8 cosmoos-aarch64-boot.tar
7a77470be4312a22db40932c6cd8ddcd6d42a29b07101cbbe135cbfa1fc1aa14 cosmoos-aarch64-cmdline
b6b474881c33a87983a1199d21dbbdbad70677e6ae92a54a0a915c829eb238f8 cosmoos-aarch64-manifest
8d25dc5353238833fb56e7d2f1673a08d0094f0e6dfa20268a02011373ba8444 cosmoos-aarch64-cosmo-upgrade
871b1df87c4227198b7bd9034f1ed060869fff094b231c93d9baf211cd72a58c cosmoos-aarch64-cosmo-upgrade.cpk
Known limitations
What CosmoOS 1.0 does not do, or does differently from what you may
expect. Each item names where it is recorded; the work that remains
after 1.0 is in docs/plan.md, and the full list of known
gaps in the deferred-work inventory.
Machines
- QEMU is the tested platform. x86-64 on
q35and AArch64 onvirt
are tested by CI; there is no physical hardware matrix. Since v1.0.1
the AArch64 image boots on Parallels Desktop 27 on Apple Silicon, and
since v1.0.3 installs on its NVMe disks and has a network there; its
SATA disks are not seen (Tested platforms). Out of scope for 1.0
(roadmap): GPU and display beyond a text console (on
the firmware's framebuffer, or a virtio-gpu adapter at the display's
own size: no 3D, cursor or display interface for programs), CPU and memory
hotplug (PCIe disks can be added and removed since v1.0.11), NUMA, more than 64 CPUs, huge pages, live migration,
RAID-Z, eBPF, and the Intel VMX backend on hardware. - Randomness from the weakest source last. The pool seeds from the
CPU's random instructions, the firmware'sEFI_RNG_PROTOCOLor a
virtio-rng; with none of them (Parallels Desktop) a timing-jitter source
seeds it, credited conservatively (docs/kernel/security/design.md §6).
random.jitter=offon the command line turns that off, and the pool
then never seeds there. The commands in this guide add-device virtio-rng-pci. - The clock is stepped, not slewed. The wall clock is set at boot
from the RTC or, with none (Parallels), the firmware's time. Since
v1.0.4 root can set it (date -s,hwclock -wwhere there is an RTC)
andntpd -qsteps it once from a server; there is no NTP daemon,
becauseadjtimexis not implemented, and no time zone. - No Wi-Fi, Bluetooth or sound.
Boot and security
- Verified boot covers the loader's three files (kernel, boot archive,
command line). The root filesystem is not verified; the loader is
not signed for UEFI Secure Boot; there is no TPM measurement
and no rollback protection for manifests or modules (inventory
2.9). - No KASLR: the kernel is at a fixed address. User-space ASLR covers
the stack, heap,mmapand PIE executables; a non-PIE (ET_EXEC)
program loads at its fixed address. - One user, root. Privileges, not uids, separate what processes may
do (Privileges). A root session holding fewer
privileges can still rewrite files in/etcthat a later boot runs
with all of them (M5 report, inventory 2.9).
Shell and commands
- The commands are the BusyBox applets listed in the shell
page: noping6; no hard links; no/sys. /prochas the process directories and a fixed set of system files
(meminfo,stat,loadavg,uptime,mounts,version,
cpuinfo). A process has no nice value and no user/system split of its
CPU time;ps'sTTcolumn is a pair of Linux device numbers (5,1
for the console), since devices here have none of their own; and a
process'senvironis what exec gave it, not what it has since written
over (inventory §13).- The terminal driver honours the common modes (canonical input, echo,
signals, raw mode, window size); most other termios flags and control
characters are accepted and ignored (inventory 1.4). - No swap.
Networking
wget's certificate authorities are fixed in the image
(/etc/ssl/certs/ca-certificates.crt, as built); nothing updates them,
and there is no certificate revocation check
(Networking).- The address comes from DHCP. There is no runtime tool to set one by
hand;/etc/resolv.confis written once per boot, not on lease
renewal; the DHCP client does no ARP probe or DECLINE, no INIT-REBOOT,
no RELEASE, and ignores classless routes (option 121) (inventory 2.5). - IPv6 is link-local; there is no IPv6 routing beyond the link, no IP
fragmentation, and no TCP SACK, window scaling or timestamps
(inventory 2.5). - ssh is dropbear with key login only (Ed25519 or RSA), root only;
no port forwarding (ssh).
Storage
...
CosmoOS 1.0.10
CosmoOS 1.0.10
fsck at boot and scrub --repair
The root is checked on every boot, before it is mounted. Init runs
the kernel's own structural check on the root's pool, read-only, and
prints one line:
cosmofs: root checked, 0 findings, 0 repaired
What a crash or a bookkeeping slip leaves is repaired without asking:
blocks allocated that nothing uses, a wrong total, a stale rollback
record or hold, a snapshot's identity -- and, named by inode on the
console, an inode no name reaches or a wrong link count. Anything else is
a question about which of two things is real, and the boot does not
answer it: the root is refused, the class is named, and you are left at
the live system's shell with the pool unmounted and the command to run:
cosmofs: root refused: cross-linked; vda2 is not mounted. From this shell: fsck.cosmofs --repair vda2
fsck=check on the kernel command line reports and repairs nothing;
fsck=skip does not check.
fsck.cosmofs checks a pool nothing has mounted. fsck.cosmofs --check DEVICE writes nothing; --repair repairs what has one right
answer -- including, offline only, a block in use that the allocator
calls free -- and reports the rest. It is the kernel's checker, through
/dev/fsctl, not a copy of it. Its output names each finding with its
class, the block or inode and what was done, one line each, and its exit
status is fsck's: 0 nothing found, 1 all repaired, 4 findings left, 8
could not check.
fsctl scrub reports; fsctl scrub --repair repairs. The scrub
reads every block of every tree -- the live one and each snapshot's --
on every copy, and on a mirror rewrites a bad copy from a good one only
when asked. It reads at most fs.scrub_rate blocks a second (4096,
16 MiB, unless set with sysctl) and steps aside between tenths of a
second, so the programs using the pool keep going. mkfs.cosmofs --mirror A B makes a two-way mirror.
See the guide's new page, Checking and repairing.
Fixes
- A read-only mount writes nothing. Mounting a cosmofs read-only used
to write the replay of what the last commit freed, or of inodes deleted
while open, at unmount; it now does that in memory only. - A root that is not a directory is refused, not a panic. One changed
mode byte on a disk stopped the kernel when the root was mounted. - An allocation that fails no longer throws away the open
transaction. A file whose extent map needed a new block, or an
inode's map path, at a moment memory was short failed every change
after it until the next unmount; the operation now fails alone and can
be retried. - Older-format pools stay readable by their kernels: a pool below
format 6 no longer gets compressed records. - The scrub's counts reach you when it finds damage, and it no longer
reports blocks it is still writing as unrecoverable. - A rollback left pending says why. When the mount could not apply a
pending rollback (no room), init's line now ends with the reason.
Upgrading from v1.0.9
cosmo-upgrade --fetch v1.0.10, reboot, then pkg update && pkg upgrade. The upgrade takes a boot environment, so cosmo-upgrade --rollback returns the root and the boot set as they were. The first boot
of v1.0.10 checks the root before it mounts it; a root an older kernel left
with findings a boot may repair is repaired then, and the line says so.
Tested: on every change, on both architectures, make test-fsck (the
installed root damaged 23 ways and booted; scrub --repair on a mirror)
beside the release tests; and on a Parallels virtual machine, upgraded from
v1.0.9 to v1.0.10-rc1 before this release was tagged.
About CosmoOS
CosmoOS 1.0.10: the 1.0 roadmap completed. CosmoOS installs to a disk, reboots into it, is used through BusyBox ash, keeps files across reboots, reaches the network by name, accepts an ssh login, and has a verified boot chain and sound randomness, on x86-64 and AArch64 under QEMU.
Start with the user guide. Each architecture's files: cosmoos-ARCH.img (the signed live image), its UEFI loader, kernel.elf, boot.tar, cmdline, the signed manifest, cosmo-upgrade and its signed package. SHA256SUMS.sig is SHA256SUMS's detached signature with the release key below (scripts/modsign.py verify-detached, or cosmo-verify on an installed system); check the files with sha256sum --ignore-missing -c SHA256SUMS.
Release signing key
The loader in these images verifies the kernel, boot archive and command line against this Ed25519 key (and the kernel trusts it for modules and packages):
- public key:
d2c778bcb38775790b6b6e843631bd2e76d6a29ec52296ece6e2d67c1bef41f8 - key id:
36ae7bb4947896ab(the first 8 bytes of SHA-512 of the key; the boot log prints it:verified boot, key 36ae7bb4947896ab) - in the repository:
tools/keys/release-2026.pub
Toolchain
Built and tested in the project's CI images (ci/Dockerfile), pinned by digest:
- toolchain:
ghcr.io/vkuttyp/cosmoos-ci@sha256:f6aee1470b952bdb426b8d55cfcccb734c9c1f4dac50c89edefba4e8be3be385 - litmus:
ghcr.io/vkuttyp/cosmoos-ci@sha256:c8b16f9c652cd99e4a557c08adc451528cc9cd36ba0e9e37b2973feffb15a5a9 - clang 1:19.0-63
- lld 1:19.0-63
- llvm 1:19.0-63
- qemu-system-x86 1:10.0.13+ds-0+deb13u1
- qemu-system-arm 1:10.0.13+ds-0+deb13u1
- ovmf 2025.02-8+deb13u1
- qemu-efi-aarch64 2025.02-8+deb13u1
- mtools 4.0.48-1
- python3 3.13.5-1
- clang-19 1:19.1.7-3+b1
- lld-19 1:19.1.7-3+b1
- llvm-19 1:19.1.7-3+b1
Third-party sources
Fetched and checked against these SHA-256 digests (ports/busybox/busybox.mk, ports/dropbear/dropbear.mk, ports/openssh/openssh.mk, ports/mbedtls/mbedtls.mk):
| Source | Version | SHA-256 |
|---|---|---|
| BusyBox | 1.37.0 | 3311dff32e746499f4df0d5df04d7eb396382d7e108bb9250e7b519b837043a4 |
| musl | 1.2.5 | a9a118bbe84d8764da0ea0d28b3ab3fae8477fc7e4085d90102b8596fc7c75e4 |
| compiler-rt | 19.1.7 | c12b6e764202c615c1a3af9a13d477846878757ae0e29e5f8979215a6958fffc |
| dropbear | 2026.94 | e098034a843699200c8c977a991fff73159735bf795d5f72ef672c41a6b1ae81 |
| OpenSSH portable (sftp-server only) | 10.6p1 | a9dc9565dffe8640f64d863cd29a32bc4a3dbdec0566a7fc44c5d6ee767d5f39 |
| mbedTLS | 3.6.7 | a7e8bcbec0e6f761b4af24f25677626b35f762f68eef79c08677a363212d11f6 |
| CA certificates (curl's extract of Mozilla's) | 2026-09-25 | a41b5d356aea97a529fe27e0f7316d2f9d946d75927476cf9cf1b90637d00505 |
Reproducibility
Each architecture was built twice from the tag v1.0.10, in two fresh containers of the toolchain image above, with the release key; every file below was identical in both:
- x86_64: two builds, 10 files each, identical; cosmoos-x86_64.img sha256 c6b379efd47c534ca7ff71ed6144a2665389f170548b4a6d6755d183d2b4b78f
- aarch64: two builds, 10 files each, identical; cosmoos-aarch64.img sha256 377a9529dd159b361c25771ecc52a65227480d61dedd67c3818c66af73053427
To rebuild: check out the tag, run the toolchain image above, and make ARCH=<arch> SIGNING=release MODSIGN_KEY=<key> KEYRING_PUBS=tools/keys/release-2026.pub release. Without the private key, a build with your own key differs in what the key reaches: the key ring compiled into the kernel and loader, the signatures on modules, packages and the manifest, and the archive and image that hold them.
SHA256SUMS
c6b379efd47c534ca7ff71ed6144a2665389f170548b4a6d6755d183d2b4b78f cosmoos-x86_64.img
115ef94c7916d2ba01ed3127701506beb2cc8199f6835a4e4489966fa34ffb67 cosmoos-x86_64-BOOTX64.EFI
1e9ef09738ddc030e721e7a48fe35cfae0c90211377c6311af36fb0860403f3f cosmoos-x86_64-kernel.elf
56ebca11eba13e474d679be2ae5ffee00cc2f7900bdceb0cdec4a8d8993ef8be cosmoos-x86_64-boot.tar
7a77470be4312a22db40932c6cd8ddcd6d42a29b07101cbbe135cbfa1fc1aa14 cosmoos-x86_64-cmdline
b6d1564b7cbbb23787dfd143bfe27f81428d92499b26c61ee7e7b689cb09154f cosmoos-x86_64-manifest
9b103eb1224401ca901357a86a1b715870092c8a78b4f738f9bb97cfaff5f24d cosmoos-x86_64-cosmo-upgrade
ff858d4c55f95bd0067259ea6f41112268cb7e2ab3802b9a9cdfb4e850c4bb2b cosmoos-x86_64-cosmo-upgrade.cpk
377a9529dd159b361c25771ecc52a65227480d61dedd67c3818c66af73053427 cosmoos-aarch64.img
0d00053d85654789deaf9fa0edc5cb8231d8d142140c1198bcb38cfedc8ff87e cosmoos-aarch64-BOOTAA64.EFI
175529abee6cda6c59555f15bad319a5af7e41c5a96a8646c6c99ac321a591c8 cosmoos-aarch64-kernel.elf
bb7b5b9505a94c90de444ba33d2e3f6f706d29017a27a63c766033d9486898f7 cosmoos-aarch64-boot.tar
7a77470be4312a22db40932c6cd8ddcd6d42a29b07101cbbe135cbfa1fc1aa14 cosmoos-aarch64-cmdline
f550ec0bc38fc3c100f2c1540ff8b487bf014f8f088bdb6c339ed1c3efa81bdb cosmoos-aarch64-manifest
d1d3d8337fca37a86aa56a36e3008552f8663fb2d4e364996fc106b49c0cd75c cosmoos-aarch64-cosmo-upgrade
ca457ff4daa632c308cecf5c0fe3751d4be859d0d93b26ca6964200fc0ee021e cosmoos-aarch64-cosmo-upgrade.cpk
Known limitations
What CosmoOS 1.0 does not do, or does differently from what you may
expect. Each item names where it is recorded; the work that remains
after 1.0 is in docs/plan.md, and the full list of known
gaps in the deferred-work inventory.
Machines
- QEMU is the tested platform. x86-64 on
q35and AArch64 onvirt
are tested by CI; there is no physical hardware matrix. Since v1.0.1
the AArch64 image boots on Parallels Desktop 27 on Apple Silicon, and
since v1.0.3 installs on its NVMe disks and has a network there; its
SATA disks are not seen (Tested platforms). Out of scope for 1.0
(roadmap): GPU and display beyond a text console (on
the firmware's framebuffer, or ...
CosmoOS 1.0.10-rc1
CosmoOS 1.0.10-rc1: the 1.0 roadmap completed. CosmoOS installs to a disk, reboots into it, is used through BusyBox ash, keeps files across reboots, reaches the network by name, accepts an ssh login, and has a verified boot chain and sound randomness, on x86-64 and AArch64 under QEMU.
Start with the user guide. Each architecture's files: cosmoos-ARCH.img (the signed live image), its UEFI loader, kernel.elf, boot.tar, cmdline, the signed manifest, cosmo-upgrade and its signed package. SHA256SUMS.sig is SHA256SUMS's detached signature with the release key below (scripts/modsign.py verify-detached, or cosmo-verify on an installed system); check the files with sha256sum --ignore-missing -c SHA256SUMS.
Release signing key
The loader in these images verifies the kernel, boot archive and command line against this Ed25519 key (and the kernel trusts it for modules and packages):
- public key:
d2c778bcb38775790b6b6e843631bd2e76d6a29ec52296ece6e2d67c1bef41f8 - key id:
36ae7bb4947896ab(the first 8 bytes of SHA-512 of the key; the boot log prints it:verified boot, key 36ae7bb4947896ab) - in the repository:
tools/keys/release-2026.pub
Toolchain
Built and tested in the project's CI images (ci/Dockerfile), pinned by digest:
- toolchain:
ghcr.io/vkuttyp/cosmoos-ci@sha256:f6aee1470b952bdb426b8d55cfcccb734c9c1f4dac50c89edefba4e8be3be385 - litmus:
ghcr.io/vkuttyp/cosmoos-ci@sha256:c8b16f9c652cd99e4a557c08adc451528cc9cd36ba0e9e37b2973feffb15a5a9 - clang 1:19.0-63
- lld 1:19.0-63
- llvm 1:19.0-63
- qemu-system-x86 1:10.0.13+ds-0+deb13u1
- qemu-system-arm 1:10.0.13+ds-0+deb13u1
- ovmf 2025.02-8+deb13u1
- qemu-efi-aarch64 2025.02-8+deb13u1
- mtools 4.0.48-1
- python3 3.13.5-1
- clang-19 1:19.1.7-3+b1
- lld-19 1:19.1.7-3+b1
- llvm-19 1:19.1.7-3+b1
Third-party sources
Fetched and checked against these SHA-256 digests (ports/busybox/busybox.mk, ports/dropbear/dropbear.mk, ports/openssh/openssh.mk, ports/mbedtls/mbedtls.mk):
| Source | Version | SHA-256 |
|---|---|---|
| BusyBox | 1.37.0 | 3311dff32e746499f4df0d5df04d7eb396382d7e108bb9250e7b519b837043a4 |
| musl | 1.2.5 | a9a118bbe84d8764da0ea0d28b3ab3fae8477fc7e4085d90102b8596fc7c75e4 |
| compiler-rt | 19.1.7 | c12b6e764202c615c1a3af9a13d477846878757ae0e29e5f8979215a6958fffc |
| dropbear | 2026.94 | e098034a843699200c8c977a991fff73159735bf795d5f72ef672c41a6b1ae81 |
| OpenSSH portable (sftp-server only) | 10.6p1 | a9dc9565dffe8640f64d863cd29a32bc4a3dbdec0566a7fc44c5d6ee767d5f39 |
| mbedTLS | 3.6.7 | a7e8bcbec0e6f761b4af24f25677626b35f762f68eef79c08677a363212d11f6 |
| CA certificates (curl's extract of Mozilla's) | 2026-09-25 | a41b5d356aea97a529fe27e0f7316d2f9d946d75927476cf9cf1b90637d00505 |
Reproducibility
Each architecture was built twice from the tag v1.0.10-rc1, in two fresh containers of the toolchain image above, with the release key; every file below was identical in both:
- x86_64: two builds, 10 files each, identical; cosmoos-x86_64.img sha256 49f9b4d77878f5085012f180c4167ca69213066118bffdc879c8f2bc988ae5e4
- aarch64: two builds, 10 files each, identical; cosmoos-aarch64.img sha256 afdfc4fe68f6ed8aa06f331c1ac476e093a07b6f01f86cb4605ca32596d266fb
To rebuild: check out the tag, run the toolchain image above, and make ARCH=<arch> SIGNING=release MODSIGN_KEY=<key> KEYRING_PUBS=tools/keys/release-2026.pub release. Without the private key, a build with your own key differs in what the key reaches: the key ring compiled into the kernel and loader, the signatures on modules, packages and the manifest, and the archive and image that hold them.
SHA256SUMS
49f9b4d77878f5085012f180c4167ca69213066118bffdc879c8f2bc988ae5e4 cosmoos-x86_64.img
115ef94c7916d2ba01ed3127701506beb2cc8199f6835a4e4489966fa34ffb67 cosmoos-x86_64-BOOTX64.EFI
ca5735e027b1335f4f414d39dcc441c1e8ce3650dd2362828b3fa2f8a9ac233b cosmoos-x86_64-kernel.elf
56ebca11eba13e474d679be2ae5ffee00cc2f7900bdceb0cdec4a8d8993ef8be cosmoos-x86_64-boot.tar
7a77470be4312a22db40932c6cd8ddcd6d42a29b07101cbbe135cbfa1fc1aa14 cosmoos-x86_64-cmdline
3f65be7f7f42210077ec18ddcb4fdef5e8f3114e86e1e18c62382b1a061f18bd cosmoos-x86_64-manifest
9b103eb1224401ca901357a86a1b715870092c8a78b4f738f9bb97cfaff5f24d cosmoos-x86_64-cosmo-upgrade
55f597877ae3ee386231f4d4fd89a39e5f8825050846e99d007f471412088aae cosmoos-x86_64-cosmo-upgrade.cpk
afdfc4fe68f6ed8aa06f331c1ac476e093a07b6f01f86cb4605ca32596d266fb cosmoos-aarch64.img
0d00053d85654789deaf9fa0edc5cb8231d8d142140c1198bcb38cfedc8ff87e cosmoos-aarch64-BOOTAA64.EFI
5c53a30185738e884d59fded42c9a46c87e85e1bc76e5a40b265a6af75a573d4 cosmoos-aarch64-kernel.elf
bb7b5b9505a94c90de444ba33d2e3f6f706d29017a27a63c766033d9486898f7 cosmoos-aarch64-boot.tar
7a77470be4312a22db40932c6cd8ddcd6d42a29b07101cbbe135cbfa1fc1aa14 cosmoos-aarch64-cmdline
fc62c7d53a05a068aa6caef0b19de13bbc26eb77b7a21e87b8cc43244041c6d3 cosmoos-aarch64-manifest
d1d3d8337fca37a86aa56a36e3008552f8663fb2d4e364996fc106b49c0cd75c cosmoos-aarch64-cosmo-upgrade
d43ffddeeae23fd134008533747de8801bda0286d24f7bb54933537c707d3887 cosmoos-aarch64-cosmo-upgrade.cpk
Known limitations
What CosmoOS 1.0 does not do, or does differently from what you may
expect. Each item names where it is recorded; the work that remains
after 1.0 is in docs/plan.md, and the full list of known
gaps in the deferred-work inventory.
Machines
- QEMU is the tested platform. x86-64 on
q35and AArch64 onvirt
are tested by CI; there is no physical hardware matrix. Since v1.0.1
the AArch64 image boots on Parallels Desktop 27 on Apple Silicon, and
since v1.0.3 installs on its NVMe disks and has a network there; its
SATA disks are not seen (Tested platforms). Out of scope for 1.0
(roadmap): GPU and display beyond a text console (on
the firmware's framebuffer, or a virtio-gpu adapter at the display's
own size: no 3D, cursor or display interface for programs), hotplug, NUMA, more than 64 CPUs, huge pages, live migration,
RAID-Z, eBPF, and the Intel VMX backend on hardware. - Randomness from the weakest source last. The pool seeds from the
CPU's random instructions, the firmware'sEFI_RNG_PROTOCOLor a
virtio-rng; with none of them (Parallels Desktop) a timing-jitter source
seeds it, credited conservatively (docs/kernel/security/design.md §6).
random.jitter=offon the command line turns that off, and the pool
then never seeds there. The commands in this guide add-device virtio-rng-pci. - The clock is stepped, not slewed. The wall clock is set at boot
from the RTC or, with none (Parallels), the firmware's time. Since
v1.0.4 root can set it (date -s,hwclock -wwhere there is an RTC)
andntpd -qsteps it once from a server; there is no NTP daemon,
becauseadjtimexis not implemented, and no time zone. - No Wi-Fi, Bluetooth or sound.
Boot and security
- Verified boot covers the loader's three files (kernel, boot archive,
command line). The root filesystem is not verified; the loader is
not signed for UEFI Secure Boot; there is no TPM measurement
and no rollback protection for manifests or modules (inventory
2.9). - No KASLR: the kernel is at a fixed address. User-space ASLR covers
the stack, heap,mmapand PIE executables; a non-PIE (ET_EXEC)
program loads at its fixed address. - One user, root. Privileges, not uids, separate what processes may
do (Privileges). A root session holding fewer
privileges can still rewrite files in/etcthat a later boot runs
with all of them (M5 report, inventory 2.9).
Shell and commands
- The commands are the BusyBox applets listed in the shell
page: noping6; no hard links; no/sys. /prochas the process directories and a fixed set of system files
(meminfo,stat,loadavg,uptime,mounts,version,
cpuinfo). A process has no nice value and no user/system split of its
CPU time;ps'sTTcolumn is a pair of Linux device numbers (5,1
for the console), since devices here have none of their own; and a
process'senvironis what exec gave it, not what it has since written
over (inventory §13).- The terminal driver honours the common modes (canonical input, echo,
signals, raw mode, window size); most other termios flags and control
characters are accepted and ignored (inventory 1.4). - No swap.
Networking
wget's certificate authorities are fixed in the image
(/etc/ssl/certs/ca-certificates.crt, as built); nothing updates them,
and there is no certificate revocation check
(Networking).- The address comes from DHCP. There is no runtime tool to set one by
hand;/etc/resolv.confis written once per boot, not on lease
renewal; the DHCP client does no ARP probe or DECLINE, no INIT-REBOOT,
no RELEASE, and ignores classless routes (option 121) (inventory 2.5). - IPv6 is link-local; there is no IPv6 routing beyond the link, no IP
fragmentation, and no TCP SACK, window scaling or timestamps
(inventory 2.5). - ssh is dropbear with key login only (Ed25519 or RSA), root only;
no port forwarding (ssh).
Storage
- cosmofs files are capped at 516128 blocks of 4 KiB (about 1.97 GiB...
CosmoOS 1.0.9
If you rolled back and forward on v1.0.8: run cosmo-upgrade --repair
On v1.0.8, cosmo-upgrade --rollback to v1.0.7, then v1.0.7's own
cosmo-upgrade --rollback forward again, left the root's record of its
base system (/var/lib/cosmo-upgrade/root-set) naming v1.0.7's set.
v1.0.8 trusted that record, so it refused every later upgrade (the root holds another set's base system than the current set's (a rollback half done): cosmo-upgrade --repair first), and its --repair found nothing
to do.
On such a system, run CosmoOS 1.0.9's cosmo-upgrade --repair once,
from the release's signed package, then upgrade as usual:
cosmo$ mkdir /tmp/up && cd /tmp/up
cosmo$ wget -q https://vkuttyp.github.io/CosmoOS/releases/v1.0.9/cosmoos-x86_64-cosmo-upgrade.cpk
cosmo$ pkg install -n ./cosmoos-x86_64-cosmo-upgrade.cpk
cosmo$ tar -xf cosmoos-x86_64-cosmo-upgrade.cpk sbin/cosmo-upgrade
cosmo$ ./sbin/cosmo-upgrade --repair
cosmo-upgrade: the root's record named the previous set's (v1.0.7, ...) base system, but its files are the current set's (v1.0.8, ...): record corrected
cosmo$ cd / && cosmo-upgrade --fetch v1.0.9
(aarch64 in place of x86_64 on an ARM machine.) --repair corrects
the record from the root's files and changes nothing else. A system that
never rolled back needs none of this: cosmo-upgrade --fetch v1.0.9.
From this release on, the record is checked, not trusted. Which set's
base system the root holds is told from the root's own files: the files
each kept boot set's boot.tar puts under /bin, /sbin, /usr, /lib
and the package repository, byte for byte (/etc is yours and is not
looked at). An upgrade is refused only when those files are the previous
set's -- a rollback really half done -- never on the record alone. When
the record disagrees with the files, cosmo-upgrade --list says so and
names both, and the upgrade, a rollback and --repair correct it. The
record now also names the release it describes and the set it was
written from, so a record an older cosmo-upgrade left behind is named
as such. cosmo-install writes it at install.
Fixes
- A long console write no longer stops a CPU's interrupts. The
console held its lock, with interrupts off, for the whole of one write
while every output device drew it.dmesgprints the kernel log in one
32 KiB write; drawn on the screen console, that kept one CPU without
interrupts for over a second, and another CPU waiting on it for a TLB
invalidation panicked (mmu: TLB shootdown ... acknowledged by 2 of 3 CPUs). A write is now passed on a line at a time. A virtio console
whose device stops answering still costs one 200 ms wait per write. pkgsays a downgrade is a downgrade.pkg install NAME=VERSION
to an older version saidNAME will be upgraded from 1.1 to 1.0; it
saysdowngraded.
Upgrading from v1.0.8
cosmo-upgrade --fetch v1.0.9 (after --repair as above, if you rolled
back and forward), reboot, then pkg update && pkg upgrade. This upgrade
takes a boot environment, so cosmo-upgrade --rollback returns the root
and the boot set as they were.
Tested: on every change and on both architectures, make test-upgrade,
whose test-be now includes the published v1.0.7 upgraded to this
build, rolled back, rolled forward by v1.0.7's own cosmo-upgrade, and
upgraded again; and on a Parallels virtual machine in that state, which
--repair cleared before it upgraded to this release.
About CosmoOS
CosmoOS 1.0.9: the 1.0 roadmap completed. CosmoOS installs to a disk, reboots into it, is used through BusyBox ash, keeps files across reboots, reaches the network by name, accepts an ssh login, and has a verified boot chain and sound randomness, on x86-64 and AArch64 under QEMU.
Start with the user guide. Each architecture's files: cosmoos-ARCH.img (the signed live image), its UEFI loader, kernel.elf, boot.tar, cmdline, the signed manifest, cosmo-upgrade and its signed package. SHA256SUMS.sig is SHA256SUMS's detached signature with the release key below (scripts/modsign.py verify-detached, or cosmo-verify on an installed system); check the files with sha256sum --ignore-missing -c SHA256SUMS.
Release signing key
The loader in these images verifies the kernel, boot archive and command line against this Ed25519 key (and the kernel trusts it for modules and packages):
- public key:
d2c778bcb38775790b6b6e843631bd2e76d6a29ec52296ece6e2d67c1bef41f8 - key id:
36ae7bb4947896ab(the first 8 bytes of SHA-512 of the key; the boot log prints it:verified boot, key 36ae7bb4947896ab) - in the repository:
tools/keys/release-2026.pub
Toolchain
Built and tested in the project's CI images (ci/Dockerfile), pinned by digest:
- toolchain:
ghcr.io/vkuttyp/cosmoos-ci@sha256:f6aee1470b952bdb426b8d55cfcccb734c9c1f4dac50c89edefba4e8be3be385 - litmus:
ghcr.io/vkuttyp/cosmoos-ci@sha256:c8b16f9c652cd99e4a557c08adc451528cc9cd36ba0e9e37b2973feffb15a5a9 - clang 1:19.0-63
- lld 1:19.0-63
- llvm 1:19.0-63
- qemu-system-x86 1:10.0.13+ds-0+deb13u1
- qemu-system-arm 1:10.0.13+ds-0+deb13u1
- ovmf 2025.02-8+deb13u1
- qemu-efi-aarch64 2025.02-8+deb13u1
- mtools 4.0.48-1
- python3 3.13.5-1
- clang-19 1:19.1.7-3+b1
- lld-19 1:19.1.7-3+b1
- llvm-19 1:19.1.7-3+b1
Third-party sources
Fetched and checked against these SHA-256 digests (ports/busybox/busybox.mk, ports/dropbear/dropbear.mk, ports/openssh/openssh.mk, ports/mbedtls/mbedtls.mk):
| Source | Version | SHA-256 |
|---|---|---|
| BusyBox | 1.37.0 | 3311dff32e746499f4df0d5df04d7eb396382d7e108bb9250e7b519b837043a4 |
| musl | 1.2.5 | a9a118bbe84d8764da0ea0d28b3ab3fae8477fc7e4085d90102b8596fc7c75e4 |
| compiler-rt | 19.1.7 | c12b6e764202c615c1a3af9a13d477846878757ae0e29e5f8979215a6958fffc |
| dropbear | 2026.94 | e098034a843699200c8c977a991fff73159735bf795d5f72ef672c41a6b1ae81 |
| OpenSSH portable (sftp-server only) | 10.6p1 | a9dc9565dffe8640f64d863cd29a32bc4a3dbdec0566a7fc44c5d6ee767d5f39 |
| mbedTLS | 3.6.7 | a7e8bcbec0e6f761b4af24f25677626b35f762f68eef79c08677a363212d11f6 |
| CA certificates (curl's extract of Mozilla's) | 2026-09-25 | a41b5d356aea97a529fe27e0f7316d2f9d946d75927476cf9cf1b90637d00505 |
Reproducibility
Each architecture was built twice from the tag v1.0.9, in two fresh containers of the toolchain image above, with the release key; every file below was identical in both:
- x86_64: two builds, 10 files each, identical; cosmoos-x86_64.img sha256 fb1541a6fd72aa1d2a68cb35d87cdaacaa1b6697eccbb2315a1f8119fc4a0c34
- aarch64: two builds, 10 files each, identical; cosmoos-aarch64.img sha256 b85c3810cfefa97c99728b3d9d9e5c72eea6652cc70f5931618a30cf5448a812
To rebuild: check out the tag, run the toolchain image above, and make ARCH=<arch> SIGNING=release MODSIGN_KEY=<key> KEYRING_PUBS=tools/keys/release-2026.pub release. Without the private key, a build with your own key differs in what the key reaches: the key ring compiled into the kernel and loader, the signatures on modules, packages and the manifest, and the archive and image that hold them.
SHA256SUMS
fb1541a6fd72aa1d2a68cb35d87cdaacaa1b6697eccbb2315a1f8119fc4a0c34 cosmoos-x86_64.img
115ef94c7916d2ba01ed3127701506beb2cc8199f6835a4e4489966fa34ffb67 cosmoos-x86_64-BOOTX64.EFI
e83d6e472bff260615596e5524a07f2aae08e239c86f33c9496828f4e0547389 cosmoos-x86_64-kernel.elf
0a0bb2f85086dd88debfadf2442950dd1ecf42c789e7919926543829547488e2 cosmoos-x86_64-boot.tar
7a77470be4312a22db40932c6cd8ddcd6d42a29b07101cbbe135cbfa1fc1aa14 cosmoos-x86_64-cmdline
991c47df43db1b9a0ece3dcc4ad34cb20abe6af55edf892fb2d53d3d03e53ed2 cosmoos-x86_64-manifest
341a4a4d4cb6948173b097980786019ac75b731302c4c63963441362d279cc14 cosmoos-x86_64-cosmo-upgrade
91a058c868f199c214bb2669a668f4a71336ff7014e9ea1355165f14f9a572f4 cosmoos-x86_64-cosmo-upgrade.cpk
b85c3810cfefa97c99728b3d9d9e5c72eea6652cc70f5931618a30cf5448a812 cosmoos-aarch64.img
0d00053d85654789deaf9fa0edc5cb8231d8d142140c1198bcb38cfedc8ff87e cosmoos-aarch64-BOOTAA64.EFI
cef949411f89dde38cb888e8afb13d5125d27a975e7afa63d770782744aa9425 cosmoos-aarch64-kernel.elf
3dbb5ff80c343909a4c01c2d505c343f013e0126580c0ce54fce88ec9a7ca986 cosmoos-aarch64-boot.tar
7a77470be4312a22db40932c6cd8ddcd6d42a29b07101cbbe135cbfa1fc1aa14 cosmoos-aarch64-cmdline
7a1f112c532cfe92f7716b9991cf8db052f645a8612f9ffecf9e69e89299c878 cosmoos-aarch64-manifest
7eeaecbdce8b2a353d88848cd8a8193dc74e6f1bafde7d7ce5666aa4835f75e1 cosmoos-aarch64-cosmo-upgrade
56e8567d2276b8cc69c626f25cc141d477def973a56ba27371cc35c05353dde3 cosmoos-aarch64-cosmo-upgrade.cpk
Known limitations
What CosmoOS 1.0 does not do, or does differently from what you may
expect. Each item names where it is recorded; the work that remains
after 1.0 is in docs/plan.md, and the full list of known
gaps in the deferred-work inventory.
Machines
- QEMU is the tested platform. x86-64 on
q35and AArch64 onvirt
are tested by CI; there is no physical hardware matrix. Since v1.0.1
the AArch64 image boots on Parallels Desktop 27 on Apple Silicon, and
since v1.0.3 installs on its NVMe disks and has a network there; its
SATA disks are not seen (Tested platforms). Out of scope for 1.0
(roadmap): GPU and display beyond a text console (on
the firmware's framebuffer, or a virtio-gpu adapter at the display's
own size: no 3D, cursor or display interface for programs), hotplug, NUMA, more than 64 CPUs, huge pages, live migration,
RAID-Z, eBPF, and the Intel VMX backend on hardware. - **Randomne...
CosmoOS 1.0.9-rc1
CosmoOS 1.0.9-rc1: the 1.0 roadmap completed. CosmoOS installs to a disk, reboots into it, is used through BusyBox ash, keeps files across reboots, reaches the network by name, accepts an ssh login, and has a verified boot chain and sound randomness, on x86-64 and AArch64 under QEMU.
Start with the user guide. Each architecture's files: cosmoos-ARCH.img (the signed live image), its UEFI loader, kernel.elf, boot.tar, cmdline, the signed manifest, cosmo-upgrade and its signed package. SHA256SUMS.sig is SHA256SUMS's detached signature with the release key below (scripts/modsign.py verify-detached, or cosmo-verify on an installed system); check the files with sha256sum --ignore-missing -c SHA256SUMS.
Release signing key
The loader in these images verifies the kernel, boot archive and command line against this Ed25519 key (and the kernel trusts it for modules and packages):
- public key:
d2c778bcb38775790b6b6e843631bd2e76d6a29ec52296ece6e2d67c1bef41f8 - key id:
36ae7bb4947896ab(the first 8 bytes of SHA-512 of the key; the boot log prints it:verified boot, key 36ae7bb4947896ab) - in the repository:
tools/keys/release-2026.pub
Toolchain
Built and tested in the project's CI images (ci/Dockerfile), pinned by digest:
- toolchain:
ghcr.io/vkuttyp/cosmoos-ci@sha256:f6aee1470b952bdb426b8d55cfcccb734c9c1f4dac50c89edefba4e8be3be385 - litmus:
ghcr.io/vkuttyp/cosmoos-ci@sha256:c8b16f9c652cd99e4a557c08adc451528cc9cd36ba0e9e37b2973feffb15a5a9 - clang 1:19.0-63
- lld 1:19.0-63
- llvm 1:19.0-63
- qemu-system-x86 1:10.0.13+ds-0+deb13u1
- qemu-system-arm 1:10.0.13+ds-0+deb13u1
- ovmf 2025.02-8+deb13u1
- qemu-efi-aarch64 2025.02-8+deb13u1
- mtools 4.0.48-1
- python3 3.13.5-1
- clang-19 1:19.1.7-3+b1
- lld-19 1:19.1.7-3+b1
- llvm-19 1:19.1.7-3+b1
Third-party sources
Fetched and checked against these SHA-256 digests (ports/busybox/busybox.mk, ports/dropbear/dropbear.mk, ports/openssh/openssh.mk, ports/mbedtls/mbedtls.mk):
| Source | Version | SHA-256 |
|---|---|---|
| BusyBox | 1.37.0 | 3311dff32e746499f4df0d5df04d7eb396382d7e108bb9250e7b519b837043a4 |
| musl | 1.2.5 | a9a118bbe84d8764da0ea0d28b3ab3fae8477fc7e4085d90102b8596fc7c75e4 |
| compiler-rt | 19.1.7 | c12b6e764202c615c1a3af9a13d477846878757ae0e29e5f8979215a6958fffc |
| dropbear | 2026.94 | e098034a843699200c8c977a991fff73159735bf795d5f72ef672c41a6b1ae81 |
| OpenSSH portable (sftp-server only) | 10.6p1 | a9dc9565dffe8640f64d863cd29a32bc4a3dbdec0566a7fc44c5d6ee767d5f39 |
| mbedTLS | 3.6.7 | a7e8bcbec0e6f761b4af24f25677626b35f762f68eef79c08677a363212d11f6 |
| CA certificates (curl's extract of Mozilla's) | 2026-09-25 | a41b5d356aea97a529fe27e0f7316d2f9d946d75927476cf9cf1b90637d00505 |
Reproducibility
Each architecture was built twice from the tag v1.0.9-rc1, in two fresh containers of the toolchain image above, with the release key; every file below was identical in both:
- x86_64: two builds, 10 files each, identical; cosmoos-x86_64.img sha256 047dc298b148c5d248ae459148c2be8fe810da7a7a9476514d44214a9a2592c4
- aarch64: two builds, 10 files each, identical; cosmoos-aarch64.img sha256 01a054eee85cbeadb5fa2f50f40775b68e325afa58a3e50b8f04046dc5b806b9
To rebuild: check out the tag, run the toolchain image above, and make ARCH=<arch> SIGNING=release MODSIGN_KEY=<key> KEYRING_PUBS=tools/keys/release-2026.pub release. Without the private key, a build with your own key differs in what the key reaches: the key ring compiled into the kernel and loader, the signatures on modules, packages and the manifest, and the archive and image that hold them.
SHA256SUMS
047dc298b148c5d248ae459148c2be8fe810da7a7a9476514d44214a9a2592c4 cosmoos-x86_64.img
115ef94c7916d2ba01ed3127701506beb2cc8199f6835a4e4489966fa34ffb67 cosmoos-x86_64-BOOTX64.EFI
964a856fd45a4fba2bdf0b943e9d580566168ef817cb00cff5050d551ef40655 cosmoos-x86_64-kernel.elf
0a0bb2f85086dd88debfadf2442950dd1ecf42c789e7919926543829547488e2 cosmoos-x86_64-boot.tar
7a77470be4312a22db40932c6cd8ddcd6d42a29b07101cbbe135cbfa1fc1aa14 cosmoos-x86_64-cmdline
5ce625bd6de98a82b413cbe993aa83fbcf02a99beefee6609158b061ad2e8bf9 cosmoos-x86_64-manifest
341a4a4d4cb6948173b097980786019ac75b731302c4c63963441362d279cc14 cosmoos-x86_64-cosmo-upgrade
6fc524a5b2d147c24cfa74d6f05ad3a7129b0a4d05da5406d5668b9d8c59c526 cosmoos-x86_64-cosmo-upgrade.cpk
01a054eee85cbeadb5fa2f50f40775b68e325afa58a3e50b8f04046dc5b806b9 cosmoos-aarch64.img
0d00053d85654789deaf9fa0edc5cb8231d8d142140c1198bcb38cfedc8ff87e cosmoos-aarch64-BOOTAA64.EFI
4f3fa5f87490c13e54cdcb1f5e2a683af00e546c1e9fcf18ef43d9acbe1600a7 cosmoos-aarch64-kernel.elf
3dbb5ff80c343909a4c01c2d505c343f013e0126580c0ce54fce88ec9a7ca986 cosmoos-aarch64-boot.tar
7a77470be4312a22db40932c6cd8ddcd6d42a29b07101cbbe135cbfa1fc1aa14 cosmoos-aarch64-cmdline
54d2df520f94d6ec9e56b8ebca86e661b0c2c5c9310ffa5a727e46f9bcd4fab3 cosmoos-aarch64-manifest
7eeaecbdce8b2a353d88848cd8a8193dc74e6f1bafde7d7ce5666aa4835f75e1 cosmoos-aarch64-cosmo-upgrade
7b953daf53df3916f386ce3fa574f4c33da05de2eec8b84955b12443fbb818ff cosmoos-aarch64-cosmo-upgrade.cpk
Known limitations
What CosmoOS 1.0 does not do, or does differently from what you may
expect. Each item names where it is recorded; the work that remains
after 1.0 is in docs/plan.md, and the full list of known
gaps in the deferred-work inventory.
Machines
- QEMU is the tested platform. x86-64 on
q35and AArch64 onvirt
are tested by CI; there is no physical hardware matrix. Since v1.0.1
the AArch64 image boots on Parallels Desktop 27 on Apple Silicon, and
since v1.0.3 installs on its NVMe disks and has a network there; its
SATA disks are not seen (Tested platforms). Out of scope for 1.0
(roadmap): GPU and display beyond a text console (on
the firmware's framebuffer, or a virtio-gpu adapter at the display's
own size: no 3D, cursor or display interface for programs), hotplug, NUMA, more than 64 CPUs, huge pages, live migration,
RAID-Z, eBPF, and the Intel VMX backend on hardware. - Randomness from the weakest source last. The pool seeds from the
CPU's random instructions, the firmware'sEFI_RNG_PROTOCOLor a
virtio-rng; with none of them (Parallels Desktop) a timing-jitter source
seeds it, credited conservatively (docs/kernel/security/design.md §6).
random.jitter=offon the command line turns that off, and the pool
then never seeds there. The commands in this guide add-device virtio-rng-pci. - The clock is stepped, not slewed. The wall clock is set at boot
from the RTC or, with none (Parallels), the firmware's time. Since
v1.0.4 root can set it (date -s,hwclock -wwhere there is an RTC)
andntpd -qsteps it once from a server; there is no NTP daemon,
becauseadjtimexis not implemented, and no time zone. - No Wi-Fi, Bluetooth or sound.
Boot and security
- Verified boot covers the loader's three files (kernel, boot archive,
command line). The root filesystem is not verified; the loader is
not signed for UEFI Secure Boot; there is no TPM measurement
and no rollback protection for manifests or modules (inventory
2.9). - No KASLR: the kernel is at a fixed address. User-space ASLR covers
the stack, heap,mmapand PIE executables; a non-PIE (ET_EXEC)
program loads at its fixed address. - One user, root. Privileges, not uids, separate what processes may
do (Privileges). A root session holding fewer
privileges can still rewrite files in/etcthat a later boot runs
with all of them (M5 report, inventory 2.9).
Shell and commands
- The commands are the BusyBox applets listed in the shell
page: noping6; no hard links; no/sys. /prochas the process directories and a fixed set of system files
(meminfo,stat,loadavg,uptime,mounts,version,
cpuinfo). A process has no nice value and no user/system split of its
CPU time;ps'sTTcolumn is a pair of Linux device numbers (5,1
for the console), since devices here have none of their own; and a
process'senvironis what exec gave it, not what it has since written
over (inventory §13).- The terminal driver honours the common modes (canonical input, echo,
signals, raw mode, window size); most other termios flags and control
characters are accepted and ignored (inventory 1.4). - No swap.
Networking
wget's certificate authorities are fixed in the image
(/etc/ssl/certs/ca-certificates.crt, as built); nothing updates them,
and there is no certificate revocation check
(Networking).- The address comes from DHCP. There is no runtime tool to set one by
hand;/etc/resolv.confis written once per boot, not on lease
renewal; the DHCP client does no ARP probe or DECLINE, no INIT-REBOOT,
no RELEASE, and ignores classless routes (option 121) (inventory 2.5). - IPv6 is link-local; there is no IPv6 routing beyond the link, no IP
fragmentation, and no TCP SACK, window scaling or timestamps
(inventory 2.5). - ssh is dropbear with key login only (Ed25519 or RSA), root only;
no port forwarding (ssh).
Storage
- cosmofs files are capped at 516128 blocks of 4 KiB (about 1.97 GiB),
64516 b...
CosmoOS 1.0.8
Upgrades can be fully undone
From this release on, cosmo-upgrade takes a snapshot of the root
before it writes anything -- a boot environment, be-<release> --
and pairs it with the boot set it ran on, in \cosmo\be on the system
partition. cosmo-upgrade --rollback then returns both halves: the boot
set at once, and the root -- packages, /etc and the base system,
byte for byte as they were -- at the reboot it starts itself.
- What you wrote is kept. Files added or changed under
/root,
/homeand/var/logsince the environment was taken are copied,
before any service starts, into/var/lib/cosmo/rollback/<the replaced tree>/. If they cannot all be copied, the replaced tree stays held
(it cannot be deleted) and the next boot tries again. - The replaced tree is an environment too: rolling back again goes
forward to it.cosmo-upgrade --listshows the environments and the
set each one pairs with; the newest two are kept, and--prune
deletes older ones. - A crash at any step boots. The intent is recorded in
\cosmo\be
before anything moves; whatever the machine boots afterwards -- the
newer kernel on the older root, or the older kernel on the newer one --
cosmo-upgrade --repairfinishes what was meant.--statussays when
a repair is needed. - Refused, with nothing written: an upgrade on a root without room
for the environment (the sentence names what is needed and what is
free), while a rollback of the root is pending, and when the root is
not the current set's.
There are no environments for v1.0.7 and earlier, and the upgrade to
v1.0.8 takes none. Those releases keep no snapshots, and their
cosmo-upgrade refuses a system partition that records environments,
which a rollback to one of them would leave behind. The first upgrade
that can be fully undone is the one made from v1.0.8. Rolling back
from v1.0.8 to v1.0.7 returns the boot set and the base system, as
before; packages pkg upgrade changed stay changed.
Package transactions
pkg install, upgrade, remove and rollback are each one
transaction: pkg snapshots the root first and deletes the snapshot when
it is done. If the machine stops in the middle -- pkg install a b with
a in place and b not -- the next boot rolls the root back to the
moment the transaction began, and reboots once to do so. pkg refuses
before changing anything when the root lacks the room.
pkg rollback NAME returns one package to the version installed
before the current one, with its files; the last two versions of each
package are kept in /var/cache/pkg/kept.
While \cosmo\prev holds v1.0.7 or older -- right after upgrading from
it -- pkg takes no snapshot and says so (no transaction: ...): the
first snapshot raises the root to cosmofs format 12, which those kernels
cannot mount. The same rule keeps the upgrade to v1.0.8 from taking an
environment.
Snapshots and rollback from the shell
cosmo-snap takes snapshots of the installed root, lists what each one
holds alone, shows what changed since (cosmo-snap diff), rolls the
system back to one, and makes writable clones. A rollback keeps the tree
it replaces as a snapshot, applies at the next mount, and holds that
snapshot -- it cannot be deleted -- until the boot completes. The guide's "Snapshots and rollback" page has the steps.
Fixes
- A write-back that fails partway keeps what it wrote. On a full
disk, a file closed while its last write-back failed could leave
blocks no file named (fsctl check: leaked) and, for a file
overwritten in place, free blocks the file still named. The inode is
now stored after every write-back, failed or not. - A foreground job owns the terminal from its first instruction. A
shell started fromcosmo-shcould stop itself withSIGTTINbefore
cosmo-shhanded it the terminal.
Known
pkg install -f NAME=VERSION to an older version says it is
"upgraded"; it is a downgrade (backlog PKG-9).
Rolling back and then forward leaves upgrades refused. After
cosmo-upgrade --rollback to v1.0.7 and v1.0.7's own cosmo-upgrade --rollback forward again, the root's record of its base system
(/var/lib/cosmo-upgrade/root-set) still names v1.0.7's set. This
release trusts that record: it refuses every later upgrade ("the root
holds another set's base system than the current set's (a rollback half
done)"), and its own --repair finds nothing to do. Nothing on the
system is wrong but the record. Run CosmoOS 1.0.9's cosmo-upgrade --repair once, from that release's signed cosmo-upgrade package, then
upgrade: see the v1.0.9 notes
and the guide's upgrading page.
Upgrading from v1.0.7
cosmo-upgrade --fetch v1.0.8, reboot, then pkg update && pkg upgrade. No boot environment is taken by this upgrade (above); the
next one is.
Tested: on every change and on both architectures, make test-upgrade
(the published v1.0.3 upgraded to this build and back; then
test-pkgtx's killed transactions and full root, and test-be: an
upgrade, pkg upgrade and a changed /etc rolled back byte for byte,
the operator's files kept, and a crash after each step), and make test-snapshot (a broken system rolled back, three kills during a
rollback, a clone).
About CosmoOS
CosmoOS 1.0.8: the 1.0 roadmap completed. CosmoOS installs to a disk, reboots into it, is used through BusyBox ash, keeps files across reboots, reaches the network by name, accepts an ssh login, and has a verified boot chain and sound randomness, on x86-64 and AArch64 under QEMU.
Start with the user guide. Each architecture's files: cosmoos-ARCH.img (the signed live image), its UEFI loader, kernel.elf, boot.tar, cmdline, the signed manifest, cosmo-upgrade and its signed package. SHA256SUMS.sig is SHA256SUMS's detached signature with the release key below (scripts/modsign.py verify-detached, or cosmo-verify on an installed system); check the files with sha256sum --ignore-missing -c SHA256SUMS.
Release signing key
The loader in these images verifies the kernel, boot archive and command line against this Ed25519 key (and the kernel trusts it for modules and packages):
- public key:
d2c778bcb38775790b6b6e843631bd2e76d6a29ec52296ece6e2d67c1bef41f8 - key id:
36ae7bb4947896ab(the first 8 bytes of SHA-512 of the key; the boot log prints it:verified boot, key 36ae7bb4947896ab) - in the repository:
tools/keys/release-2026.pub
Toolchain
Built and tested in the project's CI images (ci/Dockerfile), pinned by digest:
- toolchain:
ghcr.io/vkuttyp/cosmoos-ci@sha256:f6aee1470b952bdb426b8d55cfcccb734c9c1f4dac50c89edefba4e8be3be385 - litmus:
ghcr.io/vkuttyp/cosmoos-ci@sha256:c8b16f9c652cd99e4a557c08adc451528cc9cd36ba0e9e37b2973feffb15a5a9 - clang 1:19.0-63
- lld 1:19.0-63
- llvm 1:19.0-63
- qemu-system-x86 1:10.0.13+ds-0+deb13u1
- qemu-system-arm 1:10.0.13+ds-0+deb13u1
- ovmf 2025.02-8+deb13u1
- qemu-efi-aarch64 2025.02-8+deb13u1
- mtools 4.0.48-1
- python3 3.13.5-1
- clang-19 1:19.1.7-3+b1
- lld-19 1:19.1.7-3+b1
- llvm-19 1:19.1.7-3+b1
Third-party sources
Fetched and checked against these SHA-256 digests (ports/busybox/busybox.mk, ports/dropbear/dropbear.mk, ports/openssh/openssh.mk, ports/mbedtls/mbedtls.mk):
| Source | Version | SHA-256 |
|---|---|---|
| BusyBox | 1.37.0 | 3311dff32e746499f4df0d5df04d7eb396382d7e108bb9250e7b519b837043a4 |
| musl | 1.2.5 | a9a118bbe84d8764da0ea0d28b3ab3fae8477fc7e4085d90102b8596fc7c75e4 |
| compiler-rt | 19.1.7 | c12b6e764202c615c1a3af9a13d477846878757ae0e29e5f8979215a6958fffc |
| dropbear | 2026.94 | e098034a843699200c8c977a991fff73159735bf795d5f72ef672c41a6b1ae81 |
| OpenSSH portable (sftp-server only) | 10.6p1 | a9dc9565dffe8640f64d863cd29a32bc4a3dbdec0566a7fc44c5d6ee767d5f39 |
| mbedTLS | 3.6.7 | a7e8bcbec0e6f761b4af24f25677626b35f762f68eef79c08677a363212d11f6 |
| CA certificates (curl's extract of Mozilla's) | 2026-09-25 | a41b5d356aea97a529fe27e0f7316d2f9d946d75927476cf9cf1b90637d00505 |
Reproducibility
Each architecture was built twice from the tag v1.0.8, in two fresh containers of the toolchain image above, with the release key; every file below was identical in both:
- x86_64: two builds, 10 files each, identical; cosmoos-x86_64.img sha256 b8fcb78fb088847bd0c650d1814415e20be86437b091704079a62435a68a5282
- aarch64: two builds, 10 files each, identical; cosmoos-aarch64.img sha256 02e33a872c0d76cd23f4f80ebc09445f19694c469aabb03b06b58b2194ff22c8
To rebuild: check out the tag, run the toolchain image above, and make ARCH=<arch> SIGNING=release MODSIGN_KEY=<key> KEYRING_PUBS=tools/keys/release-2026.pub release. Without the private key, a build with your own key differs in what the key reaches: the key ring compiled into the kernel and loader, the signatures on modules, packages and the manifest, and the archive and image that hold them.
SHA256SUMS
b8fcb78fb088847bd0c650d1814415e20be86437b091704079a62435a68a5282 cosmoos-x86_64.img
115ef94c7916d2ba01ed3127701506beb2cc8199f6835a4e4489966fa34ffb67 cosmoos-x86_64-BOOTX64.EFI
f3c02a3b09d120ccdaba2ebb9d4bb7ced18dc555e5b338399d2e0861c3fdd291 cosmoos-x86_64-kernel.elf
829c5c632a62c5a1ce0de459bca8d2409ba8f6d2e096f53e9250da78e68dbcc1 cosmoos-x86_64-boot.tar
7a77470be4312a22db40932c6cd8ddcd6d42a29b07101cbbe135cbfa1fc1aa14 cosmoos-x86_64-cmdline
31c126b5c87115fb2748066194fc3e61bebd1b0b2b9fb858c7ad568105f6b548 cosmoos-x86_64-manifest
5752a899f9a7c7ea8f7836a9dd723ae70c12dd9187a4e0ab7048d57fd75056f4 cosmoos-x86_64-cosmo-upgrade
43e701eb448e992c5d29988b788a8429417c8e909fbbeb623f8c3970fc2119a9 cosmoos-x86_64-cosmo-upgrade.cpk
02e33a872c0d76cd23f4f80ebc09445f19694c469aabb03b06b58b2194ff22c8 cosmoos-aarch64.img
0d00053d85654789deaf9fa0edc5cb8231d8d...
CosmoOS 1.0.7
The package index lasts 90 days
The project's package index was signed for 30 days and renewed by a
weekly job. GitHub stops a scheduled job after 60 days without activity
in the repository, so a quiet repository would have left every installed
system's pkg update refusing an expired index. Now:
INDEX.90, signed for 90 days, sits beside the 30-dayINDEX;
both carry the same serial. This release'spkgreadsINDEX.90
first, andINDEXonly when the server has noINDEX.90. Both are
checked in the same way, and a replayed index is still refused.- Every release and pre-release signs both again, as the weekly job
does, and the release checklist starts the job by hand after a quiet
month. - An expired index is refused with one sentence, which names its
expiry and serial and says that the repository must be signed again.
pkgexits non-zero and keeps the stored index.
Systems on v1.0.6 need no action beyond their next pkg update. They
keep reading the 30-day INDEX, which is still signed weekly and at
every release. After moving to this release they read INDEX.90.
An installed system's /tmp is now mode 01777, so every user can write
there. It was 0755, owned by root.
Fixes from the Parallels test
- A large read is filled.
dd if=/dev/zero bs=1M count=4copies
four whole records. A read of a regular file or/dev/zeroused to
stop at 64 KiB. The read is one operation: another reader or a seek
on the same open file never lands in the middle of it. wgetrefusing a certificate now ends on the TLS library's reason.
Before, it addedwget: error getting response: Resource temporarily unavailable.- No free-count warning at mount: every mount of a cleanly unmounted
disk warned that the superblock's free count differed from the
bitmap's. The comparison now runs before the free-log replay, not after
it. - A Linux program's
writevis one write, as on Linux: a line a
program prints is no longer split on the console by a kernel message,
and a datagram socket sends the vector as one datagram. sftp's?link count is not a defect. It is how OpenSSH's own
client renders a long listing, as on Linux; the file's count on the
server is right (stat -c %h).
Shared libraries
Linux programs can now be dynamically linked against musl:
-
/lib/libc.so, which is also musl's dynamic linker, with
/lib/ld-musl-x86_64.so.1(orld-musl-aarch64.so.1) linking to it.
This is the interpreter every dynamic program names.dlopen,RUNPATH
and thread-local storage work. Libraries load at random addresses on
every run. -
/bin/busybox.dynis BusyBox dynamically linked, with a link for
each applet under/usr/bin. It passes the same scripted test and
BusyBox testsuite as the static/bin/busybox, which stays the shell.
/bincomes first inPATH, so nothing changes until you ask for it:cosmo$ /bin/busybox.dyn sh -c 'echo hello from a dynamic shell' cosmo$ PATH=/usr/bin:$PATH ls -l /libThe package
busybox-dyninstalls the same binary. -
The kernel tells the linker the truth.
AT_SECUREis set when the
effective ids are not the real ones, and musl then ignores
LD_LIBRARY_PATHandLD_PRELOAD.AT_HWCAPandAT_HWCAP2carry
the CPU's features.statreports a device number per mount. -
Text relocations are refused. A library that needs writable,
executable code cannot load under W^X, and the kernel log says to
build it-fPIC. -
pkgknows libraries. A package records the libraries it provides
and requires.pkg installrefuses a package whose library nothing
provides.pkg removerefuses to remove a library another package
still needs.
Native CosmoOS programs stay static.
Upgrading from v1.0.6
Run cosmo-upgrade --fetch v1.0.7 twice. The first run is v1.0.6's
program, which does not know /lib. It installs everything else,
including the new cosmo-upgrade. The second run uses that new program:
it finds the set already current, finishes, and adds /lib. Then reboot
and run pkg update && pkg upgrade. Without the second run the system
works, but /bin/busybox.dyn cannot start. From v1.0.5 and earlier,
follow the guide's "Fetching directly" page with this release's package.
Its cosmo-upgrade installs /lib in one run.
Tested: on every change and on both architectures, make test-busybox
(the static and the dynamic BusyBox, dlopen), make test-pkg-net (the
expiry sentence, INDEX.90 and the fallback to INDEX), make test-install (/tmp, no free-count warning) and make test-net-login
(the refused certificate, sftp).
About CosmoOS
CosmoOS 1.0.7: the 1.0 roadmap completed. CosmoOS installs to a disk, reboots into it, is used through BusyBox ash, keeps files across reboots, reaches the network by name, accepts an ssh login, and has a verified boot chain and sound randomness, on x86-64 and AArch64 under QEMU.
Start with the user guide. Each architecture's files: cosmoos-ARCH.img (the signed live image), its UEFI loader, kernel.elf, boot.tar, cmdline, the signed manifest, cosmo-upgrade and its signed package. SHA256SUMS.sig is SHA256SUMS's detached signature with the release key below (scripts/modsign.py verify-detached, or cosmo-verify on an installed system); check the files with sha256sum --ignore-missing -c SHA256SUMS.
Release signing key
The loader in these images verifies the kernel, boot archive and command line against this Ed25519 key (and the kernel trusts it for modules and packages):
- public key:
d2c778bcb38775790b6b6e843631bd2e76d6a29ec52296ece6e2d67c1bef41f8 - key id:
36ae7bb4947896ab(the first 8 bytes of SHA-512 of the key; the boot log prints it:verified boot, key 36ae7bb4947896ab) - in the repository:
tools/keys/release-2026.pub
Toolchain
Built and tested in the project's CI images (ci/Dockerfile), pinned by digest:
- toolchain:
ghcr.io/vkuttyp/cosmoos-ci@sha256:f6aee1470b952bdb426b8d55cfcccb734c9c1f4dac50c89edefba4e8be3be385 - litmus:
ghcr.io/vkuttyp/cosmoos-ci@sha256:c8b16f9c652cd99e4a557c08adc451528cc9cd36ba0e9e37b2973feffb15a5a9 - clang 1:19.0-63
- lld 1:19.0-63
- llvm 1:19.0-63
- qemu-system-x86 1:10.0.13+ds-0+deb13u1
- qemu-system-arm 1:10.0.13+ds-0+deb13u1
- ovmf 2025.02-8+deb13u1
- qemu-efi-aarch64 2025.02-8+deb13u1
- mtools 4.0.48-1
- python3 3.13.5-1
- clang-19 1:19.1.7-3+b1
- lld-19 1:19.1.7-3+b1
- llvm-19 1:19.1.7-3+b1
Third-party sources
Fetched and checked against these SHA-256 digests (ports/busybox/busybox.mk, ports/dropbear/dropbear.mk, ports/openssh/openssh.mk, ports/mbedtls/mbedtls.mk):
| Source | Version | SHA-256 |
|---|---|---|
| BusyBox | 1.37.0 | 3311dff32e746499f4df0d5df04d7eb396382d7e108bb9250e7b519b837043a4 |
| musl | 1.2.5 | a9a118bbe84d8764da0ea0d28b3ab3fae8477fc7e4085d90102b8596fc7c75e4 |
| compiler-rt | 19.1.7 | c12b6e764202c615c1a3af9a13d477846878757ae0e29e5f8979215a6958fffc |
| dropbear | 2026.94 | e098034a843699200c8c977a991fff73159735bf795d5f72ef672c41a6b1ae81 |
| OpenSSH portable (sftp-server only) | 10.6p1 | a9dc9565dffe8640f64d863cd29a32bc4a3dbdec0566a7fc44c5d6ee767d5f39 |
| mbedTLS | 3.6.7 | a7e8bcbec0e6f761b4af24f25677626b35f762f68eef79c08677a363212d11f6 |
| CA certificates (curl's extract of Mozilla's) | 2026-09-25 | a41b5d356aea97a529fe27e0f7316d2f9d946d75927476cf9cf1b90637d00505 |
Reproducibility
Each architecture was built twice from the tag v1.0.7, in two fresh containers of the toolchain image above, with the release key; every file below was identical in both:
- x86_64: two builds, 10 files each, identical; cosmoos-x86_64.img sha256 d6402ad061794d0d0df5b6d359532156e2312e398ca4cdf10d990689de779f34
- aarch64: two builds, 10 files each, identical; cosmoos-aarch64.img sha256 4781f61b65840258f887d5e384ba48cb105474336a5fd5e948b0ccdcce70e6e5
To rebuild: check out the tag, run the toolchain image above, and make ARCH=<arch> SIGNING=release MODSIGN_KEY=<key> KEYRING_PUBS=tools/keys/release-2026.pub release. Without the private key, a build with your own key differs in what the key reaches: the key ring compiled into the kernel and loader, the signatures on modules, packages and the manifest, and the archive and image that hold them.
SHA256SUMS
d6402ad061794d0d0df5b6d359532156e2312e398ca4cdf10d990689de779f34 cosmoos-x86_64.img
115ef94c7916d2ba01ed3127701506beb2cc8199f6835a4e4489966fa34ffb67 cosmoos-x86_64-BOOTX64.EFI
2d22b4e133071f93919bb0ca605a0a9e226261d435c30d29d553dbc5d8faa245 cosmoos-x86_64-kernel.elf
0372e739d19ce38df510b1c5260349daa39673863f7194ab9d235930909dc7f3 cosmoos-x86_64-boot.tar
7a77470be4312a22db40932c6cd8ddcd6d42a29b07101cbbe135cbfa1fc1aa14 cosmoos-x86_64-cmdline
e065a006cf80fddbdad1f8f21ca89740355fb05b7440e3bb2feaf84911f1e85e cosmoos-x86_64-manifest
78ed33b1b37f95103b1d5445396cdd7b4d414b96e16ba1bc0a4191a24ae3a16b cosmoos-x86_64-cosmo-upgrade
2ebce34d1bba4b065a7da396a57c7f41531c722e116c8b7b86b104793a47c88e cosmoos-x86_64-cosmo-upgrade.cpk
4781f61b65840258f887d5e384ba48cb105474336a5fd5e948b0ccdcce70e6e5 cosmoos-aarch64.img
0d00053d85654789deaf9fa0edc5cb8231d8d142140c1198bcb38cfedc8ff87e cosmoos-aarch64-BOOTAA64.EFI
23dc87987acae3cd537813f804b2ea56803cc55a26e6ce421c5257728cb262ae cosmoos-aarch64-kernel.elf
bf1357a0c748f841de762e69ea55260451739ac3d3d2a0a887dd5a06404a6b3e cosmoos-aarch64-boot.tar
7a77470be4312a22db40932c6cd8ddcd6d42a29b07101cbbe135cbfa1fc1aa14 cosmoos-aarch64-cmdline
851e8df9b83811bb825026a24e54139d9bd535fbb0ad7a6451c6da7699787739 cosmoos-aarch64-manifest
84729ab387e6355713c533d1cc63f126c861507c5c725924bab1cca079c328bd cosmoos-aarch64-cosmo-upgrade
bd9401af2a36481369df0ab58ac303c689086172f9c487c7f616d906fd053737 cosmoos-aarch64-cosmo-upgrade.cpk
Known limita...
CosmoOS 1.0.6
pkg and cosmo-upgrade fetch directly
An installed system now updates over the network, with nothing to fetch
by hand:
cosmo$ pkg update && pkg upgrade
cosmo$ cosmo-upgrade --check
cosmo$ cosmo-upgrade --fetch v1.0.7
- The project's repository and release index are published on GitHub
Pages,https://vkuttyp.github.io/CosmoOS/: each architecture's package
repository underrepo/ARCH/, each release's upgrade set under
releases/TAG/(without the images), andreleases/LATEST. A fresh
install's/etc/pkg/repos.confnames the network repository after the
disk's own;/etc/cosmo-release.confnames the release index. - HTTPS with the certificate checked: both programs run
/bin/cosmo-fetch, which makes the same checks aswget(the server's
certificate must chain to the Mozilla CA bundle in
/etc/ssl/certs/ca-certificates.crt, be valid now, and name the host),
all before it sends a request. Arepos.confline can also pin the
server's key (pin sha256:HEX). Plainhttp://is refused unless the
line saysinsecure. Redirects are followed only to the same host.
Transfers that are cut resume. - A fresh index or none: a network repository's index carries a
serial number, a publication time and an expiry (at most 30 days).pkg updaterefuses one older than the last it accepted (a replay), and one
that has expired, so an attacker who can only replay old signed files
cannot hold back an update for long. The project re-signs its index
weekly. A clock before the index's publication is reported with a hint
(date -s), not accepted. A repository that cannot be reached is only
a warning; the disk's packages still install. cosmo-upgrade --fetch TAGfetches the release'sSHA256SUMSand
its signature first, checks them against/etc/pkg/keys, then fetches
the four set files and upgrades exactly as from a directory, with every
check made again.cosmo-upgrade --checksays whether a newer release
is published.- Privileges:
pkg install,upgradeandremoveneed the
sys_adminprivilege;pkg update,search,infoandlistdo not.
Upgrading from v1.0.5 and earlier
These releases have no cosmo-fetch. Fetch this release's
cosmoos-ARCH-cosmo-upgrade.cpk (ARCH is x86_64 or aarch64) with wget from
https://vkuttyp.github.io/CosmoOS/releases/v1.0.6/, check it with pkg install -n, unpack sbin/cosmo-upgrade and bin/cosmo-fetch, and run
COSMO_FETCH=./bin/cosmo-fetch ./sbin/cosmo-upgrade --fetch v1.0.6
(the guide's "Upgrading" page, "Fetching directly"). Afterwards add the
network repository to the /etc/pkg/repos.conf the older installer
wrote: the first line on x86-64, the second on AArch64 (one of them):
cosmo$ echo 'cosmoos https://vkuttyp.github.io/CosmoOS/repo/x86_64' >> /etc/pkg/repos.conf
cosmo$ echo 'cosmoos https://vkuttyp.github.io/CosmoOS/repo/aarch64' >> /etc/pkg/repos.conf
Tested: make test-pkg-net on x86-64 and AArch64, on every change. The
installed system runs against repositories the test serves over HTTPS:
it refuses untrusted, expired and misnamed certificates with no request
sent, and refuses a changed package, an index signed by another key, and
a replayed or expired index. It installs and upgrades from the served
repository, fetches a release set with cosmo-upgrade, and then runs
pkg update against the published repository itself.
About CosmoOS
CosmoOS 1.0.6: the 1.0 roadmap completed. CosmoOS installs to a disk, reboots into it, is used through BusyBox ash, keeps files across reboots, reaches the network by name, accepts an ssh login, and has a verified boot chain and sound randomness, on x86-64 and AArch64 under QEMU.
Start with the user guide. Each architecture's files: cosmoos-ARCH.img (the signed live image), its UEFI loader, kernel.elf, boot.tar, cmdline, the signed manifest, cosmo-upgrade and its signed package. SHA256SUMS.sig is SHA256SUMS's detached signature with the release key below (scripts/modsign.py verify-detached, or cosmo-verify on an installed system); check the files with sha256sum --ignore-missing -c SHA256SUMS.
Release signing key
The loader in these images verifies the kernel, boot archive and command line against this Ed25519 key (and the kernel trusts it for modules and packages):
- public key:
d2c778bcb38775790b6b6e843631bd2e76d6a29ec52296ece6e2d67c1bef41f8 - key id:
36ae7bb4947896ab(the first 8 bytes of SHA-512 of the key; the boot log prints it:verified boot, key 36ae7bb4947896ab) - in the repository:
tools/keys/release-2026.pub
Toolchain
Built and tested in the project's CI images (ci/Dockerfile), pinned by digest:
- toolchain:
ghcr.io/vkuttyp/cosmoos-ci@sha256:f6aee1470b952bdb426b8d55cfcccb734c9c1f4dac50c89edefba4e8be3be385 - litmus:
ghcr.io/vkuttyp/cosmoos-ci@sha256:c8b16f9c652cd99e4a557c08adc451528cc9cd36ba0e9e37b2973feffb15a5a9 - clang 1:19.0-63
- lld 1:19.0-63
- llvm 1:19.0-63
- qemu-system-x86 1:10.0.13+ds-0+deb13u1
- qemu-system-arm 1:10.0.13+ds-0+deb13u1
- ovmf 2025.02-8+deb13u1
- qemu-efi-aarch64 2025.02-8+deb13u1
- mtools 4.0.48-1
- python3 3.13.5-1
- clang-19 1:19.1.7-3+b1
- lld-19 1:19.1.7-3+b1
- llvm-19 1:19.1.7-3+b1
Third-party sources
Fetched and checked against these SHA-256 digests (ports/busybox/busybox.mk, ports/dropbear/dropbear.mk, ports/openssh/openssh.mk, ports/mbedtls/mbedtls.mk):
| Source | Version | SHA-256 |
|---|---|---|
| BusyBox | 1.37.0 | 3311dff32e746499f4df0d5df04d7eb396382d7e108bb9250e7b519b837043a4 |
| musl | 1.2.5 | a9a118bbe84d8764da0ea0d28b3ab3fae8477fc7e4085d90102b8596fc7c75e4 |
| compiler-rt | 19.1.7 | c12b6e764202c615c1a3af9a13d477846878757ae0e29e5f8979215a6958fffc |
| dropbear | 2026.94 | e098034a843699200c8c977a991fff73159735bf795d5f72ef672c41a6b1ae81 |
| OpenSSH portable (sftp-server only) | 10.6p1 | a9dc9565dffe8640f64d863cd29a32bc4a3dbdec0566a7fc44c5d6ee767d5f39 |
| mbedTLS | 3.6.7 | a7e8bcbec0e6f761b4af24f25677626b35f762f68eef79c08677a363212d11f6 |
| CA certificates (curl's extract of Mozilla's) | 2026-09-25 | a41b5d356aea97a529fe27e0f7316d2f9d946d75927476cf9cf1b90637d00505 |
Reproducibility
Each architecture was built twice from the tag v1.0.6, in two fresh containers of the toolchain image above, with the release key; every file below was identical in both:
- x86_64: two builds, 10 files each, identical; cosmoos-x86_64.img sha256 f2f6cd791733a0342b08e25559c7a39c5aa30f372be417afb85b253cb8b59b88
- aarch64: two builds, 10 files each, identical; cosmoos-aarch64.img sha256 01cff05e15f519368304eb8e64337fd3fe4c1c0b57813ed6c6df5622016bcb1e
To rebuild: check out the tag, run the toolchain image above, and make ARCH=<arch> SIGNING=release MODSIGN_KEY=<key> KEYRING_PUBS=tools/keys/release-2026.pub release. Without the private key, a build with your own key differs in what the key reaches: the key ring compiled into the kernel and loader, the signatures on modules, packages and the manifest, and the archive and image that hold them.
SHA256SUMS
f2f6cd791733a0342b08e25559c7a39c5aa30f372be417afb85b253cb8b59b88 cosmoos-x86_64.img
115ef94c7916d2ba01ed3127701506beb2cc8199f6835a4e4489966fa34ffb67 cosmoos-x86_64-BOOTX64.EFI
58533eb6c3184af7882259bb02ccde314b6b57143360c010c5c8a3a9f4f43461 cosmoos-x86_64-kernel.elf
3672af10d24bdbecb774fe47108df80339c01536558b676cc0d45ac7a5f1a875 cosmoos-x86_64-boot.tar
7a77470be4312a22db40932c6cd8ddcd6d42a29b07101cbbe135cbfa1fc1aa14 cosmoos-x86_64-cmdline
e9941d30604f30a5964877b5228c4d55e7e2d4763bab5337728296c00fc14464 cosmoos-x86_64-manifest
bc3504296324bc52a7e6c539e88eebdc33b23a59eab6c09795b23ef182799387 cosmoos-x86_64-cosmo-upgrade
36d58063f39f4881e93a162cbdc192a3ae7391fd4fdb9742564ab3e0d0c5da31 cosmoos-x86_64-cosmo-upgrade.cpk
01cff05e15f519368304eb8e64337fd3fe4c1c0b57813ed6c6df5622016bcb1e cosmoos-aarch64.img
0d00053d85654789deaf9fa0edc5cb8231d8d142140c1198bcb38cfedc8ff87e cosmoos-aarch64-BOOTAA64.EFI
720eaeb1becc1436f3a0b7a5995f2b9da0ebb9a1074c9f1c2f36092c81b12a31 cosmoos-aarch64-kernel.elf
904df2a25701bfd23eb3bef303d58621b10c31eab1d806510f13f20e3bb2d5f3 cosmoos-aarch64-boot.tar
7a77470be4312a22db40932c6cd8ddcd6d42a29b07101cbbe135cbfa1fc1aa14 cosmoos-aarch64-cmdline
51916effad612aa9aa930c6d181ba058112862755d543d6b42262f9ac275a0bf cosmoos-aarch64-manifest
59dd09e9603b4f15107d5dbe5ee38945a491b30f3801189f6552641fc30ad1a2 cosmoos-aarch64-cosmo-upgrade
f5445833e03d5a4e329b6fb0e5d15c29f05962186e190863dee710214373ce14 cosmoos-aarch64-cosmo-upgrade.cpk
Known limitations
What CosmoOS 1.0 does not do, or does differently from what you may
expect. Each item names where it is recorded; the work that remains
after 1.0 is in docs/plan.md, and the full list of known
gaps in the deferred-work inventory.
Machines
- QEMU is the tested platform. x86-64 on
q35and AArch64 onvirt
are tested by CI; there is no physical hardware matrix. Since v1.0.1
the AArch64 image boots on Parallels Desktop 27 on Apple Silicon, and
since v1.0.3 installs on its NVMe disks and has a network there; its
SATA disks are not seen (Tested platforms). Out of scope for 1.0
(roadmap): GPU and display beyond a text console (on
the firmware's framebuffer, or a virtio-gpu adapter at the display's
own size: no 3D, cursor or display interface for programs), hotplug, NUMA, more than 64 CPUs, huge pages, live migration,
RAID-Z, eBPF, and the Intel VMX backend on hardware. - **Randomness from the weakest source last....