diff options
6 files changed, 80 insertions, 12 deletions
diff --git a/target/linux/image/generic/lzma-loader/Makefile b/target/linux/image/generic/lzma-loader/Makefile index 089254bba..3de04a81a 100644 --- a/target/linux/image/generic/lzma-loader/Makefile +++ b/target/linux/image/generic/lzma-loader/Makefile @@ -17,7 +17,8 @@ $(PKG_BUILD_DIR)/lzma.elf: $(PKG_BUILD_DIR)/.prepared $(PKG_BUILD_DIR)/vmlinux.l  		LD=$(TARGET_CROSS)ld CROSS_COMPILE=$(TARGET_CROSS) \  		RAMSIZE=$(RAMSIZE) \  		LOADADDR=$(LOADADDR) \ -		KERNEL_ENTRY=$(KERNEL_ENTRY) +		KERNEL_ENTRY=$(KERNEL_ENTRY) \ +		IMAGE_COPY=$(IMAGE_COPY)  $(PKG_BUILD_DIR)/vmlinux.lzma: $(KDIR)/vmlinux.lzma diff --git a/target/linux/image/generic/lzma-loader/src/Makefile b/target/linux/image/generic/lzma-loader/src/Makefile index 8dfd76a6a..54356889f 100644 --- a/target/linux/image/generic/lzma-loader/src/Makefile +++ b/target/linux/image/generic/lzma-loader/src/Makefile @@ -1,9 +1,16 @@  LOADADDR = 0x80400000		# RAM start + 4M  KERNEL_ENTRY = 0x80001000  RAMSIZE = 0x00100000		# 1MB +IMAGE_COPY:=0  CROSS_COMPILE = mips-linux- +OBJCOPY:= $(CROSS_COMPILE)objcopy -O binary -R .reginfo -R .note -R .comment -R .mdebug -S +CFLAGS := -fno-builtin -Os -G 0 -ffunction-sections -mno-abicalls -fno-pic -mabi=32 -march=mips32 -Wa,-32 -Wa,-march=mips32 -Wa,-mips32 -Wa,--trap -Wall -DRAMSIZE=${RAMSIZE} -DKERNEL_ENTRY=${KERNEL_ENTRY} -D_LZMA_IN_CB +ifeq ($(IMAGE_COPY),1) +CFLAGS += -DLOADADDR=${LOADADDR} -DIMAGE_COPY=1 +endif +  .S.s:  	$(CPP) $(CFLAGS) $< -o $*.s  .S.o: @@ -13,12 +20,8 @@ CROSS_COMPILE = mips-linux-  CC =       $(CROSS_COMPILE)gcc  LD =       $(CROSS_COMPILE)ld -OBJCOPY =  $(CROSS_COMPILE)objcopy  OBJDUMP =  $(CROSS_COMPILE)objdump -CFLAGS = -fno-builtin -Os -G 0 -mno-abicalls -fno-pic -Wall -DRAMSIZE=${RAMSIZE} -DKERNEL_ENTRY=${KERNEL_ENTRY} -D_LZMA_IN_CB -# CFLAGS = -fno-builtin -Os -G 0 -mno-abicalls -fno-pic -Wall -DRAMSIZE=${RAMSIZE} -  O_FORMAT = $(shell $(OBJDUMP) -i | head -2 | grep elf32)  # Drop some uninteresting sections in the kernel. @@ -26,17 +29,29 @@ O_FORMAT = $(shell $(OBJDUMP) -i | head -2 | grep elf32)  drop-sections   = .reginfo .mdebug .comment  strip-flags     = $(addprefix --remove-section=,$(drop-sections)) -  all : lzma.elf  lzma.lds: lzma.lds.in -	sed -e 's,@LOADADDR@,$(LOADADDR),g' $< >$@ +	sed -e 's,@LOADADDR@,$(LOADADDR),g' -e 's,@ENTRY@,_start,g' $< >$@  kernel.o: vmlinux.lzma lzma.lds  	$(LD) -r -b binary --oformat $(O_FORMAT) -o $@ $< +ifeq ($(IMAGE_COPY),1) +lzma.o: decompress.o LzmaDecode.o kernel.o +	sed -e 's,@LOADADDR@,$(LOADADDR),g' -e 's,@ENTRY@,entry,g' lzma.lds.in >lzma-stage2.lds +	$(LD) -static --no-warn-mismatch -e entry -Tlzma-stage2.lds -o temp-$@ $^ +	$(OBJCOPY) temp-$@ lzma.tmp +	@echo "SECTIONS { .data : { code_start = .; *(.data) code_stop = .; }}" > lzma-data.lds +	$(LD) -no-warn-mismatch -T lzma-data.lds -r -o $@ -b binary lzma.tmp --oformat $(O_FORMAT) +	 +lzma.elf: start.o lzma.o +	sed -e 's,@LOADADDR@,$(KERNEL_ENTRY),g' lzma-copy.lds.in >lzma-copy.lds +	$(LD) -s -Tlzma-copy.lds -o $@ $^ +else  lzma.elf: start.o decompress.o LzmaDecode.o kernel.o  	$(LD) -s -Tlzma.lds -o $@ $^ +endif  clean: -	rm -f *.o lzma.elf +	rm -f *.o lzma.elf *.tmp *.lds diff --git a/target/linux/image/generic/lzma-loader/src/decompress.c b/target/linux/image/generic/lzma-loader/src/decompress.c index f602276dd..4ed432d1a 100644 --- a/target/linux/image/generic/lzma-loader/src/decompress.c +++ b/target/linux/image/generic/lzma-loader/src/decompress.c @@ -106,6 +106,13 @@ void entry(unsigned long icache_size, unsigned long icache_lsize,  {  	unsigned int i;  /* temp value */  	unsigned int osize; /* uncompressed size */ +	volatile unsigned int arg0, arg1, arg2, arg3; + +	/* restore argument registers */ +	__asm__ __volatile__ ("ori %0, $12, 0":"=r"(arg0)); +	__asm__ __volatile__ ("ori %0, $13, 0":"=r"(arg1)); +	__asm__ __volatile__ ("ori %0, $14, 0":"=r"(arg2)); +	__asm__ __volatile__ ("ori %0, $15, 0":"=r"(arg3));  	ILzmaInCallback callback;  	CLzmaDecoderState vs; @@ -142,6 +149,6 @@ void entry(unsigned long icache_size, unsigned long icache_lsize,  		blast_icache(icache_size, icache_lsize);  		/* Jump to load address */ -		((void (*)(void)) KERNEL_ENTRY)(); +		((void (*)(int a0, int a1, int a2, int a3)) KERNEL_ENTRY)(arg0, arg1, arg2, arg3);  	}  } diff --git a/target/linux/image/generic/lzma-loader/src/lzma-copy.lds.in b/target/linux/image/generic/lzma-loader/src/lzma-copy.lds.in new file mode 100644 index 000000000..fbc87ab8e --- /dev/null +++ b/target/linux/image/generic/lzma-loader/src/lzma-copy.lds.in @@ -0,0 +1,20 @@ +OUTPUT_ARCH(mips) +ENTRY(_start) +SECTIONS +{ +  /* Read-only sections, merged into text segment: */ +  . = @LOADADDR@; +  .text      : +  { +    _ftext = . ; +    *(.text) +    *(.rodata) +  } =0 + +  .reginfo : { *(.reginfo) } + +  .bss       : +  { +   *(.bss) +  } +} diff --git a/target/linux/image/generic/lzma-loader/src/lzma.lds.in b/target/linux/image/generic/lzma-loader/src/lzma.lds.in index 5ac555bf7..6021cec01 100644 --- a/target/linux/image/generic/lzma-loader/src/lzma.lds.in +++ b/target/linux/image/generic/lzma-loader/src/lzma.lds.in @@ -1,5 +1,5 @@  OUTPUT_ARCH(mips) -ENTRY(_start) +ENTRY(@ENTRY@)  SECTIONS  {    /* Read-only sections, merged into text segment: */ @@ -7,6 +7,7 @@ SECTIONS    .text      :    {      _ftext = . ; +    *(.text.entry)      *(.text)      *(.rodata)      lzma_start = .; diff --git a/target/linux/image/generic/lzma-loader/src/start.S b/target/linux/image/generic/lzma-loader/src/start.S index 37c7ca36d..9a85c4c35 100644 --- a/target/linux/image/generic/lzma-loader/src/start.S +++ b/target/linux/image/generic/lzma-loader/src/start.S @@ -34,10 +34,30 @@ LEAF(_start)  	.set	mips32  	.set noreorder +	/* save argument registers */ +	move t4, a0 +	move t5, a1 +	move t6, a2 +	move t7, a3 +	  	/* set up stack */  	li	sp, 0xa0000000 + RAMSIZE - 16 -	 -	 + +#ifdef IMAGE_COPY +	/* Copy decompressor code to the right place */ +	li  t2, LOADADDR +	add a0, t2, 0 +	la  a1, code_start +	la  a2, code_stop +$L1: +	lw  t0, 0(a1) +	sw  t0, 0(a0) +	add a1, 4 +	add a0, 4 +	blt a1, a2, $L1 +	nop +#endif +  	/* At this point we need to invalidate dcache and */  	/* icache before jumping to new code */ @@ -128,7 +148,11 @@ noic:  	move    a0,s3                   /* icache line size */  	move    a1,s4                   /* icache size */  	move    a2,s1                   /* dcache line size */ +#ifdef IMAGE_COPY +	jal		t2 +#else  	jal     entry +#endif  	move    a3,s2                   /* dcache size */  	.set reorder  | 
