forked from len0rd/rockbox
Archos targets: Self-extractor for on-disk firmware images to work around the file size limit. Re-uses rockbox.ucl. Not yet integrated with build system.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@8089 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
parent
4923f49c6f
commit
dbff1f20ee
3 changed files with 266 additions and 0 deletions
42
firmware/decompressor/Makefile
Normal file
42
firmware/decompressor/Makefile
Normal file
|
@ -0,0 +1,42 @@
|
||||||
|
# __________ __ ___.
|
||||||
|
# Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
||||||
|
# Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
||||||
|
# Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
||||||
|
# Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
||||||
|
# \/ \/ \/ \/ \/
|
||||||
|
# $Id$
|
||||||
|
#
|
||||||
|
|
||||||
|
CC = sh-elf-gcc
|
||||||
|
LD = sh-elf-ld
|
||||||
|
AR = sh-elf-ar
|
||||||
|
AS = sh-elf-as
|
||||||
|
OC = sh-elf-objcopy
|
||||||
|
|
||||||
|
TOOLSDIR=../../tools
|
||||||
|
OBJDIR := .
|
||||||
|
# FIXME: get proper value from build system
|
||||||
|
MEMORYSIZE = 2
|
||||||
|
|
||||||
|
|
||||||
|
LDS := link.lds
|
||||||
|
LINKFILE = $(OBJDIR)/linkage.lds
|
||||||
|
OBJS := $(OBJDIR)/decompressor.o $(OBJDIR)/rockboxucl.o
|
||||||
|
|
||||||
|
CFLAGS = -O -W -Wall -m1 -nostdlib -ffreestanding -Wstrict-prototypes -fomit-frame-pointer -fschedule-insns
|
||||||
|
|
||||||
|
$(OBJDIR)/compressed.bin : $(OBJDIR)/compressed.elf
|
||||||
|
@echo "OBJCOPY "`basename $@`
|
||||||
|
@$(OC) -O binary $< $@
|
||||||
|
|
||||||
|
$(OBJDIR)/compressed.elf : $(OBJS) $(LINKFILE)
|
||||||
|
@echo "LD rockbox.elf"
|
||||||
|
@$(CC) $(GCCOPTS) -Os -nostdlib -o $@ $(OBJS) -T$(LINKFILE) -Wl,-Map,$(OBJDIR)/compressed.map
|
||||||
|
|
||||||
|
$(LINKFILE): $(LDS)
|
||||||
|
@echo "Build LDS file"
|
||||||
|
@cat $< | $(CC) -DMEMORYSIZE=$(MEMORYSIZE) $(INCLUDES) $(TARGET) $(DEFINES) -E -P $(ROMBUILD) - >$@
|
||||||
|
|
||||||
|
$(OBJDIR)/rockboxucl.o: $(OBJDIR)/rockbox.ucl
|
||||||
|
@echo "OBJCOPY rockbox.ucl"
|
||||||
|
@$(OC) -I binary -O elf32-sh -B sh --rename-section .data=.image,alloc,load,data,contents $< $@
|
150
firmware/decompressor/decompressor.c
Normal file
150
firmware/decompressor/decompressor.c
Normal file
|
@ -0,0 +1,150 @@
|
||||||
|
/***************************************************************************
|
||||||
|
* __________ __ ___.
|
||||||
|
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
||||||
|
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
||||||
|
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
||||||
|
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
||||||
|
* \/ \/ \/ \/ \/
|
||||||
|
* $Id$
|
||||||
|
*
|
||||||
|
* Copyright (C) 2005 by Jens Arnold
|
||||||
|
*
|
||||||
|
* Self-extracting firmware loader to work around the 200KB size limit
|
||||||
|
* for archos player and recorder v1
|
||||||
|
* Decompresses a built-in UCL-compressed image (method 2e) and executes it.
|
||||||
|
*
|
||||||
|
* All files in this archive are subject to the GNU General Public License.
|
||||||
|
* See the file COPYING in the source tree root for full license agreement.
|
||||||
|
*
|
||||||
|
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||||
|
* KIND, either express or implied.
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#define ICODE_ATTR __attribute__ ((section (".icode")))
|
||||||
|
#define UCL_HEADER 26 /* size of the header generated by uclpack */
|
||||||
|
|
||||||
|
/* Symbols defined in the linker script */
|
||||||
|
extern char iramcopy[], iramstart[], iramend[];
|
||||||
|
extern char stackend[];
|
||||||
|
extern char imgstart[], imgend[];
|
||||||
|
extern char loadaddress[], dramend[];
|
||||||
|
|
||||||
|
/* Prototypes */
|
||||||
|
void start(void) __attribute__ ((section (".start")));
|
||||||
|
void main(void) ICODE_ATTR;
|
||||||
|
int ucl_nrv2e_decompress_8(const unsigned char *src, unsigned char *dst,
|
||||||
|
unsigned long *dst_len) ICODE_ATTR;
|
||||||
|
|
||||||
|
/* Vector table */
|
||||||
|
void (*vbr[]) (void) __attribute__ ((section (".vectors"))) =
|
||||||
|
{
|
||||||
|
start, (void *)stackend,
|
||||||
|
start, (void *)stackend,
|
||||||
|
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||||
|
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Inline copy function */
|
||||||
|
static inline void longcopy(long *dst, long *dst_end, const long *src)
|
||||||
|
__attribute__ ((always_inline));
|
||||||
|
static inline void longcopy(long *dst, long *dst_end, const long *src)
|
||||||
|
{
|
||||||
|
while (dst < dst_end)
|
||||||
|
*dst++ = *src++;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Entry point */
|
||||||
|
void start(void)
|
||||||
|
{
|
||||||
|
longcopy((long *)iramstart, (long *)iramend, (long *)iramcopy);
|
||||||
|
main();
|
||||||
|
}
|
||||||
|
|
||||||
|
/** All subsequent functions are executed from IRAM **/
|
||||||
|
|
||||||
|
/* Thinned out version of the UCL 2e decompression sourcecode
|
||||||
|
* Original (C) Markus F.X.J Oberhumer under GNU GPL license */
|
||||||
|
#define GETBIT(bb, src, ilen) \
|
||||||
|
(((bb = bb & 0x7f ? bb*2 : ((unsigned)src[ilen++]*2+1)) >> 8) & 1)
|
||||||
|
|
||||||
|
int ucl_nrv2e_decompress_8(const unsigned char *src, unsigned char *dst,
|
||||||
|
unsigned long *dst_len)
|
||||||
|
{
|
||||||
|
unsigned long bb = 0;
|
||||||
|
unsigned ilen = 0, olen = 0, last_m_off = 1;
|
||||||
|
|
||||||
|
for (;;)
|
||||||
|
{
|
||||||
|
unsigned m_off, m_len;
|
||||||
|
|
||||||
|
while (GETBIT(bb,src,ilen))
|
||||||
|
dst[olen++] = src[ilen++];
|
||||||
|
|
||||||
|
m_off = 1;
|
||||||
|
for (;;)
|
||||||
|
{
|
||||||
|
m_off = m_off*2 + GETBIT(bb,src,ilen);
|
||||||
|
if (GETBIT(bb,src,ilen))
|
||||||
|
break;
|
||||||
|
m_off = (m_off-1)*2 + GETBIT(bb,src,ilen);
|
||||||
|
}
|
||||||
|
if (m_off == 2)
|
||||||
|
{
|
||||||
|
m_off = last_m_off;
|
||||||
|
m_len = GETBIT(bb,src,ilen);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_off = (m_off-3)*256 + src[ilen++];
|
||||||
|
if (m_off == 0xffffffff)
|
||||||
|
break;
|
||||||
|
m_len = (m_off ^ 0xffffffff) & 1;
|
||||||
|
m_off >>= 1;
|
||||||
|
last_m_off = ++m_off;
|
||||||
|
}
|
||||||
|
if (m_len)
|
||||||
|
m_len = 1 + GETBIT(bb,src,ilen);
|
||||||
|
else if (GETBIT(bb,src,ilen))
|
||||||
|
m_len = 3 + GETBIT(bb,src,ilen);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_len++;
|
||||||
|
do {
|
||||||
|
m_len = m_len*2 + GETBIT(bb,src,ilen);
|
||||||
|
} while (!GETBIT(bb,src,ilen));
|
||||||
|
m_len += 3;
|
||||||
|
}
|
||||||
|
m_len += (m_off > 0x500);
|
||||||
|
{
|
||||||
|
const unsigned char *m_pos;
|
||||||
|
m_pos = dst + olen - m_off;
|
||||||
|
dst[olen++] = *m_pos++;
|
||||||
|
do dst[olen++] = *m_pos++; while (--m_len > 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*dst_len = olen;
|
||||||
|
|
||||||
|
return ilen;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* This will never return */
|
||||||
|
void main(void)
|
||||||
|
{
|
||||||
|
unsigned long dst_len; /* dummy */
|
||||||
|
unsigned long img_len = (unsigned long)(imgend - imgstart);
|
||||||
|
|
||||||
|
longcopy((long *)(dramend - img_len), (long *) dramend,
|
||||||
|
(long *) imgstart);
|
||||||
|
|
||||||
|
ucl_nrv2e_decompress_8(dramend - img_len + UCL_HEADER,
|
||||||
|
loadaddress, &dst_len);
|
||||||
|
|
||||||
|
asm(
|
||||||
|
"mov.l @%0+,r0 \n"
|
||||||
|
"mov.l @%0+,r15 \n"
|
||||||
|
"jmp @r0 \n"
|
||||||
|
"nop \n"
|
||||||
|
: : "r"(loadaddress) : "r0"
|
||||||
|
);
|
||||||
|
}
|
74
firmware/decompressor/link.lds
Executable file
74
firmware/decompressor/link.lds
Executable file
|
@ -0,0 +1,74 @@
|
||||||
|
OUTPUT_FORMAT(elf32-sh)
|
||||||
|
|
||||||
|
#define DRAMORIG 0x09000000
|
||||||
|
#define DRAMSIZE (MEMORYSIZE * 0x00100000)
|
||||||
|
#define IRAMORIG 0x0f000000
|
||||||
|
#define IRAMSIZE 0x00001000
|
||||||
|
|
||||||
|
MEMORY
|
||||||
|
{
|
||||||
|
IRAM : ORIGIN = IRAMORIG, LENGTH = IRAMSIZE
|
||||||
|
DRAM : ORIGIN = DRAMORIG, LENGTH = DRAMSIZE
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTIONS
|
||||||
|
{
|
||||||
|
.vectors :
|
||||||
|
{
|
||||||
|
_loadaddress = .;
|
||||||
|
_dramend = . + DRAMSIZE;
|
||||||
|
*(.vectors)
|
||||||
|
. = ALIGN(0x200);
|
||||||
|
} > DRAM
|
||||||
|
|
||||||
|
.text :
|
||||||
|
{
|
||||||
|
*(.start)
|
||||||
|
*(.text)
|
||||||
|
. = ALIGN(0x4);
|
||||||
|
} > DRAM
|
||||||
|
|
||||||
|
.rodata :
|
||||||
|
{
|
||||||
|
*(.rodata*)
|
||||||
|
*(.rodata.str1.1)
|
||||||
|
*(.rodata.str1.4)
|
||||||
|
. = ALIGN(0x4);
|
||||||
|
} > DRAM
|
||||||
|
|
||||||
|
.data :
|
||||||
|
{
|
||||||
|
*(.data)
|
||||||
|
. = ALIGN(0x4);
|
||||||
|
_imgstart = .;
|
||||||
|
*(.image)
|
||||||
|
. = ALIGN(0x4);
|
||||||
|
_imgend = .;
|
||||||
|
_iramcopy = .;
|
||||||
|
} > DRAM
|
||||||
|
|
||||||
|
.iram IRAMORIG : AT ( _iramcopy )
|
||||||
|
{
|
||||||
|
_iramstart = .;
|
||||||
|
*(.icode)
|
||||||
|
*(.idata)
|
||||||
|
. = ALIGN(0x4);
|
||||||
|
_iramend = .;
|
||||||
|
} > IRAM
|
||||||
|
|
||||||
|
.stack :
|
||||||
|
{
|
||||||
|
_stackbegin = .;
|
||||||
|
*(.stack)
|
||||||
|
. += 0x0800;
|
||||||
|
_stackend = .;
|
||||||
|
} > IRAM
|
||||||
|
|
||||||
|
.bss :
|
||||||
|
{
|
||||||
|
_edata = .;
|
||||||
|
*(.bss)
|
||||||
|
. = ALIGN(0x4);
|
||||||
|
_end = .;
|
||||||
|
} > DRAM
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue