SCFF, the SchOS Compressed File Format (include/fs/scff.h), is a block image cut into 128 KB chunks, each its own zstd frame, behind an index. tools/mkscff writes it from fs-ram.img on every core (-19, 11 s) and checks each chunk decompresses to itself. The kernel carries the .scff as its ramdisk and unpacks a chunk the first time a block in it is read; zero blocks share one page. The kernel and the ISO are the compressed size, and the root costs memory only for what is touched. See docs/architecture/scff.md. zstd 1.5.7 comes from ports/zstd like uACPI: the decoder is compiled into the kernel at -O2, with a static context and a 64 KB stack of its own, and mkscff builds the whole library from the same release. world now has xorg-server, the fbdev and evdev drivers, xinit, Window Maker, xterm and DejaVu, and /root/.xinitrc runs wmaker. That root is 358 MB, 102 MB as SCFF. The ISO no longer carries the root a third time as an ISO 9660 tree, which nothing read. schos.iso: 1389 MB -> 318 MB. El Torito keeps its own copy of the EFI image, the layout real machines have booted. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01S1giNvrHTrPMPw7V6x1kQ4
54 lines
2 KiB
C
54 lines
2 KiB
C
// SPDX-License-Identifier: GPL-2.0-or-later
|
|
// SCFF, the SchOS Compressed File Format: a block image cut into chunks, each
|
|
// compressed on its own, with an index in front.
|
|
//
|
|
// It is what the live root is shipped as. The kernel carries the compressed
|
|
// image and decompresses a chunk the first time any block in it is read, so
|
|
// the kernel and the ISO are the compressed size, and the memory the root
|
|
// takes is what has been touched, not the whole of it. See kernel/dev/ramdisk.c
|
|
// for the reader and tools/mkscff.c for the writer; this header is the one
|
|
// definition of the layout both of them use.
|
|
//
|
|
// offset 0 struct scff_header
|
|
// index_off uint64_t off[nchunks + 1], from the start of the file
|
|
// off[i]..off[i+1] chunk i
|
|
//
|
|
// A chunk is chunk_bytes of the image (the last one may be shorter). Its
|
|
// stored length says how it is kept:
|
|
//
|
|
// 0 every byte is zero, and nothing is stored
|
|
// its full length stored as it is: it did not compress
|
|
// anything else one zstd frame
|
|
//
|
|
// Little-endian throughout, which is every machine SchOS runs on.
|
|
|
|
#ifndef SCHOS_FS_SCFF_H
|
|
#define SCHOS_FS_SCFF_H
|
|
|
|
#include <stdint.h>
|
|
|
|
#define SCFF_MAGIC "SCFF"
|
|
#define SCFF_VERSION 1
|
|
#define SCFF_CODEC_ZSTD 1
|
|
|
|
// The kernel decompresses one chunk at a time into a buffer this big, so it
|
|
// is the largest chunk a reader accepts. 128 KB is squashfs's default and
|
|
// the point past which a bigger chunk buys little ratio for a lot of
|
|
// decompression on every miss.
|
|
#define SCFF_CHUNK_MAX (1u << 20)
|
|
|
|
struct scff_header {
|
|
char magic[4]; // "SCFF"
|
|
uint16_t version; // SCFF_VERSION
|
|
uint16_t codec; // SCFF_CODEC_ZSTD
|
|
uint32_t chunk_bytes; // a power of two, a multiple of 4096, <= SCFF_CHUNK_MAX
|
|
uint32_t nchunks;
|
|
uint64_t image_bytes; // the uncompressed image
|
|
uint64_t index_off;
|
|
uint64_t stored_bytes; // the whole file, header and index included
|
|
uint8_t reserved[24];
|
|
};
|
|
|
|
_Static_assert(sizeof(struct scff_header) == 64, "scff_header is 64 bytes");
|
|
|
|
#endif
|