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

parisc: Add core code for self-extracting kernel

Signed-off-by: Helge Deller <deller@gmx.de>

+679
+2
arch/parisc/boot/.gitignore
··· 1 + image 2 + bzImage
+26
arch/parisc/boot/Makefile
··· 1 + # 2 + # Makefile for the linux parisc-specific parts of the boot image creator. 3 + # 4 + 5 + COMPILE_VERSION := __linux_compile_version_id__`hostname | \ 6 + tr -c '[0-9A-Za-z]' '_'`__`date | \ 7 + tr -c '[0-9A-Za-z]' '_'`_t 8 + 9 + ccflags-y := -DCOMPILE_VERSION=$(COMPILE_VERSION) -gstabs -I. 10 + 11 + targets := image 12 + targets += bzImage 13 + subdir- := compressed 14 + 15 + $(obj)/image: vmlinux FORCE 16 + $(call if_changed,objcopy) 17 + 18 + $(obj)/bzImage: $(obj)/compressed/vmlinux FORCE 19 + $(call if_changed,objcopy) 20 + 21 + $(obj)/compressed/vmlinux: FORCE 22 + $(Q)$(MAKE) $(build)=$(obj)/compressed $@ 23 + 24 + install: $(CONFIGURE) $(obj)/bzImage 25 + sh -x $(srctree)/$(obj)/install.sh $(KERNELRELEASE) $(obj)/bzImage \ 26 + System.map "$(INSTALL_PATH)"
+3
arch/parisc/boot/compressed/.gitignore
··· 1 + sizes.h 2 + vmlinux 3 + vmlinux.lds
+86
arch/parisc/boot/compressed/Makefile
··· 1 + # 2 + # linux/arch/parisc/boot/compressed/Makefile 3 + # 4 + # create a compressed self-extracting vmlinux image from the original vmlinux 5 + # 6 + 7 + KCOV_INSTRUMENT := n 8 + GCOV_PROFILE := n 9 + UBSAN_SANITIZE := n 10 + 11 + targets := vmlinux.lds vmlinux vmlinux.bin vmlinux.bin.gz vmlinux.bin.bz2 12 + targets += vmlinux.bin.xz vmlinux.bin.lzma vmlinux.bin.lzo vmlinux.bin.lz4 13 + targets += misc.o piggy.o sizes.h head.o real2.o firmware.o 14 + 15 + KBUILD_CFLAGS := -D__KERNEL__ -O2 -DBOOTLOADER 16 + KBUILD_CFLAGS += -DDISABLE_BRANCH_PROFILING 17 + KBUILD_CFLAGS += $(cflags-y) -fno-delete-null-pointer-checks 18 + KBUILD_CFLAGS += -fno-PIE -mno-space-regs -mdisable-fpregs 19 + ifndef CONFIG_64BIT 20 + KBUILD_CFLAGS += -mfast-indirect-calls 21 + endif 22 + 23 + OBJECTS += $(obj)/head.o $(obj)/real2.o $(obj)/firmware.o $(obj)/misc.o $(obj)/piggy.o 24 + 25 + # LDFLAGS_vmlinux := -X --whole-archive -e startup -T 26 + LDFLAGS_vmlinux := -X -e startup --as-needed -T 27 + $(obj)/vmlinux: $(obj)/vmlinux.lds $(OBJECTS) $(LIBGCC) 28 + $(call if_changed,ld) 29 + 30 + sed-sizes := -e 's/^\([0-9a-fA-F]*\) . \(__bss_start\|_end\|parisc_kernel_start\)$$/\#define SZ\2 0x\1/p' 31 + 32 + quiet_cmd_sizes = GEN $@ 33 + cmd_sizes = $(NM) $< | sed -n $(sed-sizes) > $@ 34 + 35 + $(obj)/sizes.h: vmlinux 36 + $(call if_changed,sizes) 37 + 38 + AFLAGS_head.o += -I$(objtree)/$(obj) -DBOOTLOADER 39 + $(obj)/head.o: $(obj)/sizes.h 40 + 41 + CFLAGS_misc.o += -I$(objtree)/$(obj) 42 + $(obj)/misc.o: $(obj)/sizes.h 43 + 44 + $(obj)/firmware.o: $(obj)/firmware.c 45 + $(obj)/firmware.c: $(srctree)/arch/$(SRCARCH)/kernel/firmware.c 46 + $(call cmd,shipped) 47 + 48 + AFLAGS_real2.o += -DBOOTLOADER 49 + $(obj)/real2.o: $(obj)/real2.S 50 + $(obj)/real2.S: $(srctree)/arch/$(SRCARCH)/kernel/real2.S 51 + $(call cmd,shipped) 52 + 53 + $(obj)/misc.o: $(obj)/sizes.h 54 + 55 + CPPFLAGS_vmlinux.lds += -I$(objtree)/$(obj) -DBOOTLOADER 56 + $(obj)/vmlinux.lds: $(obj)/sizes.h 57 + 58 + OBJCOPYFLAGS_vmlinux.bin := -O binary -R .comment -S 59 + $(obj)/vmlinux.bin: vmlinux 60 + $(call if_changed,objcopy) 61 + 62 + vmlinux.bin.all-y := $(obj)/vmlinux.bin 63 + 64 + suffix-$(CONFIG_KERNEL_GZIP) := gz 65 + suffix-$(CONFIG_KERNEL_BZIP2) := bz2 66 + suffix-$(CONFIG_KERNEL_LZ4) := lz4 67 + suffix-$(CONFIG_KERNEL_LZMA) := lzma 68 + suffix-$(CONFIG_KERNEL_LZO) := lzo 69 + suffix-$(CONFIG_KERNEL_XZ) := xz 70 + 71 + $(obj)/vmlinux.bin.gz: $(vmlinux.bin.all-y) 72 + $(call if_changed,gzip) 73 + $(obj)/vmlinux.bin.bz2: $(vmlinux.bin.all-y) 74 + $(call if_changed,bzip2) 75 + $(obj)/vmlinux.bin.lz4: $(vmlinux.bin.all-y) 76 + $(call if_changed,lz4) 77 + $(obj)/vmlinux.bin.lzma: $(vmlinux.bin.all-y) 78 + $(call if_changed,lzma) 79 + $(obj)/vmlinux.bin.lzo: $(vmlinux.bin.all-y) 80 + $(call if_changed,lzo) 81 + $(obj)/vmlinux.bin.xz: $(vmlinux.bin.all-y) 82 + $(call if_changed,xzkern) 83 + 84 + LDFLAGS_piggy.o := -r --format binary --oformat $(LD_BFD) -T 85 + $(obj)/piggy.o: $(obj)/vmlinux.scr $(obj)/vmlinux.bin.$(suffix-y) 86 + $(call if_changed,ld)
+85
arch/parisc/boot/compressed/head.S
··· 1 + /* 2 + * Startup glue code to uncompress the kernel 3 + * 4 + * (C) 2017 Helge Deller <deller@gmx.de> 5 + */ 6 + 7 + #include <linux/init.h> 8 + #include <linux/linkage.h> 9 + #include <asm/asm-offsets.h> 10 + #include <asm/page.h> 11 + #include <asm/psw.h> 12 + #include <asm/pdc.h> 13 + #include <asm/assembly.h> 14 + #include "sizes.h" 15 + 16 + #define BOOTADDR(x) (x) 17 + 18 + #ifndef CONFIG_64BIT 19 + .import $global$ /* forward declaration */ 20 + #endif /*!CONFIG_64BIT*/ 21 + 22 + __HEAD 23 + 24 + ENTRY(startup) 25 + .level LEVEL 26 + 27 + #define PSW_W_SM 0x200 28 + #define PSW_W_BIT 36 29 + 30 + ;! nuke the W bit, saving original value 31 + .level 2.0 32 + rsm PSW_W_SM, %r1 33 + 34 + .level 1.1 35 + extrw,u %r1, PSW_W_BIT-32, 1, %r1 36 + copy %r1, %arg0 37 + 38 + /* Make sure sr4-sr7 are set to zero for the kernel address space */ 39 + mtsp %r0,%sr4 40 + mtsp %r0,%sr5 41 + mtsp %r0,%sr6 42 + mtsp %r0,%sr7 43 + 44 + /* Clear BSS */ 45 + 46 + .import _bss,data 47 + .import _ebss,data 48 + 49 + load32 BOOTADDR(_bss),%r3 50 + load32 BOOTADDR(_ebss),%r4 51 + ldo FRAME_SIZE(%r4),%sp /* stack at end of bss */ 52 + $bss_loop: 53 + cmpb,<<,n %r3,%r4,$bss_loop 54 + stw,ma %r0,4(%r3) 55 + 56 + /* Initialize the global data pointer */ 57 + loadgp 58 + 59 + /* arg0..arg4 were set by palo. */ 60 + copy %arg1, %r6 /* command line */ 61 + copy %arg2, %r7 /* rd-start */ 62 + copy %arg3, %r8 /* rd-end */ 63 + load32 BOOTADDR(decompress_kernel),%r3 64 + 65 + #ifdef CONFIG_64BIT 66 + .level LEVEL 67 + ssm PSW_W_SM, %r0 /* set W-bit */ 68 + depdi 0, 31, 32, %r3 69 + #endif 70 + load32 BOOTADDR(startup_continue), %r2 71 + bv,n 0(%r3) 72 + 73 + startup_continue: 74 + #ifdef CONFIG_64BIT 75 + .level LEVEL 76 + rsm PSW_W_SM, %r0 /* clear W-bit */ 77 + #endif 78 + 79 + load32 KERNEL_BINARY_TEXT_START, %arg0 /* free mem */ 80 + copy %r6, %arg1 /* command line */ 81 + copy %r7, %arg2 /* rd-start */ 82 + copy %r8, %arg3 /* rd-end */ 83 + 84 + bv,n 0(%ret0) 85 + END(startup)
+301
arch/parisc/boot/compressed/misc.c
··· 1 + /* 2 + * Definitions and wrapper functions for kernel decompressor 3 + * 4 + * (C) 2017 Helge Deller <deller@gmx.de> 5 + */ 6 + 7 + #include <linux/uaccess.h> 8 + #include <asm/unaligned.h> 9 + #include <asm/page.h> 10 + #include "sizes.h" 11 + 12 + /* 13 + * gzip declarations 14 + */ 15 + #define STATIC static 16 + 17 + #undef memmove 18 + #define memmove memmove 19 + #define memzero(s, n) memset((s), 0, (n)) 20 + 21 + #define malloc malloc_gzip 22 + #define free free_gzip 23 + 24 + /* Symbols defined by linker scripts */ 25 + extern char input_data[]; 26 + extern int input_len; 27 + extern __le32 output_len; /* at unaligned address, little-endian */ 28 + extern char _text, _end; 29 + extern char _bss, _ebss; 30 + extern char _startcode_end; 31 + extern void startup_continue(void *entry, unsigned long cmdline, 32 + unsigned long rd_start, unsigned long rd_end) __noreturn; 33 + 34 + void error(char *m) __noreturn; 35 + 36 + static unsigned long free_mem_ptr; 37 + static unsigned long free_mem_end_ptr; 38 + 39 + #ifdef CONFIG_KERNEL_GZIP 40 + #include "../../../../lib/decompress_inflate.c" 41 + #endif 42 + 43 + #ifdef CONFIG_KERNEL_BZIP2 44 + #include "../../../../lib/decompress_bunzip2.c" 45 + #endif 46 + 47 + #ifdef CONFIG_KERNEL_LZ4 48 + #include "../../../../lib/decompress_unlz4.c" 49 + #endif 50 + 51 + #ifdef CONFIG_KERNEL_LZMA 52 + #include "../../../../lib/decompress_unlzma.c" 53 + #endif 54 + 55 + #ifdef CONFIG_KERNEL_LZO 56 + #include "../../../../lib/decompress_unlzo.c" 57 + #endif 58 + 59 + #ifdef CONFIG_KERNEL_XZ 60 + #include "../../../../lib/decompress_unxz.c" 61 + #endif 62 + 63 + void *memmove(void *dest, const void *src, size_t n) 64 + { 65 + const char *s = src; 66 + char *d = dest; 67 + 68 + if (d <= s) { 69 + while (n--) 70 + *d++ = *s++; 71 + } else { 72 + d += n; 73 + s += n; 74 + while (n--) 75 + *--d = *--s; 76 + } 77 + return dest; 78 + } 79 + 80 + void *memset(void *s, int c, size_t count) 81 + { 82 + char *xs = (char *)s; 83 + 84 + while (count--) 85 + *xs++ = c; 86 + return s; 87 + } 88 + 89 + void *memcpy(void *d, const void *s, size_t len) 90 + { 91 + char *dest = (char *)d; 92 + const char *source = (const char *)s; 93 + 94 + while (len--) 95 + *dest++ = *source++; 96 + return d; 97 + } 98 + 99 + size_t strlen(const char *s) 100 + { 101 + const char *sc; 102 + 103 + for (sc = s; *sc != '\0'; ++sc) 104 + ; 105 + return sc - s; 106 + } 107 + 108 + char *strchr(const char *s, int c) 109 + { 110 + while (*s) { 111 + if (*s == (char)c) 112 + return (char *)s; 113 + ++s; 114 + } 115 + return NULL; 116 + } 117 + 118 + int puts(const char *s) 119 + { 120 + const char *nuline = s; 121 + 122 + while ((nuline = strchr(s, '\n')) != NULL) { 123 + if (nuline != s) 124 + pdc_iodc_print(s, nuline - s); 125 + pdc_iodc_print("\r\n", 2); 126 + s = nuline + 1; 127 + } 128 + if (*s != '\0') 129 + pdc_iodc_print(s, strlen(s)); 130 + 131 + return 0; 132 + } 133 + 134 + static int putchar(int c) 135 + { 136 + char buf[2]; 137 + 138 + buf[0] = c; 139 + buf[1] = '\0'; 140 + puts(buf); 141 + return c; 142 + } 143 + 144 + void __noreturn error(char *x) 145 + { 146 + puts("\n\n"); 147 + puts(x); 148 + puts("\n\n -- System halted"); 149 + while (1) /* wait forever */ 150 + ; 151 + } 152 + 153 + static int print_hex(unsigned long num) 154 + { 155 + const char hex[] = "0123456789abcdef"; 156 + char str[40]; 157 + int i = sizeof(str)-1; 158 + 159 + str[i--] = '\0'; 160 + do { 161 + str[i--] = hex[num & 0x0f]; 162 + num >>= 4; 163 + } while (num); 164 + 165 + str[i--] = 'x'; 166 + str[i] = '0'; 167 + puts(&str[i]); 168 + 169 + return 0; 170 + } 171 + 172 + int printf(const char *fmt, ...) 173 + { 174 + va_list args; 175 + int i = 0; 176 + 177 + va_start(args, fmt); 178 + 179 + while (fmt[i]) { 180 + if (fmt[i] != '%') { 181 + put: 182 + putchar(fmt[i++]); 183 + continue; 184 + } 185 + 186 + if (fmt[++i] == '%') 187 + goto put; 188 + ++i; 189 + print_hex(va_arg(args, unsigned long)); 190 + } 191 + 192 + va_end(args); 193 + return 0; 194 + } 195 + 196 + /* helper functions for libgcc */ 197 + void abort(void) 198 + { 199 + error("aborted."); 200 + } 201 + 202 + #undef malloc 203 + void *malloc(size_t size) 204 + { 205 + return malloc_gzip(size); 206 + } 207 + 208 + #undef free 209 + void free(void *ptr) 210 + { 211 + return free_gzip(ptr); 212 + } 213 + 214 + 215 + static void flush_data_cache(char *start, unsigned long length) 216 + { 217 + char *end = start + length; 218 + 219 + do { 220 + asm volatile("fdc 0(%0)" : : "r" (start)); 221 + asm volatile("fic 0(%%sr0,%0)" : : "r" (start)); 222 + start += 16; 223 + } while (start < end); 224 + asm volatile("fdc 0(%0)" : : "r" (end)); 225 + 226 + asm ("sync"); 227 + } 228 + 229 + unsigned long decompress_kernel(unsigned int started_wide, 230 + unsigned int command_line, 231 + const unsigned int rd_start, 232 + const unsigned int rd_end) 233 + { 234 + char *output; 235 + unsigned long len, len_all; 236 + 237 + #ifdef CONFIG_64BIT 238 + parisc_narrow_firmware = 0; 239 + #endif 240 + 241 + set_firmware_width_unlocked(); 242 + 243 + putchar('U'); /* if you get this p and no more, string storage */ 244 + /* in $GLOBAL$ is wrong or %dp is wrong */ 245 + puts("ncompressing ...\n"); 246 + 247 + output = (char *) KERNEL_BINARY_TEXT_START; 248 + len_all = __pa(SZ_end) - __pa(SZparisc_kernel_start); 249 + 250 + if ((unsigned long) &_startcode_end > (unsigned long) output) 251 + error("Bootcode overlaps kernel code"); 252 + 253 + len = get_unaligned_le32(&output_len); 254 + if (len > len_all) 255 + error("Output len too big."); 256 + else 257 + memset(&output[len], 0, len_all - len); 258 + 259 + /* 260 + * Initialize free_mem_ptr and free_mem_end_ptr. 261 + */ 262 + free_mem_ptr = (unsigned long) &_ebss; 263 + free_mem_ptr += 2*1024*1024; /* leave 2 MB for stack */ 264 + 265 + /* Limit memory for bootoader to 1GB */ 266 + #define ARTIFICIAL_LIMIT (1*1024*1024*1024) 267 + free_mem_end_ptr = PAGE0->imm_max_mem; 268 + if (free_mem_end_ptr > ARTIFICIAL_LIMIT) 269 + free_mem_end_ptr = ARTIFICIAL_LIMIT; 270 + 271 + #ifdef CONFIG_BLK_DEV_INITRD 272 + /* if we have ramdisk this is at end of memory */ 273 + if (rd_start && rd_start < free_mem_end_ptr) 274 + free_mem_end_ptr = rd_start; 275 + #endif 276 + 277 + #ifdef DEBUG 278 + printf("startcode_end = %x\n", &_startcode_end); 279 + printf("commandline = %x\n", command_line); 280 + printf("rd_start = %x\n", rd_start); 281 + printf("rd_end = %x\n", rd_end); 282 + 283 + printf("free_ptr = %x\n", free_mem_ptr); 284 + printf("free_ptr_end = %x\n", free_mem_end_ptr); 285 + 286 + printf("input_data = %x\n", input_data); 287 + printf("input_len = %x\n", input_len); 288 + printf("output = %x\n", output); 289 + printf("output_len = %x\n", len); 290 + printf("output_max = %x\n", len_all); 291 + #endif 292 + 293 + __decompress(input_data, input_len, NULL, NULL, 294 + output, 0, NULL, error); 295 + 296 + flush_data_cache(output, len); 297 + 298 + printf("Booting kernel ...\n\n"); 299 + 300 + return (unsigned long) output; 301 + }
+101
arch/parisc/boot/compressed/vmlinux.lds.S
··· 1 + #include <asm-generic/vmlinux.lds.h> 2 + #include <asm/page.h> 3 + #include "sizes.h" 4 + 5 + #ifndef CONFIG_64BIT 6 + OUTPUT_FORMAT("elf32-hppa-linux") 7 + OUTPUT_ARCH(hppa) 8 + #else 9 + OUTPUT_FORMAT("elf64-hppa-linux") 10 + OUTPUT_ARCH(hppa:hppa2.0w) 11 + #endif 12 + 13 + ENTRY(startup) 14 + 15 + SECTIONS 16 + { 17 + /* palo loads at 0x60000 */ 18 + /* loaded kernel will move to 0x10000 */ 19 + . = 0xe0000; /* should not overwrite palo code */ 20 + 21 + .head.text : { 22 + _head = . ; 23 + HEAD_TEXT 24 + _ehead = . ; 25 + } 26 + 27 + /* keep __gp below 0x1000000 */ 28 + #ifdef CONFIG_64BIT 29 + . = ALIGN(16); 30 + /* Linkage tables */ 31 + .opd : { 32 + *(.opd) 33 + } PROVIDE (__gp = .); 34 + .plt : { 35 + *(.plt) 36 + } 37 + .dlt : { 38 + *(.dlt) 39 + } 40 + #endif 41 + _startcode_end = .; 42 + 43 + /* bootloader code and data starts behind area of extracted kernel */ 44 + . = (SZ_end - SZparisc_kernel_start + KERNEL_BINARY_TEXT_START); 45 + 46 + /* align on next page boundary */ 47 + . = ALIGN(4096); 48 + .text : { 49 + _text = .; /* Text */ 50 + *(.text) 51 + *(.text.*) 52 + _etext = . ; 53 + } 54 + . = ALIGN(8); 55 + .data : { 56 + _data = . ; 57 + *(.data) 58 + *(.data.*) 59 + _edata = . ; 60 + } 61 + . = ALIGN(8); 62 + .rodata : { 63 + _rodata = . ; 64 + *(.rodata) /* read-only data */ 65 + *(.rodata.*) 66 + _erodata = . ; 67 + } 68 + . = ALIGN(8); 69 + .rodata.compressed : { 70 + *(.rodata.compressed) 71 + } 72 + . = ALIGN(8); 73 + .bss : { 74 + _bss = . ; 75 + *(.bss) 76 + *(.bss.*) 77 + *(COMMON) 78 + . = ALIGN(4096); 79 + _ebss = .; 80 + } 81 + 82 + STABS_DEBUG 83 + .note 0 : { *(.note) } 84 + 85 + /* Sections to be discarded */ 86 + DISCARDS 87 + /DISCARD/ : { 88 + #ifdef CONFIG_64BIT 89 + /* temporary hack until binutils is fixed to not emit these 90 + * for static binaries 91 + */ 92 + *(.PARISC.unwind) /* no unwind data */ 93 + *(.interp) 94 + *(.dynsym) 95 + *(.dynstr) 96 + *(.dynamic) 97 + *(.hash) 98 + *(.gnu.hash) 99 + #endif 100 + } 101 + }
+10
arch/parisc/boot/compressed/vmlinux.scr
··· 1 + SECTIONS 2 + { 3 + .rodata.compressed : { 4 + input_len = .; 5 + LONG(input_data_end - input_data) input_data = .; 6 + *(.data) 7 + output_len = . - 4; /* can be at unaligned address */ 8 + input_data_end = .; 9 + } 10 + }
+65
arch/parisc/boot/install.sh
··· 1 + #!/bin/sh 2 + # 3 + # arch/parisc/install.sh, derived from arch/i386/boot/install.sh 4 + # 5 + # This file is subject to the terms and conditions of the GNU General Public 6 + # License. See the file "COPYING" in the main directory of this archive 7 + # for more details. 8 + # 9 + # Copyright (C) 1995 by Linus Torvalds 10 + # 11 + # Adapted from code in arch/i386/boot/Makefile by H. Peter Anvin 12 + # 13 + # "make install" script for i386 architecture 14 + # 15 + # Arguments: 16 + # $1 - kernel version 17 + # $2 - kernel image file 18 + # $3 - kernel map file 19 + # $4 - default install path (blank if root directory) 20 + # 21 + 22 + verify () { 23 + if [ ! -f "$1" ]; then 24 + echo "" 1>&2 25 + echo " *** Missing file: $1" 1>&2 26 + echo ' *** You need to run "make" before "make install".' 1>&2 27 + echo "" 1>&2 28 + exit 1 29 + fi 30 + } 31 + 32 + # Make sure the files actually exist 33 + 34 + verify "$2" 35 + verify "$3" 36 + 37 + # User may have a custom install script 38 + 39 + if [ -n "${INSTALLKERNEL}" ]; then 40 + if [ -x ~/bin/${INSTALLKERNEL} ]; then exec ~/bin/${INSTALLKERNEL} "$@"; fi 41 + if [ -x /sbin/${INSTALLKERNEL} ]; then exec /sbin/${INSTALLKERNEL} "$@"; fi 42 + fi 43 + 44 + # Default install 45 + 46 + if [ "$(basename $2)" = "zImage" ]; then 47 + # Compressed install 48 + echo "Installing compressed kernel" 49 + base=vmlinuz 50 + else 51 + # Normal install 52 + echo "Installing normal kernel" 53 + base=vmlinux 54 + fi 55 + 56 + if [ -f $4/$base-$1 ]; then 57 + mv $4/$base-$1 $4/$base-$1.old 58 + fi 59 + cat $2 > $4/$base-$1 60 + 61 + # Install system map file 62 + if [ -f $4/System.map-$1 ]; then 63 + mv $4/System.map-$1 $4/System.map-$1.old 64 + fi 65 + cp $3 $4/System.map-$1