Self-extracting loader: Cleaner method for inclusion of the UCL-compressed image. The input image is now checked for correctness and converted to C source. The Makefile still needs fixing...


git-svn-id: svn://svn.rockbox.org/rockbox/trunk@8109 a1c6a512-1295-4272-9138-f99709370657
diff --git a/firmware/decompressor/Makefile b/firmware/decompressor/Makefile
index 29a7852..4136eaf 100644
--- a/firmware/decompressor/Makefile
+++ b/firmware/decompressor/Makefile
@@ -18,13 +18,14 @@
 # FIXME: get proper value from build system
 MEMORYSIZE = 2
 
-
 LDS := link.lds
 LINKFILE = $(OBJDIR)/linkage.lds
-OBJS := $(OBJDIR)/decompressor.o $(OBJDIR)/rockboxucl.o $(OBJDIR)/startup.o
+OBJS := $(OBJDIR)/decompressor.o $(OBJDIR)/uclimage.o $(OBJDIR)/startup.o
 
 CFLAGS = -O -W -Wall -m1 -nostdlib -ffreestanding -Wstrict-prototypes -fomit-frame-pointer -fschedule-insns
 
+all: $(OBJDIR)/compressed.bin
+
 $(OBJDIR)/compressed.bin : $(OBJDIR)/compressed.elf
 	@echo "OBJCOPY "`basename $@`
 	@$(OC) -O binary $< $@
@@ -37,6 +38,12 @@
 	@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 $< $@
+$(OBJDIR)/decompressor.o : $(OBJDIR)/uclimage.h
+
+$(OBJDIR)/uclimage.c : $(OBJDIR)/rockbox.ucl  $(TOOLSDIR)/ucl2src.pl
+	@echo "UCL2SRC"
+	@perl -s $(TOOLSDIR)/ucl2src.pl -p=uclimage $< $@
+
+$(OBJDIR)/uclimage.h : $(OBJDIR)/rockbox.ucl  $(TOOLSDIR)/ucl2src.pl
+	@echo "UCL2SRC"
+	@perl -s $(TOOLSDIR)/ucl2src.pl -p=uclimage $< $@
diff --git a/firmware/decompressor/decompressor.c b/firmware/decompressor/decompressor.c
index 9cd7d59..d368c79 100644
--- a/firmware/decompressor/decompressor.c
+++ b/firmware/decompressor/decompressor.c
@@ -21,13 +21,13 @@
  *
  ****************************************************************************/
 
+#include "uclimage.h"
+
 #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 */
@@ -113,20 +113,19 @@
     return ilen;
 }
 
+#define ALIGNED_IMG_SIZE ((sizeof(image) + 3) & ~3)
 /* This will never return */
 void main(void)
 {
     unsigned long dst_len; /* dummy */
-    unsigned long img_len = (unsigned long)(imgend - imgstart);
-    unsigned long *src = (unsigned long *)imgstart;
-    unsigned long *dst = (unsigned long *)(dramend - img_len);
+    unsigned long *src = (unsigned long *)image;
+    unsigned long *dst = (unsigned long *)(dramend - ALIGNED_IMG_SIZE);
     
     do
         *dst++ = *src++;
     while (dst < (unsigned long *)dramend);
     
-    ucl_nrv2e_decompress_8(dramend - img_len + UCL_HEADER,
-                           loadaddress, &dst_len);
+    ucl_nrv2e_decompress_8(dramend - ALIGNED_IMG_SIZE, loadaddress, &dst_len);
 
     asm(
         "mov.l   @%0+,r0     \n"
diff --git a/firmware/decompressor/link.lds b/firmware/decompressor/link.lds
index 9cb4be8..d0e11c1 100755
--- a/firmware/decompressor/link.lds
+++ b/firmware/decompressor/link.lds
@@ -40,15 +40,11 @@
 	{
 		*(.data)
 		. = ALIGN(0x4);
-		_imgstart = .;
-		*(.image)
-		. = ALIGN(0x4);
-		_imgend = .;
 		_iramcopy = .;
 	} > DRAM
 
 	.iram IRAMORIG : AT ( _iramcopy )
-	{	 
+	{
 		_iramstart = .;
 		*(.icode)
 		*(.idata)
diff --git a/tools/ucl2src.pl b/tools/ucl2src.pl
new file mode 100755
index 0000000..54cda5b
--- /dev/null
+++ b/tools/ucl2src.pl
@@ -0,0 +1,110 @@
+#!/usr/bin/env perl
+############################################################################
+#             __________               __   ___.                  
+#   Open      \______   \ ____   ____ |  | _\_ |__   _______  ___  
+#   Source     |       _//  _ \_/ ___\|  |/ /| __ \ /  _ \  \/  /  
+#   Jukebox    |    |   (  <_> )  \___|    < | \_\ (  <_> > <  <   
+#   Firmware   |____|_  /\____/ \___  >__|_ \|___  /\____/__/\_ \
+#                     \/            \/     \/    \/            \/ 
+# $Id$
+#
+# Copyright (C) 2005 by Jens Arnold
+#
+# 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.
+#
+############################################################################
+
+if (!$ARGV[0])
+{
+    print <<HERE
+Usage: ucl2src  [-p=<prefix>] <ucl file>
+
+Check & strip header from an .ucl file and generate <prefix>.c and
+<prefix>.h from it.
+HERE
+;
+    exit;
+}
+
+my $prefix = $p;
+if(!$prefix) {
+    $prefix="uclimage";
+}
+
+my $input = $ARGV[0];
+my $buffer;
+my $insize;
+my $readsize = 0;
+
+open(INF, "<$input") or die "Can't open $input";
+binmode INF;
+
+# check UCL header
+
+# magic header
+read(INF, $buffer, 8);
+if ($buffer ne pack("C8", 0x00, 0xe9, 0x55, 0x43, 0x4c, 0xff, 0x01, 0x1a))
+{
+    die "Not an UCL file.";
+}
+read(INF, $buffer, 4);
+
+# method
+read(INF, $buffer, 1);
+if (ord($buffer) != 0x2E)
+{
+    die sprintf("Wrong compression method (expected 0x2E, found 0x%02X)",
+                ord($buffer));
+}
+
+read(INF, $buffer, 9);
+
+# file size
+read(INF, $buffer, 4);
+$insize = unpack("N", $buffer) + 8;
+
+open(OUTF, ">$prefix.c") or die "Can't open $prefix.c";
+
+print OUTF <<HERE
+/* This file was automatically generated using ucl2src.pl */
+
+/* Data compressed with UCL method 0x2e follows */
+const unsigned char image[] = {
+HERE
+    ;
+    
+while (read(INF, $buffer, 1))
+{
+    $readsize++;
+    printf OUTF ("0x%02x,", ord($buffer));
+    if (!($readsize % 16))
+    {
+        print OUTF "\n";
+    }
+}
+
+close(INF);
+
+if ($readsize != $insize)
+{
+    die "Input file truncated, got $readsize of $insize bytes."
+}
+
+print OUTF <<HERE
+};
+/* end of compressed image */
+HERE
+    ;
+close(OUTF);
+
+open(OUTF, ">$prefix.h") or die "Can't open $prefix.h";
+
+print OUTF "/* This file was automatically generated using ucl2src.pl */\n";
+print OUTF "extern const unsigned char image[".$insize."];\n";
+
+close(OUTF);
+