1Notes on Filesystem Layout 2-------------------------- 3 4These notes describe what mkcramfs generates. Kernel requirements are 5a bit looser, e.g. it doesn't care if the <file_data> items are 6swapped around (though it does care that directory entries (inodes) in 7a given directory are contiguous, as this is used by readdir). 8 9All data is currently in host-endian format; neither mkcramfs nor the 10kernel ever do swabbing. (See section `Block Size' below.) 11 12<filesystem>: 13 <superblock> 14 <directory_structure> 15 <data> 16 17<superblock>: struct cramfs_super (see cramfs_fs.h). 18 19<directory_structure>: 20 For each file: 21 struct cramfs_inode (see cramfs_fs.h). 22 Filename. Not generally null-terminated, but it is 23 null-padded to a multiple of 4 bytes. 24 25The order of inode traversal is described as "width-first" (not to be 26confused with breadth-first); i.e. like depth-first but listing all of 27a directory's entries before recursing down its subdirectories: the 28same order as `ls -AUR' (but without the /^\..*:$/ directory header 29lines); put another way, the same order as `find -type d -exec 30ls -AU1 {} \;'. 31 32Beginning in 2.4.7, directory entries are sorted. This optimization 33allows cramfs_lookup to return more quickly when a filename does not 34exist, speeds up user-space directory sorts, etc. 35 36<data>: 37 One <file_data> for each file that's either a symlink or a 38 regular file of non-zero st_size. 39 40<file_data>: 41 nblocks * <block_pointer> 42 (where nblocks = (st_size - 1) / blksize + 1) 43 nblocks * <block> 44 padding to multiple of 4 bytes 45 46The i'th <block_pointer> for a file stores the byte offset of the 47*end* of the i'th <block> (i.e. one past the last byte, which is the 48same as the start of the (i+1)'th <block> if there is one). The first 49<block> immediately follows the last <block_pointer> for the file. 50<block_pointer>s are each 32 bits long. 51 52When the CRAMFS_FLAG_EXT_BLOCK_POINTERS capability bit is set, each 53<block_pointer>'s top bits may contain special flags as follows: 54 55CRAMFS_BLK_FLAG_UNCOMPRESSED (bit 31): 56 The block data is not compressed and should be copied verbatim. 57 58CRAMFS_BLK_FLAG_DIRECT_PTR (bit 30): 59 The <block_pointer> stores the actual block start offset and not 60 its end, shifted right by 2 bits. The block must therefore be 61 aligned to a 4-byte boundary. The block size is either blksize 62 if CRAMFS_BLK_FLAG_UNCOMPRESSED is also specified, otherwise 63 the compressed data length is included in the first 2 bytes of 64 the block data. This is used to allow discontiguous data layout 65 and specific data block alignments e.g. for XIP applications. 66 67 68The order of <file_data>'s is a depth-first descent of the directory 69tree, i.e. the same order as `find -size +0 \( -type f -o -type l \) 70-print'. 71 72 73<block>: The i'th <block> is the output of zlib's compress function 74applied to the i'th blksize-sized chunk of the input data if the 75corresponding CRAMFS_BLK_FLAG_UNCOMPRESSED <block_ptr> bit is not set, 76otherwise it is the input data directly. 77(For the last <block> of the file, the input may of course be smaller.) 78Each <block> may be a different size. (See <block_pointer> above.) 79 80<block>s are merely byte-aligned, not generally u32-aligned. 81 82When CRAMFS_BLK_FLAG_DIRECT_PTR is specified then the corresponding 83<block> may be located anywhere and not necessarily contiguous with 84the previous/next blocks. In that case it is minimally u32-aligned. 85If CRAMFS_BLK_FLAG_UNCOMPRESSED is also specified then the size is always 86blksize except for the last block which is limited by the file length. 87If CRAMFS_BLK_FLAG_DIRECT_PTR is set and CRAMFS_BLK_FLAG_UNCOMPRESSED 88is not set then the first 2 bytes of the block contains the size of the 89remaining block data as this cannot be determined from the placement of 90logically adjacent blocks. 91 92 93Holes 94----- 95 96This kernel supports cramfs holes (i.e. [efficient representation of] 97blocks in uncompressed data consisting entirely of NUL bytes), but by 98default mkcramfs doesn't test for & create holes, since cramfs in 99kernels up to at least 2.3.39 didn't support holes. Run mkcramfs 100with -z if you want it to create files that can have holes in them. 101 102 103Tools 104----- 105 106The cramfs user-space tools, including mkcramfs and cramfsck, are 107located at <https://github.com/npitre/cramfs-tools>. 108