📄 readme
字号:
Notes on Filesystem Layout--------------------------These notes describe what mkcramfs generates. Kernel requirements area bit looser, e.g. it doesn't care if the <file_data> items areswapped around (though it does care that directory entries (inodes) ina given directory are contiguous, as this is used by readdir).All data is in host-endian format; neither mkcramfs nor the kernelever do swabbing. (See section `Block Size' below.)<filesystem>: <superblock> <directory_structure> <data><superblock>: struct cramfs_super (see cramfs_fs.h).<directory_structure>: 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 beconfused with breadth-first); i.e. like depth-first but listing all ofa directory's entries before recursing down its subdirectories: thesame order as `ls -AUR' (but without the /^\..*:$/ directory headerlines); put another way, the same order as `find -type d -execls -AU1 {} \;'.<data>: One <file_data> for each file that's either a symlink or a regular file of non-zero st_size.<file_data>: nblocks * <block_pointer> (where nblocks = (st_size - 1) / blksize + 1) nblocks * <block> padding to multiple of 4 bytesThe i'th <block_pointer> for a file stores the byte offset of the*end* of the i'th <block> (i.e. one past the last byte, which is thesame as the start of the (i+1)'th <block> if there is one). The first<block> immediately follows the last <block_pointer> for the file.<block_pointer>s are each 32 bits long.The order of <file_data>'s is a depth-first descent of the directorytree, i.e. the same order as `find -size +0 \( -type f -o -type l \)-print'.<block>: The i'th <block> is the output of zlib's compress functionapplied to the i'th blksize-sized chunk of the input data.(For the last <block> of the file, the input may of course be smaller.)Each <block> may be a different size. (See <block_pointer> above.)<block>s are merely byte-aligned, not generally u32-aligned.Holes-----This kernel supports cramfs holes (i.e. [efficient representation of]blocks in uncompressed data consisting entirely of NUL bytes), but bydefault mkcramfs doesn't test for & create holes, since cramfs inkernels up to at least 2.3.39 didn't support holes. Compile mkcramfswith -DDO_HOLES if you want it to create files that can have holes inthem.Tools-----If you're hacking on cramfs, you might find useful some tools fortesting cramfs at <http://cvs.bofh.asn.au/cramfs/>, including arudimentary fsck for cramfs.Future Development==================Block Size----------(Block size in cramfs refers to the size of input data that iscompressed at a time. It's intended to be somewhere aroundPAGE_CACHE_SIZE for cramfs_readpage's convenience.)The superblock ought to indicate the block size that the fs waswritten for, since comments in <linux/pagemap.h> indicate thatPAGE_CACHE_SIZE may grow in future (if I interpret the commentcorrectly).Currently, mkcramfs #define's PAGE_CACHE_SIZE as 4096 and uses thatfor blksize, whereas Linux-2.3.39 uses its PAGE_CACHE_SIZE, which inturn is defined as PAGE_SIZE (which can be as large as 32KB on arm).This discrepancy is a bug, though it's not clear which should bechanged.One option is to change mkcramfs to take its PAGE_CACHE_SIZE from<asm/page.h>. Personally I don't like this option, but it doesrequire the least amount of change: just change `#definePAGE_CACHE_SIZE (4096)' to `#include <asm/page.h>'. The disadvantageis that the generated cramfs cannot always be shared between differentkernels, not even necessarily kernels of the same architecture ifPAGE_CACHE_SIZE is subject to change between kernel versions.The remaining options try to make cramfs more sharable.One part of that is addressing endianness. The two options here are`always use little-endian' (like ext2fs) or `writer choosesendianness; kernel adapts at runtime'. Little-endian wins because ofcode simplicity and little CPU overhead even on big-endian machines.The cost of swabbing is changing the code to use the le32_to_cpuetc. macros as used by ext2fs. We don't need to swab the compresseddata, only the superblock, inodes and block pointers.The other part of making cramfs more sharable is choosing a blocksize. The options are: 1. Always 4096 bytes. 2. Writer chooses blocksize; kernel adapts but rejects blocksize > PAGE_CACHE_SIZE. 3. Writer chooses blocksize; kernel adapts even to blocksize > PAGE_CACHE_SIZE.It's easy enough to change the kernel to use a smaller value thanPAGE_CACHE_SIZE: just make cramfs_readpage read multiple blocks.The cost of option 1 is that kernels with a larger PAGE_CACHE_SIZEvalue don't get as good compression as they can.The cost of option 2 relative to option 1 is that the code usesvariables instead of #define'd constants. The gain is that peoplewith kernels having larger PAGE_CACHE_SIZE can make use of that ifthey don't mind their cramfs being inaccessible to kernels withsmaller PAGE_CACHE_SIZE values.Option 3 is easy to implement if we don't mind being CPU-inefficient:e.g. get readpage to decompress to a buffer of size MAX_BLKSIZE (whichmust be no larger than 32KB) and discard what it doesn't need.Getting readpage to read into all the covered pages is harder.The main advantage of option 3 over 1, 2, is better compression. Thecost is greater complexity. Probably not worth it, but I hope someonewill disagree. (If it is implemented, then I'll re-use that code ine2compr.)Another cost of 2 and 3 over 1 is making mkcramfs use a differentblock size, but that just means adding and parsing a -b option.Inode Size----------Given that cramfs will probably be used for CDs etc. as well as justsilicon ROMs, it might make sense to expand the inode a little fromits current 12 bytes. Inodes other than the root inode are followedby filename, so the expansion doesn't even have to be a multiple of 4bytes.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -