1 /***************************************************************************
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
10 * Copyright (C) 2005 by Jens Arnold
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.
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.
19 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
20 * KIND, either express or implied.
22 ****************************************************************************/
26 #define ICODE_ATTR __attribute__ ((section (".icode")))
28 /* Symbols defined in the linker script */
29 extern char iramcopy
[], iramstart
[], iramend
[];
30 extern char stackend
[];
31 extern char loadaddress
[], dramend
[];
34 extern void start(void);
36 void main(void) ICODE_ATTR
;
37 int ucl_nrv2e_decompress_8(const unsigned char *src
, unsigned char *dst
,
38 unsigned long *dst_len
) ICODE_ATTR
;
41 void (*vbr
[]) (void) __attribute__ ((section (".vectors"))) =
43 start
, (void *)stackend
,
44 start
, (void *)stackend
,
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,
46 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,
49 /** All subsequent functions are executed from IRAM **/
51 /* Thinned out version of the UCL 2e decompression sourcecode
52 * Original (C) Markus F.X.J Oberhumer under GNU GPL license */
53 #define GETBIT(bb, src, ilen) \
54 (((bb = bb & 0x7f ? bb*2 : ((unsigned)src[ilen++]*2+1)) >> 8) & 1)
56 int ucl_nrv2e_decompress_8(const unsigned char *src
, unsigned char *dst
,
57 unsigned long *dst_len
)
60 unsigned ilen
= 0, olen
= 0, last_m_off
= 1;
64 unsigned m_off
, m_len
;
66 while (GETBIT(bb
,src
,ilen
))
67 dst
[olen
++] = src
[ilen
++];
72 m_off
= m_off
*2 + GETBIT(bb
,src
,ilen
);
73 if (GETBIT(bb
,src
,ilen
))
75 m_off
= (m_off
-1)*2 + GETBIT(bb
,src
,ilen
);
80 m_len
= GETBIT(bb
,src
,ilen
);
84 m_off
= (m_off
-3)*256 + src
[ilen
++];
85 if (m_off
== 0xffffffff)
87 m_len
= (m_off
^ 0xffffffff) & 1;
92 m_len
= 1 + GETBIT(bb
,src
,ilen
);
93 else if (GETBIT(bb
,src
,ilen
))
94 m_len
= 3 + GETBIT(bb
,src
,ilen
);
99 m_len
= m_len
*2 + GETBIT(bb
,src
,ilen
);
100 } while (!GETBIT(bb
,src
,ilen
));
103 m_len
+= (m_off
> 0x500);
105 const unsigned char *m_pos
;
106 m_pos
= dst
+ olen
- m_off
;
107 dst
[olen
++] = *m_pos
++;
108 do dst
[olen
++] = *m_pos
++; while (--m_len
> 0);
116 #define ALIGNED_IMG_SIZE ((sizeof(image) + 3) & ~3)
117 /* This will never return */
120 unsigned long dst_len
; /* dummy */
121 unsigned long *src
= (unsigned long *)image
;
122 unsigned long *dst
= (unsigned long *)(dramend
- ALIGNED_IMG_SIZE
);
126 while (dst
< (unsigned long *)dramend
);
128 ucl_nrv2e_decompress_8(dramend
- ALIGNED_IMG_SIZE
, loadaddress
, &dst_len
);
134 : : "r"(loadaddress
) : "r0"