add vdsl firmware loader/cutter

Signed-off-by: John Crispin <blogic@openwrt.org>

SVN-Revision: 36025
owl
John Crispin 2013-03-14 18:43:29 +00:00
parent ef93053696
commit c876ae5e0f
9 changed files with 1249 additions and 0 deletions

View File

@ -0,0 +1,40 @@
# Copyright (C) 2012 OpenWrt.org
#
# This is free software, licensed under the GNU General Public License v2.
# See /LICENSE for more information.
include $(TOPDIR)/rules.mk
PKG_NAME:=ltq-vdsl-fw
PKG_VERSION:=1
PKG_RELEASE:=1
PKG_MAINTAINER:=John Crispin <blogic@openwrt.org>
include $(INCLUDE_DIR)/package.mk
define Package/ltq-vdsl-vr9-fw-installer
TITLE:=Firmware installer
SECTION:=net
CATEGORY:=Network
DEPENDS:=@TARGET_lantiq_xway +kmod-ltq-vdsl-vr9
endef
define Build/Prepare
$(INSTALL_DIR) $(PKG_BUILD_DIR)
$(CP) ./src/* $(PKG_BUILD_DIR)
endef
define Build/Compile
$(TARGET_CONFIGURE_OPTS) \
CFLAGS="$(TARGET_CFLAGS)" \
LDFLAGS="$(TARGET_LDFLAGS)" \
$(MAKE) -C $(PKG_BUILD_DIR)
endef
define Package/ltq-vdsl-vr9-fw-installer/install
$(INSTALL_DIR) $(1)/sbin
$(CP) $(PKG_BUILD_DIR)/w921v_fw_cutter $(PKG_BUILD_DIR)/vdsl_fw_install.sh $(1)/sbin/
endef
$(eval $(call BuildPackage,ltq-vdsl-vr9-fw-installer))

View File

@ -0,0 +1,584 @@
/*
LzmaDecode.c
LZMA Decoder (optimized for Speed version)
LZMA SDK 4.40 Copyright (c) 1999-2006 Igor Pavlov (2006-05-01)
http://www.7-zip.org/
LZMA SDK is licensed under two licenses:
1) GNU Lesser General Public License (GNU LGPL)
2) Common Public License (CPL)
It means that you can select one of these two licenses and
follow rules of that license.
SPECIAL EXCEPTION:
Igor Pavlov, as the author of this Code, expressly permits you to
statically or dynamically link your Code (or bind by name) to the
interfaces of this file without subjecting your linked Code to the
terms of the CPL or GNU LGPL. Any modifications or additions
to this file, however, are subject to the LGPL or CPL terms.
*/
#include "LzmaDecode.h"
#define kNumTopBits 24
#define kTopValue ((UInt32)1 << kNumTopBits)
#define kNumBitModelTotalBits 11
#define kBitModelTotal (1 << kNumBitModelTotalBits)
#define kNumMoveBits 5
#define RC_READ_BYTE (*Buffer++)
#define RC_INIT2 Code = 0; Range = 0xFFFFFFFF; \
{ int i; for(i = 0; i < 5; i++) { RC_TEST; Code = (Code << 8) | RC_READ_BYTE; }}
#ifdef _LZMA_IN_CB
#define RC_TEST { if (Buffer == BufferLim) \
{ SizeT size; int result = InCallback->Read(InCallback, &Buffer, &size); if (result != LZMA_RESULT_OK) return result; \
BufferLim = Buffer + size; if (size == 0) return LZMA_RESULT_DATA_ERROR; }}
#define RC_INIT Buffer = BufferLim = 0; RC_INIT2
#else
#define RC_TEST { if (Buffer == BufferLim) return LZMA_RESULT_DATA_ERROR; }
#define RC_INIT(buffer, bufferSize) Buffer = buffer; BufferLim = buffer + bufferSize; RC_INIT2
#endif
#define RC_NORMALIZE if (Range < kTopValue) { RC_TEST; Range <<= 8; Code = (Code << 8) | RC_READ_BYTE; }
#define IfBit0(p) RC_NORMALIZE; bound = (Range >> kNumBitModelTotalBits) * *(p); if (Code < bound)
#define UpdateBit0(p) Range = bound; *(p) += (kBitModelTotal - *(p)) >> kNumMoveBits;
#define UpdateBit1(p) Range -= bound; Code -= bound; *(p) -= (*(p)) >> kNumMoveBits;
#define RC_GET_BIT2(p, mi, A0, A1) IfBit0(p) \
{ UpdateBit0(p); mi <<= 1; A0; } else \
{ UpdateBit1(p); mi = (mi + mi) + 1; A1; }
#define RC_GET_BIT(p, mi) RC_GET_BIT2(p, mi, ; , ;)
#define RangeDecoderBitTreeDecode(probs, numLevels, res) \
{ int i = numLevels; res = 1; \
do { CProb *p = probs + res; RC_GET_BIT(p, res) } while(--i != 0); \
res -= (1 << numLevels); }
#define kNumPosBitsMax 4
#define kNumPosStatesMax (1 << kNumPosBitsMax)
#define kLenNumLowBits 3
#define kLenNumLowSymbols (1 << kLenNumLowBits)
#define kLenNumMidBits 3
#define kLenNumMidSymbols (1 << kLenNumMidBits)
#define kLenNumHighBits 8
#define kLenNumHighSymbols (1 << kLenNumHighBits)
#define LenChoice 0
#define LenChoice2 (LenChoice + 1)
#define LenLow (LenChoice2 + 1)
#define LenMid (LenLow + (kNumPosStatesMax << kLenNumLowBits))
#define LenHigh (LenMid + (kNumPosStatesMax << kLenNumMidBits))
#define kNumLenProbs (LenHigh + kLenNumHighSymbols)
#define kNumStates 12
#define kNumLitStates 7
#define kStartPosModelIndex 4
#define kEndPosModelIndex 14
#define kNumFullDistances (1 << (kEndPosModelIndex >> 1))
#define kNumPosSlotBits 6
#define kNumLenToPosStates 4
#define kNumAlignBits 4
#define kAlignTableSize (1 << kNumAlignBits)
#define kMatchMinLen 2
#define IsMatch 0
#define IsRep (IsMatch + (kNumStates << kNumPosBitsMax))
#define IsRepG0 (IsRep + kNumStates)
#define IsRepG1 (IsRepG0 + kNumStates)
#define IsRepG2 (IsRepG1 + kNumStates)
#define IsRep0Long (IsRepG2 + kNumStates)
#define PosSlot (IsRep0Long + (kNumStates << kNumPosBitsMax))
#define SpecPos (PosSlot + (kNumLenToPosStates << kNumPosSlotBits))
#define Align (SpecPos + kNumFullDistances - kEndPosModelIndex)
#define LenCoder (Align + kAlignTableSize)
#define RepLenCoder (LenCoder + kNumLenProbs)
#define Literal (RepLenCoder + kNumLenProbs)
#if Literal != LZMA_BASE_SIZE
StopCompilingDueBUG
#endif
int LzmaDecodeProperties(CLzmaProperties *propsRes, const unsigned char *propsData, int size)
{
unsigned char prop0;
if (size < LZMA_PROPERTIES_SIZE)
return LZMA_RESULT_DATA_ERROR;
prop0 = propsData[0];
if (prop0 >= (9 * 5 * 5))
return LZMA_RESULT_DATA_ERROR;
{
for (propsRes->pb = 0; prop0 >= (9 * 5); propsRes->pb++, prop0 -= (9 * 5));
for (propsRes->lp = 0; prop0 >= 9; propsRes->lp++, prop0 -= 9);
propsRes->lc = prop0;
/*
unsigned char remainder = (unsigned char)(prop0 / 9);
propsRes->lc = prop0 % 9;
propsRes->pb = remainder / 5;
propsRes->lp = remainder % 5;
*/
}
#ifdef _LZMA_OUT_READ
{
int i;
propsRes->DictionarySize = 0;
for (i = 0; i < 4; i++)
propsRes->DictionarySize += (UInt32)(propsData[1 + i]) << (i * 8);
if (propsRes->DictionarySize == 0)
propsRes->DictionarySize = 1;
}
#endif
return LZMA_RESULT_OK;
}
#define kLzmaStreamWasFinishedId (-1)
int LzmaDecode(CLzmaDecoderState *vs,
#ifdef _LZMA_IN_CB
ILzmaInCallback *InCallback,
#else
const unsigned char *inStream, SizeT inSize, SizeT *inSizeProcessed,
#endif
unsigned char *outStream, SizeT outSize, SizeT *outSizeProcessed)
{
CProb *p = vs->Probs;
SizeT nowPos = 0;
Byte previousByte = 0;
UInt32 posStateMask = (1 << (vs->Properties.pb)) - 1;
UInt32 literalPosMask = (1 << (vs->Properties.lp)) - 1;
int lc = vs->Properties.lc;
#ifdef _LZMA_OUT_READ
UInt32 Range = vs->Range;
UInt32 Code = vs->Code;
#ifdef _LZMA_IN_CB
const Byte *Buffer = vs->Buffer;
const Byte *BufferLim = vs->BufferLim;
#else
const Byte *Buffer = inStream;
const Byte *BufferLim = inStream + inSize;
#endif
int state = vs->State;
UInt32 rep0 = vs->Reps[0], rep1 = vs->Reps[1], rep2 = vs->Reps[2], rep3 = vs->Reps[3];
int len = vs->RemainLen;
UInt32 globalPos = vs->GlobalPos;
UInt32 distanceLimit = vs->DistanceLimit;
Byte *dictionary = vs->Dictionary;
UInt32 dictionarySize = vs->Properties.DictionarySize;
UInt32 dictionaryPos = vs->DictionaryPos;
Byte tempDictionary[4];
#ifndef _LZMA_IN_CB
*inSizeProcessed = 0;
#endif
*outSizeProcessed = 0;
if (len == kLzmaStreamWasFinishedId)
return LZMA_RESULT_OK;
if (dictionarySize == 0)
{
dictionary = tempDictionary;
dictionarySize = 1;
tempDictionary[0] = vs->TempDictionary[0];
}
if (len == kLzmaNeedInitId)
{
{
UInt32 numProbs = Literal + ((UInt32)LZMA_LIT_SIZE << (lc + vs->Properties.lp));
UInt32 i;
for (i = 0; i < numProbs; i++)
p[i] = kBitModelTotal >> 1;
rep0 = rep1 = rep2 = rep3 = 1;
state = 0;
globalPos = 0;
distanceLimit = 0;
dictionaryPos = 0;
dictionary[dictionarySize - 1] = 0;
#ifdef _LZMA_IN_CB
RC_INIT;
#else
RC_INIT(inStream, inSize);
#endif
}
len = 0;
}
while(len != 0 && nowPos < outSize)
{
UInt32 pos = dictionaryPos - rep0;
if (pos >= dictionarySize)
pos += dictionarySize;
outStream[nowPos++] = dictionary[dictionaryPos] = dictionary[pos];
if (++dictionaryPos == dictionarySize)
dictionaryPos = 0;
len--;
}
if (dictionaryPos == 0)
previousByte = dictionary[dictionarySize - 1];
else
previousByte = dictionary[dictionaryPos - 1];
#else /* if !_LZMA_OUT_READ */
int state = 0;
UInt32 rep0 = 1, rep1 = 1, rep2 = 1, rep3 = 1;
int len = 0;
const Byte *Buffer;
const Byte *BufferLim;
UInt32 Range;
UInt32 Code;
#ifndef _LZMA_IN_CB
*inSizeProcessed = 0;
#endif
*outSizeProcessed = 0;
{
UInt32 i;
UInt32 numProbs = Literal + ((UInt32)LZMA_LIT_SIZE << (lc + vs->Properties.lp));
for (i = 0; i < numProbs; i++)
p[i] = kBitModelTotal >> 1;
}
#ifdef _LZMA_IN_CB
RC_INIT;
#else
RC_INIT(inStream, inSize);
#endif
#endif /* _LZMA_OUT_READ */
while(nowPos < outSize)
{
CProb *prob;
UInt32 bound;
int posState = (int)(
(nowPos
#ifdef _LZMA_OUT_READ
+ globalPos
#endif
)
& posStateMask);
prob = p + IsMatch + (state << kNumPosBitsMax) + posState;
IfBit0(prob)
{
int symbol = 1;
UpdateBit0(prob)
prob = p + Literal + (LZMA_LIT_SIZE *
(((
(nowPos
#ifdef _LZMA_OUT_READ
+ globalPos
#endif
)
& literalPosMask) << lc) + (previousByte >> (8 - lc))));
if (state >= kNumLitStates)
{
int matchByte;
#ifdef _LZMA_OUT_READ
UInt32 pos = dictionaryPos - rep0;
if (pos >= dictionarySize)
pos += dictionarySize;
matchByte = dictionary[pos];
#else
matchByte = outStream[nowPos - rep0];
#endif
do
{
int bit;
CProb *probLit;
matchByte <<= 1;
bit = (matchByte & 0x100);
probLit = prob + 0x100 + bit + symbol;
RC_GET_BIT2(probLit, symbol, if (bit != 0) break, if (bit == 0) break)
}
while (symbol < 0x100);
}
while (symbol < 0x100)
{
CProb *probLit = prob + symbol;
RC_GET_BIT(probLit, symbol)
}
previousByte = (Byte)symbol;
outStream[nowPos++] = previousByte;
#ifdef _LZMA_OUT_READ
if (distanceLimit < dictionarySize)
distanceLimit++;
dictionary[dictionaryPos] = previousByte;
if (++dictionaryPos == dictionarySize)
dictionaryPos = 0;
#endif
if (state < 4) state = 0;
else if (state < 10) state -= 3;
else state -= 6;
}
else
{
UpdateBit1(prob);
prob = p + IsRep + state;
IfBit0(prob)
{
UpdateBit0(prob);
rep3 = rep2;
rep2 = rep1;
rep1 = rep0;
state = state < kNumLitStates ? 0 : 3;
prob = p + LenCoder;
}
else
{
UpdateBit1(prob);
prob = p + IsRepG0 + state;
IfBit0(prob)
{
UpdateBit0(prob);
prob = p + IsRep0Long + (state << kNumPosBitsMax) + posState;
IfBit0(prob)
{
#ifdef _LZMA_OUT_READ
UInt32 pos;
#endif
UpdateBit0(prob);
#ifdef _LZMA_OUT_READ
if (distanceLimit == 0)
#else
if (nowPos == 0)
#endif
return LZMA_RESULT_DATA_ERROR;
state = state < kNumLitStates ? 9 : 11;
#ifdef _LZMA_OUT_READ
pos = dictionaryPos - rep0;
if (pos >= dictionarySize)
pos += dictionarySize;
previousByte = dictionary[pos];
dictionary[dictionaryPos] = previousByte;
if (++dictionaryPos == dictionarySize)
dictionaryPos = 0;
#else
previousByte = outStream[nowPos - rep0];
#endif
outStream[nowPos++] = previousByte;
#ifdef _LZMA_OUT_READ
if (distanceLimit < dictionarySize)
distanceLimit++;
#endif
continue;
}
else
{
UpdateBit1(prob);
}
}
else
{
UInt32 distance;
UpdateBit1(prob);
prob = p + IsRepG1 + state;
IfBit0(prob)
{
UpdateBit0(prob);
distance = rep1;
}
else
{
UpdateBit1(prob);
prob = p + IsRepG2 + state;
IfBit0(prob)
{
UpdateBit0(prob);
distance = rep2;
}
else
{
UpdateBit1(prob);
distance = rep3;
rep3 = rep2;
}
rep2 = rep1;
}
rep1 = rep0;
rep0 = distance;
}
state = state < kNumLitStates ? 8 : 11;
prob = p + RepLenCoder;
}
{
int numBits, offset;
CProb *probLen = prob + LenChoice;
IfBit0(probLen)
{
UpdateBit0(probLen);
probLen = prob + LenLow + (posState << kLenNumLowBits);
offset = 0;
numBits = kLenNumLowBits;
}
else
{
UpdateBit1(probLen);
probLen = prob + LenChoice2;
IfBit0(probLen)
{
UpdateBit0(probLen);
probLen = prob + LenMid + (posState << kLenNumMidBits);
offset = kLenNumLowSymbols;
numBits = kLenNumMidBits;
}
else
{
UpdateBit1(probLen);
probLen = prob + LenHigh;
offset = kLenNumLowSymbols + kLenNumMidSymbols;
numBits = kLenNumHighBits;
}
}
RangeDecoderBitTreeDecode(probLen, numBits, len);
len += offset;
}
if (state < 4)
{
int posSlot;
state += kNumLitStates;
prob = p + PosSlot +
((len < kNumLenToPosStates ? len : kNumLenToPosStates - 1) <<
kNumPosSlotBits);
RangeDecoderBitTreeDecode(prob, kNumPosSlotBits, posSlot);
if (posSlot >= kStartPosModelIndex)
{
int numDirectBits = ((posSlot >> 1) - 1);
rep0 = (2 | ((UInt32)posSlot & 1));
if (posSlot < kEndPosModelIndex)
{
rep0 <<= numDirectBits;
prob = p + SpecPos + rep0 - posSlot - 1;
}
else
{
numDirectBits -= kNumAlignBits;
do
{
RC_NORMALIZE
Range >>= 1;
rep0 <<= 1;
if (Code >= Range)
{
Code -= Range;
rep0 |= 1;
}
}
while (--numDirectBits != 0);
prob = p + Align;
rep0 <<= kNumAlignBits;
numDirectBits = kNumAlignBits;
}
{
int i = 1;
int mi = 1;
do
{
CProb *prob3 = prob + mi;
RC_GET_BIT2(prob3, mi, ; , rep0 |= i);
i <<= 1;
}
while(--numDirectBits != 0);
}
}
else
rep0 = posSlot;
if (++rep0 == (UInt32)(0))
{
/* it's for stream version */
len = kLzmaStreamWasFinishedId;
break;
}
}
len += kMatchMinLen;
#ifdef _LZMA_OUT_READ
if (rep0 > distanceLimit)
#else
if (rep0 > nowPos)
#endif
return LZMA_RESULT_DATA_ERROR;
#ifdef _LZMA_OUT_READ
if (dictionarySize - distanceLimit > (UInt32)len)
distanceLimit += len;
else
distanceLimit = dictionarySize;
#endif
do
{
#ifdef _LZMA_OUT_READ
UInt32 pos = dictionaryPos - rep0;
if (pos >= dictionarySize)
pos += dictionarySize;
previousByte = dictionary[pos];
dictionary[dictionaryPos] = previousByte;
if (++dictionaryPos == dictionarySize)
dictionaryPos = 0;
#else
previousByte = outStream[nowPos - rep0];
#endif
len--;
outStream[nowPos++] = previousByte;
}
while(len != 0 && nowPos < outSize);
}
}
RC_NORMALIZE;
#ifdef _LZMA_OUT_READ
vs->Range = Range;
vs->Code = Code;
vs->DictionaryPos = dictionaryPos;
vs->GlobalPos = globalPos + (UInt32)nowPos;
vs->DistanceLimit = distanceLimit;
vs->Reps[0] = rep0;
vs->Reps[1] = rep1;
vs->Reps[2] = rep2;
vs->Reps[3] = rep3;
vs->State = state;
vs->RemainLen = len;
vs->TempDictionary[0] = tempDictionary[0];
#endif
#ifdef _LZMA_IN_CB
vs->Buffer = Buffer;
vs->BufferLim = BufferLim;
#else
*inSizeProcessed = (SizeT)(Buffer - inStream);
#endif
*outSizeProcessed = nowPos;
return LZMA_RESULT_OK;
}

View File

@ -0,0 +1,113 @@
/*
LzmaDecode.h
LZMA Decoder interface
LZMA SDK 4.40 Copyright (c) 1999-2006 Igor Pavlov (2006-05-01)
http://www.7-zip.org/
LZMA SDK is licensed under two licenses:
1) GNU Lesser General Public License (GNU LGPL)
2) Common Public License (CPL)
It means that you can select one of these two licenses and
follow rules of that license.
SPECIAL EXCEPTION:
Igor Pavlov, as the author of this code, expressly permits you to
statically or dynamically link your code (or bind by name) to the
interfaces of this file without subjecting your linked code to the
terms of the CPL or GNU LGPL. Any modifications or additions
to this file, however, are subject to the LGPL or CPL terms.
*/
#ifndef __LZMADECODE_H
#define __LZMADECODE_H
#include "LzmaTypes.h"
/* #define _LZMA_IN_CB */
/* Use callback for input data */
/* #define _LZMA_OUT_READ */
/* Use read function for output data */
/* #define _LZMA_PROB32 */
/* It can increase speed on some 32-bit CPUs,
but memory usage will be doubled in that case */
/* #define _LZMA_LOC_OPT */
/* Enable local speed optimizations inside code */
#ifdef _LZMA_PROB32
#define CProb UInt32
#else
#define CProb UInt16
#endif
#define LZMA_RESULT_OK 0
#define LZMA_RESULT_DATA_ERROR 1
#ifdef _LZMA_IN_CB
typedef struct _ILzmaInCallback
{
int (*Read)(void *object, const unsigned char **buffer, SizeT *bufferSize);
} ILzmaInCallback;
#endif
#define LZMA_BASE_SIZE 1846
#define LZMA_LIT_SIZE 768
#define LZMA_PROPERTIES_SIZE 5
typedef struct _CLzmaProperties
{
int lc;
int lp;
int pb;
#ifdef _LZMA_OUT_READ
UInt32 DictionarySize;
#endif
}CLzmaProperties;
int LzmaDecodeProperties(CLzmaProperties *propsRes, const unsigned char *propsData, int size);
#define LzmaGetNumProbs(Properties) (LZMA_BASE_SIZE + (LZMA_LIT_SIZE << ((Properties)->lc + (Properties)->lp)))
#define kLzmaNeedInitId (-2)
typedef struct _CLzmaDecoderState
{
CLzmaProperties Properties;
CProb *Probs;
#ifdef _LZMA_IN_CB
const unsigned char *Buffer;
const unsigned char *BufferLim;
#endif
#ifdef _LZMA_OUT_READ
unsigned char *Dictionary;
UInt32 Range;
UInt32 Code;
UInt32 DictionaryPos;
UInt32 GlobalPos;
UInt32 DistanceLimit;
UInt32 Reps[4];
int State;
int RemainLen;
unsigned char TempDictionary[4];
#endif
} CLzmaDecoderState;
#ifdef _LZMA_OUT_READ
#define LzmaDecoderInit(vs) { (vs)->RemainLen = kLzmaNeedInitId; }
#endif
int LzmaDecode(CLzmaDecoderState *vs,
#ifdef _LZMA_IN_CB
ILzmaInCallback *inCallback,
#else
const unsigned char *inStream, SizeT inSize, SizeT *inSizeProcessed,
#endif
unsigned char *outStream, SizeT outSize, SizeT *outSizeProcessed);
#endif

View File

@ -0,0 +1,45 @@
/*
LzmaTypes.h
Types for LZMA Decoder
This file written and distributed to public domain by Igor Pavlov.
This file is part of LZMA SDK 4.40 (2006-05-01)
*/
#ifndef __LZMATYPES_H
#define __LZMATYPES_H
#ifndef _7ZIP_BYTE_DEFINED
#define _7ZIP_BYTE_DEFINED
typedef unsigned char Byte;
#endif
#ifndef _7ZIP_UINT16_DEFINED
#define _7ZIP_UINT16_DEFINED
typedef unsigned short UInt16;
#endif
#ifndef _7ZIP_UINT32_DEFINED
#define _7ZIP_UINT32_DEFINED
#ifdef _LZMA_UINT32_IS_ULONG
typedef unsigned long UInt32;
#else
typedef unsigned int UInt32;
#endif
#endif
/* #define _LZMA_NO_SYSTEM_SIZE_T */
/* You can use it, if you don't want <stddef.h> */
#ifndef _7ZIP_SIZET_DEFINED
#define _7ZIP_SIZET_DEFINED
#ifdef _LZMA_NO_SYSTEM_SIZE_T
typedef UInt32 SizeT;
#else
#include <stddef.h>
typedef size_t SizeT;
#endif
#endif
#endif

View File

@ -0,0 +1,206 @@
/******************************************************************************
**
** FILE NAME : LzmaWrapper.c
** PROJECT : bootloader
** MODULES : U-boot
**
** DATE : 2 Nov 2006
** AUTHOR : Lin Mars
** DESCRIPTION : LZMA decoder support for U-boot 1.1.5
** COPYRIGHT : Copyright (c) 2006
** Infineon Technologies AG
** Am Campeon 1-12, 85579 Neubiberg, Germany
**
** This program 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.
**
** HISTORY
** $Date $Author $Comment
** 2 Nov 2006 Lin Mars init version which derived from LzmaTest.c from
** LZMA v4.43 SDK
** 24 May 2007 Lin Mars Fix issue for multiple lzma_inflate involved
*******************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "LzmaDecode.h"
#include "LzmaWrapper.h"
#if defined(DEBUG_ENABLE_BOOTSTRAP_PRINTF) || !defined(CFG_BOOTSTRAP_CODE)
static const char *kCantReadMessage = "Can not read from source buffer";
static const char *kCantAllocateMessage = "Not enough buffer for decompression";
#endif
static size_t rpos=0, dpos=0;
static int MyReadFileAndCheck(unsigned char *src, void *dest, size_t size)
{
if (size == 0)
return 0;
memcpy(dest, src + rpos, size);
rpos += size;
return 1;
}
int lzma_inflate(unsigned char *source, int s_len, unsigned char *dest, int *d_len)
{
/* We use two 32-bit integers to construct 64-bit integer for file size.
You can remove outSizeHigh, if you don't need >= 4GB supporting,
or you can use UInt64 outSize, if your compiler supports 64-bit integers*/
UInt32 outSize = 0;
UInt32 outSizeHigh = 0;
SizeT outSizeFull;
unsigned char *outStream;
int waitEOS = 1;
/* waitEOS = 1, if there is no uncompressed size in headers,
so decoder will wait EOS (End of Stream Marker) in compressed stream */
SizeT compressedSize;
unsigned char *inStream;
CLzmaDecoderState state; /* it's about 24-80 bytes structure, if int is 32-bit */
unsigned char properties[LZMA_PROPERTIES_SIZE];
int res;
rpos=0; dpos=0;
if (sizeof(UInt32) < 4)
{
#if defined(DEBUG_ENABLE_BOOTSTRAP_PRINTF) || !defined(CFG_BOOTSTRAP_CODE)
printf("LZMA decoder needs correct UInt32\n");
#endif
return LZMA_RESULT_DATA_ERROR;
}
{
long length=s_len;
if ((long)(SizeT)length != length)
{
#if defined(DEBUG_ENABLE_BOOTSTRAP_PRINTF) || !defined(CFG_BOOTSTRAP_CODE)
printf("Too big compressed stream\n");
#endif
return LZMA_RESULT_DATA_ERROR;
}
compressedSize = (SizeT)(length - (LZMA_PROPERTIES_SIZE + 8));
}
/* Read LZMA properties for compressed stream */
if (!MyReadFileAndCheck(source, properties, sizeof(properties)))
{
#if defined(DEBUG_ENABLE_BOOTSTRAP_PRINTF) || !defined(CFG_BOOTSTRAP_CODE)
printf("%s\n", kCantReadMessage);
#endif
return LZMA_RESULT_DATA_ERROR;
}
/* Read uncompressed size */
{
int i;
for (i = 0; i < 8; i++)
{
unsigned char b;
if (!MyReadFileAndCheck(source, &b, 1))
{
#if defined(DEBUG_ENABLE_BOOTSTRAP_PRINTF) || !defined(CFG_BOOTSTRAP_CODE)
printf("%s\n", kCantReadMessage);
#endif
return LZMA_RESULT_DATA_ERROR;
}
if (b != 0xFF)
waitEOS = 0;
if (i < 4)
outSize += (UInt32)(b) << (i * 8);
else
outSizeHigh += (UInt32)(b) << ((i - 4) * 8);
}
if (waitEOS)
{
#if defined(DEBUG_ENABLE_BOOTSTRAP_PRINTF) || !defined(CFG_BOOTSTRAP_CODE)
printf("Stream with EOS marker is not supported");
#endif
return LZMA_RESULT_DATA_ERROR;
}
outSizeFull = (SizeT)outSize;
if (sizeof(SizeT) >= 8)
outSizeFull |= (((SizeT)outSizeHigh << 16) << 16);
else if (outSizeHigh != 0 || (UInt32)(SizeT)outSize != outSize)
{
#if defined(DEBUG_ENABLE_BOOTSTRAP_PRINTF) || !defined(CFG_BOOTSTRAP_CODE)
printf("Too big uncompressed stream");
#endif
return LZMA_RESULT_DATA_ERROR;
}
}
/* Decode LZMA properties and allocate memory */
if (LzmaDecodeProperties(&state.Properties, properties, LZMA_PROPERTIES_SIZE) != LZMA_RESULT_OK)
{
#if defined(DEBUG_ENABLE_BOOTSTRAP_PRINTF) || !defined(CFG_BOOTSTRAP_CODE)
printf("Incorrect stream properties");
#endif
return LZMA_RESULT_DATA_ERROR;
}
state.Probs = (CProb *)malloc(LzmaGetNumProbs(&state.Properties) * sizeof(CProb));
if (outSizeFull == 0)
outStream = 0;
else
{
if (outSizeFull > d_len)
outStream = 0;
else
outStream = dest;
}
if (compressedSize == 0)
inStream = 0;
else
{
if ((compressedSize+rpos) > s_len )
inStream = 0;
else
inStream = source + rpos;
}
if (state.Probs == 0
|| (outStream == 0 && outSizeFull != 0)
|| (inStream == 0 && compressedSize != 0)
)
{
free(state.Probs);
#if defined(DEBUG_ENABLE_BOOTSTRAP_PRINTF) || !defined(CFG_BOOTSTRAP_CODE)
printf("%s\n", kCantAllocateMessage);
#endif
return LZMA_RESULT_DATA_ERROR;
}
/* Decompress */
{
SizeT inProcessed;
SizeT outProcessed;
res = LzmaDecode(&state,
inStream, compressedSize, &inProcessed,
outStream, outSizeFull, &outProcessed);
if (res != 0)
{
#if defined(DEBUG_ENABLE_BOOTSTRAP_PRINTF) || !defined(CFG_BOOTSTRAP_CODE)
printf("\nDecoding error = %d\n", res);
#endif
res = 1;
}
else
{
*d_len = outProcessed;
}
}
free(state.Probs);
return res;
}

View File

@ -0,0 +1,36 @@
/******************************************************************************
**
** FILE NAME : LzmaWrapper.h
** PROJECT : bootloader
** MODULES : U-boot
**
** DATE : 2 Nov 2006
** AUTHOR : Lin Mars
** DESCRIPTION : LZMA decoder support for U-boot 1.1.5
** COPYRIGHT : Copyright (c) 2006
** Infineon Technologies AG
** Am Campeon 1-12, 85579 Neubiberg, Germany
**
** This program 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.
**
** HISTORY
** $Date $Author $Comment
** 2 Nov 2006 Lin Mars init version which derived from LzmaTest.c from
** LZMA v4.43 SDK
*******************************************************************************/
#ifndef __LZMA_WRAPPER_H__
#define __LZMA_WRAPPER_H__
#ifndef LZMA_RESULT_OK
#define LZMA_RESULT_OK 0
#endif
#ifndef LZMA_RESULT_DATA_ERROR
#define LZMA_RESULT_DATA_ERROR 1
#endif
extern int lzma_inflate(unsigned char *source, int s_len, unsigned char *dest, int *d_len);
#endif /*__LZMA_WRAPPER_H__*/

View File

@ -0,0 +1,13 @@
PROG=w921v_fw_cutter
OBJS=w921v_fw_cutter.c LzmaDecode.c LzmaWrapper.c
all: $(PROG)
$(PROG): $(OBJS)
$(CC) $(CFLAGS) $(LDFLAGS) $^ -o $@
clean:
rm *.o $(PROG)
%.o: %.c
$(CC) $(CFLAGS) -c $^ -o $@

View File

@ -0,0 +1,48 @@
#!/bin/sh
FW="/tmp/Firmware_Speedport_W921V_1.20.000.bin"
URL="http://hilfe.telekom.de/dlp/eki/downloads/Speedport/Speedport%20W%20921V/Firmware_Speedport_W921V_1.20.000.bin"
FW_TAPI="/tmp/vr9_tapi_fw.bin"
FW_DSL="/tmp/vr9_dsl_fw_annex_b.bin"
FW_TGZ="/tmp/vr9_fw.tgz"
MD5_FW="4d812f2c3476dadd738b022c4767c491"
MD5_TAPI="06b6ab3481b8d3eb7e8bf6131f7f6b7f"
MD5_DSL="59dd9dc81195c6854433c691b163f757"
[ -f /lib/firmware/vdsl.bin] && exit 0
[ -z "$1" ] || URL=$1
[ -f "${FW}" ] || {
echo "${FW} does not exist. Try to Download it ? (y/N)"
read -n 1 R
echo ""
[ "$R" = "y" ] || {
echo "Please manually download the firmware from ${URL} and copy the file to ${FW}"
exit 1
}
echo "Download w921v Firmware"
wget "${URL}" -O "${FW}"
[ $? -eq 0 -a -f "${FW}" ] || exit 1
}
F=`md5sum -b ${FW} | cut -d" " -f1`
[ "$F" = "${MD5_FW}" ] || {
echo "Failed to verify Firmware MD5"
exit 1
}
echo "Unpack and decompress w921v Firmware"
w921v_fw_cutter
[ $? -eq 0 ] || exit 1
T=`md5sum -b ${FW_TAPI} | cut -d" " -f1`
D=`md5sum -b ${FW_DSL} | cut -d" " -f1`
[ "$T" = "${MD5_TAPI}" -a "$D" = "${MD5_DSL}" ] || {
echo "Failed to verify MD5"
exit 1
}
cp ${FW_TAPI} ${FW_DSL} /lib/firmware/
ln -s /lib/firmware/vr9_dsl_fw_annex_b.bin /lib/firmware/vdsl.bin

View File

@ -0,0 +1,164 @@
/*
* This program 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; version 2 of the License
*
* This program 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 this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
*
* Copyright (C) 2012 John Crispin <blogic@openwrt.org>
*/
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <fcntl.h>
#include "LzmaWrapper.h"
#define FW_NAME "/tmp/Firmware_Speedport_W921V_1.20.000.bin"
#define MAGIC 0x50
#define MAGIC_SZ 0x3FFC00
#if __BYTE_ORDER == __LITTLE_ENDIAN
#define MAGIC_PART 0x12345678
#define MAGIC_LZMA 0x8000005D
#define MAGIC_ANNEX_B 0x3C
#define MAGIC_TAPI 0x5A
#else
#define MAGIC_PART 0x78563412
#define MAGIC_LZMA 0x5D000080
#define MAGIC_ANNEX_B 0x3C000000
#define MAGIC_TAPI 0x5A000000
#endif
const char* part_type(u_int32_t id)
{
switch(id) {
case MAGIC_ANNEX_B:
return "/tmp/vr9_dsl_fw_annex_b.bin";
case MAGIC_TAPI:
return "/tmp/vr9_tapi_fw.bin";
}
printf("\tUnknown lzma type 0x%02X\n", id);
return "/tmp/unknown.lzma";
}
int main(int argc, char **argv)
{
struct stat s;
u_int8_t *buf_orig;
u_int32_t *buf;
int buflen;
int fd;
int i;
int err;
int start = 0, end = 0;
printf("Arcadyan Firmware cutter v0.1\n");
printf("-----------------------------\n");
printf("This tool extracts the different parts of an arcadyan firmware update file\n");
printf("This tool is for private use only. The Firmware that gets extracted has a license that forbids redistribution\n");
printf("Please only run this if you understand the risks\n\n");
printf("I understand the risks ? (y/N)\n");
if (getchar() != 'y')
return -1;
if (stat(FW_NAME, &s) != 0) {
printf("Failed to find %s\n", FW_NAME);
printf("Ask Google or try http://hilfe.telekom.de/dlp/eki/downloads/Speedport/Speedport%20W%20921V/Firmware_Speedport_W921V_1.20.000.bin\n");
return -1;
}
buf_orig = malloc(s.st_size);
if (!buf_orig) {
printf("Failed to alloc %d bytes\n", s.st_size);
return -1;
}
fd = open(FW_NAME, O_RDONLY);
if (fd < 0) {
printf("Unable to open %s\n", FW_NAME);
return -1;
}
buflen = read(fd, buf_orig, s.st_size);
close(fd);
if (buflen != s.st_size) {
printf("Loaded %d instead of %d bytes inside %s\n", buflen, s.st_size, FW_NAME);
return -1;
}
/* <magic> */
buf_orig++;
buflen -= 1;
for (i = 0; i < MAGIC_SZ; i++) {
if ((i % 16) < 3)
buf_orig[i] = buf_orig[i + 16] ^ MAGIC;
else
buf_orig[i] = buf_orig[i] ^ MAGIC;
}
buflen -= 3;
memmove(&buf_orig[MAGIC_SZ], &buf_orig[MAGIC_SZ + 3], buflen - MAGIC_SZ);
/* </magic> */
buf = (u_int32_t*) buf_orig;
do {
if (buf[end] == MAGIC_PART) {
end += 2;
printf("Found partition at 0x%08X with size %d\n",
start * sizeof(u_int32_t),
(end - start) * sizeof(u_int32_t));
if (buf[start] == MAGIC_LZMA) {
int dest_len = 1024 * 1024;
int len = buf[end - 3];
u_int32_t id = buf[end - 6];
const char *type = part_type(id);
u_int8_t *dest;
dest = malloc(dest_len);
if (!dest) {
printf("Failed to alloc dest buffer\n");
return -1;
}
if (lzma_inflate((u_int8_t*)&buf[start], len, dest, &dest_len)) {
printf("Failed to decompress data\n");
return -1;
}
fd = creat(type, S_IRUSR | S_IWUSR);
if (fd != -1) {
if (write(fd, dest, dest_len) != dest_len)
printf("\tFailed to write %d bytes\n", dest_len);
else
printf("\tWrote %d bytes to %s\n", dest_len, type);
close(fd);
} else {
printf("\tFailed to open %s\n", type);
}
free(dest);
} else {
printf("\tThis is not lzma\n");
}
start = end;
} else {
end++;
}
} while(end < buflen / sizeof(u_int32_t));
return 0;
}