Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

nios2: Add support for compressed kernel

Signed-off-by: Ley Foon Tan <lftan@altera.com>

+549
+8
arch/nios2/Kconfig
··· 134 134 will override "Default kernel command string". 135 135 Say N if you are unsure. 136 136 137 + config NIOS2_BOOT_LINK_OFFSET 138 + hex "Link address offset for booting" 139 + default "0x00500000" 140 + help 141 + This option allows you to set the link address offset of the zImage. 142 + This can be useful if you are on a board which has a small amount of 143 + memory. 144 + 137 145 endmenu 138 146 139 147 menu "Advanced setup"
+7
arch/nios2/boot/Makefile
··· 24 24 $(call if_changed,uimage) 25 25 @$(kecho) 'Kernel: $@ is ready' 26 26 27 + $(obj)/zImage: $(obj)/compressed/vmlinux FORCE 28 + $(call if_changed,objcopy) 29 + @$(kecho) 'Kernel: $@ is ready' 30 + 31 + $(obj)/compressed/vmlinux: $(obj)/vmlinux.gz FORCE 32 + $(Q)$(MAKE) $(build)=$(obj)/compressed $@ 33 + 27 34 # Rule to build device tree blobs 28 35 DTB_SRC := $(patsubst "%",%,$(CONFIG_NIOS2_DTB_SOURCE)) 29 36
+19
arch/nios2/boot/compressed/Makefile
··· 1 + # 2 + # create a compressed vmlinux image from the original vmlinux 3 + # 4 + 5 + targets := vmlinux head.o misc.o piggy.o vmlinux.lds 6 + asflags-y := 7 + 8 + OBJECTS = $(obj)/head.o $(obj)/misc.o 9 + 10 + LDFLAGS_vmlinux := -T 11 + 12 + $(obj)/vmlinux: $(obj)/vmlinux.lds $(OBJECTS) $(obj)/piggy.o FORCE 13 + $(call if_changed,ld) 14 + @: 15 + 16 + LDFLAGS_piggy.o := -r --format binary --oformat elf32-littlenios2 -T 17 + 18 + $(obj)/piggy.o: $(obj)/vmlinux.scr $(obj)/../vmlinux.gz FORCE 19 + $(call if_changed,ld)
+125
arch/nios2/boot/compressed/console.c
··· 1 + /* 2 + * Copyright (C) 2008-2010 Thomas Chou <thomas@wytron.com.tw> 3 + * 4 + * This program is free software; you can redistribute it and/or modify 5 + * it under the terms of the GNU General Public License as published by 6 + * the Free Software Foundation; either version 2 of the License, or 7 + * (at your option) any later version. 8 + * 9 + * This program is distributed in the hope that it will be useful, 10 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 + * GNU General Public License for more details. 13 + * 14 + * You should have received a copy of the GNU General Public License 15 + * along with this program. If not, see <http://www.gnu.org/licenses/>. 16 + * 17 + */ 18 + 19 + #include <linux/io.h> 20 + 21 + #if (defined(CONFIG_SERIAL_ALTERA_JTAGUART_CONSOLE) && defined(JTAG_UART_BASE))\ 22 + || (defined(CONFIG_SERIAL_ALTERA_UART_CONSOLE) && defined(UART0_BASE)) 23 + static void *my_ioremap(unsigned long physaddr) 24 + { 25 + return (void *)(physaddr | CONFIG_NIOS2_IO_REGION_BASE); 26 + } 27 + #endif 28 + 29 + #if defined(CONFIG_SERIAL_ALTERA_JTAGUART_CONSOLE) && defined(JTAG_UART_BASE) 30 + 31 + #define ALTERA_JTAGUART_SIZE 8 32 + #define ALTERA_JTAGUART_DATA_REG 0 33 + #define ALTERA_JTAGUART_CONTROL_REG 4 34 + #define ALTERA_JTAGUART_CONTROL_AC_MSK (0x00000400) 35 + #define ALTERA_JTAGUART_CONTROL_WSPACE_MSK (0xFFFF0000) 36 + static void *uartbase; 37 + 38 + #if defined(CONFIG_SERIAL_ALTERA_JTAGUART_CONSOLE_BYPASS) 39 + static void jtag_putc(int ch) 40 + { 41 + if (readl(uartbase + ALTERA_JTAGUART_CONTROL_REG) & 42 + ALTERA_JTAGUART_CONTROL_WSPACE_MSK) 43 + writeb(ch, uartbase + ALTERA_JTAGUART_DATA_REG); 44 + } 45 + #else 46 + static void jtag_putc(int ch) 47 + { 48 + while ((readl(uartbase + ALTERA_JTAGUART_CONTROL_REG) & 49 + ALTERA_JTAGUART_CONTROL_WSPACE_MSK) == 0) 50 + ; 51 + writeb(ch, uartbase + ALTERA_JTAGUART_DATA_REG); 52 + } 53 + #endif 54 + 55 + static int putchar(int ch) 56 + { 57 + jtag_putc(ch); 58 + return ch; 59 + } 60 + 61 + static void console_init(void) 62 + { 63 + uartbase = my_ioremap((unsigned long) JTAG_UART_BASE); 64 + writel(ALTERA_JTAGUART_CONTROL_AC_MSK, 65 + uartbase + ALTERA_JTAGUART_CONTROL_REG); 66 + } 67 + 68 + #elif defined(CONFIG_SERIAL_ALTERA_UART_CONSOLE) && defined(UART0_BASE) 69 + 70 + #define ALTERA_UART_SIZE 32 71 + #define ALTERA_UART_TXDATA_REG 4 72 + #define ALTERA_UART_STATUS_REG 8 73 + #define ALTERA_UART_DIVISOR_REG 16 74 + #define ALTERA_UART_STATUS_TRDY_MSK (0x40) 75 + static unsigned uartbase; 76 + 77 + static void uart_putc(int ch) 78 + { 79 + int i; 80 + 81 + for (i = 0; (i < 0x10000); i++) { 82 + if (readw(uartbase + ALTERA_UART_STATUS_REG) & 83 + ALTERA_UART_STATUS_TRDY_MSK) 84 + break; 85 + } 86 + writeb(ch, uartbase + ALTERA_UART_TXDATA_REG); 87 + } 88 + 89 + static int putchar(int ch) 90 + { 91 + uart_putc(ch); 92 + if (ch == '\n') 93 + uart_putc('\r'); 94 + return ch; 95 + } 96 + 97 + static void console_init(void) 98 + { 99 + unsigned int baud, baudclk; 100 + 101 + uartbase = (unsigned long) my_ioremap((unsigned long) UART0_BASE); 102 + baud = CONFIG_SERIAL_ALTERA_UART_BAUDRATE; 103 + baudclk = UART0_FREQ / baud; 104 + writew(baudclk, uartbase + ALTERA_UART_DIVISOR_REG); 105 + } 106 + 107 + #else 108 + 109 + static int putchar(int ch) 110 + { 111 + return ch; 112 + } 113 + 114 + static void console_init(void) 115 + { 116 + } 117 + 118 + #endif 119 + 120 + static int puts(const char *s) 121 + { 122 + while (*s) 123 + putchar(*s++); 124 + return 0; 125 + }
+117
arch/nios2/boot/compressed/head.S
··· 1 + /* 2 + * Copyright (C) 2009 Thomas Chou <thomas@wytron.com.tw> 3 + * 4 + * Based on arch/nios2/kernel/head.S 5 + * 6 + * This file is subject to the terms and conditions of the GNU General Public 7 + * License. See the file "COPYING" in the main directory of this archive 8 + * for more details. 9 + * 10 + */ 11 + 12 + /* 13 + * This code can be loaded anywhere, eg FLASH ROM as reset vector, 14 + * as long as output does not overlap it. 15 + */ 16 + 17 + #include <linux/linkage.h> 18 + #include <asm/cache.h> 19 + 20 + .text 21 + .set noat 22 + ENTRY(_start) 23 + wrctl status, r0 /* disable interrupt */ 24 + /* invalidate all instruction cache */ 25 + movia r1, NIOS2_ICACHE_SIZE 26 + movui r2, NIOS2_ICACHE_LINE_SIZE 27 + 1: initi r1 28 + sub r1, r1, r2 29 + bgt r1, r0, 1b 30 + /* invalidate all data cache */ 31 + movia r1, NIOS2_DCACHE_SIZE 32 + movui r2, NIOS2_DCACHE_LINE_SIZE 33 + 1: initd 0(r1) 34 + sub r1, r1, r2 35 + bgt r1, r0, 1b 36 + 37 + nextpc r1 /* Find out where we are */ 38 + chkadr: 39 + movia r2, chkadr 40 + beq r1, r2, finish_move /* We are running in correct address, 41 + done */ 42 + /* move code, r1: src, r2: dest, r3: last dest */ 43 + addi r1, r1, (_start - chkadr) /* Source */ 44 + movia r2, _start /* Destination */ 45 + movia r3, __bss_start /* End of copy */ 46 + 1: ldw r8, 0(r1) /* load a word from [r1] */ 47 + stw r8, 0(r2) /* stort a word to dest [r2] */ 48 + addi r1, r1, 4 /* inc the src addr */ 49 + addi r2, r2, 4 /* inc the dest addr */ 50 + blt r2, r3, 1b 51 + /* flush the data cache after moving */ 52 + movia r1, NIOS2_DCACHE_SIZE 53 + movui r2, NIOS2_DCACHE_LINE_SIZE 54 + 1: flushd 0(r1) 55 + sub r1, r1, r2 56 + bgt r1, r0, 1b 57 + movia r1, finish_move 58 + jmp r1 /* jmp to linked address */ 59 + 60 + finish_move: 61 + /* zero out the .bss segment (uninitialized common data) */ 62 + movia r2, __bss_start /* presume nothing is between */ 63 + movia r1, _end /* the .bss and _end. */ 64 + 1: stb r0, 0(r2) 65 + addi r2, r2, 1 66 + bne r1, r2, 1b 67 + /* 68 + * set up the stack pointer, some where higher than _end. 69 + * The stack space must be greater than 32K for decompress. 70 + */ 71 + movia sp, 0x10000 72 + add sp, sp, r1 73 + /* save args passed from u-boot, maybe */ 74 + addi sp, sp, -16 75 + stw r4, 0(sp) 76 + stw r5, 4(sp) 77 + stw r6, 8(sp) 78 + stw r7, 12(sp) 79 + /* decompress the kernel */ 80 + call decompress_kernel 81 + /* pass saved args to kernel */ 82 + ldw r4, 0(sp) 83 + ldw r5, 4(sp) 84 + ldw r6, 8(sp) 85 + ldw r7, 12(sp) 86 + 87 + /* flush all data cache after decompressing */ 88 + movia r1, NIOS2_DCACHE_SIZE 89 + movui r2, NIOS2_DCACHE_LINE_SIZE 90 + 1: flushd 0(r1) 91 + sub r1, r1, r2 92 + bgt r1, r0, 1b 93 + /* flush all instruction cache */ 94 + movia r1, NIOS2_ICACHE_SIZE 95 + movui r2, NIOS2_ICACHE_LINE_SIZE 96 + 1: flushi r1 97 + sub r1, r1, r2 98 + bgt r1, r0, 1b 99 + flushp 100 + /* jump to start real kernel */ 101 + movia r1, (CONFIG_NIOS2_MEM_BASE | CONFIG_NIOS2_KERNEL_REGION_BASE) 102 + jmp r1 103 + 104 + .balign 512 105 + fake_headers_as_bzImage: 106 + .short 0 107 + .ascii "HdrS" 108 + .short 0x0202 109 + .short 0 110 + .short 0 111 + .byte 0x00, 0x10 112 + .short 0 113 + .byte 0 114 + .byte 1 115 + .byte 0x00, 0x80 116 + .long 0 117 + .long 0
+187
arch/nios2/boot/compressed/misc.c
··· 1 + /* 2 + * Copyright (C) 2009 Thomas Chou <thomas@wytron.com.tw> 3 + * 4 + * This is a collection of several routines from gzip-1.0.3 5 + * adapted for Linux. 6 + * 7 + * malloc by Hannu Savolainen 1993 and Matthias Urlichs 1994 8 + * 9 + * Adapted for SH by Stuart Menefy, Aug 1999 10 + * 11 + * Modified to use standard LinuxSH BIOS by Greg Banks 7Jul2000 12 + * 13 + * Based on arch/sh/boot/compressed/misc.c 14 + * 15 + * This program is free software; you can redistribute it and/or modify 16 + * it under the terms of the GNU General Public License as published by 17 + * the Free Software Foundation; either version 2 of the License, or 18 + * (at your option) any later version. 19 + * 20 + * This program is distributed in the hope that it will be useful, 21 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 22 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 23 + * GNU General Public License for more details. 24 + * 25 + * You should have received a copy of the GNU General Public License 26 + * along with this program. If not, see <http://www.gnu.org/licenses/>. 27 + * 28 + */ 29 + 30 + #include <linux/string.h> 31 + 32 + /* 33 + * gzip declarations 34 + */ 35 + #define OF(args) args 36 + #define STATIC static 37 + 38 + #undef memset 39 + #undef memcpy 40 + #define memzero(s, n) memset((s), 0, (n)) 41 + 42 + typedef unsigned char uch; 43 + typedef unsigned short ush; 44 + typedef unsigned long ulg; 45 + #define WSIZE 0x8000 /* Window size must be at least 32k, */ 46 + /* and a power of two */ 47 + 48 + static uch *inbuf; /* input buffer */ 49 + static uch window[WSIZE]; /* Sliding window buffer */ 50 + 51 + static unsigned insize; /* valid bytes in inbuf */ 52 + static unsigned inptr; /* index of next byte to be processed in inbuf */ 53 + static unsigned outcnt; /* bytes in output buffer */ 54 + 55 + /* gzip flag byte */ 56 + #define ASCII_FLAG 0x01 /* bit 0 set: file probably ASCII text */ 57 + #define CONTINUATION 0x02 /* bit 1 set: continuation of multi-part gzip 58 + file */ 59 + #define EXTRA_FIELD 0x04 /* bit 2 set: extra field present */ 60 + #define ORIG_NAME 0x08 /* bit 3 set: original file name present */ 61 + #define COMMENT 0x10 /* bit 4 set: file comment present */ 62 + #define ENCRYPTED 0x20 /* bit 5 set: file is encrypted */ 63 + #define RESERVED 0xC0 /* bit 6,7: reserved */ 64 + 65 + #define get_byte() (inptr < insize ? inbuf[inptr++] : fill_inbuf()) 66 + 67 + #ifdef DEBUG 68 + # define Assert(cond, msg) {if (!(cond)) error(msg); } 69 + # define Trace(x) fprintf x 70 + # define Tracev(x) {if (verbose) fprintf x ; } 71 + # define Tracevv(x) {if (verbose > 1) fprintf x ; } 72 + # define Tracec(c, x) {if (verbose && (c)) fprintf x ; } 73 + # define Tracecv(c, x) {if (verbose > 1 && (c)) fprintf x ; } 74 + #else 75 + # define Assert(cond, msg) 76 + # define Trace(x) 77 + # define Tracev(x) 78 + # define Tracevv(x) 79 + # define Tracec(c, x) 80 + # define Tracecv(c, x) 81 + #endif 82 + static int fill_inbuf(void); 83 + static void flush_window(void); 84 + static void error(char *m); 85 + 86 + extern char input_data[]; 87 + extern int input_len; 88 + 89 + static long bytes_out; 90 + static uch *output_data; 91 + static unsigned long output_ptr; 92 + 93 + #include "console.c" 94 + 95 + static void error(char *m); 96 + 97 + int puts(const char *); 98 + 99 + extern int _end; 100 + static unsigned long free_mem_ptr; 101 + static unsigned long free_mem_end_ptr; 102 + 103 + #define HEAP_SIZE 0x10000 104 + 105 + #include "../../../../lib/inflate.c" 106 + 107 + void *memset(void *s, int c, size_t n) 108 + { 109 + int i; 110 + char *ss = (char *)s; 111 + 112 + for (i = 0; i < n; i++) 113 + ss[i] = c; 114 + return s; 115 + } 116 + 117 + void *memcpy(void *__dest, __const void *__src, size_t __n) 118 + { 119 + int i; 120 + char *d = (char *)__dest, *s = (char *)__src; 121 + 122 + for (i = 0; i < __n; i++) 123 + d[i] = s[i]; 124 + return __dest; 125 + } 126 + 127 + /* 128 + * Fill the input buffer. This is called only when the buffer is empty 129 + * and at least one byte is really needed. 130 + */ 131 + static int fill_inbuf(void) 132 + { 133 + if (insize != 0) 134 + error("ran out of input data"); 135 + 136 + inbuf = input_data; 137 + insize = input_len; 138 + inptr = 1; 139 + return inbuf[0]; 140 + } 141 + 142 + /* 143 + * Write the output window window[0..outcnt-1] and update crc and bytes_out. 144 + * (Used for the decompressed data only.) 145 + */ 146 + static void flush_window(void) 147 + { 148 + ulg c = crc; /* temporary variable */ 149 + unsigned n; 150 + uch *in, *out, ch; 151 + 152 + in = window; 153 + out = &output_data[output_ptr]; 154 + for (n = 0; n < outcnt; n++) { 155 + ch = *out++ = *in++; 156 + c = crc_32_tab[((int)c ^ ch) & 0xff] ^ (c >> 8); 157 + } 158 + crc = c; 159 + bytes_out += (ulg)outcnt; 160 + output_ptr += (ulg)outcnt; 161 + outcnt = 0; 162 + } 163 + 164 + static void error(char *x) 165 + { 166 + puts("\nERROR\n"); 167 + puts(x); 168 + puts("\n\n -- System halted"); 169 + 170 + while (1) /* Halt */ 171 + ; 172 + } 173 + 174 + void decompress_kernel(void) 175 + { 176 + output_data = (void *) (CONFIG_NIOS2_MEM_BASE | 177 + CONFIG_NIOS2_KERNEL_REGION_BASE); 178 + output_ptr = 0; 179 + free_mem_ptr = (unsigned long)&_end; 180 + free_mem_end_ptr = free_mem_ptr + HEAP_SIZE; 181 + 182 + console_init(); 183 + makecrc(); 184 + puts("Uncompressing Linux... "); 185 + gunzip(); 186 + puts("Ok, booting the kernel.\n"); 187 + }
+58
arch/nios2/boot/compressed/vmlinux.lds.S
··· 1 + /* 2 + * Copyright (C) 2009 Thomas Chou <thomas@wytron.com.tw> 3 + * 4 + * This program is free software; you can redistribute it and/or modify 5 + * it under the terms of the GNU General Public License as published by 6 + * the Free Software Foundation; either version 2 of the License, or 7 + * (at your option) any later version. 8 + * 9 + * This program is distributed in the hope that it will be useful, 10 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 + * GNU General Public License for more details. 13 + * 14 + * You should have received a copy of the GNU General Public License 15 + * along with this program. If not, see <http://www.gnu.org/licenses/>. 16 + * 17 + */ 18 + 19 + #include <asm-generic/vmlinux.lds.h> 20 + 21 + OUTPUT_FORMAT("elf32-littlenios2", "elf32-littlenios2", "elf32-littlenios2") 22 + 23 + OUTPUT_ARCH(nios) 24 + ENTRY(_start) /* Defined in head.S */ 25 + 26 + SECTIONS 27 + { 28 + . = (CONFIG_NIOS2_MEM_BASE + CONFIG_NIOS2_BOOT_LINK_OFFSET) | \ 29 + CONFIG_NIOS2_KERNEL_REGION_BASE; 30 + 31 + _text = .; 32 + .text : { *(.text) } = 0 33 + .rodata : { *(.rodata) *(.rodata.*) } 34 + _etext = .; 35 + 36 + . = ALIGN(32 / 8); 37 + .data : { *(.data) } 38 + . = ALIGN(32 / 8); 39 + _got = .; 40 + .got : { 41 + *(.got.plt) 42 + *(.igot.plt) 43 + *(.got) 44 + *(.igot) 45 + } 46 + _egot = .; 47 + _edata = .; 48 + 49 + . = ALIGN(32 / 8); 50 + __bss_start = .; 51 + .bss : { *(.bss) *(.sbss) } 52 + . = ALIGN(32 / 8); 53 + _ebss = .; 54 + end = . ; 55 + _end = . ; 56 + 57 + got_len = (_egot - _got); 58 + }
+28
arch/nios2/boot/compressed/vmlinux.scr
··· 1 + /* 2 + * Copyright (C) 2009 Thomas Chou <thomas@wytron.com.tw> 3 + * 4 + * This program is free software; you can redistribute it and/or modify 5 + * it under the terms of the GNU General Public License as published by 6 + * the Free Software Foundation; either version 2 of the License, or 7 + * (at your option) any later version. 8 + * 9 + * This program is distributed in the hope that it will be useful, 10 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 + * GNU General Public License for more details. 13 + * 14 + * You should have received a copy of the GNU General Public License 15 + * along with this program. If not, see <http://www.gnu.org/licenses/>. 16 + * 17 + */ 18 + 19 + SECTIONS 20 + { 21 + .data : { 22 + input_len = .; 23 + LONG(input_data_end - input_data) input_data = .; 24 + *(.data) 25 + . = ALIGN(4); 26 + input_data_end = .; 27 + } 28 + }