summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJens Arnold <amiconn@rockbox.org>2005-11-27 23:55:13 +0000
committerJens Arnold <amiconn@rockbox.org>2005-11-27 23:55:13 +0000
commitdbff1f20eec246d9c9f720b1fa64696fd7671737 (patch)
tree0a8a73832532bc6b194d5b74f789ba501998e651
parent4923f49c6f89b751c89678d328d6b5adb7d7bcfb (diff)
downloadrockbox-dbff1f20eec246d9c9f720b1fa64696fd7671737.tar.gz
rockbox-dbff1f20eec246d9c9f720b1fa64696fd7671737.zip
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
-rw-r--r--firmware/decompressor/Makefile42
-rw-r--r--firmware/decompressor/decompressor.c150
-rwxr-xr-xfirmware/decompressor/link.lds74
3 files changed, 266 insertions, 0 deletions
diff --git a/firmware/decompressor/Makefile b/firmware/decompressor/Makefile
new file mode 100644
index 0000000000..99e91aa35e
--- /dev/null
+++ b/firmware/decompressor/Makefile
@@ -0,0 +1,42 @@
1# __________ __ ___.
2# Open \______ \ ____ ____ | | _\_ |__ _______ ___
3# Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
4# Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
5# Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
6# \/ \/ \/ \/ \/
7# $Id$
8#
9
10CC = sh-elf-gcc
11LD = sh-elf-ld
12AR = sh-elf-ar
13AS = sh-elf-as
14OC = sh-elf-objcopy
15
16TOOLSDIR=../../tools
17OBJDIR := .
18# FIXME: get proper value from build system
19MEMORYSIZE = 2
20
21
22LDS := link.lds
23LINKFILE = $(OBJDIR)/linkage.lds
24OBJS := $(OBJDIR)/decompressor.o $(OBJDIR)/rockboxucl.o
25
26CFLAGS = -O -W -Wall -m1 -nostdlib -ffreestanding -Wstrict-prototypes -fomit-frame-pointer -fschedule-insns
27
28$(OBJDIR)/compressed.bin : $(OBJDIR)/compressed.elf
29 @echo "OBJCOPY "`basename $@`
30 @$(OC) -O binary $< $@
31
32$(OBJDIR)/compressed.elf : $(OBJS) $(LINKFILE)
33 @echo "LD rockbox.elf"
34 @$(CC) $(GCCOPTS) -Os -nostdlib -o $@ $(OBJS) -T$(LINKFILE) -Wl,-Map,$(OBJDIR)/compressed.map
35
36$(LINKFILE): $(LDS)
37 @echo "Build LDS file"
38 @cat $< | $(CC) -DMEMORYSIZE=$(MEMORYSIZE) $(INCLUDES) $(TARGET) $(DEFINES) -E -P $(ROMBUILD) - >$@
39
40$(OBJDIR)/rockboxucl.o: $(OBJDIR)/rockbox.ucl
41 @echo "OBJCOPY rockbox.ucl"
42 @$(OC) -I binary -O elf32-sh -B sh --rename-section .data=.image,alloc,load,data,contents $< $@
diff --git a/firmware/decompressor/decompressor.c b/firmware/decompressor/decompressor.c
new file mode 100644
index 0000000000..1223ff2f05
--- /dev/null
+++ b/firmware/decompressor/decompressor.c
@@ -0,0 +1,150 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2005 by Jens Arnold
11 *
12 * Self-extracting firmware loader to work around the 200KB size limit
13 * for archos player and recorder v1
14 * Decompresses a built-in UCL-compressed image (method 2e) and executes it.
15 *
16 * All files in this archive are subject to the GNU General Public License.
17 * See the file COPYING in the source tree root for full license agreement.
18 *
19 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
20 * KIND, either express or implied.
21 *
22 ****************************************************************************/
23
24#define ICODE_ATTR __attribute__ ((section (".icode")))
25#define UCL_HEADER 26 /* size of the header generated by uclpack */
26
27/* Symbols defined in the linker script */
28extern char iramcopy[], iramstart[], iramend[];
29extern char stackend[];
30extern char imgstart[], imgend[];
31extern char loadaddress[], dramend[];
32
33/* Prototypes */
34void start(void) __attribute__ ((section (".start")));
35void main(void) ICODE_ATTR;
36int ucl_nrv2e_decompress_8(const unsigned char *src, unsigned char *dst,
37 unsigned long *dst_len) ICODE_ATTR;
38
39/* Vector table */
40void (*vbr[]) (void) __attribute__ ((section (".vectors"))) =
41{
42 start, (void *)stackend,
43 start, (void *)stackend,
44 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,
45 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,
46};
47
48/* Inline copy function */
49static inline void longcopy(long *dst, long *dst_end, const long *src)
50 __attribute__ ((always_inline));
51static inline void longcopy(long *dst, long *dst_end, const long *src)
52{
53 while (dst < dst_end)
54 *dst++ = *src++;
55}
56
57/* Entry point */
58void start(void)
59{
60 longcopy((long *)iramstart, (long *)iramend, (long *)iramcopy);
61 main();
62}
63
64/** All subsequent functions are executed from IRAM **/
65
66/* Thinned out version of the UCL 2e decompression sourcecode
67 * Original (C) Markus F.X.J Oberhumer under GNU GPL license */
68#define GETBIT(bb, src, ilen) \
69 (((bb = bb & 0x7f ? bb*2 : ((unsigned)src[ilen++]*2+1)) >> 8) & 1)
70
71int ucl_nrv2e_decompress_8(const unsigned char *src, unsigned char *dst,
72 unsigned long *dst_len)
73{
74 unsigned long bb = 0;
75 unsigned ilen = 0, olen = 0, last_m_off = 1;
76
77 for (;;)
78 {
79 unsigned m_off, m_len;
80
81 while (GETBIT(bb,src,ilen))
82 dst[olen++] = src[ilen++];
83
84 m_off = 1;
85 for (;;)
86 {
87 m_off = m_off*2 + GETBIT(bb,src,ilen);
88 if (GETBIT(bb,src,ilen))
89 break;
90 m_off = (m_off-1)*2 + GETBIT(bb,src,ilen);
91 }
92 if (m_off == 2)
93 {
94 m_off = last_m_off;
95 m_len = GETBIT(bb,src,ilen);
96 }
97 else
98 {
99 m_off = (m_off-3)*256 + src[ilen++];
100 if (m_off == 0xffffffff)
101 break;
102 m_len = (m_off ^ 0xffffffff) & 1;
103 m_off >>= 1;
104 last_m_off = ++m_off;
105 }
106 if (m_len)
107 m_len = 1 + GETBIT(bb,src,ilen);
108 else if (GETBIT(bb,src,ilen))
109 m_len = 3 + GETBIT(bb,src,ilen);
110 else
111 {
112 m_len++;
113 do {
114 m_len = m_len*2 + GETBIT(bb,src,ilen);
115 } while (!GETBIT(bb,src,ilen));
116 m_len += 3;
117 }
118 m_len += (m_off > 0x500);
119 {
120 const unsigned char *m_pos;
121 m_pos = dst + olen - m_off;
122 dst[olen++] = *m_pos++;
123 do dst[olen++] = *m_pos++; while (--m_len > 0);
124 }
125 }
126 *dst_len = olen;
127
128 return ilen;
129}
130
131/* This will never return */
132void main(void)
133{
134 unsigned long dst_len; /* dummy */
135 unsigned long img_len = (unsigned long)(imgend - imgstart);
136
137 longcopy((long *)(dramend - img_len), (long *) dramend,
138 (long *) imgstart);
139
140 ucl_nrv2e_decompress_8(dramend - img_len + UCL_HEADER,
141 loadaddress, &dst_len);
142
143 asm(
144 "mov.l @%0+,r0 \n"
145 "mov.l @%0+,r15 \n"
146 "jmp @r0 \n"
147 "nop \n"
148 : : "r"(loadaddress) : "r0"
149 );
150}
diff --git a/firmware/decompressor/link.lds b/firmware/decompressor/link.lds
new file mode 100755
index 0000000000..9cb4be8830
--- /dev/null
+++ b/firmware/decompressor/link.lds
@@ -0,0 +1,74 @@
1OUTPUT_FORMAT(elf32-sh)
2
3#define DRAMORIG 0x09000000
4#define DRAMSIZE (MEMORYSIZE * 0x00100000)
5#define IRAMORIG 0x0f000000
6#define IRAMSIZE 0x00001000
7
8MEMORY
9{
10 IRAM : ORIGIN = IRAMORIG, LENGTH = IRAMSIZE
11 DRAM : ORIGIN = DRAMORIG, LENGTH = DRAMSIZE
12}
13
14SECTIONS
15{
16 .vectors :
17 {
18 _loadaddress = .;
19 _dramend = . + DRAMSIZE;
20 *(.vectors)
21 . = ALIGN(0x200);
22 } > DRAM
23
24 .text :
25 {
26 *(.start)
27 *(.text)
28 . = ALIGN(0x4);
29 } > DRAM
30
31 .rodata :
32 {
33 *(.rodata*)
34 *(.rodata.str1.1)
35 *(.rodata.str1.4)
36 . = ALIGN(0x4);
37 } > DRAM
38
39 .data :
40 {
41 *(.data)
42 . = ALIGN(0x4);
43 _imgstart = .;
44 *(.image)
45 . = ALIGN(0x4);
46 _imgend = .;
47 _iramcopy = .;
48 } > DRAM
49
50 .iram IRAMORIG : AT ( _iramcopy )
51 {
52 _iramstart = .;
53 *(.icode)
54 *(.idata)
55 . = ALIGN(0x4);
56 _iramend = .;
57 } > IRAM
58
59 .stack :
60 {
61 _stackbegin = .;
62 *(.stack)
63 . += 0x0800;
64 _stackend = .;
65 } > IRAM
66
67 .bss :
68 {
69 _edata = .;
70 *(.bss)
71 . = ALIGN(0x4);
72 _end = .;
73 } > DRAM
74}