// 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 #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