Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 01623627 authored by Ley Foon Tan's avatar Ley Foon Tan
Browse files

nios2: Add support for compressed kernel



Signed-off-by: default avatarLey Foon Tan <lftan@altera.com>
parent e8bf5bc7
Loading
Loading
Loading
Loading
+8 −0
Original line number Diff line number Diff line
@@ -134,6 +134,14 @@ config NIOS2_PASS_CMDLINE
	  will override "Default kernel command string".
	  Say N if you are unsure.

config NIOS2_BOOT_LINK_OFFSET
	hex "Link address offset for booting"
	default "0x00500000"
	help
	  This option allows you to set the link address offset of the zImage.
	  This can be useful if you are on a board which has a small amount of
	  memory.

endmenu

menu "Advanced setup"
+7 −0
Original line number Diff line number Diff line
@@ -24,6 +24,13 @@ $(obj)/vmImage: $(obj)/vmlinux.gz
	$(call if_changed,uimage)
	@$(kecho) 'Kernel: $@ is ready'

$(obj)/zImage: $(obj)/compressed/vmlinux FORCE
	$(call if_changed,objcopy)
	@$(kecho) 'Kernel: $@ is ready'

$(obj)/compressed/vmlinux: $(obj)/vmlinux.gz FORCE
	$(Q)$(MAKE) $(build)=$(obj)/compressed $@

# Rule to build device tree blobs
DTB_SRC := $(patsubst "%",%,$(CONFIG_NIOS2_DTB_SOURCE))

+19 −0
Original line number Diff line number Diff line
#
# create a compressed vmlinux image from the original vmlinux
#

targets		:= vmlinux head.o misc.o piggy.o vmlinux.lds
asflags-y	:=

OBJECTS = $(obj)/head.o $(obj)/misc.o

LDFLAGS_vmlinux := -T

$(obj)/vmlinux: $(obj)/vmlinux.lds $(OBJECTS) $(obj)/piggy.o FORCE
	$(call if_changed,ld)
	@:

LDFLAGS_piggy.o := -r --format binary --oformat elf32-littlenios2 -T

$(obj)/piggy.o: $(obj)/vmlinux.scr $(obj)/../vmlinux.gz FORCE
	$(call if_changed,ld)
+125 −0
Original line number Diff line number Diff line
/*
 *  Copyright (C) 2008-2010 Thomas Chou <thomas@wytron.com.tw>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 */

#include <linux/io.h>

#if (defined(CONFIG_SERIAL_ALTERA_JTAGUART_CONSOLE) && defined(JTAG_UART_BASE))\
	|| (defined(CONFIG_SERIAL_ALTERA_UART_CONSOLE) && defined(UART0_BASE))
static void *my_ioremap(unsigned long physaddr)
{
	return (void *)(physaddr | CONFIG_NIOS2_IO_REGION_BASE);
}
#endif

#if defined(CONFIG_SERIAL_ALTERA_JTAGUART_CONSOLE) && defined(JTAG_UART_BASE)

#define ALTERA_JTAGUART_SIZE				8
#define ALTERA_JTAGUART_DATA_REG			0
#define ALTERA_JTAGUART_CONTROL_REG			4
#define ALTERA_JTAGUART_CONTROL_AC_MSK			(0x00000400)
#define ALTERA_JTAGUART_CONTROL_WSPACE_MSK		(0xFFFF0000)
static void *uartbase;

#if defined(CONFIG_SERIAL_ALTERA_JTAGUART_CONSOLE_BYPASS)
static void jtag_putc(int ch)
{
	if (readl(uartbase + ALTERA_JTAGUART_CONTROL_REG) &
		ALTERA_JTAGUART_CONTROL_WSPACE_MSK)
		writeb(ch, uartbase + ALTERA_JTAGUART_DATA_REG);
}
#else
static void jtag_putc(int ch)
{
	while ((readl(uartbase + ALTERA_JTAGUART_CONTROL_REG) &
		ALTERA_JTAGUART_CONTROL_WSPACE_MSK) == 0)
		;
	writeb(ch, uartbase + ALTERA_JTAGUART_DATA_REG);
}
#endif

static int putchar(int ch)
{
	jtag_putc(ch);
	return ch;
}

static void console_init(void)
{
	uartbase = my_ioremap((unsigned long) JTAG_UART_BASE);
	writel(ALTERA_JTAGUART_CONTROL_AC_MSK,
		uartbase + ALTERA_JTAGUART_CONTROL_REG);
}

#elif defined(CONFIG_SERIAL_ALTERA_UART_CONSOLE) && defined(UART0_BASE)

#define ALTERA_UART_SIZE		32
#define ALTERA_UART_TXDATA_REG		4
#define ALTERA_UART_STATUS_REG		8
#define ALTERA_UART_DIVISOR_REG		16
#define ALTERA_UART_STATUS_TRDY_MSK	(0x40)
static unsigned uartbase;

static void uart_putc(int ch)
{
	int i;

	for (i = 0; (i < 0x10000); i++) {
		if (readw(uartbase + ALTERA_UART_STATUS_REG) &
			ALTERA_UART_STATUS_TRDY_MSK)
			break;
	}
	writeb(ch, uartbase + ALTERA_UART_TXDATA_REG);
}

static int putchar(int ch)
{
	uart_putc(ch);
	if (ch == '\n')
		uart_putc('\r');
	return ch;
}

static void console_init(void)
{
	unsigned int baud, baudclk;

	uartbase = (unsigned long) my_ioremap((unsigned long) UART0_BASE);
	baud = CONFIG_SERIAL_ALTERA_UART_BAUDRATE;
	baudclk = UART0_FREQ / baud;
	writew(baudclk, uartbase + ALTERA_UART_DIVISOR_REG);
}

#else

static int putchar(int ch)
{
	return ch;
}

static void console_init(void)
{
}

#endif

static int puts(const char *s)
{
	while (*s)
		putchar(*s++);
	return 0;
}
+117 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2009 Thomas Chou <thomas@wytron.com.tw>
 *
 * Based on arch/nios2/kernel/head.S
 *
 * This file is subject to the terms and conditions of the GNU General Public
 * License. See the file "COPYING" in the main directory of this archive
 * for more details.
 *
 */

/*
 *  This code can be loaded anywhere, eg FLASH ROM as reset vector,
 *  as long as output does not overlap it.
 */

#include <linux/linkage.h>
#include <asm/cache.h>

	.text
	.set noat
ENTRY(_start)
	wrctl	status, r0		/* disable interrupt */
	/* invalidate all instruction cache */
	movia	r1, NIOS2_ICACHE_SIZE
	movui	r2, NIOS2_ICACHE_LINE_SIZE
1:	initi	r1
	sub	r1, r1, r2
	bgt	r1, r0, 1b
	/* invalidate all data cache */
	movia	r1, NIOS2_DCACHE_SIZE
	movui	r2, NIOS2_DCACHE_LINE_SIZE
1:	initd	0(r1)
	sub	r1, r1, r2
	bgt	r1, r0, 1b

	nextpc	r1			/* Find out where we are */
chkadr:
	movia	r2, chkadr
	beq	r1, r2, finish_move	/* We are running in correct address,
					   done */
	/* move code, r1: src, r2: dest, r3: last dest */
	addi	r1, r1, (_start - chkadr)	/* Source */
	movia	r2, _start		/* Destination */
	movia	r3, __bss_start		/* End of copy */
1:	ldw	r8, 0(r1)		/* load a word from [r1] */
	stw	r8, 0(r2)		/* stort a word to dest [r2] */
	addi	r1, r1, 4		/* inc the src addr */
	addi	r2, r2, 4		/* inc the dest addr */
	blt	r2, r3, 1b
	/* flush the data cache after moving */
	movia	r1, NIOS2_DCACHE_SIZE
	movui	r2, NIOS2_DCACHE_LINE_SIZE
1:	flushd	0(r1)
	sub	r1, r1, r2
	bgt	r1, r0, 1b
	movia	r1, finish_move
	jmp	r1			/* jmp to linked address */

finish_move:
	/* zero out the .bss segment (uninitialized common data) */
	movia	r2, __bss_start		/* presume nothing is between */
	movia	r1, _end		/* the .bss and _end. */
1: 	stb	r0, 0(r2)
	addi	r2, r2, 1
	bne	r1, r2, 1b
	/*
	 * set up the stack pointer, some where higher than _end.
	 * The stack space must be greater than 32K for decompress.
	 */
	movia	sp, 0x10000
	add	sp, sp, r1
	/* save args passed from u-boot, maybe */
	addi	sp, sp, -16
	stw	r4, 0(sp)
	stw	r5, 4(sp)
	stw	r6, 8(sp)
	stw	r7, 12(sp)
	/* decompress the kernel */
	call	decompress_kernel
	/* pass saved args to kernel */
	ldw	r4, 0(sp)
	ldw	r5, 4(sp)
	ldw	r6, 8(sp)
	ldw	r7, 12(sp)

	/* flush all data cache after decompressing */
	movia	r1, NIOS2_DCACHE_SIZE
	movui	r2, NIOS2_DCACHE_LINE_SIZE
1:	flushd	0(r1)
	sub	r1, r1, r2
	bgt	r1, r0, 1b
	/* flush all instruction cache */
	movia	r1, NIOS2_ICACHE_SIZE
	movui	r2, NIOS2_ICACHE_LINE_SIZE
1:	flushi	r1
	sub	r1, r1, r2
	bgt	r1, r0, 1b
	flushp
	/* jump to start real kernel */
	movia	r1, (CONFIG_NIOS2_MEM_BASE | CONFIG_NIOS2_KERNEL_REGION_BASE)
	jmp	r1

	.balign 512
fake_headers_as_bzImage:
	.short	0
	.ascii	"HdrS"
	.short	0x0202
	.short	0
	.short	0
	.byte	0x00, 0x10
	.short	0
	.byte	0
	.byte	1
	.byte	0x00, 0x80
	.long	0
	.long	0
Loading