GK SDK 源码库: XMIPCLinuxV100R005C00SPC030 (kernel/tools/open_source excluded)
This commit is contained in:
@@ -0,0 +1,7 @@
|
||||
config FS_JFFS2
|
||||
bool "Enable JFFS2 filesystem support"
|
||||
help
|
||||
This provides support for reading images from JFFS2 (Journalling
|
||||
Flash File System version 2). JFFS2 is a log-structured file system
|
||||
for use with flash memory devices. It supports raw NAND devices,
|
||||
hard links and compression.
|
||||
@@ -0,0 +1,30 @@
|
||||
The files in this directory and elsewhere which refer to this LICENCE
|
||||
file are part of JFFS2, the Journalling Flash File System v2.
|
||||
|
||||
Copyright © 2001-2007 Red Hat, Inc. and others
|
||||
|
||||
JFFS2 is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free
|
||||
Software Foundation; either version 2 or (at your option) any later
|
||||
version.
|
||||
|
||||
JFFS2 is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along
|
||||
with JFFS2; if not, write to the Free Software Foundation, Inc.,
|
||||
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
|
||||
|
||||
As a special exception, if other files instantiate templates or use
|
||||
macros or inline functions from these files, or you compile these
|
||||
files and link them with other works to produce a work based on these
|
||||
files, these files do not by themselves cause the resulting work to be
|
||||
covered by the GNU General Public License. However the source code for
|
||||
these files must still be made available in accordance with section (3)
|
||||
of the GNU General Public License.
|
||||
|
||||
This exception does not invalidate any other reasons why a work based on
|
||||
this file might be covered by the GNU General Public License.
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
# SPDX-License-Identifier: GPL-2.0+
|
||||
#
|
||||
# (C) Copyright 2000-2006
|
||||
# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
|
||||
|
||||
obj-$(CONFIG_JFFS2_LZO) += compr_lzo.o
|
||||
obj-y += compr_rtime.o
|
||||
obj-y += compr_rubin.o
|
||||
obj-y += compr_zlib.o
|
||||
obj-y += jffs2_1pass.o
|
||||
obj-$(CONFIG_SYS_JFFS2_SORT_FRAGMENTS) += mergesort.o
|
||||
obj-y += mini_inflate.o
|
||||
@@ -0,0 +1,401 @@
|
||||
/*
|
||||
* JFFS2 -- Journalling Flash File System, Version 2.
|
||||
*
|
||||
* Copyright (C) 2004 Patrik Kluba,
|
||||
* University of Szeged, Hungary
|
||||
*
|
||||
* For licensing information, see the file 'LICENCE' in the
|
||||
* jffs2 directory.
|
||||
*
|
||||
* $Id: compr_lzo.c,v 1.3 2004/06/23 16:34:39 havasi Exp $
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
LZO1X-1 (and -999) compression module for jffs2
|
||||
based on the original LZO sources
|
||||
*/
|
||||
|
||||
/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
|
||||
|
||||
/*
|
||||
Original copyright notice follows:
|
||||
|
||||
lzo1x_9x.c -- implementation of the LZO1X-999 compression algorithm
|
||||
lzo_ptr.h -- low-level pointer constructs
|
||||
lzo_swd.ch -- sliding window dictionary
|
||||
lzoconf.h -- configuration for the LZO real-time data compression library
|
||||
lzo_mchw.ch -- matching functions using a window
|
||||
minilzo.c -- mini subset of the LZO real-time data compression library
|
||||
config1x.h -- configuration for the LZO1X algorithm
|
||||
lzo1x.h -- public interface of the LZO1X compression algorithm
|
||||
|
||||
These files are part of the LZO real-time data compression library.
|
||||
|
||||
Copyright (C) 1996-2002 Markus Franz Xaver Johannes Oberhumer
|
||||
All Rights Reserved.
|
||||
|
||||
The LZO library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of
|
||||
the License, or (at your option) any later version.
|
||||
|
||||
The LZO library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with the LZO library; see the file COPYING.
|
||||
If not, write to the Free Software Foundation, Inc.,
|
||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
Markus F.X.J. Oberhumer
|
||||
<markus@oberhumer.com>
|
||||
*/
|
||||
|
||||
/*
|
||||
|
||||
2004-02-16 pajko <pajko(AT)halom(DOT)u-szeged(DOT)hu>
|
||||
Initial release
|
||||
-removed all 16 bit code
|
||||
-all sensitive data will be on 4 byte boundary
|
||||
-removed check parts for library use
|
||||
-removed all but LZO1X-* compression
|
||||
|
||||
*/
|
||||
|
||||
|
||||
#include <config.h>
|
||||
#include <linux/stddef.h>
|
||||
#include <jffs2/jffs2.h>
|
||||
#include <jffs2/compr_rubin.h>
|
||||
|
||||
/* Integral types that have *exactly* the same number of bits as a lzo_voidp */
|
||||
typedef unsigned long lzo_ptr_t;
|
||||
typedef long lzo_sptr_t;
|
||||
|
||||
/* data type definitions */
|
||||
#define U32 unsigned long
|
||||
#define S32 signed long
|
||||
#define I32 long
|
||||
#define U16 unsigned short
|
||||
#define S16 signed short
|
||||
#define I16 short
|
||||
#define U8 unsigned char
|
||||
#define S8 signed char
|
||||
#define I8 char
|
||||
|
||||
#define M1_MAX_OFFSET 0x0400
|
||||
#define M2_MAX_OFFSET 0x0800
|
||||
#define M3_MAX_OFFSET 0x4000
|
||||
#define M4_MAX_OFFSET 0xbfff
|
||||
|
||||
#define __COPY4(dst,src) * (lzo_uint32p)(dst) = * (const lzo_uint32p)(src)
|
||||
#define COPY4(dst,src) __COPY4((lzo_ptr_t)(dst),(lzo_ptr_t)(src))
|
||||
|
||||
#define TEST_IP (ip < ip_end)
|
||||
#define TEST_OP (op <= op_end)
|
||||
|
||||
#define NEED_IP(x) \
|
||||
if ((lzo_uint)(ip_end - ip) < (lzo_uint)(x)) goto input_overrun
|
||||
#define NEED_OP(x) \
|
||||
if ((lzo_uint)(op_end - op) < (lzo_uint)(x)) goto output_overrun
|
||||
#define TEST_LOOKBEHIND(m_pos,out) if (m_pos < out) goto lookbehind_overrun
|
||||
|
||||
typedef U32 lzo_uint32;
|
||||
typedef I32 lzo_int32;
|
||||
typedef U32 lzo_uint;
|
||||
typedef I32 lzo_int;
|
||||
typedef int lzo_bool;
|
||||
|
||||
#define lzo_byte U8
|
||||
#define lzo_bytep U8 *
|
||||
#define lzo_charp char *
|
||||
#define lzo_voidp void *
|
||||
#define lzo_shortp short *
|
||||
#define lzo_ushortp unsigned short *
|
||||
#define lzo_uint32p lzo_uint32 *
|
||||
#define lzo_int32p lzo_int32 *
|
||||
#define lzo_uintp lzo_uint *
|
||||
#define lzo_intp lzo_int *
|
||||
#define lzo_voidpp lzo_voidp *
|
||||
#define lzo_bytepp lzo_bytep *
|
||||
#define lzo_sizeof_dict_t sizeof(lzo_bytep)
|
||||
|
||||
#define LZO_E_OK 0
|
||||
#define LZO_E_ERROR (-1)
|
||||
#define LZO_E_OUT_OF_MEMORY (-2) /* not used right now */
|
||||
#define LZO_E_NOT_COMPRESSIBLE (-3) /* not used right now */
|
||||
#define LZO_E_INPUT_OVERRUN (-4)
|
||||
#define LZO_E_OUTPUT_OVERRUN (-5)
|
||||
#define LZO_E_LOOKBEHIND_OVERRUN (-6)
|
||||
#define LZO_E_EOF_NOT_FOUND (-7)
|
||||
#define LZO_E_INPUT_NOT_CONSUMED (-8)
|
||||
|
||||
#define PTR(a) ((lzo_ptr_t) (a))
|
||||
#define PTR_LINEAR(a) PTR(a)
|
||||
#define PTR_ALIGNED_4(a) ((PTR_LINEAR(a) & 3) == 0)
|
||||
#define PTR_ALIGNED_8(a) ((PTR_LINEAR(a) & 7) == 0)
|
||||
#define PTR_ALIGNED2_4(a,b) (((PTR_LINEAR(a) | PTR_LINEAR(b)) & 3) == 0)
|
||||
#define PTR_ALIGNED2_8(a,b) (((PTR_LINEAR(a) | PTR_LINEAR(b)) & 7) == 0)
|
||||
#define PTR_LT(a,b) (PTR(a) < PTR(b))
|
||||
#define PTR_GE(a,b) (PTR(a) >= PTR(b))
|
||||
#define PTR_DIFF(a,b) ((lzo_ptrdiff_t) (PTR(a) - PTR(b)))
|
||||
#define pd(a,b) ((lzo_uint) ((a)-(b)))
|
||||
|
||||
typedef ptrdiff_t lzo_ptrdiff_t;
|
||||
|
||||
static int
|
||||
lzo1x_decompress (const lzo_byte * in, lzo_uint in_len,
|
||||
lzo_byte * out, lzo_uintp out_len, lzo_voidp wrkmem)
|
||||
{
|
||||
register lzo_byte *op;
|
||||
register const lzo_byte *ip;
|
||||
register lzo_uint t;
|
||||
|
||||
register const lzo_byte *m_pos;
|
||||
|
||||
const lzo_byte *const ip_end = in + in_len;
|
||||
lzo_byte *const op_end = out + *out_len;
|
||||
|
||||
*out_len = 0;
|
||||
|
||||
op = out;
|
||||
ip = in;
|
||||
|
||||
if (*ip > 17)
|
||||
{
|
||||
t = *ip++ - 17;
|
||||
if (t < 4)
|
||||
goto match_next;
|
||||
NEED_OP (t);
|
||||
NEED_IP (t + 1);
|
||||
do
|
||||
*op++ = *ip++;
|
||||
while (--t > 0);
|
||||
goto first_literal_run;
|
||||
}
|
||||
|
||||
while (TEST_IP && TEST_OP)
|
||||
{
|
||||
t = *ip++;
|
||||
if (t >= 16)
|
||||
goto match;
|
||||
if (t == 0)
|
||||
{
|
||||
NEED_IP (1);
|
||||
while (*ip == 0)
|
||||
{
|
||||
t += 255;
|
||||
ip++;
|
||||
NEED_IP (1);
|
||||
}
|
||||
t += 15 + *ip++;
|
||||
}
|
||||
NEED_OP (t + 3);
|
||||
NEED_IP (t + 4);
|
||||
if (PTR_ALIGNED2_4 (op, ip))
|
||||
{
|
||||
COPY4 (op, ip);
|
||||
|
||||
op += 4;
|
||||
ip += 4;
|
||||
if (--t > 0)
|
||||
{
|
||||
if (t >= 4)
|
||||
{
|
||||
do
|
||||
{
|
||||
COPY4 (op, ip);
|
||||
op += 4;
|
||||
ip += 4;
|
||||
t -= 4;
|
||||
}
|
||||
while (t >= 4);
|
||||
if (t > 0)
|
||||
do
|
||||
*op++ = *ip++;
|
||||
while (--t > 0);
|
||||
}
|
||||
else
|
||||
do
|
||||
*op++ = *ip++;
|
||||
while (--t > 0);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
*op++ = *ip++;
|
||||
*op++ = *ip++;
|
||||
*op++ = *ip++;
|
||||
do
|
||||
*op++ = *ip++;
|
||||
while (--t > 0);
|
||||
}
|
||||
first_literal_run:
|
||||
|
||||
t = *ip++;
|
||||
if (t >= 16)
|
||||
goto match;
|
||||
|
||||
m_pos = op - (1 + M2_MAX_OFFSET);
|
||||
m_pos -= t >> 2;
|
||||
m_pos -= *ip++ << 2;
|
||||
TEST_LOOKBEHIND (m_pos, out);
|
||||
NEED_OP (3);
|
||||
*op++ = *m_pos++;
|
||||
*op++ = *m_pos++;
|
||||
*op++ = *m_pos;
|
||||
|
||||
goto match_done;
|
||||
|
||||
while (TEST_IP && TEST_OP)
|
||||
{
|
||||
match:
|
||||
if (t >= 64)
|
||||
{
|
||||
m_pos = op - 1;
|
||||
m_pos -= (t >> 2) & 7;
|
||||
m_pos -= *ip++ << 3;
|
||||
t = (t >> 5) - 1;
|
||||
TEST_LOOKBEHIND (m_pos, out);
|
||||
NEED_OP (t + 3 - 1);
|
||||
goto copy_match;
|
||||
|
||||
}
|
||||
else if (t >= 32)
|
||||
{
|
||||
t &= 31;
|
||||
if (t == 0)
|
||||
{
|
||||
NEED_IP (1);
|
||||
while (*ip == 0)
|
||||
{
|
||||
t += 255;
|
||||
ip++;
|
||||
NEED_IP (1);
|
||||
}
|
||||
t += 31 + *ip++;
|
||||
}
|
||||
|
||||
m_pos = op - 1;
|
||||
m_pos -= (ip[0] >> 2) + (ip[1] << 6);
|
||||
|
||||
ip += 2;
|
||||
}
|
||||
else if (t >= 16)
|
||||
{
|
||||
m_pos = op;
|
||||
m_pos -= (t & 8) << 11;
|
||||
|
||||
t &= 7;
|
||||
if (t == 0)
|
||||
{
|
||||
NEED_IP (1);
|
||||
while (*ip == 0)
|
||||
{
|
||||
t += 255;
|
||||
ip++;
|
||||
NEED_IP (1);
|
||||
}
|
||||
t += 7 + *ip++;
|
||||
}
|
||||
|
||||
m_pos -= (ip[0] >> 2) + (ip[1] << 6);
|
||||
|
||||
ip += 2;
|
||||
if (m_pos == op)
|
||||
goto eof_found;
|
||||
m_pos -= 0x4000;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
m_pos = op - 1;
|
||||
m_pos -= t >> 2;
|
||||
m_pos -= *ip++ << 2;
|
||||
TEST_LOOKBEHIND (m_pos, out);
|
||||
NEED_OP (2);
|
||||
*op++ = *m_pos++;
|
||||
*op++ = *m_pos;
|
||||
|
||||
goto match_done;
|
||||
}
|
||||
|
||||
TEST_LOOKBEHIND (m_pos, out);
|
||||
NEED_OP (t + 3 - 1);
|
||||
if (t >= 2 * 4 - (3 - 1)
|
||||
&& PTR_ALIGNED2_4 (op, m_pos))
|
||||
{
|
||||
COPY4 (op, m_pos);
|
||||
op += 4;
|
||||
m_pos += 4;
|
||||
t -= 4 - (3 - 1);
|
||||
do
|
||||
{
|
||||
COPY4 (op, m_pos);
|
||||
op += 4;
|
||||
m_pos += 4;
|
||||
t -= 4;
|
||||
}
|
||||
while (t >= 4);
|
||||
if (t > 0)
|
||||
do
|
||||
*op++ = *m_pos++;
|
||||
while (--t > 0);
|
||||
}
|
||||
else
|
||||
|
||||
{
|
||||
copy_match:
|
||||
*op++ = *m_pos++;
|
||||
*op++ = *m_pos++;
|
||||
do
|
||||
*op++ = *m_pos++;
|
||||
while (--t > 0);
|
||||
}
|
||||
|
||||
match_done:
|
||||
t = ip[-2] & 3;
|
||||
|
||||
if (t == 0)
|
||||
break;
|
||||
|
||||
match_next:
|
||||
NEED_OP (t);
|
||||
NEED_IP (t + 1);
|
||||
do
|
||||
*op++ = *ip++;
|
||||
while (--t > 0);
|
||||
t = *ip++;
|
||||
}
|
||||
}
|
||||
*out_len = op - out;
|
||||
return LZO_E_EOF_NOT_FOUND;
|
||||
|
||||
eof_found:
|
||||
*out_len = op - out;
|
||||
return (ip == ip_end ? LZO_E_OK :
|
||||
(ip <
|
||||
ip_end ? LZO_E_INPUT_NOT_CONSUMED : LZO_E_INPUT_OVERRUN));
|
||||
|
||||
input_overrun:
|
||||
*out_len = op - out;
|
||||
return LZO_E_INPUT_OVERRUN;
|
||||
|
||||
output_overrun:
|
||||
*out_len = op - out;
|
||||
return LZO_E_OUTPUT_OVERRUN;
|
||||
|
||||
lookbehind_overrun:
|
||||
*out_len = op - out;
|
||||
return LZO_E_LOOKBEHIND_OVERRUN;
|
||||
}
|
||||
|
||||
int lzo_decompress(unsigned char *data_in, unsigned char *cpage_out,
|
||||
u32 srclen, u32 destlen)
|
||||
{
|
||||
lzo_uint outlen = destlen;
|
||||
return lzo1x_decompress (data_in, srclen, cpage_out, &outlen, NULL);
|
||||
}
|
||||
@@ -0,0 +1,87 @@
|
||||
/*
|
||||
* JFFS2 -- Journalling Flash File System, Version 2.
|
||||
*
|
||||
* Copyright (C) 2001 Red Hat, Inc.
|
||||
*
|
||||
* Created by Arjan van de Ven <arjanv@redhat.com>
|
||||
*
|
||||
* The original JFFS, from which the design for JFFS2 was derived,
|
||||
* was designed and implemented by Axis Communications AB.
|
||||
*
|
||||
* The contents of this file are subject to the Red Hat eCos Public
|
||||
* License Version 1.1 (the "Licence"); you may not use this file
|
||||
* except in compliance with the Licence. You may obtain a copy of
|
||||
* the Licence at http://www.redhat.com/
|
||||
*
|
||||
* Software distributed under the Licence is distributed on an "AS IS"
|
||||
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.
|
||||
* See the Licence for the specific language governing rights and
|
||||
* limitations under the Licence.
|
||||
*
|
||||
* The Original Code is JFFS2 - Journalling Flash File System, version 2
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the
|
||||
* terms of the GNU General Public License version 2 (the "GPL"), in
|
||||
* which case the provisions of the GPL are applicable instead of the
|
||||
* above. If you wish to allow the use of your version of this file
|
||||
* only under the terms of the GPL and not to allow others to use your
|
||||
* version of this file under the RHEPL, indicate your decision by
|
||||
* deleting the provisions above and replace them with the notice and
|
||||
* other provisions required by the GPL. If you do not delete the
|
||||
* provisions above, a recipient may use your version of this file
|
||||
* under either the RHEPL or the GPL.
|
||||
*
|
||||
* $Id: compr_rtime.c,v 1.2 2002/01/24 22:58:42 rfeany Exp $
|
||||
*
|
||||
*
|
||||
* Very simple lz77-ish encoder.
|
||||
*
|
||||
* Theory of operation: Both encoder and decoder have a list of "last
|
||||
* occurances" for every possible source-value; after sending the
|
||||
* first source-byte, the second byte indicated the "run" length of
|
||||
* matches
|
||||
*
|
||||
* The algorithm is intended to only send "whole bytes", no bit-messing.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
#include <jffs2/jffs2.h>
|
||||
|
||||
void rtime_decompress(unsigned char *data_in, unsigned char *cpage_out,
|
||||
u32 srclen, u32 destlen)
|
||||
{
|
||||
int positions[256];
|
||||
int outpos;
|
||||
int pos;
|
||||
int i;
|
||||
|
||||
outpos = pos = 0;
|
||||
|
||||
for (i = 0; i < 256; positions[i++] = 0);
|
||||
|
||||
while (outpos<destlen) {
|
||||
unsigned char value;
|
||||
int backoffs;
|
||||
int repeat;
|
||||
|
||||
value = data_in[pos++];
|
||||
cpage_out[outpos++] = value; /* first the verbatim copied byte */
|
||||
repeat = data_in[pos++];
|
||||
backoffs = positions[value];
|
||||
|
||||
positions[value]=outpos;
|
||||
if (repeat) {
|
||||
if (backoffs + repeat >= outpos) {
|
||||
while(repeat) {
|
||||
cpage_out[outpos++] = cpage_out[backoffs++];
|
||||
repeat--;
|
||||
}
|
||||
} else {
|
||||
for (i = 0; i < repeat; i++)
|
||||
*(cpage_out + outpos + i) = *(cpage_out + backoffs + i);
|
||||
outpos+=repeat;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,122 @@
|
||||
/*
|
||||
* JFFS2 -- Journalling Flash File System, Version 2.
|
||||
*
|
||||
* Copyright (C) 2001 Red Hat, Inc.
|
||||
*
|
||||
* Created by Arjan van de Ven <arjanv@redhat.com>
|
||||
*
|
||||
* Heavily modified by Russ Dill <Russ.Dill@asu.edu> in an attempt at
|
||||
* a little more speed.
|
||||
*
|
||||
* The original JFFS, from which the design for JFFS2 was derived,
|
||||
* was designed and implemented by Axis Communications AB.
|
||||
*
|
||||
* The contents of this file are subject to the Red Hat eCos Public
|
||||
* License Version 1.1 (the "Licence"); you may not use this file
|
||||
* except in compliance with the Licence. You may obtain a copy of
|
||||
* the Licence at http://www.redhat.com/
|
||||
*
|
||||
* Software distributed under the Licence is distributed on an "AS IS"
|
||||
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.
|
||||
* See the Licence for the specific language governing rights and
|
||||
* limitations under the Licence.
|
||||
*
|
||||
* The Original Code is JFFS2 - Journalling Flash File System, version 2
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the
|
||||
* terms of the GNU General Public License version 2 (the "GPL"), in
|
||||
* which case the provisions of the GPL are applicable instead of the
|
||||
* above. If you wish to allow the use of your version of this file
|
||||
* only under the terms of the GPL and not to allow others to use your
|
||||
* version of this file under the RHEPL, indicate your decision by
|
||||
* deleting the provisions above and replace them with the notice and
|
||||
* other provisions required by the GPL. If you do not delete the
|
||||
* provisions above, a recipient may use your version of this file
|
||||
* under either the RHEPL or the GPL.
|
||||
*
|
||||
* $Id: compr_rubin.c,v 1.2 2002/01/24 22:58:42 rfeany Exp $
|
||||
*
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
#include <jffs2/jffs2.h>
|
||||
#include <jffs2/compr_rubin.h>
|
||||
|
||||
|
||||
void rubin_do_decompress(unsigned char *bits, unsigned char *in,
|
||||
unsigned char *page_out, __u32 destlen)
|
||||
{
|
||||
register char *curr = (char *)page_out;
|
||||
char *end = (char *)(page_out + destlen);
|
||||
register unsigned long temp;
|
||||
register unsigned long result;
|
||||
register unsigned long p;
|
||||
register unsigned long q;
|
||||
register unsigned long rec_q;
|
||||
register unsigned long bit;
|
||||
register long i0;
|
||||
unsigned long i;
|
||||
|
||||
/* init_pushpull */
|
||||
temp = *(u32 *) in;
|
||||
bit = 16;
|
||||
|
||||
/* init_rubin */
|
||||
q = 0;
|
||||
p = (long) (2 * UPPER_BIT_RUBIN);
|
||||
|
||||
/* init_decode */
|
||||
rec_q = (in[0] << 8) | in[1];
|
||||
|
||||
while (curr < end) {
|
||||
/* in byte */
|
||||
|
||||
result = 0;
|
||||
for (i = 0; i < 8; i++) {
|
||||
/* decode */
|
||||
|
||||
while ((q & UPPER_BIT_RUBIN) || ((p + q) <= UPPER_BIT_RUBIN)) {
|
||||
q &= ~UPPER_BIT_RUBIN;
|
||||
q <<= 1;
|
||||
p <<= 1;
|
||||
rec_q &= ~UPPER_BIT_RUBIN;
|
||||
rec_q <<= 1;
|
||||
rec_q |= (temp >> (bit++ ^ 7)) & 1;
|
||||
if (bit > 31) {
|
||||
u32 *p = (u32 *)in;
|
||||
bit = 0;
|
||||
temp = *(++p);
|
||||
in = (unsigned char *)p;
|
||||
}
|
||||
}
|
||||
i0 = (bits[i] * p) >> 8;
|
||||
|
||||
if (i0 <= 0) i0 = 1;
|
||||
/* if it fails, it fails, we have our crc
|
||||
if (i0 >= p) i0 = p - 1; */
|
||||
|
||||
result >>= 1;
|
||||
if (rec_q < q + i0) {
|
||||
/* result |= 0x00; */
|
||||
p = i0;
|
||||
} else {
|
||||
result |= 0x80;
|
||||
p -= i0;
|
||||
q += i0;
|
||||
}
|
||||
}
|
||||
*(curr++) = result;
|
||||
}
|
||||
}
|
||||
|
||||
void dynrubin_decompress(unsigned char *data_in, unsigned char *cpage_out,
|
||||
unsigned long sourcelen, unsigned long dstlen)
|
||||
{
|
||||
unsigned char bits[8];
|
||||
int c;
|
||||
|
||||
for (c=0; c<8; c++)
|
||||
bits[c] = (256 - data_in[c]);
|
||||
|
||||
rubin_do_decompress(bits, data_in+8, cpage_out, dstlen);
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
* JFFS2 -- Journalling Flash File System, Version 2.
|
||||
*
|
||||
* Copyright (C) 2001 Red Hat, Inc.
|
||||
*
|
||||
* Created by David Woodhouse <dwmw2@cambridge.redhat.com>
|
||||
*
|
||||
* The original JFFS, from which the design for JFFS2 was derived,
|
||||
* was designed and implemented by Axis Communications AB.
|
||||
*
|
||||
* The contents of this file are subject to the Red Hat eCos Public
|
||||
* License Version 1.1 (the "Licence"); you may not use this file
|
||||
* except in compliance with the Licence. You may obtain a copy of
|
||||
* the Licence at http://www.redhat.com/
|
||||
*
|
||||
* Software distributed under the Licence is distributed on an "AS IS"
|
||||
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.
|
||||
* See the Licence for the specific language governing rights and
|
||||
* limitations under the Licence.
|
||||
*
|
||||
* The Original Code is JFFS2 - Journalling Flash File System, version 2
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the
|
||||
* terms of the GNU General Public License version 2 (the "GPL"), in
|
||||
* which case the provisions of the GPL are applicable instead of the
|
||||
* above. If you wish to allow the use of your version of this file
|
||||
* only under the terms of the GPL and not to allow others to use your
|
||||
* version of this file under the RHEPL, indicate your decision by
|
||||
* deleting the provisions above and replace them with the notice and
|
||||
* other provisions required by the GPL. If you do not delete the
|
||||
* provisions above, a recipient may use your version of this file
|
||||
* under either the RHEPL or the GPL.
|
||||
*
|
||||
* $Id: compr_zlib.c,v 1.2 2002/01/24 22:58:42 rfeany Exp $
|
||||
*
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <config.h>
|
||||
#include <jffs2/jffs2.h>
|
||||
#include <jffs2/mini_inflate.h>
|
||||
|
||||
long zlib_decompress(unsigned char *data_in, unsigned char *cpage_out,
|
||||
__u32 srclen, __u32 destlen)
|
||||
{
|
||||
return (decompress_block(cpage_out, data_in + 2, (void *) ldr_memcpy));
|
||||
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,105 @@
|
||||
#ifndef jffs2_private_h
|
||||
#define jffs2_private_h
|
||||
|
||||
#include <jffs2/jffs2.h>
|
||||
|
||||
|
||||
struct b_node {
|
||||
u32 offset;
|
||||
struct b_node *next;
|
||||
enum { CRC_UNKNOWN = 0, CRC_OK, CRC_BAD } datacrc;
|
||||
};
|
||||
|
||||
struct b_list {
|
||||
struct b_node *listTail;
|
||||
struct b_node *listHead;
|
||||
#ifdef CONFIG_SYS_JFFS2_SORT_FRAGMENTS
|
||||
struct b_node *listLast;
|
||||
int (*listCompare)(struct b_node *new, struct b_node *node);
|
||||
u32 listLoops;
|
||||
#endif
|
||||
u32 listCount;
|
||||
struct mem_block *listMemBase;
|
||||
};
|
||||
|
||||
struct b_lists {
|
||||
struct b_list dir;
|
||||
struct b_list frag;
|
||||
void *readbuf;
|
||||
};
|
||||
|
||||
struct b_compr_info {
|
||||
u32 num_frags;
|
||||
u32 compr_sum;
|
||||
u32 decompr_sum;
|
||||
};
|
||||
|
||||
struct b_jffs2_info {
|
||||
struct b_compr_info compr_info[JFFS2_NUM_COMPR];
|
||||
};
|
||||
|
||||
static inline int
|
||||
hdr_crc(struct jffs2_unknown_node *node)
|
||||
{
|
||||
#if 1
|
||||
u32 crc = crc32_no_comp(0, (unsigned char *)node, sizeof(struct jffs2_unknown_node) - 4);
|
||||
#else
|
||||
/* what's the semantics of this? why is this here? */
|
||||
u32 crc = crc32_no_comp(~0, (unsigned char *)node, sizeof(struct jffs2_unknown_node) - 4);
|
||||
|
||||
crc ^= ~0;
|
||||
#endif
|
||||
if (node->hdr_crc != crc) {
|
||||
return 0;
|
||||
} else {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
static inline int
|
||||
dirent_crc(struct jffs2_raw_dirent *node)
|
||||
{
|
||||
if (node->node_crc != crc32_no_comp(0, (unsigned char *)node, sizeof(struct jffs2_raw_dirent) - 8)) {
|
||||
return 0;
|
||||
} else {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
static inline int
|
||||
dirent_name_crc(struct jffs2_raw_dirent *node)
|
||||
{
|
||||
if (node->name_crc != crc32_no_comp(0, (unsigned char *)&(node->name), node->nsize)) {
|
||||
return 0;
|
||||
} else {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
static inline int
|
||||
inode_crc(struct jffs2_raw_inode *node)
|
||||
{
|
||||
if (node->node_crc != crc32_no_comp(0, (unsigned char *)node, sizeof(struct jffs2_raw_inode) - 8)) {
|
||||
return 0;
|
||||
} else {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
static inline int
|
||||
data_crc(struct jffs2_raw_inode *node)
|
||||
{
|
||||
if (node->data_crc != crc32_no_comp(0, (unsigned char *)
|
||||
((int) &node->node_crc + sizeof (node->node_crc)),
|
||||
node->csize)) {
|
||||
return 0;
|
||||
} else {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(CONFIG_SYS_JFFS2_SORT_FRAGMENTS)
|
||||
/* External merge sort. */
|
||||
int sort_list(struct b_list *list);
|
||||
#endif
|
||||
#endif /* jffs2_private.h */
|
||||
@@ -0,0 +1,51 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
/*
|
||||
* This file is copyright 2001 Simon Tatham.
|
||||
* Rewritten from original source 2006 by Dan Merillat for use in u-boot.
|
||||
*
|
||||
* Original code can be found at:
|
||||
* http://www.chiark.greenend.org.uk/~sgtatham/algorithms/listsort.html
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include "jffs2_private.h"
|
||||
|
||||
int sort_list(struct b_list *list)
|
||||
{
|
||||
struct b_node *p, *q, *e, **tail;
|
||||
int k, psize, qsize;
|
||||
|
||||
if (!list->listHead)
|
||||
return 0;
|
||||
|
||||
for (k = 1; k < list->listCount; k *= 2) {
|
||||
tail = &list->listHead;
|
||||
for (p = q = list->listHead; p; p = q) {
|
||||
/* step 'k' places from p; */
|
||||
for (psize = 0; q && psize < k; psize++)
|
||||
q = q->next;
|
||||
qsize = k;
|
||||
|
||||
/* two lists, merge them. */
|
||||
while (psize || (qsize && q)) {
|
||||
/* merge the next element */
|
||||
if (psize == 0 ||
|
||||
((qsize && q) &&
|
||||
list->listCompare(p, q))) {
|
||||
/* p is empty, or p > q, so q next */
|
||||
e = q;
|
||||
q = q->next;
|
||||
qsize--;
|
||||
} else {
|
||||
e = p;
|
||||
p = p->next;
|
||||
psize--;
|
||||
}
|
||||
e->next = NULL; /* break accidental loops. */
|
||||
*tail = e;
|
||||
tail = &e->next;
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,375 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*-------------------------------------------------------------------------
|
||||
* Filename: mini_inflate.c
|
||||
* Version: $Id: mini_inflate.c,v 1.3 2002/01/24 22:58:42 rfeany Exp $
|
||||
* Copyright: Copyright (C) 2001, Russ Dill
|
||||
* Author: Russ Dill <Russ.Dill@asu.edu>
|
||||
* Description: Mini inflate implementation (RFC 1951)
|
||||
*-----------------------------------------------------------------------*/
|
||||
|
||||
#include <config.h>
|
||||
#include <jffs2/mini_inflate.h>
|
||||
|
||||
/* The order that the code lengths in section 3.2.7 are in */
|
||||
static unsigned char huffman_order[] = {16, 17, 18, 0, 8, 7, 9, 6, 10, 5,
|
||||
11, 4, 12, 3, 13, 2, 14, 1, 15};
|
||||
|
||||
static inline void cramfs_memset(int *s, const int c, size n)
|
||||
{
|
||||
n--;
|
||||
for (;n > 0; n--) s[n] = c;
|
||||
s[0] = c;
|
||||
}
|
||||
|
||||
/* associate a stream with a block of data and reset the stream */
|
||||
static void init_stream(struct bitstream *stream, unsigned char *data,
|
||||
void *(*inflate_memcpy)(void *, const void *, size))
|
||||
{
|
||||
stream->error = NO_ERROR;
|
||||
stream->memcpy = inflate_memcpy;
|
||||
stream->decoded = 0;
|
||||
stream->data = data;
|
||||
stream->bit = 0; /* The first bit of the stream is the lsb of the
|
||||
* first byte */
|
||||
|
||||
/* really sorry about all this initialization, think of a better way,
|
||||
* let me know and it will get cleaned up */
|
||||
stream->codes.bits = 8;
|
||||
stream->codes.num_symbols = 19;
|
||||
stream->codes.lengths = stream->code_lengths;
|
||||
stream->codes.symbols = stream->code_symbols;
|
||||
stream->codes.count = stream->code_count;
|
||||
stream->codes.first = stream->code_first;
|
||||
stream->codes.pos = stream->code_pos;
|
||||
|
||||
stream->lengths.bits = 16;
|
||||
stream->lengths.num_symbols = 288;
|
||||
stream->lengths.lengths = stream->length_lengths;
|
||||
stream->lengths.symbols = stream->length_symbols;
|
||||
stream->lengths.count = stream->length_count;
|
||||
stream->lengths.first = stream->length_first;
|
||||
stream->lengths.pos = stream->length_pos;
|
||||
|
||||
stream->distance.bits = 16;
|
||||
stream->distance.num_symbols = 32;
|
||||
stream->distance.lengths = stream->distance_lengths;
|
||||
stream->distance.symbols = stream->distance_symbols;
|
||||
stream->distance.count = stream->distance_count;
|
||||
stream->distance.first = stream->distance_first;
|
||||
stream->distance.pos = stream->distance_pos;
|
||||
|
||||
}
|
||||
|
||||
/* pull 'bits' bits out of the stream. The last bit pulled it returned as the
|
||||
* msb. (section 3.1.1)
|
||||
*/
|
||||
static inline unsigned long pull_bits(struct bitstream *stream,
|
||||
const unsigned int bits)
|
||||
{
|
||||
unsigned long ret;
|
||||
int i;
|
||||
|
||||
ret = 0;
|
||||
for (i = 0; i < bits; i++) {
|
||||
ret += ((*(stream->data) >> stream->bit) & 1) << i;
|
||||
|
||||
/* if, before incrementing, we are on bit 7,
|
||||
* go to the lsb of the next byte */
|
||||
if (stream->bit++ == 7) {
|
||||
stream->bit = 0;
|
||||
stream->data++;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline int pull_bit(struct bitstream *stream)
|
||||
{
|
||||
int ret = ((*(stream->data) >> stream->bit) & 1);
|
||||
if (stream->bit++ == 7) {
|
||||
stream->bit = 0;
|
||||
stream->data++;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* discard bits up to the next whole byte */
|
||||
static void discard_bits(struct bitstream *stream)
|
||||
{
|
||||
if (stream->bit != 0) {
|
||||
stream->bit = 0;
|
||||
stream->data++;
|
||||
}
|
||||
}
|
||||
|
||||
/* No decompression, the data is all literals (section 3.2.4) */
|
||||
static void decompress_none(struct bitstream *stream, unsigned char *dest)
|
||||
{
|
||||
unsigned int length;
|
||||
|
||||
discard_bits(stream);
|
||||
length = *(stream->data++);
|
||||
length += *(stream->data++) << 8;
|
||||
pull_bits(stream, 16); /* throw away the inverse of the size */
|
||||
|
||||
stream->decoded += length;
|
||||
stream->memcpy(dest, stream->data, length);
|
||||
stream->data += length;
|
||||
}
|
||||
|
||||
/* Read in a symbol from the stream (section 3.2.2) */
|
||||
static int read_symbol(struct bitstream *stream, struct huffman_set *set)
|
||||
{
|
||||
int bits = 0;
|
||||
int code = 0;
|
||||
while (!(set->count[bits] && code < set->first[bits] +
|
||||
set->count[bits])) {
|
||||
code = (code << 1) + pull_bit(stream);
|
||||
if (++bits > set->bits) {
|
||||
/* error decoding (corrupted data?) */
|
||||
stream->error = CODE_NOT_FOUND;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
return set->symbols[set->pos[bits] + code - set->first[bits]];
|
||||
}
|
||||
|
||||
/* decompress a stream of data encoded with the passed length and distance
|
||||
* huffman codes */
|
||||
static void decompress_huffman(struct bitstream *stream, unsigned char *dest)
|
||||
{
|
||||
struct huffman_set *lengths = &(stream->lengths);
|
||||
struct huffman_set *distance = &(stream->distance);
|
||||
|
||||
int symbol, length, dist, i;
|
||||
|
||||
do {
|
||||
if ((symbol = read_symbol(stream, lengths)) < 0) return;
|
||||
if (symbol < 256) {
|
||||
*(dest++) = symbol; /* symbol is a literal */
|
||||
stream->decoded++;
|
||||
} else if (symbol > 256) {
|
||||
/* Determine the length of the repitition
|
||||
* (section 3.2.5) */
|
||||
if (symbol < 265) length = symbol - 254;
|
||||
else if (symbol == 285) length = 258;
|
||||
else {
|
||||
length = pull_bits(stream, (symbol - 261) >> 2);
|
||||
length += (4 << ((symbol - 261) >> 2)) + 3;
|
||||
length += ((symbol - 1) % 4) <<
|
||||
((symbol - 261) >> 2);
|
||||
}
|
||||
|
||||
/* Determine how far back to go */
|
||||
if ((symbol = read_symbol(stream, distance)) < 0)
|
||||
return;
|
||||
if (symbol < 4) dist = symbol + 1;
|
||||
else {
|
||||
dist = pull_bits(stream, (symbol - 2) >> 1);
|
||||
dist += (2 << ((symbol - 2) >> 1)) + 1;
|
||||
dist += (symbol % 2) << ((symbol - 2) >> 1);
|
||||
}
|
||||
stream->decoded += length;
|
||||
for (i = 0; i < length; i++) {
|
||||
*dest = dest[-dist];
|
||||
dest++;
|
||||
}
|
||||
}
|
||||
} while (symbol != 256); /* 256 is the end of the data block */
|
||||
}
|
||||
|
||||
/* Fill the lookup tables (section 3.2.2) */
|
||||
static void fill_code_tables(struct huffman_set *set)
|
||||
{
|
||||
int code = 0, i, length;
|
||||
|
||||
/* fill in the first code of each bit length, and the pos pointer */
|
||||
set->pos[0] = 0;
|
||||
for (i = 1; i < set->bits; i++) {
|
||||
code = (code + set->count[i - 1]) << 1;
|
||||
set->first[i] = code;
|
||||
set->pos[i] = set->pos[i - 1] + set->count[i - 1];
|
||||
}
|
||||
|
||||
/* Fill in the table of symbols in order of their huffman code */
|
||||
for (i = 0; i < set->num_symbols; i++) {
|
||||
if ((length = set->lengths[i]))
|
||||
set->symbols[set->pos[length]++] = i;
|
||||
}
|
||||
|
||||
/* reset the pos pointer */
|
||||
for (i = 1; i < set->bits; i++) set->pos[i] -= set->count[i];
|
||||
}
|
||||
|
||||
static void init_code_tables(struct huffman_set *set)
|
||||
{
|
||||
cramfs_memset(set->lengths, 0, set->num_symbols);
|
||||
cramfs_memset(set->count, 0, set->bits);
|
||||
cramfs_memset(set->first, 0, set->bits);
|
||||
}
|
||||
|
||||
/* read in the huffman codes for dynamic decoding (section 3.2.7) */
|
||||
static void decompress_dynamic(struct bitstream *stream, unsigned char *dest)
|
||||
{
|
||||
/* I tried my best to minimize the memory footprint here, while still
|
||||
* keeping up performance. I really dislike the _lengths[] tables, but
|
||||
* I see no way of eliminating them without a sizable performance
|
||||
* impact. The first struct table keeps track of stats on each bit
|
||||
* length. The _length table keeps a record of the bit length of each
|
||||
* symbol. The _symbols table is for looking up symbols by the huffman
|
||||
* code (the pos element points to the first place in the symbol table
|
||||
* where that bit length occurs). I also hate the initization of these
|
||||
* structs, if someone knows how to compact these, lemme know. */
|
||||
|
||||
struct huffman_set *codes = &(stream->codes);
|
||||
struct huffman_set *lengths = &(stream->lengths);
|
||||
struct huffman_set *distance = &(stream->distance);
|
||||
|
||||
int hlit = pull_bits(stream, 5) + 257;
|
||||
int hdist = pull_bits(stream, 5) + 1;
|
||||
int hclen = pull_bits(stream, 4) + 4;
|
||||
int length, curr_code, symbol, i, last_code;
|
||||
|
||||
last_code = 0;
|
||||
|
||||
init_code_tables(codes);
|
||||
init_code_tables(lengths);
|
||||
init_code_tables(distance);
|
||||
|
||||
/* fill in the count of each bit length' as well as the lengths
|
||||
* table */
|
||||
for (i = 0; i < hclen; i++) {
|
||||
length = pull_bits(stream, 3);
|
||||
codes->lengths[huffman_order[i]] = length;
|
||||
if (length) codes->count[length]++;
|
||||
|
||||
}
|
||||
fill_code_tables(codes);
|
||||
|
||||
/* Do the same for the length codes, being carefull of wrap through
|
||||
* to the distance table */
|
||||
curr_code = 0;
|
||||
while (curr_code < hlit) {
|
||||
if ((symbol = read_symbol(stream, codes)) < 0) return;
|
||||
if (symbol == 0) {
|
||||
curr_code++;
|
||||
last_code = 0;
|
||||
} else if (symbol < 16) { /* Literal length */
|
||||
lengths->lengths[curr_code] = last_code = symbol;
|
||||
lengths->count[symbol]++;
|
||||
curr_code++;
|
||||
} else if (symbol == 16) { /* repeat the last symbol 3 - 6
|
||||
* times */
|
||||
length = 3 + pull_bits(stream, 2);
|
||||
for (;length; length--, curr_code++)
|
||||
if (curr_code < hlit) {
|
||||
lengths->lengths[curr_code] =
|
||||
last_code;
|
||||
lengths->count[last_code]++;
|
||||
} else { /* wrap to the distance table */
|
||||
distance->lengths[curr_code - hlit] =
|
||||
last_code;
|
||||
distance->count[last_code]++;
|
||||
}
|
||||
} else if (symbol == 17) { /* repeat a bit length 0 */
|
||||
curr_code += 3 + pull_bits(stream, 3);
|
||||
last_code = 0;
|
||||
} else { /* same, but more times */
|
||||
curr_code += 11 + pull_bits(stream, 7);
|
||||
last_code = 0;
|
||||
}
|
||||
}
|
||||
fill_code_tables(lengths);
|
||||
|
||||
/* Fill the distance table, don't need to worry about wrapthrough
|
||||
* here */
|
||||
curr_code -= hlit;
|
||||
while (curr_code < hdist) {
|
||||
if ((symbol = read_symbol(stream, codes)) < 0) return;
|
||||
if (symbol == 0) {
|
||||
curr_code++;
|
||||
last_code = 0;
|
||||
} else if (symbol < 16) {
|
||||
distance->lengths[curr_code] = last_code = symbol;
|
||||
distance->count[symbol]++;
|
||||
curr_code++;
|
||||
} else if (symbol == 16) {
|
||||
length = 3 + pull_bits(stream, 2);
|
||||
for (;length; length--, curr_code++) {
|
||||
distance->lengths[curr_code] =
|
||||
last_code;
|
||||
distance->count[last_code]++;
|
||||
}
|
||||
} else if (symbol == 17) {
|
||||
curr_code += 3 + pull_bits(stream, 3);
|
||||
last_code = 0;
|
||||
} else {
|
||||
curr_code += 11 + pull_bits(stream, 7);
|
||||
last_code = 0;
|
||||
}
|
||||
}
|
||||
fill_code_tables(distance);
|
||||
|
||||
decompress_huffman(stream, dest);
|
||||
}
|
||||
|
||||
/* fill in the length and distance huffman codes for fixed encoding
|
||||
* (section 3.2.6) */
|
||||
static void decompress_fixed(struct bitstream *stream, unsigned char *dest)
|
||||
{
|
||||
/* let gcc fill in the initial values */
|
||||
struct huffman_set *lengths = &(stream->lengths);
|
||||
struct huffman_set *distance = &(stream->distance);
|
||||
|
||||
cramfs_memset(lengths->count, 0, 16);
|
||||
cramfs_memset(lengths->first, 0, 16);
|
||||
cramfs_memset(lengths->lengths, 8, 144);
|
||||
cramfs_memset(lengths->lengths + 144, 9, 112);
|
||||
cramfs_memset(lengths->lengths + 256, 7, 24);
|
||||
cramfs_memset(lengths->lengths + 280, 8, 8);
|
||||
lengths->count[7] = 24;
|
||||
lengths->count[8] = 152;
|
||||
lengths->count[9] = 112;
|
||||
|
||||
cramfs_memset(distance->count, 0, 16);
|
||||
cramfs_memset(distance->first, 0, 16);
|
||||
cramfs_memset(distance->lengths, 5, 32);
|
||||
distance->count[5] = 32;
|
||||
|
||||
|
||||
fill_code_tables(lengths);
|
||||
fill_code_tables(distance);
|
||||
|
||||
|
||||
decompress_huffman(stream, dest);
|
||||
}
|
||||
|
||||
/* returns the number of bytes decoded, < 0 if there was an error. Note that
|
||||
* this function assumes that the block starts on a byte boundry
|
||||
* (non-compliant, but I don't see where this would happen). section 3.2.3 */
|
||||
long decompress_block(unsigned char *dest, unsigned char *source,
|
||||
void *(*inflate_memcpy)(void *, const void *, size))
|
||||
{
|
||||
int bfinal, btype;
|
||||
struct bitstream stream;
|
||||
|
||||
init_stream(&stream, source, inflate_memcpy);
|
||||
do {
|
||||
bfinal = pull_bit(&stream);
|
||||
btype = pull_bits(&stream, 2);
|
||||
if (btype == NO_COMP) decompress_none(&stream, dest + stream.decoded);
|
||||
else if (btype == DYNAMIC_COMP)
|
||||
decompress_dynamic(&stream, dest + stream.decoded);
|
||||
else if (btype == FIXED_COMP) decompress_fixed(&stream, dest + stream.decoded);
|
||||
else stream.error = COMP_UNKNOWN;
|
||||
} while (!bfinal && !stream.error);
|
||||
|
||||
#if 0
|
||||
putstr("decompress_block start\r\n");
|
||||
putLabeledWord("stream.error = ",stream.error);
|
||||
putLabeledWord("stream.decoded = ",stream.decoded);
|
||||
putLabeledWord("dest = ",dest);
|
||||
putstr("decompress_block end\r\n");
|
||||
#endif
|
||||
return stream.error ? -stream.error : stream.decoded;
|
||||
}
|
||||
@@ -0,0 +1,163 @@
|
||||
/*
|
||||
* JFFS2 -- Journalling Flash File System, Version 2.
|
||||
*
|
||||
* Copyright © 2004 Ferenc Havasi <havasi@inf.u-szeged.hu>,
|
||||
* Zoltan Sogor <weth@inf.u-szeged.hu>,
|
||||
* Patrik Kluba <pajko@halom.u-szeged.hu>,
|
||||
* University of Szeged, Hungary
|
||||
*
|
||||
* For licensing information, see the file 'LICENCE' in this directory.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef JFFS2_SUMMARY_H
|
||||
#define JFFS2_SUMMARY_H
|
||||
|
||||
#define BLK_STATE_ALLFF 0
|
||||
#define BLK_STATE_CLEAN 1
|
||||
#define BLK_STATE_PARTDIRTY 2
|
||||
#define BLK_STATE_CLEANMARKER 3
|
||||
#define BLK_STATE_ALLDIRTY 4
|
||||
#define BLK_STATE_BADBLOCK 5
|
||||
|
||||
#define JFFS2_SUMMARY_NOSUM_SIZE 0xffffffff
|
||||
#define JFFS2_SUMMARY_INODE_SIZE (sizeof(struct jffs2_sum_inode_flash))
|
||||
#define JFFS2_SUMMARY_DIRENT_SIZE(x) (sizeof(struct jffs2_sum_dirent_flash) + (x))
|
||||
#define JFFS2_SUMMARY_XATTR_SIZE (sizeof(struct jffs2_sum_xattr_flash))
|
||||
#define JFFS2_SUMMARY_XREF_SIZE (sizeof(struct jffs2_sum_xref_flash))
|
||||
|
||||
/* Summary structures used on flash */
|
||||
|
||||
struct jffs2_sum_unknown_flash
|
||||
{
|
||||
__u16 nodetype; /* node type */
|
||||
};
|
||||
|
||||
struct jffs2_sum_inode_flash
|
||||
{
|
||||
__u16 nodetype; /* node type */
|
||||
__u32 inode; /* inode number */
|
||||
__u32 version; /* inode version */
|
||||
__u32 offset; /* offset on jeb */
|
||||
__u32 totlen; /* record length */
|
||||
} __attribute__((packed));
|
||||
|
||||
struct jffs2_sum_dirent_flash
|
||||
{
|
||||
__u16 nodetype; /* == JFFS_NODETYPE_DIRENT */
|
||||
__u32 totlen; /* record length */
|
||||
__u32 offset; /* offset on jeb */
|
||||
__u32 pino; /* parent inode */
|
||||
__u32 version; /* dirent version */
|
||||
__u32 ino; /* == zero for unlink */
|
||||
uint8_t nsize; /* dirent name size */
|
||||
uint8_t type; /* dirent type */
|
||||
uint8_t name[0]; /* dirent name */
|
||||
} __attribute__((packed));
|
||||
|
||||
struct jffs2_sum_xattr_flash
|
||||
{
|
||||
__u16 nodetype; /* == JFFS2_NODETYPE_XATR */
|
||||
__u32 xid; /* xattr identifier */
|
||||
__u32 version; /* version number */
|
||||
__u32 offset; /* offset on jeb */
|
||||
__u32 totlen; /* node length */
|
||||
} __attribute__((packed));
|
||||
|
||||
struct jffs2_sum_xref_flash
|
||||
{
|
||||
__u16 nodetype; /* == JFFS2_NODETYPE_XREF */
|
||||
__u32 offset; /* offset on jeb */
|
||||
} __attribute__((packed));
|
||||
|
||||
union jffs2_sum_flash
|
||||
{
|
||||
struct jffs2_sum_unknown_flash u;
|
||||
struct jffs2_sum_inode_flash i;
|
||||
struct jffs2_sum_dirent_flash d;
|
||||
struct jffs2_sum_xattr_flash x;
|
||||
struct jffs2_sum_xref_flash r;
|
||||
};
|
||||
|
||||
/* Summary structures used in the memory */
|
||||
|
||||
struct jffs2_sum_unknown_mem
|
||||
{
|
||||
union jffs2_sum_mem *next;
|
||||
__u16 nodetype; /* node type */
|
||||
};
|
||||
|
||||
struct jffs2_sum_inode_mem
|
||||
{
|
||||
union jffs2_sum_mem *next;
|
||||
__u16 nodetype; /* node type */
|
||||
__u32 inode; /* inode number */
|
||||
__u32 version; /* inode version */
|
||||
__u32 offset; /* offset on jeb */
|
||||
__u32 totlen; /* record length */
|
||||
} __attribute__((packed));
|
||||
|
||||
struct jffs2_sum_dirent_mem
|
||||
{
|
||||
union jffs2_sum_mem *next;
|
||||
__u16 nodetype; /* == JFFS_NODETYPE_DIRENT */
|
||||
__u32 totlen; /* record length */
|
||||
__u32 offset; /* ofset on jeb */
|
||||
__u32 pino; /* parent inode */
|
||||
__u32 version; /* dirent version */
|
||||
__u32 ino; /* == zero for unlink */
|
||||
uint8_t nsize; /* dirent name size */
|
||||
uint8_t type; /* dirent type */
|
||||
uint8_t name[0]; /* dirent name */
|
||||
} __attribute__((packed));
|
||||
|
||||
struct jffs2_sum_xattr_mem
|
||||
{
|
||||
union jffs2_sum_mem *next;
|
||||
__u16 nodetype;
|
||||
__u32 xid;
|
||||
__u32 version;
|
||||
__u32 offset;
|
||||
__u32 totlen;
|
||||
} __attribute__((packed));
|
||||
|
||||
struct jffs2_sum_xref_mem
|
||||
{
|
||||
union jffs2_sum_mem *next;
|
||||
__u16 nodetype;
|
||||
__u32 offset;
|
||||
} __attribute__((packed));
|
||||
|
||||
union jffs2_sum_mem
|
||||
{
|
||||
struct jffs2_sum_unknown_mem u;
|
||||
struct jffs2_sum_inode_mem i;
|
||||
struct jffs2_sum_dirent_mem d;
|
||||
struct jffs2_sum_xattr_mem x;
|
||||
struct jffs2_sum_xref_mem r;
|
||||
};
|
||||
|
||||
/* Summary related information stored in superblock */
|
||||
|
||||
struct jffs2_summary
|
||||
{
|
||||
uint32_t sum_size; /* collected summary information for nextblock */
|
||||
uint32_t sum_num;
|
||||
uint32_t sum_padded;
|
||||
union jffs2_sum_mem *sum_list_head;
|
||||
union jffs2_sum_mem *sum_list_tail;
|
||||
|
||||
__u32 *sum_buf; /* buffer for writing out summary */
|
||||
};
|
||||
|
||||
/* Summary marker is stored at the end of every sumarized erase block */
|
||||
|
||||
struct jffs2_sum_marker
|
||||
{
|
||||
__u32 offset; /* offset of the summary node in the jeb */
|
||||
__u32 magic; /* == JFFS2_SUM_MAGIC */
|
||||
};
|
||||
|
||||
#define JFFS2_SUMMARY_FRAME_SIZE (sizeof(struct jffs2_raw_summary) + sizeof(struct jffs2_sum_marker))
|
||||
|
||||
#endif /* JFFS2_SUMMARY_H */
|
||||
Reference in New Issue
Block a user