Commit cbda1b27 authored by Linus Torvalds's avatar Linus Torvalds

Merge branch 'work.cramfs' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs

Pull cramfs updates from Al Viro:
 "Nicolas Pitre's cramfs work"

* 'work.cramfs' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs:
  cramfs: rehabilitate it
  cramfs: add mmap support
  cramfs: implement uncompressed and arbitrary data block positioning
  cramfs: direct memory access support
parents ca5b857c 8d59598c
......@@ -45,6 +45,48 @@ you can just change the #define in mkcramfs.c, so long as you don't
mind the filesystem becoming unreadable to future kernels.
Memory Mapped cramfs image
--------------------------
The CRAMFS_MTD Kconfig option adds support for loading data directly from
a physical linear memory range (usually non volatile memory like Flash)
instead of going through the block device layer. This saves some memory
since no intermediate buffering is necessary to hold the data before
decompressing.
And when data blocks are kept uncompressed and properly aligned, they will
automatically be mapped directly into user space whenever possible providing
eXecute-In-Place (XIP) from ROM of read-only segments. Data segments mapped
read-write (hence they have to be copied to RAM) may still be compressed in
the cramfs image in the same file along with non compressed read-only
segments. Both MMU and no-MMU systems are supported. This is particularly
handy for tiny embedded systems with very tight memory constraints.
The location of the cramfs image in memory is system dependent. You must
know the proper physical address where the cramfs image is located and
configure an MTD device for it. Also, that MTD device must be supported
by a map driver that implements the "point" method. Examples of such
MTD drivers are cfi_cmdset_0001 (Intel/Sharp CFI flash) or physmap
(Flash device in physical memory map). MTD partitions based on such devices
are fine too. Then that device should be specified with the "mtd:" prefix
as the mount device argument. For example, to mount the MTD device named
"fs_partition" on the /mnt directory:
$ mount -t cramfs mtd:fs_partition /mnt
To boot a kernel with this as root filesystem, suffice to specify
something like "root=mtd:fs_partition" on the kernel command line.
Tools
-----
A version of mkcramfs that can take advantage of the latest capabilities
described above can be found here:
https://github.com/npitre/cramfs-tools
For /usr/share/magic
--------------------
......
......@@ -3720,8 +3720,8 @@ F: drivers/cpuidle/*
F: include/linux/cpuidle.h
CRAMFS FILESYSTEM
W: http://sourceforge.net/projects/cramfs/
S: Orphan / Obsolete
M: Nicolas Pitre <nico@linaro.org>
S: Maintained
F: Documentation/filesystems/cramfs.txt
F: fs/cramfs/
......
config CRAMFS
tristate "Compressed ROM file system support (cramfs) (OBSOLETE)"
depends on BLOCK
tristate "Compressed ROM file system support (cramfs)"
select ZLIB_INFLATE
help
Saying Y here includes support for CramFs (Compressed ROM File
......@@ -16,7 +15,39 @@ config CRAMFS
cramfs. Note that the root file system (the one containing the
directory /) cannot be compiled as a module.
This filesystem is obsoleted by SquashFS, which is much better
in terms of performance and features.
This filesystem is limited in capabilities and performance on
purpose to remain small and low on RAM usage. It is most suitable
for small embedded systems. If you have ample RAM to spare, you may
consider a more capable compressed filesystem such as SquashFS
which is much better in terms of performance and features.
If unsure, say N.
config CRAMFS_BLOCKDEV
bool "Support CramFs image over a regular block device" if EXPERT
depends on CRAMFS && BLOCK
default y
help
This option allows the CramFs driver to load data from a regular
block device such a disk partition or a ramdisk.
config CRAMFS_MTD
bool "Support CramFs image directly mapped in physical memory"
depends on CRAMFS && MTD
default y if !CRAMFS_BLOCKDEV
help
This option allows the CramFs driver to load data directly from
a linear adressed memory range (usually non volatile memory
like flash) instead of going through the block device layer.
This saves some memory since no intermediate buffering is
necessary.
The location of the CramFs image is determined by a
MTD device capable of direct memory mapping e.g. from
the 'physmap' map driver or a resulting MTD partition.
For example, this would mount the cramfs image stored in
the MTD partition named "xip_fs" on the /mnt mountpoint:
mount -t cramfs mtd:xip_fs /mnt
If unsure, say N.
......@@ -49,17 +49,46 @@ same 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.
When the CRAMFS_FLAG_EXT_BLOCK_POINTERS capability bit is set, each
<block_pointer>'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 <block_pointer> 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 <file_data>'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'.
<block>: The i'th <block> is the output of zlib's compress function
applied to the i'th blksize-sized chunk of the input data.
applied to the i'th blksize-sized chunk of the input data if the
corresponding CRAMFS_BLK_FLAG_UNCOMPRESSED <block_ptr> bit is not set,
otherwise it is the input data directly.
(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.
When CRAMFS_BLK_FLAG_DIRECT_PTR is specified then the corresponding
<block> 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 diff is collapsed.
......@@ -74,6 +74,7 @@ struct cramfs_super {
#define CRAMFS_FLAG_HOLES 0x00000100 /* support for holes */
#define CRAMFS_FLAG_WRONG_SIGNATURE 0x00000200 /* reserved */
#define CRAMFS_FLAG_SHIFTED_ROOT_OFFSET 0x00000400 /* shifted root fs */
#define CRAMFS_FLAG_EXT_BLOCK_POINTERS 0x00000800 /* block pointer extensions */
/*
* Valid values in super.flags. Currently we refuse to mount
......@@ -83,7 +84,30 @@ struct cramfs_super {
#define CRAMFS_SUPPORTED_FLAGS ( 0x000000ff \
| CRAMFS_FLAG_HOLES \
| CRAMFS_FLAG_WRONG_SIGNATURE \
| CRAMFS_FLAG_SHIFTED_ROOT_OFFSET )
| CRAMFS_FLAG_SHIFTED_ROOT_OFFSET \
| CRAMFS_FLAG_EXT_BLOCK_POINTERS )
/*
* Block pointer flags
*
* The maximum block offset that needs to be represented is roughly:
*
* (1 << CRAMFS_OFFSET_WIDTH) * 4 +
* (1 << CRAMFS_SIZE_WIDTH) / PAGE_SIZE * (4 + PAGE_SIZE)
* = 0x11004000
*
* That leaves room for 3 flag bits in the block pointer table.
*/
#define CRAMFS_BLK_FLAG_UNCOMPRESSED (1 << 31)
#define CRAMFS_BLK_FLAG_DIRECT_PTR (1 << 30)
#define CRAMFS_BLK_FLAGS ( CRAMFS_BLK_FLAG_UNCOMPRESSED \
| CRAMFS_BLK_FLAG_DIRECT_PTR )
/*
* Direct blocks are at least 4-byte aligned.
* Pointers to direct blocks are shifted down by 2 bits.
*/
#define CRAMFS_BLK_DIRECT_PTR_SHIFT 2
#endif /* _UAPI__CRAMFS_H */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment