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:
parent
e35228ece9
commit
8b4b61f140
@ -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
|
||||
****************************************************************************/
|
||||
|
@ -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
|
||||
****************************************************************************/
|
||||
|
@ -51,18 +51,6 @@
|
||||
|
||||
#ifndef CONFIG_BINFMT_DISABLE
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Function Prototypes
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -52,18 +52,6 @@
|
||||
|
||||
#ifndef CONFIG_BINFMT_DISABLE
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Function Prototypes
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
@ -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.
|
||||
|
@ -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.
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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.
|
||||
|
@ -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 */
|
||||
|
||||
|
@ -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)
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user