fs/cromfs: Fix a error in reading partial compressed blocks. The LZF decompressor does not support that operation. Instead we have to decompress full block into a temporary buffer and copy out the parts that we need. To compensate for the performance hit, a caching mechanism was added so that we do not have to read the same block repeatedly. Unrelated: Also updates some README files.

This commit is contained in:
Gregory Nutt 2018-03-24 11:30:35 -06:00
parent e35228ece9
commit 8b4b61f140
11 changed files with 85 additions and 85 deletions

View File

@ -49,22 +49,6 @@
#if defined(CONFIG_DEBUG_FEATURES) && defined(CONFIG_DEBUG_BINFMT) && !defined(CONFIG_BINFMT_DISABLE)
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/****************************************************************************
* Private Function Prototypes
****************************************************************************/
/****************************************************************************
* Private Data
****************************************************************************/
/****************************************************************************
* Private Functions
****************************************************************************/
/****************************************************************************
* Public Functions
****************************************************************************/

View File

@ -52,10 +52,6 @@
#if !defined(CONFIG_BINFMT_DISABLE) && defined(CONFIG_BINFMT_EXEPATH)
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/****************************************************************************
* Private Types
****************************************************************************/
@ -67,14 +63,6 @@ struct exepath_s
};
#define SIZEOF_EXEPATH_S(n) (sizeof(struct exepath_s) + (n) - 1)
/****************************************************************************
* Private Data
****************************************************************************/
/****************************************************************************
* Private Functions
****************************************************************************/
/****************************************************************************
* Public Functions
****************************************************************************/

View File

@ -51,18 +51,6 @@
#ifndef CONFIG_BINFMT_DISABLE
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/****************************************************************************
* Private Function Prototypes
****************************************************************************/
/****************************************************************************
* Private Data
****************************************************************************/
/****************************************************************************
* Private Functions
****************************************************************************/

View File

@ -50,22 +50,6 @@
#ifndef CONFIG_BINFMT_DISABLE
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/****************************************************************************
* Private Function Prototypes
****************************************************************************/
/****************************************************************************
* Private Data
****************************************************************************/
/****************************************************************************
* Private Functions
****************************************************************************/
/****************************************************************************
* Public Functions
****************************************************************************/
@ -97,6 +81,7 @@ int register_binfmt(FAR struct binfmt_s *binfmt)
sched_unlock();
return OK;
}
return -EINVAL;
}

View File

@ -52,18 +52,6 @@
#ifndef CONFIG_BINFMT_DISABLE
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/****************************************************************************
* Private Function Prototypes
****************************************************************************/
/****************************************************************************
* Private Data
****************************************************************************/
/****************************************************************************
* Private Functions
****************************************************************************/

View File

@ -3920,6 +3920,18 @@ Configurations
Application Configurations -> Examples -> ELF Loader Example
CONFIG_EXAMPLES_ELF_SYSCALL=y : Link apps with the SYStem call library
5. By default, this configuration uses the ROMFS file system. It can also
be modified to use the compressed CROMFS:
-CONFIG_PATH_INITIAL="/mnt/romfs"
+CONFIG_PATH_INITIAL="/mnt/cromfs"
-CONFIG_FS_ROMFS=y
+CONFIG_FS_CROMFS=y
-CONFIG_EXAMPLES_ELF_ROMFS=y
+CONFIG_EXAMPLES_ELF_CROMFS=y
STATUS:
2014-8-24: This configuration works with the address environment
and system call options disabled.

View File

@ -1150,7 +1150,19 @@ Where <subdir> is one of the following:
CONFIG_EXAMPLES_ELF_CXXINITIALIZE=y
CONFIG_EXAMPLES_ELF_UCLIBCXX=y
4. The network initialization thread is enabled in this configuration.
7. By default, this configuration uses the ROMFS file system. It can also
be modified to use the compressed CROMFS:
-CONFIG_PATH_INITIAL="/mnt/romfs"
+CONFIG_PATH_INITIAL="/mnt/cromfs"
-CONFIG_FS_ROMFS=y
+CONFIG_FS_CROMFS=y
-CONFIG_EXAMPLES_ELF_ROMFS=y
+CONFIG_EXAMPLES_ELF_CROMFS=y
8. The network initialization thread is enabled in this configuration.
As a result, networking initialization is performed asynchronously with
NSH bring-up.

View File

@ -8,6 +8,7 @@ config FS_CROMFS
default n
depends on !DISABLE_MOUNTPOINT
select FS_READABLE
select LIBC_LZF
---help---
Enable Compessed Read-Only Filesystem (CROMFS) support

View File

@ -236,13 +236,21 @@ configuration:
CONFIG_LIBC_LZF=y
NOTE: This should be selected automatically when CONFIG_FS_CROMFS
is enabled.
2. Enable the CROMFS file system:
CONFIG_FS_CROMFS=y
3. Enable the apps/examples/cromfs example if you like:
3. Enable the apps/examples/cromfs example:
CONFIG_EXAMPLES_CROMFS=y
Or the apps/examples/elf example if you like:
CONFIG_EXAMPLES_ELF=y
CONFIG_EXAMPLES_ELF_CROMFS=y
Or implement your own custom CROMFS file system that example as a
guideline.

View File

@ -71,6 +71,8 @@
struct cromfs_file_s
{
FAR const struct cromfs_node_s *ff_node; /* The open file node */
uint32_t ff_offset; /* Cached offset (zero means none) */
uint32_t ff_ulen; /* Length of uncompressed data in cache */
FAR uint8_t *ff_buffer; /* Decompression buffer */
};
@ -720,31 +722,49 @@ static ssize_t cromfs_read(FAR struct file *filep, FAR char *buffer,
src = (FAR const uint8_t *)currhdr + LZF_TYPE0_HDR_SIZE;
memcpy(dest, &src[copyoffs], copysize);
finfo("blkoffs=%lu ulen=%u copysize=%u\n",
(unsigned long)blkoffs, ulen, copysize);
}
else
{
unsigned int decomplen;
/* If the source of the data is at the beginning of the compressed
* data buffer, then we can decompress directly into the user buffer.
* data buffer and if the uncompressed data would not overrun the
* buffer, then we can decompress directly into the user buffer.
*/
if (filep->f_pos <= blkoffs)
if (filep->f_pos <= blkoffs && ulen <= remaining)
{
uint32_t voloffs;
copyoffs = 0;
copysize = ulen;
if (copysize > remaining)
/* Get the address and offset in the CROMFS image to obtain
* the data. Check if we already have this offset in the
* cache.
*/
src = (FAR const uint8_t *)currhdr + LZF_TYPE1_HDR_SIZE;
voloffs = cromfs_addr2offset(fs, src);
if (voloffs != ff->ff_offset)
{
copysize = remaining;
unsigned int decomplen;
decomplen = lzf_decompress(src, clen, dest, fs->cv_bsize);
ff->ff_offset = voloffs;
ff->ff_ulen = decomplen;
}
src = (FAR const uint8_t *)currhdr + LZF_TYPE1_HDR_SIZE;
decomplen = lzf_decompress(src, clen, dest, copysize);
DEBUGASSERT(decomplen == copysize);
finfo("voloffs=%lu blkoffs=%lu ulen=%u ff_offset=%u copysize=%u\n",
(unsigned long)voloffs, (unsigned long)blkoffs, ulen,
ff->ff_offset, copysize);
DEBUGASSERT(ff->ff_ulen >= copysize);
}
else
{
unsigned int outsize;
uint32_t voloffs;
/* No, we will need to decompress into the our intermediate
* decompression buffer.
@ -759,12 +779,26 @@ static ssize_t cromfs_read(FAR struct file *filep, FAR char *buffer,
copysize = remaining;
}
outsize = copyoffs + copysize;
DEBUGASSERT(outsize <= fs->cv_bsize);
DEBUGASSERT((copyoffs + copysize) <= fs->cv_bsize);
src = (FAR const uint8_t *)currhdr + LZF_TYPE1_HDR_SIZE;
decomplen = lzf_decompress(src, clen, ff->ff_buffer, outsize);
DEBUGASSERT(decomplen == outsize);
voloffs = cromfs_addr2offset(fs, src);
if (voloffs != ff->ff_offset)
{
unsigned int decomplen;
decomplen = lzf_decompress(src, clen, ff->ff_buffer,
fs->cv_bsize);
ff->ff_offset = voloffs;
ff->ff_ulen = decomplen;
}
finfo("voloffs=%lu blkoffs=%lu ulen=%u clen=%u ff_offset=%u "
"copyoffs=%u copysize=%u\n",
(unsigned long)voloffs, (unsigned long)blkoffs, ulen,
clen, ff->ff_offset, copyoffs, copysize);
DEBUGASSERT(ff->ff_ulen >= (copyoffs + copysize));
/* Then copy to user buffer */

View File

@ -233,7 +233,7 @@ unsigned int lzf_decompress (FAR const void *const in_data,
#ifdef lzf_movsb
len += 2;
lzf_movsb (op, ref, len);
lzf_movsb(op, ref, len);
#else
switch (len)
{