Notes on Filesystem Layout -------------------------- These notes describe what mkcramfs generates. Kernel requirements are a bit looser, e.g. it doesn't care if the items are swapped around (though it does care that directory entries (inodes) in a given directory are contiguous, as this is used by readdir). All data is currently in host-endian format; neither mkcramfs nor the kernel ever do swabbing. (See section `Block Size' below.) : : struct cramfs_super (see cramfs_fs.h). : For each file: struct cramfs_inode (see cramfs_fs.h). Filename. Not generally null-terminated, but it is null-padded to a multiple of 4 bytes. The order of inode traversal is described as "width-first" (not to be confused with breadth-first); i.e. like depth-first but listing all of a directory's entries before recursing down its subdirectories: the same order as `ls -AUR' (but without the /^\..*:$/ directory header lines); put another way, the same order as `find -type d -exec ls -AU1 {} \;'. Beginning in 2.4.7, directory entries are sorted. This optimization allows cramfs_lookup to return more quickly when a filename does not exist, speeds up user-space directory sorts, etc. : One for each file that's either a symlink or a regular file of non-zero st_size. : nblocks * (where nblocks = (st_size - 1) / blksize + 1) nblocks * padding to multiple of 4 bytes The i'th for a file stores the byte offset of the *end* of the i'th (i.e. one past the last byte, which is the same as the start of the (i+1)'th if there is one). The first immediately follows the last for the file. s are each 32 bits long. When the CRAMFS_FLAG_EXT_BLOCK_POINTERS capability bit is set, each 's top bits may contain special flags as follows: CRAMFS_BLK_FLAG_UNCOMPRESSED (bit 31): The block data is not compressed and should be copied verbatim. CRAMFS_BLK_FLAG_DIRECT_PTR (bit 30): The stores the actual block start offset and not its end, shifted right by 2 bits. The block must therefore be aligned to a 4-byte boundary. The block size is either blksize if CRAMFS_BLK_FLAG_UNCOMPRESSED is also specified, otherwise the compressed data length is included in the first 2 bytes of the block data. This is used to allow discontiguous data layout and specific data block alignments e.g. for XIP applications. The order of 's is a depth-first descent of the directory tree, i.e. the same order as `find -size +0 \( -type f -o -type l \) -print'. : The i'th is the output of zlib's compress function applied to the i'th blksize-sized chunk of the input data if the corresponding CRAMFS_BLK_FLAG_UNCOMPRESSED bit is not set, otherwise it is the input data directly. (For the last of the file, the input may of course be smaller.) Each may be a different size. (See above.) s are merely byte-aligned, not generally u32-aligned. When CRAMFS_BLK_FLAG_DIRECT_PTR is specified then the corresponding may be located anywhere and not necessarily contiguous with the previous/next blocks. In that case it is minimally u32-aligned. If CRAMFS_BLK_FLAG_UNCOMPRESSED is also specified then the size is always blksize except for the last block which is limited by the file length. If CRAMFS_BLK_FLAG_DIRECT_PTR is set and CRAMFS_BLK_FLAG_UNCOMPRESSED is not set then the first 2 bytes of the block contains the size of the remaining block data as this cannot be determined from the placement of logically adjacent blocks. Holes ----- This kernel supports cramfs holes (i.e. [efficient representation of] blocks in uncompressed data consisting entirely of NUL bytes), but by default mkcramfs doesn't test for & create holes, since cramfs in kernels up to at least 2.3.39 didn't support holes. Run mkcramfs with -z if you want it to create files that can have holes in them. Tools ----- The cramfs user-space tools, including mkcramfs and cramfsck, are located at .