cramfs: GraphViz block diagram (.dot) source

KS implementation details

License: MIT

This page hosts a formal specification of cramfs using Kaitai Struct. This specification can be automatically translated into a variety of programming languages to get a parsing library.

GraphViz block diagram source

cramfs.dot

digraph {
	rankdir=LR;
	node [shape=plaintext];
	subgraph cluster__cramfs {
		label="Cramfs";
		graph[style=dotted];

		cramfs__seq [label=<<TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0">
			<TR><TD BGCOLOR="#E0FFE0">pos</TD><TD BGCOLOR="#E0FFE0">size</TD><TD BGCOLOR="#E0FFE0">type</TD><TD BGCOLOR="#E0FFE0">id</TD></TR>
			<TR><TD PORT="super_block_pos">0</TD><TD PORT="super_block_size">...</TD><TD>SuperBlockStruct</TD><TD PORT="super_block_type">super_block</TD></TR>
		</TABLE>>];
		cramfs__inst__page_size [label=<<TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0">
			<TR><TD BGCOLOR="#E0FFE0">id</TD><TD BGCOLOR="#E0FFE0">value</TD></TR>
			<TR><TD>page_size</TD><TD>4096</TD></TR>
		</TABLE>>];
		subgraph cluster__super_block_struct {
			label="Cramfs::SuperBlockStruct";
			graph[style=dotted];

			super_block_struct__seq [label=<<TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0">
				<TR><TD BGCOLOR="#E0FFE0">pos</TD><TD BGCOLOR="#E0FFE0">size</TD><TD BGCOLOR="#E0FFE0">type</TD><TD BGCOLOR="#E0FFE0">id</TD></TR>
				<TR><TD PORT="magic_pos">0</TD><TD PORT="magic_size">4</TD><TD>45 3D CD 28</TD><TD PORT="magic_type">magic</TD></TR>
				<TR><TD PORT="size_pos">4</TD><TD PORT="size_size">4</TD><TD>u4le</TD><TD PORT="size_type">size</TD></TR>
				<TR><TD PORT="flags_pos">8</TD><TD PORT="flags_size">4</TD><TD>u4le</TD><TD PORT="flags_type">flags</TD></TR>
				<TR><TD PORT="future_pos">12</TD><TD PORT="future_size">4</TD><TD>u4le</TD><TD PORT="future_type">future</TD></TR>
				<TR><TD PORT="signature_pos">16</TD><TD PORT="signature_size">16</TD><TD>43 6F 6D 70 72 65 73 73 65 64 20 52 4F 4D 46 53</TD><TD PORT="signature_type">signature</TD></TR>
				<TR><TD PORT="fsid_pos">32</TD><TD PORT="fsid_size">16</TD><TD>Info</TD><TD PORT="fsid_type">fsid</TD></TR>
				<TR><TD PORT="name_pos">48</TD><TD PORT="name_size">16</TD><TD>str(ASCII)</TD><TD PORT="name_type">name</TD></TR>
				<TR><TD PORT="root_pos">64</TD><TD PORT="root_size">...</TD><TD>Inode</TD><TD PORT="root_type">root</TD></TR>
			</TABLE>>];
			super_block_struct__inst__flag_fsid_v2 [label=<<TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0">
				<TR><TD BGCOLOR="#E0FFE0">id</TD><TD BGCOLOR="#E0FFE0">value</TD></TR>
				<TR><TD>flag_fsid_v2</TD><TD>((flags &gt;&gt; 0) &amp; 1)</TD></TR>
			</TABLE>>];
			super_block_struct__inst__flag_holes [label=<<TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0">
				<TR><TD BGCOLOR="#E0FFE0">id</TD><TD BGCOLOR="#E0FFE0">value</TD></TR>
				<TR><TD>flag_holes</TD><TD>((flags &gt;&gt; 8) &amp; 1)</TD></TR>
			</TABLE>>];
			super_block_struct__inst__flag_wrong_signature [label=<<TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0">
				<TR><TD BGCOLOR="#E0FFE0">id</TD><TD BGCOLOR="#E0FFE0">value</TD></TR>
				<TR><TD>flag_wrong_signature</TD><TD>((flags &gt;&gt; 9) &amp; 1)</TD></TR>
			</TABLE>>];
			super_block_struct__inst__flag_sorted_dirs [label=<<TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0">
				<TR><TD BGCOLOR="#E0FFE0">id</TD><TD BGCOLOR="#E0FFE0">value</TD></TR>
				<TR><TD>flag_sorted_dirs</TD><TD>((flags &gt;&gt; 1) &amp; 1)</TD></TR>
			</TABLE>>];
			super_block_struct__inst__flag_shifted_root_offset [label=<<TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0">
				<TR><TD BGCOLOR="#E0FFE0">id</TD><TD BGCOLOR="#E0FFE0">value</TD></TR>
				<TR><TD>flag_shifted_root_offset</TD><TD>((flags &gt;&gt; 10) &amp; 1)</TD></TR>
			</TABLE>>];
		}
		subgraph cluster__chunked_data_inode {
			label="Cramfs::ChunkedDataInode";
			graph[style=dotted];

			chunked_data_inode__seq [label=<<TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0">
				<TR><TD BGCOLOR="#E0FFE0">pos</TD><TD BGCOLOR="#E0FFE0">size</TD><TD BGCOLOR="#E0FFE0">type</TD><TD BGCOLOR="#E0FFE0">id</TD></TR>
				<TR><TD PORT="block_end_index_pos">0</TD><TD PORT="block_end_index_size">4</TD><TD>u4le</TD><TD PORT="block_end_index_type">block_end_index</TD></TR>
				<TR><TD COLSPAN="4" PORT="block_end_index__repeat">repeat (((_parent.size + _root.page_size) - 1) / _root.page_size) times</TD></TR>
				<TR><TD PORT="raw_blocks_pos">...</TD><TD PORT="raw_blocks_size">⇲</TD><TD></TD><TD PORT="raw_blocks_type">raw_blocks</TD></TR>
			</TABLE>>];
		}
		subgraph cluster__inode {
			label="Cramfs::Inode";
			graph[style=dotted];

			inode__seq [label=<<TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0">
				<TR><TD BGCOLOR="#E0FFE0">pos</TD><TD BGCOLOR="#E0FFE0">size</TD><TD BGCOLOR="#E0FFE0">type</TD><TD BGCOLOR="#E0FFE0">id</TD></TR>
				<TR><TD PORT="mode_pos">0</TD><TD PORT="mode_size">2</TD><TD>u2le</TD><TD PORT="mode_type">mode</TD></TR>
				<TR><TD PORT="uid_pos">2</TD><TD PORT="uid_size">2</TD><TD>u2le</TD><TD PORT="uid_type">uid</TD></TR>
				<TR><TD PORT="size_gid_pos">4</TD><TD PORT="size_gid_size">4</TD><TD>u4le</TD><TD PORT="size_gid_type">size_gid</TD></TR>
				<TR><TD PORT="namelen_offset_pos">8</TD><TD PORT="namelen_offset_size">4</TD><TD>u4le</TD><TD PORT="namelen_offset_type">namelen_offset</TD></TR>
				<TR><TD PORT="name_pos">12</TD><TD PORT="name_size">namelen</TD><TD>str(utf-8)</TD><TD PORT="name_type">name</TD></TR>
			</TABLE>>];
			inode__inst__attr [label=<<TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0">
				<TR><TD BGCOLOR="#E0FFE0">id</TD><TD BGCOLOR="#E0FFE0">value</TD></TR>
				<TR><TD>attr</TD><TD>((mode &gt;&gt; 9) &amp; 7)</TD></TR>
			</TABLE>>];
			inode__inst__as_reg_file [label=<<TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0">
				<TR><TD BGCOLOR="#E0FFE0">pos</TD><TD BGCOLOR="#E0FFE0">size</TD><TD BGCOLOR="#E0FFE0">type</TD><TD BGCOLOR="#E0FFE0">id</TD></TR>
				<TR><TD PORT="as_reg_file_pos">offset</TD><TD PORT="as_reg_file_size">...</TD><TD>ChunkedDataInode</TD><TD PORT="as_reg_file_type">as_reg_file</TD></TR>
			</TABLE>>];
			inode__inst__perm_u [label=<<TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0">
				<TR><TD BGCOLOR="#E0FFE0">id</TD><TD BGCOLOR="#E0FFE0">value</TD></TR>
				<TR><TD>perm_u</TD><TD>((mode &gt;&gt; 6) &amp; 7)</TD></TR>
			</TABLE>>];
			inode__inst__as_symlink [label=<<TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0">
				<TR><TD BGCOLOR="#E0FFE0">pos</TD><TD BGCOLOR="#E0FFE0">size</TD><TD BGCOLOR="#E0FFE0">type</TD><TD BGCOLOR="#E0FFE0">id</TD></TR>
				<TR><TD PORT="as_symlink_pos">offset</TD><TD PORT="as_symlink_size">...</TD><TD>ChunkedDataInode</TD><TD PORT="as_symlink_type">as_symlink</TD></TR>
			</TABLE>>];
			inode__inst__perm_o [label=<<TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0">
				<TR><TD BGCOLOR="#E0FFE0">id</TD><TD BGCOLOR="#E0FFE0">value</TD></TR>
				<TR><TD>perm_o</TD><TD>(mode &amp; 7)</TD></TR>
			</TABLE>>];
			inode__inst__size [label=<<TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0">
				<TR><TD BGCOLOR="#E0FFE0">id</TD><TD BGCOLOR="#E0FFE0">value</TD></TR>
				<TR><TD>size</TD><TD>(size_gid &amp; 16777215)</TD></TR>
			</TABLE>>];
			inode__inst__gid [label=<<TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0">
				<TR><TD BGCOLOR="#E0FFE0">id</TD><TD BGCOLOR="#E0FFE0">value</TD></TR>
				<TR><TD>gid</TD><TD>(size_gid &gt;&gt; 24)</TD></TR>
			</TABLE>>];
			inode__inst__perm_g [label=<<TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0">
				<TR><TD BGCOLOR="#E0FFE0">id</TD><TD BGCOLOR="#E0FFE0">value</TD></TR>
				<TR><TD>perm_g</TD><TD>((mode &gt;&gt; 3) &amp; 7)</TD></TR>
			</TABLE>>];
			inode__inst__namelen [label=<<TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0">
				<TR><TD BGCOLOR="#E0FFE0">id</TD><TD BGCOLOR="#E0FFE0">value</TD></TR>
				<TR><TD>namelen</TD><TD>((namelen_offset &amp; 63) &lt;&lt; 2)</TD></TR>
			</TABLE>>];
			inode__inst__as_dir [label=<<TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0">
				<TR><TD BGCOLOR="#E0FFE0">pos</TD><TD BGCOLOR="#E0FFE0">size</TD><TD BGCOLOR="#E0FFE0">type</TD><TD BGCOLOR="#E0FFE0">id</TD></TR>
				<TR><TD PORT="as_dir_pos">offset</TD><TD PORT="as_dir_size">size</TD><TD>DirInode</TD><TD PORT="as_dir_type">as_dir</TD></TR>
			</TABLE>>];
			inode__inst__type [label=<<TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0">
				<TR><TD BGCOLOR="#E0FFE0">id</TD><TD BGCOLOR="#E0FFE0">value</TD></TR>
				<TR><TD>type</TD><TD>Kaitai::Struct::Stream::resolve_enum(FILE_TYPE, ((mode &gt;&gt; 12) &amp; 15))</TD></TR>
			</TABLE>>];
			inode__inst__offset [label=<<TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0">
				<TR><TD BGCOLOR="#E0FFE0">id</TD><TD BGCOLOR="#E0FFE0">value</TD></TR>
				<TR><TD>offset</TD><TD>(((namelen_offset &gt;&gt; 6) &amp; 67108863) &lt;&lt; 2)</TD></TR>
			</TABLE>>];
		}
		subgraph cluster__dir_inode {
			label="Cramfs::DirInode";
			graph[style=dotted];

			dir_inode__seq [label=<<TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0">
				<TR><TD BGCOLOR="#E0FFE0">pos</TD><TD BGCOLOR="#E0FFE0">size</TD><TD BGCOLOR="#E0FFE0">type</TD><TD BGCOLOR="#E0FFE0">id</TD></TR>
				<TR><TD PORT="children_pos">0</TD><TD PORT="children_size">...</TD><TD>Inode</TD><TD PORT="children_type">children</TD></TR>
				<TR><TD COLSPAN="4" PORT="children__repeat">repeat to end of stream</TD></TR>
			</TABLE>>];
		}
		subgraph cluster__info {
			label="Cramfs::Info";
			graph[style=dotted];

			info__seq [label=<<TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0">
				<TR><TD BGCOLOR="#E0FFE0">pos</TD><TD BGCOLOR="#E0FFE0">size</TD><TD BGCOLOR="#E0FFE0">type</TD><TD BGCOLOR="#E0FFE0">id</TD></TR>
				<TR><TD PORT="crc_pos">0</TD><TD PORT="crc_size">4</TD><TD>u4le</TD><TD PORT="crc_type">crc</TD></TR>
				<TR><TD PORT="edition_pos">4</TD><TD PORT="edition_size">4</TD><TD>u4le</TD><TD PORT="edition_type">edition</TD></TR>
				<TR><TD PORT="blocks_pos">8</TD><TD PORT="blocks_size">4</TD><TD>u4le</TD><TD PORT="blocks_type">blocks</TD></TR>
				<TR><TD PORT="files_pos">12</TD><TD PORT="files_size">4</TD><TD>u4le</TD><TD PORT="files_type">files</TD></TR>
			</TABLE>>];
		}
	}
	cramfs__seq:super_block_type -> super_block_struct__seq [style=bold];
	super_block_struct__seq:fsid_type -> info__seq [style=bold];
	super_block_struct__seq:root_type -> inode__seq [style=bold];
	super_block_struct__seq:flags_type -> super_block_struct__inst__flag_fsid_v2 [color="#404040"];
	super_block_struct__seq:flags_type -> super_block_struct__inst__flag_holes [color="#404040"];
	super_block_struct__seq:flags_type -> super_block_struct__inst__flag_wrong_signature [color="#404040"];
	super_block_struct__seq:flags_type -> super_block_struct__inst__flag_sorted_dirs [color="#404040"];
	super_block_struct__seq:flags_type -> super_block_struct__inst__flag_shifted_root_offset [color="#404040"];
	inode__inst__size:size_type -> chunked_data_inode__seq:block_end_index__repeat [color="#404040"];
	cramfs__inst__page_size:page_size_type -> chunked_data_inode__seq:block_end_index__repeat [color="#404040"];
	cramfs__inst__page_size:page_size_type -> chunked_data_inode__seq:block_end_index__repeat [color="#404040"];
	inode__inst__namelen:namelen_type -> inode__seq:name_size [color="#404040"];
	inode__seq:mode_type -> inode__inst__attr [color="#404040"];
	inode__inst__offset:offset_type -> inode__inst__as_reg_file:as_reg_file_pos [color="#404040"];
	inode__inst__as_reg_file:as_reg_file_type -> chunked_data_inode__seq [style=bold];
	inode__seq:mode_type -> inode__inst__perm_u [color="#404040"];
	inode__inst__offset:offset_type -> inode__inst__as_symlink:as_symlink_pos [color="#404040"];
	inode__inst__as_symlink:as_symlink_type -> chunked_data_inode__seq [style=bold];
	inode__seq:mode_type -> inode__inst__perm_o [color="#404040"];
	inode__seq:size_gid_type -> inode__inst__size [color="#404040"];
	inode__seq:size_gid_type -> inode__inst__gid [color="#404040"];
	inode__seq:mode_type -> inode__inst__perm_g [color="#404040"];
	inode__seq:namelen_offset_type -> inode__inst__namelen [color="#404040"];
	inode__inst__offset:offset_type -> inode__inst__as_dir:as_dir_pos [color="#404040"];
	inode__inst__size:size_type -> inode__inst__as_dir:as_dir_size [color="#404040"];
	inode__inst__as_dir:as_dir_type -> dir_inode__seq [style=bold];
	inode__seq:mode_type -> inode__inst__type [color="#404040"];
	inode__seq:namelen_offset_type -> inode__inst__offset [color="#404040"];
	dir_inode__seq:children_type -> inode__seq [style=bold];
}