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)
|
#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
|
* Public Functions
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
@ -52,10 +52,6 @@
|
|||||||
|
|
||||||
#if !defined(CONFIG_BINFMT_DISABLE) && defined(CONFIG_BINFMT_EXEPATH)
|
#if !defined(CONFIG_BINFMT_DISABLE) && defined(CONFIG_BINFMT_EXEPATH)
|
||||||
|
|
||||||
/****************************************************************************
|
|
||||||
* Pre-processor Definitions
|
|
||||||
****************************************************************************/
|
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Private Types
|
* Private Types
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
@ -67,14 +63,6 @@ struct exepath_s
|
|||||||
};
|
};
|
||||||
#define SIZEOF_EXEPATH_S(n) (sizeof(struct exepath_s) + (n) - 1)
|
#define SIZEOF_EXEPATH_S(n) (sizeof(struct exepath_s) + (n) - 1)
|
||||||
|
|
||||||
/****************************************************************************
|
|
||||||
* Private Data
|
|
||||||
****************************************************************************/
|
|
||||||
|
|
||||||
/****************************************************************************
|
|
||||||
* Private Functions
|
|
||||||
****************************************************************************/
|
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Public Functions
|
* Public Functions
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
@ -51,18 +51,6 @@
|
|||||||
|
|
||||||
#ifndef CONFIG_BINFMT_DISABLE
|
#ifndef CONFIG_BINFMT_DISABLE
|
||||||
|
|
||||||
/****************************************************************************
|
|
||||||
* Pre-processor Definitions
|
|
||||||
****************************************************************************/
|
|
||||||
|
|
||||||
/****************************************************************************
|
|
||||||
* Private Function Prototypes
|
|
||||||
****************************************************************************/
|
|
||||||
|
|
||||||
/****************************************************************************
|
|
||||||
* Private Data
|
|
||||||
****************************************************************************/
|
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Private Functions
|
* Private Functions
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
@ -50,22 +50,6 @@
|
|||||||
|
|
||||||
#ifndef CONFIG_BINFMT_DISABLE
|
#ifndef CONFIG_BINFMT_DISABLE
|
||||||
|
|
||||||
/****************************************************************************
|
|
||||||
* Pre-processor Definitions
|
|
||||||
****************************************************************************/
|
|
||||||
|
|
||||||
/****************************************************************************
|
|
||||||
* Private Function Prototypes
|
|
||||||
****************************************************************************/
|
|
||||||
|
|
||||||
/****************************************************************************
|
|
||||||
* Private Data
|
|
||||||
****************************************************************************/
|
|
||||||
|
|
||||||
/****************************************************************************
|
|
||||||
* Private Functions
|
|
||||||
****************************************************************************/
|
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Public Functions
|
* Public Functions
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
@ -97,6 +81,7 @@ int register_binfmt(FAR struct binfmt_s *binfmt)
|
|||||||
sched_unlock();
|
sched_unlock();
|
||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -52,18 +52,6 @@
|
|||||||
|
|
||||||
#ifndef CONFIG_BINFMT_DISABLE
|
#ifndef CONFIG_BINFMT_DISABLE
|
||||||
|
|
||||||
/****************************************************************************
|
|
||||||
* Pre-processor Definitions
|
|
||||||
****************************************************************************/
|
|
||||||
|
|
||||||
/****************************************************************************
|
|
||||||
* Private Function Prototypes
|
|
||||||
****************************************************************************/
|
|
||||||
|
|
||||||
/****************************************************************************
|
|
||||||
* Private Data
|
|
||||||
****************************************************************************/
|
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Private Functions
|
* Private Functions
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
@ -3920,6 +3920,18 @@ Configurations
|
|||||||
Application Configurations -> Examples -> ELF Loader Example
|
Application Configurations -> Examples -> ELF Loader Example
|
||||||
CONFIG_EXAMPLES_ELF_SYSCALL=y : Link apps with the SYStem call library
|
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:
|
STATUS:
|
||||||
2014-8-24: This configuration works with the address environment
|
2014-8-24: This configuration works with the address environment
|
||||||
and system call options disabled.
|
and system call options disabled.
|
||||||
|
@ -1150,7 +1150,19 @@ Where <subdir> is one of the following:
|
|||||||
CONFIG_EXAMPLES_ELF_CXXINITIALIZE=y
|
CONFIG_EXAMPLES_ELF_CXXINITIALIZE=y
|
||||||
CONFIG_EXAMPLES_ELF_UCLIBCXX=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
|
As a result, networking initialization is performed asynchronously with
|
||||||
NSH bring-up.
|
NSH bring-up.
|
||||||
|
|
||||||
|
@ -8,6 +8,7 @@ config FS_CROMFS
|
|||||||
default n
|
default n
|
||||||
depends on !DISABLE_MOUNTPOINT
|
depends on !DISABLE_MOUNTPOINT
|
||||||
select FS_READABLE
|
select FS_READABLE
|
||||||
|
select LIBC_LZF
|
||||||
---help---
|
---help---
|
||||||
Enable Compessed Read-Only Filesystem (CROMFS) support
|
Enable Compessed Read-Only Filesystem (CROMFS) support
|
||||||
|
|
||||||
|
@ -236,13 +236,21 @@ configuration:
|
|||||||
|
|
||||||
CONFIG_LIBC_LZF=y
|
CONFIG_LIBC_LZF=y
|
||||||
|
|
||||||
|
NOTE: This should be selected automatically when CONFIG_FS_CROMFS
|
||||||
|
is enabled.
|
||||||
|
|
||||||
2. Enable the CROMFS file system:
|
2. Enable the CROMFS file system:
|
||||||
|
|
||||||
CONFIG_FS_CROMFS=y
|
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
|
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
|
Or implement your own custom CROMFS file system that example as a
|
||||||
guideline.
|
guideline.
|
||||||
|
@ -71,6 +71,8 @@
|
|||||||
struct cromfs_file_s
|
struct cromfs_file_s
|
||||||
{
|
{
|
||||||
FAR const struct cromfs_node_s *ff_node; /* The open file node */
|
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 */
|
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;
|
src = (FAR const uint8_t *)currhdr + LZF_TYPE0_HDR_SIZE;
|
||||||
memcpy(dest, &src[copyoffs], copysize);
|
memcpy(dest, &src[copyoffs], copysize);
|
||||||
|
|
||||||
|
finfo("blkoffs=%lu ulen=%u copysize=%u\n",
|
||||||
|
(unsigned long)blkoffs, ulen, copysize);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
unsigned int decomplen;
|
|
||||||
|
|
||||||
/* If the source of the data is at the beginning of the compressed
|
/* 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;
|
copyoffs = 0;
|
||||||
copysize = ulen;
|
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;
|
finfo("voloffs=%lu blkoffs=%lu ulen=%u ff_offset=%u copysize=%u\n",
|
||||||
decomplen = lzf_decompress(src, clen, dest, copysize);
|
(unsigned long)voloffs, (unsigned long)blkoffs, ulen,
|
||||||
DEBUGASSERT(decomplen == copysize);
|
ff->ff_offset, copysize);
|
||||||
|
DEBUGASSERT(ff->ff_ulen >= copysize);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
unsigned int outsize;
|
uint32_t voloffs;
|
||||||
|
|
||||||
/* No, we will need to decompress into the our intermediate
|
/* No, we will need to decompress into the our intermediate
|
||||||
* decompression buffer.
|
* decompression buffer.
|
||||||
@ -759,12 +779,26 @@ static ssize_t cromfs_read(FAR struct file *filep, FAR char *buffer,
|
|||||||
copysize = remaining;
|
copysize = remaining;
|
||||||
}
|
}
|
||||||
|
|
||||||
outsize = copyoffs + copysize;
|
DEBUGASSERT((copyoffs + copysize) <= fs->cv_bsize);
|
||||||
DEBUGASSERT(outsize <= fs->cv_bsize);
|
|
||||||
|
|
||||||
src = (FAR const uint8_t *)currhdr + LZF_TYPE1_HDR_SIZE;
|
src = (FAR const uint8_t *)currhdr + LZF_TYPE1_HDR_SIZE;
|
||||||
decomplen = lzf_decompress(src, clen, ff->ff_buffer, outsize);
|
voloffs = cromfs_addr2offset(fs, src);
|
||||||
DEBUGASSERT(decomplen == outsize);
|
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 */
|
/* Then copy to user buffer */
|
||||||
|
|
||||||
|
@ -233,7 +233,7 @@ unsigned int lzf_decompress (FAR const void *const in_data,
|
|||||||
|
|
||||||
#ifdef lzf_movsb
|
#ifdef lzf_movsb
|
||||||
len += 2;
|
len += 2;
|
||||||
lzf_movsb (op, ref, len);
|
lzf_movsb(op, ref, len);
|
||||||
#else
|
#else
|
||||||
switch (len)
|
switch (len)
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user