strip the kernel version suffix from target directories, except for brcm-2.4 (the -2.4 will be included in the board name here). CONFIG_LINUX_<ver>_<board> becomes CONFIG_TARGET_<board>, same for profiles.

SVN-Revision: 8653
This commit is contained in:
Felix Fietkau
2007-09-06 16:27:37 +00:00
parent e1184aaa1a
commit 56231056ea
701 changed files with 48 additions and 105 deletions

View File

@@ -0,0 +1,177 @@
#
# Copyright (C) 2006,2007 OpenWrt.org
#
# This is free software, licensed under the GNU General Public License v2.
# See /LICENSE for more information.
#
include $(TOPDIR)/rules.mk
include $(INCLUDE_DIR)/image.mk
IMGNAME = $(BIN_DIR)/openwrt-$(BOARD)-$(KERNEL)
LOADER_MAKE = $(NO_TRACE_MAKE) -C lzma-loader KDIR=$(KDIR)
define Image/Build/Loader
$(LOADER_MAKE) LOADER=loader-$(1).$(2) LOADER_DATA="" \
LZMA_TEXT_START=$(3) LZMA_STARTUP_ORG=$(4) \
CONFIG_PASS_KARGS=$(5) CONFIG_BOARD=$(6) \
compile loader.$(2)
endef
define Build/Clean
$(LOADER_MAKE) clean
endef
define Image/Prepare
cat $(KDIR)/vmlinux | $(STAGING_DIR_HOST)/bin/lzma e -si -so -eos -lc1 -lp2 -pb2 > $(KDIR)/vmlinux.lzma
endef
define trxalign/jffs2-128k
-a 0x20000
endef
define trxalign/jffs2-64k
-a 0x10000
endef
define trxalign/squashfs
-a 1024
endef
define Image/Build/TRX
$(STAGING_DIR_HOST)/bin/trx -o $(1) -f $(3) -f $(KDIR)/vmlinux.lzma \
$(call trxalign/$(2)) -f $(KDIR)/root.$(2)
endef
define Image/Build/TRXNoloader
$(STAGING_DIR_HOST)/bin/trx -o $(1) -f $(KDIR)/vmlinux.lzma \
$(call trxalign/$(2)) -f $(KDIR)/root.$(2)
endef
define Image/Build/Compex
$(call Image/Build/Loader,$(2),gz,0x80500000,0,y,$(2))
$(call Image/Build/TRX,$(IMGNAME)-$(3)-$(2).trx,$(1),$(KDIR)/loader-$(2).gz)
endef
define Image/Build/Edimax
$(call Image/Build/Loader,$(2),gz,0x80500000,0x6D8,y,$(2))
$(call Image/Build/TRXNoloader,$(IMGNAME)-$(3)-$(2).trx,$(1))
$(STAGING_DIR_HOST)/bin/mkcsysimg -B $(2) -d -w \
-r $(KDIR)/loader-$(2).gz \
-x $(IMGNAME)-$(3)-$(2).trx \
$(IMGNAME)-$(3)-$(2).bin
endef
define Image/Build/Infineon
$(call Image/Build/Loader,$(2),gz,0x80500000,0x6D8,y,$(2))
$(call Image/Build/TRXNoloader,$(IMGNAME)-$(3)-$(2).trx,$(1))
dd if=$(KDIR)/loader-$(2).gz of=$(IMGNAME)-$(3)-$(2).img bs=64k conv=sync
cat $(IMGNAME)-$(3)-$(2).trx >>$(IMGNAME)-$(3)-$(2).img
endef
define Image/Build/MyLoader
$(call Image/Build/Loader,$(2),gz,0x80500000,0)
$(call Image/Build/TRXNoloader,$(IMGNAME)-$(3)-$(2).trx,$(1))
$(STAGING_DIR_HOST)/bin/mkmylofw -B $(2) \
-p0x20000:0x10000:ahp:0x80001000 \
-p0x30000:0 \
-b0x20000:0x10000:h:$(KDIR)/loader-$(2).gz \
-b0x30000:0::$(IMGNAME)-$(3)-$(2).trx \
$(IMGNAME)-$(3)-$(2).bin
endef
define Image/cmdline/yaffs2
root=/dev/mtdblock1 rootfstype=yaffs2 init=/etc/preinit
endef
define Image/Build/RouterBoard
$(CP) $(KDIR)/vmlinux.elf $(IMGNAME)-rb1xx-vmlinux
$(STAGING_DIR_HOST)/bin/patch-cmdline $(KDIR)/vmlinux.elf '$(strip $(call Image/cmdline/yaffs2)) '
endef
define Image/Build/jffs2-64k
$(call Image/Build/Compex,$(1),wp54g-wrt,$(patsubst jffs2-%,jffs2,$(1)))
ifeq ($(CONFIG_DEVEL),y)
$(call Image/Build/Edimax,$(1),br-6104k,$(patsubst jffs2-%,jffs2,$(1)))
$(call Image/Build/Edimax,$(1),br-6104kp,$(patsubst jffs2-%,jffs2,$(1)))
$(call Image/Build/Edimax,$(1),br-6114wg,$(patsubst jffs2-%,jffs2,$(1)))
$(call Image/Build/Edimax,$(1),br-6524k,$(patsubst jffs2-%,jffs2,$(1)))
$(call Image/Build/Edimax,$(1),br-6524kp,$(patsubst jffs2-%,jffs2,$(1)))
$(call Image/Build/Edimax,$(1),br-6541k,$(patsubst jffs2-%,jffs2,$(1)))
$(call Image/Build/Edimax,$(1),br-6541kp,$(patsubst jffs2-%,jffs2,$(1)))
$(call Image/Build/Edimax,$(1),ew-7207apg,$(patsubst jffs2-%,jffs2,$(1)))
$(call Image/Build/Edimax,$(1),ps-1205uwg,$(patsubst jffs2-%,jffs2,$(1)))
$(call Image/Build/Edimax,$(1),ps-3205u,$(patsubst jffs2-%,jffs2,$(1)))
$(call Image/Build/Edimax,$(1),ps-3205uwg,$(patsubst jffs2-%,jffs2,$(1)))
$(call Image/Build/Edimax,$(1),br-6524wg,$(patsubst jffs2-%,jffs2,$(1)))
$(call Image/Build/Edimax,$(1),br-6524wp,$(patsubst jffs2-%,jffs2,$(1)))
$(call Image/Build/Infineon,$(1),easy-5120p-ata,$(patsubst jffs2-%,jffs2,$(1)))
$(call Image/Build/Infineon,$(1),easy-5120-rt,$(patsubst jffs2-%,jffs2,$(1)))
$(call Image/Build/Infineon,$(1),easy-5120-wvoip,$(patsubst jffs2-%,jffs2,$(1)))
$(call Image/Build/Infineon,$(1),easy-83000,$(patsubst jffs2-%,jffs2,$(1)))
$(call Image/Build/MyLoader,$(1),np27g,$(patsubst jffs2-%,jffs2,$(1)))
$(call Image/Build/MyLoader,$(1),np28g,$(patsubst jffs2-%,jffs2,$(1)))
$(call Image/Build/MyLoader,$(1),np28ghs,$(patsubst jffs2-%,jffs2,$(1)))
$(call Image/Build/MyLoader,$(1),wp54g,$(patsubst jffs2-%,jffs2,$(1)))
$(call Image/Build/MyLoader,$(1),wp54ag,$(patsubst jffs2-%,jffs2,$(1)))
$(call Image/Build/MyLoader,$(1),wpp54g,$(patsubst jffs2-%,jffs2,$(1)))
$(call Image/Build/MyLoader,$(1),wpp54ag,$(patsubst jffs2-%,jffs2,$(1)))
endif
endef
define Image/Build/squashfs
$(call Image/Build/jffs2-64k,$(1))
endef
define Image/Build
$(call Image/Build/$(1),$(1))
endef
ifneq ($(CONFIG_TARGET_ROOTFS_INITRAMFS),y)
define Image/BuildKernel
$(call Image/Build/RouterBoard)
endef
endif
define Image/Build/LZMAKernel
$(LOADER_MAKE) TARGET_DIR=$(BIN_DIR) \
LOADER=openwrt-$(BOARD)-$(KERNEL)-ramfs-lzma-$(1).$(2) \
LOADER_DATA=$(KDIR)/vmlinux.lzma \
LZMA_TEXT_START=$(3) LZMA_STARTUP_ORG=$(4) \
CONFIG_PASS_KARGS=$(5) CONFIG_BOARD=$(6) \
compile loader.$(2)
endef
define Image/Build/LZMAKernel/Compex
$(call Image/Build/LZMAKernel,$(1),$(2),0x80500000,0,y,$(1))
endef
define Image/Build/LZMAKernel/Generic
$(call Image/Build/LZMAKernel,$(1),$(2),0x80500000,0)
endef
define Image/Build/LZMAKernel/Admboot
$(call Image/Build/LZMAKernel,$(1),$(2),0x80500000,0x6D8,y,$(1))
endef
define Image/Build/Initramfs/RouterBoard
$(CP) $(KDIR)/vmlinux.elf $(IMGNAME)-ramfs-rb1xx.elf
endef
define Image/Build/Initramfs
$(call Image/Build/Initramfs/RouterBoard)
$(call Image/Build/LZMAKernel/Compex,wp54g-wrt,bin)
ifeq ($(CONFIG_DEVEL),y)
$(call Image/Build/LZMAKernel/Generic,generic,bin)
$(call Image/Build/LZMAKernel/Generic,np27g,bin)
$(call Image/Build/LZMAKernel/Generic,wp54g,bin)
$(call Image/Build/LZMAKernel/Admboot,br-6104k,gz)
$(call Image/Build/LZMAKernel/Admboot,easy-5120,gz)
$(call Image/Build/LZMAKernel/Admboot,easy-83000,gz)
$(call Image/Build/LZMAKernel/Admboot,cas-630,gz)
$(call Image/Build/LZMAKernel/Admboot,cas-670,gz)
$(call Image/Build/LZMAKernel/Admboot,cas-700,gz)
$(call Image/Build/LZMAKernel/Admboot,cas-771,gz)
$(call Image/Build/LZMAKernel/Admboot,cas-790,gz)
$(call Image/Build/LZMAKernel/Admboot,cas-861,gz)
endif
endef
$(eval $(call BuildImage))

View File

@@ -0,0 +1,63 @@
#
# Copyright (C) 2006 OpenWrt.org
#
# This is free software, licensed under the GNU General Public License v2.
# See /LICENSE for more information.
#
# $Id$
include $(TOPDIR)/rules.mk
LOADER := loader.bin
LOADER_NAME := $(basename $(notdir $(LOADER)))
LOADER_DATA :=
TARGET_DIR :=
ifeq ($(TARGET_DIR),)
TARGET_DIR := $(KDIR)
endif
LOADER_BIN := $(TARGET_DIR)/$(LOADER_NAME).bin
LOADER_GZ := $(TARGET_DIR)/$(LOADER_NAME).gz
LOADER_ELF := $(TARGET_DIR)/$(LOADER_NAME).elf
LZMA_STARTUP_ORG:= 0
LZMA_TEXT_START := 0x80300000
PKG_NAME := lzma-loader
PKG_BUILD_DIR := $(KDIR)/$(PKG_NAME)
.PHONY : loader-compile loader.bin loader.elf loader.gz
$(PKG_BUILD_DIR)/.prepared:
mkdir $(PKG_BUILD_DIR)
$(CP) ./src/* $(PKG_BUILD_DIR)/
touch $@
loader-compile: $(PKG_BUILD_DIR)/.prepared
$(MAKE) -C $(PKG_BUILD_DIR) CROSS_COMPILE="$(TARGET_CROSS)" \
LZMA_STARTUP_ORG=$(LZMA_STARTUP_ORG) \
LZMA_TEXT_START=$(LZMA_TEXT_START) \
LOADER_DATA=$(LOADER_DATA) \
CONFIG_BOARD=$(CONFIG_BOARD) \
CONFIG_PASS_KARGS=$(CONFIG_PASS_KARGS) \
clean all
loader.gz: $(PKG_BUILD_DIR)/loader.bin
gzip -nc9 $< > $(LOADER_GZ)
loader.elf: $(PKG_BUILD_DIR)/loader.elf
$(CP) $< $(LOADER_ELF)
loader.bin: $(PKG_BUILD_DIR)/loader.bin
$(CP) $< $(LOADER_BIN)
download:
prepare: $(PKG_BUILD_DIR)/.prepared
compile: loader-compile
install:
clean:
rm -rf $(PKG_BUILD_DIR)

View File

@@ -0,0 +1,589 @@
/*
LzmaDecode.c
LZMA Decoder (optimized for Speed version)
LZMA SDK 4.16 Copyright (c) 1999-2005 Igor Pavlov (2005-03-18)
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"
#ifndef Byte
#define Byte unsigned char
#endif
#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) \
{ UInt32 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
#ifdef _LZMA_OUT_READ
typedef struct _LzmaVarState
{
Byte *Buffer;
Byte *BufferLim;
UInt32 Range;
UInt32 Code;
#ifdef _LZMA_IN_CB
ILzmaInCallback *InCallback;
#endif
Byte *Dictionary;
UInt32 DictionarySize;
UInt32 DictionaryPos;
UInt32 GlobalPos;
UInt32 Reps[4];
int lc;
int lp;
int pb;
int State;
int RemainLen;
Byte TempDictionary[4];
} LzmaVarState;
int LzmaDecoderInit(
unsigned char *buffer, UInt32 bufferSize,
int lc, int lp, int pb,
unsigned char *dictionary, UInt32 dictionarySize,
#ifdef _LZMA_IN_CB
ILzmaInCallback *InCallback
#else
unsigned char *inStream, UInt32 inSize
#endif
)
{
Byte *Buffer;
Byte *BufferLim;
UInt32 Range;
UInt32 Code;
LzmaVarState *vs = (LzmaVarState *)buffer;
CProb *p = (CProb *)(buffer + sizeof(LzmaVarState));
UInt32 numProbs = Literal + ((UInt32)LZMA_LIT_SIZE << (lc + lp));
UInt32 i;
if (bufferSize < numProbs * sizeof(CProb) + sizeof(LzmaVarState))
return LZMA_RESULT_NOT_ENOUGH_MEM;
vs->Dictionary = dictionary;
vs->DictionarySize = dictionarySize;
vs->DictionaryPos = 0;
vs->GlobalPos = 0;
vs->Reps[0] = vs->Reps[1] = vs->Reps[2] = vs->Reps[3] = 1;
vs->lc = lc;
vs->lp = lp;
vs->pb = pb;
vs->State = 0;
vs->RemainLen = 0;
dictionary[dictionarySize - 1] = 0;
for (i = 0; i < numProbs; i++)
p[i] = kBitModelTotal >> 1;
#ifdef _LZMA_IN_CB
RC_INIT;
#else
RC_INIT(inStream, inSize);
#endif
vs->Buffer = Buffer;
vs->BufferLim = BufferLim;
vs->Range = Range;
vs->Code = Code;
#ifdef _LZMA_IN_CB
vs->InCallback = InCallback;
#endif
return LZMA_RESULT_OK;
}
int LzmaDecode(unsigned char *buffer,
unsigned char *outStream, UInt32 outSize,
UInt32 *outSizeProcessed)
{
LzmaVarState *vs = (LzmaVarState *)buffer;
Byte *Buffer = vs->Buffer;
Byte *BufferLim = vs->BufferLim;
UInt32 Range = vs->Range;
UInt32 Code = vs->Code;
#ifdef _LZMA_IN_CB
ILzmaInCallback *InCallback = vs->InCallback;
#endif
CProb *p = (CProb *)(buffer + sizeof(LzmaVarState));
int state = vs->State;
Byte previousByte;
UInt32 rep0 = vs->Reps[0], rep1 = vs->Reps[1], rep2 = vs->Reps[2], rep3 = vs->Reps[3];
UInt32 nowPos = 0;
UInt32 posStateMask = (1 << (vs->pb)) - 1;
UInt32 literalPosMask = (1 << (vs->lp)) - 1;
int lc = vs->lc;
int len = vs->RemainLen;
UInt32 globalPos = vs->GlobalPos;
Byte *dictionary = vs->Dictionary;
UInt32 dictionarySize = vs->DictionarySize;
UInt32 dictionaryPos = vs->DictionaryPos;
Byte tempDictionary[4];
if (dictionarySize == 0)
{
dictionary = tempDictionary;
dictionarySize = 1;
tempDictionary[0] = vs->TempDictionary[0];
}
if (len == -1)
{
*outSizeProcessed = 0;
return LZMA_RESULT_OK;
}
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
int LzmaDecode(
Byte *buffer, UInt32 bufferSize,
int lc, int lp, int pb,
#ifdef _LZMA_IN_CB
ILzmaInCallback *InCallback,
#else
unsigned char *inStream, UInt32 inSize,
#endif
unsigned char *outStream, UInt32 outSize,
UInt32 *outSizeProcessed)
{
UInt32 numProbs = Literal + ((UInt32)LZMA_LIT_SIZE << (lc + lp));
CProb *p = (CProb *)buffer;
UInt32 i;
int state = 0;
Byte previousByte = 0;
UInt32 rep0 = 1, rep1 = 1, rep2 = 1, rep3 = 1;
UInt32 nowPos = 0;
UInt32 posStateMask = (1 << pb) - 1;
UInt32 literalPosMask = (1 << lp) - 1;
int len = 0;
Byte *Buffer;
Byte *BufferLim;
UInt32 Range;
UInt32 Code;
if (bufferSize < numProbs * sizeof(CProb))
return LZMA_RESULT_NOT_ENOUGH_MEM;
for (i = 0; i < numProbs; i++)
p[i] = kBitModelTotal >> 1;
#ifdef _LZMA_IN_CB
RC_INIT;
#else
RC_INIT(inStream, inSize);
#endif
#endif
*outSizeProcessed = 0;
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
// prob += 0x100;
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);
// prob -= 0x100;
}
while (symbol < 0x100)
{
CProb *probLit = prob + symbol;
RC_GET_BIT(probLit, symbol)
}
previousByte = (Byte)symbol;
outStream[nowPos++] = previousByte;
#ifdef _LZMA_OUT_READ
dictionary[dictionaryPos] = previousByte;
if (++dictionaryPos == dictionarySize)
dictionaryPos = 0;
#endif
if (state < 4) state = 0;
else if (state < 10) state -= 3;
else state -= 6;
}
else
{
// int isItRep;
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);
if (nowPos
#ifdef _LZMA_OUT_READ
+ globalPos
#endif
== 0)
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;
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 = -1;
break;
}
}
len += kMatchMinLen;
if (rep0 > nowPos
#ifdef _LZMA_OUT_READ
+ globalPos || rep0 > dictionarySize
#endif
)
return LZMA_RESULT_DATA_ERROR;
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->Buffer = Buffer;
vs->BufferLim = BufferLim;
vs->Range = Range;
vs->Code = Code;
vs->DictionaryPos = dictionaryPos;
vs->GlobalPos = globalPos + nowPos;
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
*outSizeProcessed = nowPos;
return LZMA_RESULT_OK;
}

View File

@@ -0,0 +1,100 @@
/*
LzmaDecode.h
LZMA Decoder interface
LZMA SDK 4.16 Copyright (c) 1999-2005 Igor Pavlov (2005-03-18)
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
/* #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 */
#ifndef UInt32
#ifdef _LZMA_UINT32_IS_ULONG
#define UInt32 unsigned long
#else
#define UInt32 unsigned int
#endif
#endif
#ifdef _LZMA_PROB32
#define CProb UInt32
#else
#define CProb unsigned short
#endif
#define LZMA_RESULT_OK 0
#define LZMA_RESULT_DATA_ERROR 1
#define LZMA_RESULT_NOT_ENOUGH_MEM 2
#ifdef _LZMA_IN_CB
typedef struct _ILzmaInCallback
{
int (*Read)(void *object, unsigned char **buffer, UInt32 *bufferSize);
} ILzmaInCallback;
#endif
#define LZMA_BASE_SIZE 1846
#define LZMA_LIT_SIZE 768
/*
bufferSize = (LZMA_BASE_SIZE + (LZMA_LIT_SIZE << (lc + lp)))* sizeof(CProb)
bufferSize += 100 in case of _LZMA_OUT_READ
by default CProb is unsigned short,
but if specify _LZMA_PROB_32, CProb will be UInt32(unsigned int)
*/
#ifdef _LZMA_OUT_READ
int LzmaDecoderInit(
unsigned char *buffer, UInt32 bufferSize,
int lc, int lp, int pb,
unsigned char *dictionary, UInt32 dictionarySize,
#ifdef _LZMA_IN_CB
ILzmaInCallback *inCallback
#else
unsigned char *inStream, UInt32 inSize
#endif
);
#endif
int LzmaDecode(
unsigned char *buffer,
#ifndef _LZMA_OUT_READ
UInt32 bufferSize,
int lc, int lp, int pb,
#ifdef _LZMA_IN_CB
ILzmaInCallback *inCallback,
#else
unsigned char *inStream, UInt32 inSize,
#endif
#endif
unsigned char *outStream, UInt32 outSize,
UInt32 *outSizeProcessed);
#endif

View File

@@ -0,0 +1,99 @@
#
# Makefile for Broadcom BCM947XX boards
#
# Copyright 2001-2003, Broadcom Corporation
# All Rights Reserved.
#
# THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
# KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM
# SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
# FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
#
# Copyright 2004 Manuel Novoa III <mjn3@codepoet.org>
# Modified to support bzip'd kernels.
# Of course, it would be better to integrate bunzip capability into CFE.
#
# Copyright 2005 Oleg I. Vdovikin <oleg@cs.msu.su>
# Cleaned up, modified for lzma support, removed from kernel
#
# Copyright 2007 Gabor Juhos <juhosg at openwrt.org>
# Modified to support user defined entry point address.
# Added support for make targets with different names
#
LOADADDR := 0x80001000
LZMA_TEXT_START := 0x80500000
LZMA_STARTUP_ORG:= 0
LOADER_DATA :=
CONFIG_PASS_KARGS :=
CONFIG_BOARD :=
CC := $(CROSS_COMPILE)gcc
LD := $(CROSS_COMPILE)ld
OBJCOPY := $(CROSS_COMPILE)objcopy
OBJDUMP := $(CROSS_COMPILE)objdump
BIN_FLAGS := -O binary -R .reginfo -R .note -R .comment -R .mdebug -S
CFLAGS = -D__KERNEL__ -Wall -Wstrict-prototypes -Wno-trigraphs -Os \
-fno-strict-aliasing -fno-common -fomit-frame-pointer -G 0 -mno-abicalls -fno-pic \
-ffunction-sections -pipe -mlong-calls -fno-common \
-ffreestanding \
-mabi=32 -march=mips32 -Wa,-32 -Wa,-march=mips32 -Wa,-mips32 -Wa,--trap
CFLAGS += -DLOADADDR=$(LOADADDR)
ASFLAGS = $(CFLAGS) -D__ASSEMBLY__ -DLZMA_STARTUP_ORG=$(LZMA_STARTUP_ORG)
LDFLAGS = -static --gc-sections -no-warn-mismatch
LDFLAGS += -e startup -T loader.lds -Ttext $(LZMA_TEXT_START)
O_FORMAT = $(shell $(OBJDUMP) -i | head -2 | grep elf32)
OBJECTS := head.o decompress.o board.o printf.o LzmaDecode.o
ifneq ($(strip $(LOADER_DATA)),)
OBJECTS += data.o
CFLAGS += -DLZMA_WRAPPER=1
else
CFLAGS += -D_LZMA_IN_CB
endif
ifneq ($(strip $(CONFIG_PASS_KARGS)),)
CFLAGS += -DCONFIG_PASS_KARGS
endif
BOARD_DEF := $(strip $(CONFIG_BOARD))
BOARD_DEF := $(shell echo $(BOARD_DEF) | tr a-z A-Z | tr -d -)
ifneq ($(BOARD_DEF),)
CFLAGS += -DCONFIG_BOARD_$(BOARD_DEF)
endif
all: loader.bin
# Don't build dependencies, this may die if $(CC) isn't gcc
dep:
install:
%.o : %.c
$(CC) $(CFLAGS) -c -o $@ $<
%.o : %.S
$(CC) $(ASFLAGS) -c -o $@ $<
data.o: $(LOADER_DATA)
$(LD) -r -b binary --oformat $(O_FORMAT) -T lzma-data.lds -o $@ $<
loader.bin: loader.elf
$(OBJCOPY) $(BIN_FLAGS) $< $@
loader.elf: $(OBJECTS)
$(LD) $(LDFLAGS) -o $@ $(OBJECTS)
mrproper: clean
clean:
rm -f *.elf *.bin *.o

View File

@@ -0,0 +1,55 @@
/*
* LZMA compressed kernel decompressor for bcm947xx boards
*
* Copyright (C) 2005 by Oleg I. Vdovikin <oleg@cs.msu.su>
*
* 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.
*
* 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
*
*/
The code is intended to decompress kernel, being compressed using lzma utility
build using 7zip LZMA SDK. This utility is located in the LZMA_Alone directory
decompressor code expects that your .trx file consist of three partitions:
1) decompressor itself (this is gziped code which pmon/cfe will extract and run
on boot-up instead of real kernel)
2) LZMA compressed kernel (both streamed and regular modes are supported now)
3) Root filesystem
Please be sure to apply the following patch for use this new trx layout (it will
allow using both new and old trx files for root filesystem lookup code)
--- linuz/arch/mips/brcm-boards/bcm947xx/setup.c 2005-01-23 19:24:27.503322896 +0300
+++ linux/arch/mips/brcm-boards/bcm947xx/setup.c 2005-01-23 19:29:05.237100944 +0300
@@ -221,7 +221,9 @@
/* Try looking at TRX header for rootfs offset */
if (le32_to_cpu(trx->magic) == TRX_MAGIC) {
bcm947xx_parts[1].offset = off;
- if (le32_to_cpu(trx->offsets[1]) > off)
+ if (le32_to_cpu(trx->offsets[2]) > off)
+ off = le32_to_cpu(trx->offsets[2]);
+ else if (le32_to_cpu(trx->offsets[1]) > off)
off = le32_to_cpu(trx->offsets[1]);
continue;
}
Revision history:
0.02 Initial release
0.03 Added Mineharu Takahara <mtakahar@yahoo.com> patch to pass actual
output size to decoder (stream mode compressed input is not
a requirement anymore)
0.04 Reordered functions using lds script

View File

@@ -0,0 +1,178 @@
/*
* ADM5120 specific board support for LZMA decompressor
*
* Copyright (C) 2007 OpenWrt.org
* Copyright (C) 2007 Gabor Juhos <juhosg at openwrt.org>
*
* 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.
*
* 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
*/
#include <stddef.h>
#define READREG(r) *(volatile unsigned int *)(r)
#define WRITEREG(r,v) *(volatile unsigned int *)(r) = v
/*
* INTC definitions
*/
#define INTC_BASE 0xB2200000
/* INTC registers */
#define INTC_REG_IRQ_DISABLE 0x0C
/*
* UART definitions
*/
#define UART_BASE 0xB2600000
/* UART registers */
#define UART_REG_DATA 0x00 /* Data register */
#define UART_REG_ECR 0x04 /* Error Clear register */
#define UART_REG_LCRH 0x08 /* Line Control High register */
#define UART_REG_LCRM 0x0C /* Line Control Middle register */
#define UART_REG_LCRL 0x10 /* Line Control Low register */
#define UART_REG_CTRL 0x14 /* Control register */
#define UART_REG_FLAG 0x18 /* Flag register */
/* Control register bits */
#define UART_CTRL_EN ( 1 << 0 ) /* UART enable */
/* Line Control High register bits */
#define UART_LCRH_FEN ( 1 << 4 ) /* FIFO enable */
/* Flag register bits */
#define UART_FLAG_CTS ( 1 << 0 )
#define UART_FLAG_DSR ( 1 << 1 )
#define UART_FLAG_DCD ( 1 << 2 )
#define UART_FLAG_BUSY ( 1 << 3 )
#define UART_FLAG_RXFE ( 1 << 4 ) /* RX FIFO empty */
#define UART_FLAG_TXFF ( 1 << 5 ) /* TX FIFO full */
#define UART_FLAG_RXFF ( 1 << 6 ) /* RX FIFO full */
#define UART_FLAG_TXFE ( 1 << 7 ) /* TX FIFO empty */
/*
* SWITCH definitions
*/
#define SWITCH_BASE 0xB2000000
#define SWITCH_REG_CPUP_CONF 0x0024
#define SWITCH_REG_PORT_CONF0 0x0028
#define SWITCH_REG_GPIO_CONF0 0x00B8
#define SWITCH_REG_GPIO_CONF2 0x00BC
#define SWITCH_REG_PORT0_LED 0x0100
#define SWITCH_REG_PORT1_LED 0x0104
#define SWITCH_REG_PORT2_LED 0x0108
#define SWITCH_REG_PORT3_LED 0x010C
#define SWITCH_REG_PORT4_LED 0x0110
#define SWITCH_PORTS_HW 0x3F /* Hardware Ports */
/* CPUP_CONF register bits */
#define CPUP_CONF_DCPUP ( 1 << 0 ) /* Disable CPU port */
/* PORT_CONF0 register bits */
#define PORT_CONF0_DP_SHIFT 0 /* disable port shift*/
/*
* UART routines
*/
#define UART_READ(r) READREG(UART_BASE+(r))
#define UART_WRITE(r,v) WRITEREG(UART_BASE+(r),(v))
static void uart_init(void)
{
#if 0
unsigned int t;
/* disable uart */
UART_WRITE(UART_REG_CTRL, 0);
/* keep current baud rate */
t = UART_READ(UART_REG_LCRM);
UART_WRITE(UART_REG_LCRM, t);
t = UART_READ(UART_REG_LCRL);
UART_WRITE(UART_REG_LCRL, t);
/* keep data, stop, and parity bits, but disable FIFO */
t = UART_READ(UART_REG_LCRH);
t &= ~(UART_LCRH_FEN);
UART_WRITE(UART_REG_LCRH, t );
/* clear error bits */
UART_WRITE(UART_REG_ECR, 0xFF);
/* enable uart, and disable interrupts */
UART_WRITE(UART_REG_CTRL, UART_CTRL_EN);
#endif
}
/*
* INTC routines
*/
#define INTC_READ(r) READREG(INTC_BASE+(r))
#define INTC_WRITE(r,v) WRITEREG(INTC_BASE+(r),v)
static void intc_init(void)
{
INTC_WRITE(INTC_REG_IRQ_DISABLE, 0xFFFFFFFF);
}
/*
* SWITCH routines
*/
#define SWITCH_READ(r) READREG(SWITCH_BASE+(r))
#define SWITCH_WRITE(r,v) WRITEREG(SWITCH_BASE+(r),v)
static void switch_init(void)
{
/* disable PHYS ports */
SWITCH_WRITE(SWITCH_REG_PORT_CONF0,
(SWITCH_PORTS_HW << PORT_CONF0_DP_SHIFT));
/* disable CPU port */
SWITCH_WRITE(SWITCH_REG_CPUP_CONF, CPUP_CONF_DCPUP);
/* disable GPIO lines */
SWITCH_WRITE(SWITCH_REG_GPIO_CONF0, 0);
SWITCH_WRITE(SWITCH_REG_GPIO_CONF2, 0);
/* disable LED lines */
SWITCH_WRITE(SWITCH_REG_PORT0_LED, 0);
SWITCH_WRITE(SWITCH_REG_PORT1_LED, 0);
SWITCH_WRITE(SWITCH_REG_PORT2_LED, 0);
SWITCH_WRITE(SWITCH_REG_PORT3_LED, 0);
SWITCH_WRITE(SWITCH_REG_PORT4_LED, 0);
}
void board_putc(int ch)
{
while ((UART_READ(UART_REG_FLAG) & UART_FLAG_TXFE) == 0);
UART_WRITE(UART_REG_DATA, ch);
while ((UART_READ(UART_REG_FLAG) & UART_FLAG_TXFE) == 0);
}
void board_init(void)
{
intc_init();
switch_init();
uart_init();
}

View File

@@ -0,0 +1,119 @@
#ifndef _CONFIG_H_
#define _CONFIG_H_
#define FLASH_2M (2<<20)
#define FLASH_4M (4<<20)
/*
* Cellvision/SparkLAN boards
*/
#if defined(CONFIG_BOARD_CAS630)
# define CONFIG_BOARD_NAME "CAS-630"
# define CONFIG_FLASH_SIZE FLASH_4M
#endif
#if defined(CONFIG_BOARD_CAS670)
# define CONFIG_BOARD_NAME "CAS-670"
# define CONFIG_FLASH_SIZE FLASH_4M
#endif
#if defined(CONFIG_BOARD_CAS700)
# define CONFIG_BOARD_NAME "CAS-700"
# define CONFIG_FLASH_SIZE FLASH_4M
#endif
#if defined(CONFIG_BOARD_CAS790)
# define CONFIG_BOARD_NAME "CAS-790"
# define CONFIG_FLASH_SIZE FLASH_4M
#endif
#if defined(CONFIG_BOARD_CAS771)
# define CONFIG_BOARD_NAME "CAS-771"
# define CONFIG_FLASH_SIZE FLASH_4M
#endif
#if defined(CONFIG_BOARD_CAS861)
# define CONFIG_BOARD_NAME "CAS-861"
# define CONFIG_FLASH_SIZE FLASH_4M
#endif
#if defined(CONFIG_BOARD_NFS101U)
# define CONFIG_BOARD_NAME "NFS-101U"
# define CONFIG_FLASH_SIZE FLASH_4M
#endif
#if defined(CONFIG_BOARD_NFS202U)
# define CONFIG_BOARD_NAME "NFS-202U"
# define CONFIG_FLASH_SIZE FLASH_4M
#endif
/*
* Compex boards
*/
#if defined(CONFIG_BOARD_WP54GWRT)
# define CONFIG_BOARD_NAME "WP54G-WRT"
# define CONFIG_FLASH_SIZE FLASH_4M
#endif
/*
* Edimax boards
*/
#if defined(CONFIG_BOARD_BR6104K)
# define CONFIG_BOARD_NAME "BR-6104K"
# define CONFIG_FLASH_SIZE FLASH_2M
#endif
#if defined(CONFIG_BOARD_BR6104KP)
# define CONFIG_BOARD_NAME "BR-6104KP"
# define CONFIG_FLASH_SIZE FLASH_2M
#endif
/*
* Infineon boards
*/
#if defined(CONFIG_BOARD_EASY5120PATA)
# define CONFIG_BOARD_NAME "EASY 5120P-ATA"
# define CONFIG_FLASH_SIZE FLASH_4M
#endif
#if defined(CONFIG_BOARD_EASY5120RT)
# define CONFIG_BOARD_NAME "EASY 5120-RT"
# define CONFIG_FLASH_SIZE FLASH_4M
#endif
#if defined(CONFIG_BOARD_EASY5120WVOIP)
# define CONFIG_BOARD_NAME "EASY 5120-WVOIP"
# define CONFIG_FLASH_SIZE FLASH_4M
#endif
#if defined(CONFIG_BOARD_EASY83000)
# define CONFIG_BOARD_NAME "EASY 83000"
# define CONFIG_FLASH_SIZE FLASH_4M
#endif
/*
* ZyXEL boards
*/
#if defined(CONFIG_BOARD_P334WT)
# define CONFIG_BOARD_NAME "P-334WT"
# define CONFIG_FLASH_SIZE FLASH_4M
#endif
#if defined(CONFIG_BOARD_P335)
# define CONFIG_BOARD_NAME "P-335"
# define CONFIG_FLASH_SIZE FLASH_4M
#endif
/*
* Default values
*/
#ifndef CONFIG_BOARD_NAME
# define CONFIG_BOARD_NAME "ADM5120"
#endif
#ifndef CONFIG_FLASH_SIZE
# define CONFIG_FLASH_SIZE FLASH_2M
#endif
#endif /* _CONFIG_H_ */

View File

@@ -0,0 +1,349 @@
/*
* $Id$
*
* LZMA compressed kernel decompressor for ADM5120 boards
*
* Copyright (C) 2005 by Oleg I. Vdovikin <oleg@cs.msu.su>
* Copyright (C) 2007 OpenWrt.org
*
* 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.
*
* 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
*
*
* Please note, this was code based on the bunzip2 decompressor code
* by Manuel Novoa III (mjn3@codepoet.org), although the only thing left
* is an idea and part of original vendor code
*
*
* 12-Mar-2005 Mineharu Takahara <mtakahar@yahoo.com>
* pass actual output size to decoder (stream mode
* compressed input is not a requirement anymore)
*
* 24-Apr-2005 Oleg I. Vdovikin
* reordered functions using lds script, removed forward decl
*
* 24-Mar-2007 Gabor Juhos
* pass original values of the a0,a1,a2,a3 registers to the kernel
*
* 19-May-2007 Gabor Juhos
* endiannes related cleanups
* add support for decompressing an embedded kernel
*
*/
#include <stddef.h>
#include "config.h"
#include "printf.h"
#include "LzmaDecode.h"
#define ADM5120_FLASH_START 0x1fc00000 /* Flash start */
#define ADM5120_FLASH_END 0x1fe00000 /* Flash end */
#define KSEG0 0x80000000
#define KSEG1 0xa0000000
#define KSEG1ADDR(a) ((((unsigned)(a)) & 0x1fffffffU) | KSEG1)
#define Index_Invalidate_I 0x00
#define Index_Writeback_Inv_D 0x01
#define cache_unroll(base,op) \
__asm__ __volatile__( \
".set noreorder;\n" \
".set mips3;\n" \
"cache %1, (%0);\n" \
".set mips0;\n" \
".set reorder\n" \
: \
: "r" (base), \
"i" (op));
#ifdef LZMA_DEBUG
# define DBG(f, a...) printf(f, ## a)
#else
# define DBG(f, a...) do {} while (0)
#endif
static __inline__ void blast_icache(unsigned long size, unsigned long lsize)
{
unsigned long start = KSEG0;
unsigned long end = (start + size);
while(start < end) {
cache_unroll(start,Index_Invalidate_I);
start += lsize;
}
}
static __inline__ void blast_dcache(unsigned long size, unsigned long lsize)
{
unsigned long start = KSEG0;
unsigned long end = (start + size);
while(start < end) {
cache_unroll(start,Index_Writeback_Inv_D);
start += lsize;
}
}
#define TRX_MAGIC 0x30524448 /* "HDR0" */
#define TRX_ALIGN 0x1000
struct trx_header {
unsigned int magic; /* "HDR0" */
unsigned int len; /* Length of file including header */
unsigned int crc32; /* 32-bit CRC from flag_version to end of file */
unsigned int flag_version; /* 0:15 flags, 16:31 version */
unsigned int offsets[3]; /* Offsets of partitions from start of header */
};
struct env_var {
char *name;
char *value;
};
/* beyound the image end, size not known in advance */
extern unsigned char workspace[];
extern void board_init(void);
typedef void (*kernel_entry)(unsigned long reg_a0, unsigned long reg_a1,
unsigned long reg_a2, unsigned long reg_a3);
static int decompress_data(unsigned char *buffer, UInt32 bufferSize,
int lc, int lp, int pb, unsigned char *outStream, UInt32 outSize,
UInt32 *outSizeProcessed);
#ifdef CONFIG_PASS_KARGS
#define ENVV(n,v) {.name = (n), .value = (v)}
struct env_var env_vars[] = {
ENVV("board_name", CONFIG_BOARD_NAME),
ENVV(NULL, NULL)
};
#endif
static void halt(void)
{
printf("\nSystem halted!\n");
for(;;);
}
#if LZMA_WRAPPER
extern unsigned char _lzma_data_start[];
extern unsigned char _lzma_data_end[];
unsigned char *data;
unsigned long datalen;
static __inline__ unsigned char get_byte(void)
{
datalen--;
return *data++;
}
static void decompress_init(void)
{
data = _lzma_data_start;
datalen = _lzma_data_end - _lzma_data_start;
}
static int decompress_data(unsigned char *buffer, UInt32 bufferSize,
int lc, int lp, int pb, unsigned char *outStream, UInt32 outSize,
UInt32 *outSizeProcessed)
{
return LzmaDecode(buffer, bufferSize, lc, lp, pb, data, datalen,
outStream, outSize, outSizeProcessed);
}
#endif /* LZMA_WRAPPER */
#if !(LZMA_WRAPPER)
#define FLASH_BANK_SIZE (2<<20)
static unsigned char *flash_base = (unsigned char *) KSEG1ADDR(ADM5120_FLASH_START);
static unsigned long flash_ofs = 0;
static unsigned long flash_max = 0;
static unsigned long flash_ofs_mask = (FLASH_BANK_SIZE-1);
static __inline__ unsigned char get_byte(void)
{
return *(flash_base+flash_ofs++);
}
static int lzma_read_byte(void *object, unsigned char **buffer, UInt32 *bufferSize)
{
unsigned long len;
if (flash_ofs >= flash_max)
return LZMA_RESULT_DATA_ERROR;
len = flash_max-flash_ofs;
#if (CONFIG_FLASH_SIZE > FLASH_BANK_SIZE)
if (flash_ofs < FLASH_BANK_SIZE) {
/* switch to bank 0 */
DBG("lzma_read_byte: switch to bank 0\n");
if (len > FLASH_BANK_SIZE-flash_ofs)
len = FLASH_BANK_SIZE-flash_ofs;
} else {
/* switch to bank 1 */
DBG("lzma_read_byte: switch to bank 1\n");
}
#endif
DBG("lzma_read_byte: ofs=%08X, len=%08X\n", flash_ofs, len);
*buffer = flash_base+(flash_ofs & flash_ofs_mask);
*bufferSize = len;
flash_ofs += len;
return LZMA_RESULT_OK;
}
static ILzmaInCallback lzma_callback = {
.Read = lzma_read_byte,
};
static __inline__ unsigned int read_le32(void *buf)
{
unsigned char *p = buf;
return ((unsigned int)p[0] + ((unsigned int)p[1] << 8) +
((unsigned int)p[2] << 16) +((unsigned int)p[3] << 24));
}
static void decompress_init(void)
{
struct trx_header *hdr = NULL;
unsigned long kofs,klen;
printf("Looking for TRX header... ");
/* look for trx header, 32-bit data access */
for (flash_ofs = 0; flash_ofs < FLASH_BANK_SIZE; flash_ofs += TRX_ALIGN) {
if (read_le32(&flash_base[flash_ofs]) == TRX_MAGIC) {
hdr = (struct trx_header *)&flash_base[flash_ofs];
break;
}
}
if (hdr == NULL) {
printf("not found!\n");
/* no compressed kernel found, halting */
halt();
}
/* compressed kernel is in the partition 0 or 1 */
kofs = read_le32(&hdr->offsets[1]);
if (kofs == 0 || kofs > 65536) {
klen = kofs-read_le32(&hdr->offsets[0]);
kofs = read_le32(&hdr->offsets[0]);
} else {
klen = read_le32(&hdr->offsets[2]);
if (klen > kofs)
klen -= kofs;
else
klen = read_le32(&hdr->len)-kofs;
}
printf("found at %08X, kernel:%08X len:%08X\n", flash_ofs,
kofs, klen);
flash_ofs += kofs;
flash_max = flash_ofs+klen;
}
static int decompress_data(unsigned char *buffer, UInt32 bufferSize,
int lc, int lp, int pb, unsigned char *outStream, UInt32 outSize,
UInt32 *outSizeProcessed)
{
return LzmaDecode(buffer, bufferSize, lc, lp, pb, &lzma_callback,
outStream, outSize, outSizeProcessed);
}
#endif /* !(LZMA_WRAPPER) */
/* should be the first function */
void decompress_entry(unsigned long reg_a0, unsigned long reg_a1,
unsigned long reg_a2, unsigned long reg_a3,
unsigned long icache_size, unsigned long icache_lsize,
unsigned long dcache_size, unsigned long dcache_lsize)
{
unsigned int i; /* temp value */
unsigned int lc; /* literal context bits */
unsigned int lp; /* literal pos state bits */
unsigned int pb; /* pos state bits */
unsigned int osize; /* uncompressed size */
int res;
board_init();
printf("\n\nLZMA loader for " CONFIG_BOARD_NAME
", Copyright (C) 2007 OpenWrt.org\n\n");
decompress_init();
/* lzma args */
i = get_byte();
lc = i % 9, i = i / 9;
lp = i % 5, pb = i / 5;
/* skip rest of the LZMA coder property */
for (i = 0; i < 4; i++)
get_byte();
/* read the lower half of uncompressed size in the header */
osize = ((unsigned int)get_byte()) +
((unsigned int)get_byte() << 8) +
((unsigned int)get_byte() << 16) +
((unsigned int)get_byte() << 24);
/* skip rest of the header (upper half of uncompressed size) */
for (i = 0; i < 4; i++)
get_byte();
printf("decompressing kernel... ");
/* decompress kernel */
res = decompress_data(workspace, ~0, lc, lp, pb,
(unsigned char *)LOADADDR, osize, &i);
if (res != LZMA_RESULT_OK) {
printf("failed, ");
switch (res) {
case LZMA_RESULT_DATA_ERROR:
printf("data error!\n");
break;
case LZMA_RESULT_NOT_ENOUGH_MEM:
printf("not enough memory!\n");
break;
default:
printf("unknown error %d!\n", res);
}
halt();
} else
printf("done!\n");
blast_dcache(dcache_size, dcache_lsize);
blast_icache(icache_size, icache_lsize);
printf("launching kernel...\n\n");
#ifdef CONFIG_PASS_KARGS
reg_a0 = 0;
reg_a1 = 0;
reg_a2 = (unsigned long)env_vars;
reg_a3 = 0;
#endif
/* Jump to load address */
((kernel_entry) LOADADDR)(reg_a0, reg_a1, reg_a2, reg_a3);
}

View File

@@ -0,0 +1,209 @@
/* Copyright 2007 Gabor Juhos <juhosg@freemail.hu> */
/* keep original values of the a0,a1,a2,a3 registers */
/* modifed to support user defined entry point address */
/* Copyright 2005 Oleg I. Vdovikin (oleg@cs.msu.su) */
/* cache manipulation adapted from Broadcom code */
/* idea taken from original bunzip2 decompressor code */
/* Copyright 2004 Manuel Novoa III (mjn3@codepoet.org) */
/* Licensed under the linux kernel's version of the GPL.*/
#include <asm/asm.h>
#include <asm/regdef.h>
#define KSEG0 0x80000000
#define C0_STATUS $12
#define C0_CAUSE $13
#define C0_CONFIG $16
#define C0_WATCHLO $18
#define C0_WATCHHI $19
#define C0_TAGLO $28
#define C0_TAGHI $29
#define CONF1_DA_SHIFT 7 /* D$ associativity */
#define CONF1_DA_MASK 0x00000380
#define CONF1_DA_BASE 1
#define CONF1_DL_SHIFT 10 /* D$ line size */
#define CONF1_DL_MASK 0x00001c00
#define CONF1_DL_BASE 2
#define CONF1_DS_SHIFT 13 /* D$ sets/way */
#define CONF1_DS_MASK 0x0000e000
#define CONF1_DS_BASE 64
#define CONF1_IA_SHIFT 16 /* I$ associativity */
#define CONF1_IA_MASK 0x00070000
#define CONF1_IA_BASE 1
#define CONF1_IL_SHIFT 19 /* I$ line size */
#define CONF1_IL_MASK 0x00380000
#define CONF1_IL_BASE 2
#define CONF1_IS_SHIFT 22 /* Instruction cache sets/way */
#define CONF1_IS_MASK 0x01c00000
#define CONF1_IS_BASE 64
#define Index_Invalidate_I 0x00
#define Index_Writeback_Inv_D 0x01
.text
#if (LZMA_STARTUP_ORG)
.set noreorder
b startup
nop
.org LZMA_STARTUP_ORG
#endif
LEAF(startup)
.set noreorder
.set mips32
mtc0 zero, C0_WATCHLO # clear watch registers
mtc0 zero, C0_WATCHHI
mtc0 zero, C0_CAUSE # clear before writing status register
mfc0 t0, C0_STATUS # get status register
li t1, ~(0xFF01)
and t0, t1 # mask interrupts
mtc0 t0, C0_STATUS # set up status register
move t1, ra # save return address
la t0, __reloc_label # get linked address of label
bal __reloc_label # branch and link to label to
nop # get actual address
__reloc_label:
subu t0, ra, t0 # get reloc_delta
move ra, t1 # restore return address
beqz t0, __reloc_end # if delta is 0 we are in the right place
nop
/* Copy our code to the right place */
la t1, _code_start # get linked address of _code_start
la t2, _code_end # get linked address of _code_end
addu t0, t0, t1 # calculate actual address of _code_start
__reloc_copy:
lw t3, 0(t0)
sw t3, 0(t1)
add t1, 4
blt t1, t2, __reloc_copy
add t0, 4
__reloc_end:
/* At this point we need to invalidate dcache and */
/* icache before jumping to new code */
1: /* Get cache sizes */
.set mips32
mfc0 s0,C0_CONFIG,1
.set mips0
li s1,CONF1_DL_MASK
and s1,s0
beq s1,zero,nodc
nop
srl s1,CONF1_DL_SHIFT
li t0,CONF1_DL_BASE
sll s1,t0,s1 /* s1 has D$ cache line size */
li s2,CONF1_DA_MASK
and s2,s0
srl s2,CONF1_DA_SHIFT
addiu s2,CONF1_DA_BASE /* s2 now has D$ associativity */
li t0,CONF1_DS_MASK
and t0,s0
srl t0,CONF1_DS_SHIFT
li s3,CONF1_DS_BASE
sll s3,s3,t0 /* s3 has D$ sets per way */
multu s2,s3 /* sets/way * associativity */
mflo t0 /* total cache lines */
multu s1,t0 /* D$ linesize * lines */
mflo s2 /* s2 is now D$ size in bytes */
/* Initilize the D$: */
mtc0 zero,C0_TAGLO
mtc0 zero,C0_TAGHI
li t0,KSEG0 /* Just an address for the first $ line */
addu t1,t0,s2 /* + size of cache == end */
.set mips3
1: cache Index_Writeback_Inv_D,0(t0)
.set mips0
bne t0,t1,1b
addu t0,s1
nodc:
/* Now we get to do it all again for the I$ */
move s3,zero /* just in case there is no icache */
move s4,zero
li t0,CONF1_IL_MASK
and t0,s0
beq t0,zero,noic
nop
srl t0,CONF1_IL_SHIFT
li s3,CONF1_IL_BASE
sll s3,t0 /* s3 has I$ cache line size */
li t0,CONF1_IA_MASK
and t0,s0
srl t0,CONF1_IA_SHIFT
addiu s4,t0,CONF1_IA_BASE /* s4 now has I$ associativity */
li t0,CONF1_IS_MASK
and t0,s0
srl t0,CONF1_IS_SHIFT
li s5,CONF1_IS_BASE
sll s5,t0 /* s5 has I$ sets per way */
multu s4,s5 /* sets/way * associativity */
mflo t0 /* s4 is now total cache lines */
multu s3,t0 /* I$ linesize * lines */
mflo s4 /* s4 is cache size in bytes */
/* Initilize the I$: */
mtc0 zero,C0_TAGLO
mtc0 zero,C0_TAGHI
li t0,KSEG0 /* Just an address for the first $ line */
addu t1,t0,s4 /* + size of cache == end */
.set mips3
1: cache Index_Invalidate_I,0(t0)
.set mips0
bne t0,t1,1b
addu t0,s3
noic:
/* Setup new "C" stack */
la sp, _stack
addiu sp, -32 /* reserve stack for parameters */
#if 0
sw a0, 0(sp)
sw a1, 4(sp)
sw a2, 8(sp)
sw a3, 12(sp)
#endif
sw s3, 16(sp) /* icache line size */
sw s4, 20(sp) /* icache size */
sw s1, 24(sp) /* dcache line size */
sw s2, 28(sp) /* dcache size */
/* jump to the decompressor routine */
la t0, decompress_entry
jr t0
nop
.set reorder
END(startup)

View File

@@ -0,0 +1,29 @@
OUTPUT_ARCH(mips)
SECTIONS {
.text : {
_code_start = .;
*(.text)
*(.text.*)
*(.rodata)
*(.rodata.*)
. = ALIGN(16);
*(.data.lzma)
}
.data : {
*(.data)
*(.data.*)
}
_code_end = .;
.bss : {
*(.bss)
*(.bss.*)
}
. = ALIGN(16);
. = . + 8192;
_stack = .;
workspace = .;
}

View File

@@ -0,0 +1,8 @@
OUTPUT_ARCH(mips)
SECTIONS {
.data.lzma : {
_lzma_data_start = .;
*(.data)
_lzma_data_end = .;
}
}

View File

@@ -0,0 +1,350 @@
/*
* Copyright (C) 2001 MontaVista Software Inc.
* Author: Jun Sun, jsun@mvista.com or jsun@junsun.net
*
* 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.
*
*/
#include "printf.h"
extern void board_putc(int ch);
/* this is the maximum width for a variable */
#define LP_MAX_BUF 256
/* macros */
#define IsDigit(x) ( ((x) >= '0') && ((x) <= '9') )
#define Ctod(x) ( (x) - '0')
/* forward declaration */
static int PrintChar(char *, char, int, int);
static int PrintString(char *, char *, int, int);
static int PrintNum(char *, unsigned long, int, int, int, int, char, int);
/* private variable */
static const char theFatalMsg[] = "fatal error in lp_Print!";
/* -*-
* A low level printf() function.
*/
static void
lp_Print(void (*output)(void *, char *, int),
void * arg,
char *fmt,
va_list ap)
{
#define OUTPUT(arg, s, l) \
{ if (((l) < 0) || ((l) > LP_MAX_BUF)) { \
(*output)(arg, (char*)theFatalMsg, sizeof(theFatalMsg)-1); for(;;); \
} else { \
(*output)(arg, s, l); \
} \
}
char buf[LP_MAX_BUF];
char c;
char *s;
long int num;
int longFlag;
int negFlag;
int width;
int prec;
int ladjust;
char padc;
int length;
for(;;) {
{
/* scan for the next '%' */
char *fmtStart = fmt;
while ( (*fmt != '\0') && (*fmt != '%')) {
fmt ++;
}
/* flush the string found so far */
OUTPUT(arg, fmtStart, fmt-fmtStart);
/* are we hitting the end? */
if (*fmt == '\0') break;
}
/* we found a '%' */
fmt ++;
/* check for long */
if (*fmt == 'l') {
longFlag = 1;
fmt ++;
} else {
longFlag = 0;
}
/* check for other prefixes */
width = 0;
prec = -1;
ladjust = 0;
padc = ' ';
if (*fmt == '-') {
ladjust = 1;
fmt ++;
}
if (*fmt == '0') {
padc = '0';
fmt++;
}
if (IsDigit(*fmt)) {
while (IsDigit(*fmt)) {
width = 10 * width + Ctod(*fmt++);
}
}
if (*fmt == '.') {
fmt ++;
if (IsDigit(*fmt)) {
prec = 0;
while (IsDigit(*fmt)) {
prec = prec*10 + Ctod(*fmt++);
}
}
}
/* check format flag */
negFlag = 0;
switch (*fmt) {
case 'b':
if (longFlag) {
num = va_arg(ap, long int);
} else {
num = va_arg(ap, int);
}
length = PrintNum(buf, num, 2, 0, width, ladjust, padc, 0);
OUTPUT(arg, buf, length);
break;
case 'd':
case 'D':
if (longFlag) {
num = va_arg(ap, long int);
} else {
num = va_arg(ap, int);
}
if (num < 0) {
num = - num;
negFlag = 1;
}
length = PrintNum(buf, num, 10, negFlag, width, ladjust, padc, 0);
OUTPUT(arg, buf, length);
break;
case 'o':
case 'O':
if (longFlag) {
num = va_arg(ap, long int);
} else {
num = va_arg(ap, int);
}
length = PrintNum(buf, num, 8, 0, width, ladjust, padc, 0);
OUTPUT(arg, buf, length);
break;
case 'u':
case 'U':
if (longFlag) {
num = va_arg(ap, long int);
} else {
num = va_arg(ap, int);
}
length = PrintNum(buf, num, 10, 0, width, ladjust, padc, 0);
OUTPUT(arg, buf, length);
break;
case 'x':
if (longFlag) {
num = va_arg(ap, long int);
} else {
num = va_arg(ap, int);
}
length = PrintNum(buf, num, 16, 0, width, ladjust, padc, 0);
OUTPUT(arg, buf, length);
break;
case 'X':
if (longFlag) {
num = va_arg(ap, long int);
} else {
num = va_arg(ap, int);
}
length = PrintNum(buf, num, 16, 0, width, ladjust, padc, 1);
OUTPUT(arg, buf, length);
break;
case 'c':
c = (char)va_arg(ap, int);
length = PrintChar(buf, c, width, ladjust);
OUTPUT(arg, buf, length);
break;
case 's':
s = (char*)va_arg(ap, char *);
length = PrintString(buf, s, width, ladjust);
OUTPUT(arg, buf, length);
break;
case '\0':
fmt --;
break;
default:
/* output this char as it is */
OUTPUT(arg, fmt, 1);
} /* switch (*fmt) */
fmt ++;
} /* for(;;) */
/* special termination call */
OUTPUT(arg, "\0", 1);
}
/* --------------- local help functions --------------------- */
static int
PrintChar(char * buf, char c, int length, int ladjust)
{
int i;
if (length < 1) length = 1;
if (ladjust) {
*buf = c;
for (i=1; i< length; i++) buf[i] = ' ';
} else {
for (i=0; i< length-1; i++) buf[i] = ' ';
buf[length - 1] = c;
}
return length;
}
static int
PrintString(char * buf, char* s, int length, int ladjust)
{
int i;
int len=0;
char* s1 = s;
while (*s1++) len++;
if (length < len) length = len;
if (ladjust) {
for (i=0; i< len; i++) buf[i] = s[i];
for (i=len; i< length; i++) buf[i] = ' ';
} else {
for (i=0; i< length-len; i++) buf[i] = ' ';
for (i=length-len; i < length; i++) buf[i] = s[i-length+len];
}
return length;
}
static int
PrintNum(char * buf, unsigned long u, int base, int negFlag,
int length, int ladjust, char padc, int upcase)
{
/* algorithm :
* 1. prints the number from left to right in reverse form.
* 2. fill the remaining spaces with padc if length is longer than
* the actual length
* TRICKY : if left adjusted, no "0" padding.
* if negtive, insert "0" padding between "0" and number.
* 3. if (!ladjust) we reverse the whole string including paddings
* 4. otherwise we only reverse the actual string representing the num.
*/
int actualLength =0;
char *p = buf;
int i;
do {
int tmp = u %base;
if (tmp <= 9) {
*p++ = '0' + tmp;
} else if (upcase) {
*p++ = 'A' + tmp - 10;
} else {
*p++ = 'a' + tmp - 10;
}
u /= base;
} while (u != 0);
if (negFlag) {
*p++ = '-';
}
/* figure out actual length and adjust the maximum length */
actualLength = p - buf;
if (length < actualLength) length = actualLength;
/* add padding */
if (ladjust) {
padc = ' ';
}
if (negFlag && !ladjust && (padc == '0')) {
for (i = actualLength-1; i< length-1; i++) buf[i] = padc;
buf[length -1] = '-';
} else {
for (i = actualLength; i< length; i++) buf[i] = padc;
}
/* prepare to reverse the string */
{
int begin = 0;
int end;
if (ladjust) {
end = actualLength - 1;
} else {
end = length -1;
}
while (end > begin) {
char tmp = buf[begin];
buf[begin] = buf[end];
buf[end] = tmp;
begin ++;
end --;
}
}
/* adjust the string pointer */
return length;
}
static void printf_output(void *arg, char *s, int l)
{
int i;
// special termination call
if ((l==1) && (s[0] == '\0')) return;
for (i=0; i< l; i++) {
board_putc(s[i]);
if (s[i] == '\n') board_putc('\r');
}
}
void printf(char *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
lp_Print(printf_output, 0, fmt, ap);
va_end(ap);
}

View File

@@ -0,0 +1,18 @@
/*
* Copyright (C) 2001 MontaVista Software Inc.
* Author: Jun Sun, jsun@mvista.com or jsun@junsun.net
*
* 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.
*
*/
#ifndef _printf_h_
#define _printf_h_
#include <stdarg.h>
void printf(char *fmt, ...);
#endif /* _printf_h_ */