From 4c385148ac4a2f4959ec39841c20eaeb42ace668 Mon Sep 17 00:00:00 2001 From: Jens Arnold Date: Wed, 30 Nov 2005 00:05:40 +0000 Subject: [PATCH] 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 --- firmware/decompressor/Makefile | 17 +++-- firmware/decompressor/decompressor.c | 13 ++-- firmware/decompressor/link.lds | 6 +- tools/ucl2src.pl | 110 +++++++++++++++++++++++++++ 4 files changed, 129 insertions(+), 17 deletions(-) create mode 100755 tools/ucl2src.pl diff --git a/firmware/decompressor/Makefile b/firmware/decompressor/Makefile index 29a78523ea..4136eafdb7 100644 --- a/firmware/decompressor/Makefile +++ b/firmware/decompressor/Makefile @@ -18,13 +18,14 @@ OBJDIR := . # 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 @@ $(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 $< $@ +$(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 9cd7d5998e..d368c79538 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 @@ int ucl_nrv2e_decompress_8(const unsigned char *src, unsigned char *dst, 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 9cb4be8830..d0e11c1094 100755 --- a/firmware/decompressor/link.lds +++ b/firmware/decompressor/link.lds @@ -40,15 +40,11 @@ SECTIONS { *(.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 0000000000..54cda5b3c0 --- /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 <] + +Check & strip header from an .ucl file and generate .c and +.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 <$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); +