Commit 1b93b3c3e94be2605759735a89fc935ba5f58dcf

Authored by Wu Zhangjin
Committed by Ralf Baechle
1 parent bea4c899f2

MIPS: Add support for GZIP / BZIP2 / LZMA compressed kernel images

This patch helps to generate smaller kernel images for linux-MIPS,

Here is the effect when using lzma:

$ ls -sh vmlinux
7.1M vmlinux
$ ls -sh vmlinuz
1.5M vmlinuz

Have tested the 32bit kernel on Qemu/Malta and 64bit kernel on FuLoong
Mini PC. both of them work well. and also, tested by Alexander Clouter
on an AR7 based Linksys WAG54Gv2, and by Manuel Lauss on an Alchemy
board.

This -v2 version incorporate the feedback from Ralf, and add the
following changes:

1. add .ecoff, .bin, .erec format support
2. only enable it and the debug source code for the machines we tested
3. a dozen of fixups and cleanups

and if you want to enable it for your board, please try to select
SYS_SUPPORTS_ZBOOT for it, and if the board have an 16550 compatible
uart, you can select SYS_SUPPORTS_ZBOOT_UART16550 directly. and then
sending the relative patches to Ralf.

Tested-by: Manuel Lauss <manuel.lauss@googlemail.com>
Tested-by: Alexander Clouter <alex@digriz.org.uk>
Signed-off-by: Wu Zhangjin <wuzhangjin@gmail.com>
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>

Showing 9 changed files with 558 additions and 3 deletions Side-by-side Diff

... ... @@ -22,6 +22,7 @@
22 22  
23 23 config MACH_ALCHEMY
24 24 bool "Alchemy processor based machines"
  25 + select SYS_SUPPORTS_ZBOOT
25 26  
26 27 config AR7
27 28 bool "Texas Instruments AR7"
... ... @@ -36,6 +37,7 @@
36 37 select SYS_HAS_EARLY_PRINTK
37 38 select SYS_SUPPORTS_32BIT_KERNEL
38 39 select SYS_SUPPORTS_LITTLE_ENDIAN
  40 + select SYS_SUPPORTS_ZBOOT_UART16550
39 41 select GENERIC_GPIO
40 42 select GCD
41 43 select VLYNQ
... ... @@ -192,6 +194,7 @@
192 194  
193 195 config MACH_LOONGSON
194 196 bool "Loongson family of machines"
  197 + select SYS_SUPPORTS_ZBOOT_UART16550
195 198 help
196 199 This enables the support of Loongson family of machines.
197 200  
... ... @@ -233,6 +236,7 @@
233 236 select SYS_SUPPORTS_MIPS_CMP
234 237 select SYS_SUPPORTS_MULTITHREADING
235 238 select SYS_SUPPORTS_SMARTMIPS
  239 + select SYS_SUPPORTS_ZBOOT
236 240 help
237 241 This enables support for the MIPS Technologies Malta evaluation
238 242 board.
... ... @@ -1293,6 +1297,16 @@
1293 1297 Full details can be found at http://www.caviumnetworks.com.
1294 1298  
1295 1299 endchoice
  1300 +
  1301 +config SYS_SUPPORTS_ZBOOT
  1302 + bool
  1303 + select HAVE_KERNEL_GZIP
  1304 + select HAVE_KERNEL_BZIP2
  1305 + select HAVE_KERNEL_LZMA
  1306 +
  1307 +config SYS_SUPPORTS_ZBOOT_UART16550
  1308 + bool
  1309 + select SYS_SUPPORTS_ZBOOT
1296 1310  
1297 1311 config CPU_LOONGSON2
1298 1312 bool
... ... @@ -69,6 +69,7 @@
69 69  
70 70 all-$(CONFIG_BOOT_ELF32) := $(vmlinux-32)
71 71 all-$(CONFIG_BOOT_ELF64) := $(vmlinux-64)
  72 +all-$(CONFIG_SYS_SUPPORTS_ZBOOT)+= vmlinuz
72 73  
73 74 #
74 75 # GCC uses -G 0 -mabicalls -fpic as default. We don't want PIC in the kernel
... ... @@ -331,7 +332,7 @@
331 332 core-$(CONFIG_MIPS_MALTA) += arch/mips/mti-malta/
332 333 cflags-$(CONFIG_MIPS_MALTA) += -I$(srctree)/arch/mips/include/asm/mach-malta
333 334 load-$(CONFIG_MIPS_MALTA) += 0xffffffff80100000
334   -all-$(CONFIG_MIPS_MALTA) := vmlinux.bin
  335 +all-$(CONFIG_MIPS_MALTA) := vmlinuz.bin
335 336  
336 337 #
337 338 # MIPS SIM
... ... @@ -581,7 +582,7 @@
581 582 else
582 583 load-$(CONFIG_SNI_RM) += 0xffffffff80030000
583 584 endif
584   -all-$(CONFIG_SNI_RM) := vmlinux.ecoff
  585 +all-$(CONFIG_SNI_RM) := vmlinuz.ecoff
585 586  
586 587 #
587 588 # Common TXx9
588 589  
... ... @@ -699,9 +700,23 @@
699 700 $(OBJCOPY) -O $(64bit-bfd) $(OBJCOPYFLAGS) $< $@
700 701  
701 702 makeboot =$(Q)$(MAKE) $(build)=arch/mips/boot VMLINUX=$(vmlinux-32) $(1)
  703 +makezboot =$(Q)$(MAKE) $(build)=arch/mips/boot/compressed \
  704 + VMLINUX_LOAD_ADDRESS=$(load-y) 32bit-bfd=$(32bit-bfd) $(1)
702 705  
703 706 all: $(all-y)
704 707  
  708 +vmlinuz: vmlinux FORCE
  709 + +@$(call makezboot,$@)
  710 +
  711 +vmlinuz.bin: vmlinux
  712 + +@$(call makezboot,$@)
  713 +
  714 +vmlinuz.ecoff: vmlinux
  715 + +@$(call makezboot,$@)
  716 +
  717 +vmlinuz.srec: vmlinux
  718 + +@$(call makezboot,$@)
  719 +
705 720 vmlinux.bin: $(vmlinux-32)
706 721 +@$(call makeboot,$@)
707 722  
708 723  
... ... @@ -726,11 +741,13 @@
726 741  
727 742 install:
728 743 $(Q)install -D -m 755 vmlinux $(INSTALL_PATH)/vmlinux-$(KERNELRELEASE)
  744 + $(Q)install -D -m 755 vmlinuz $(INSTALL_PATH)/vmlinuz-$(KERNELRELEASE)
729 745 $(Q)install -D -m 644 .config $(INSTALL_PATH)/config-$(KERNELRELEASE)
730 746 $(Q)install -D -m 644 System.map $(INSTALL_PATH)/System.map-$(KERNELRELEASE)
731 747  
732 748 archclean:
733 749 @$(MAKE) $(clean)=arch/mips/boot
  750 + @$(MAKE) $(clean)=arch/mips/boot/compressed
734 751 @$(MAKE) $(clean)=arch/mips/lasat
735 752  
736 753 define archhelp
737 754  
... ... @@ -738,11 +755,19 @@
738 755 echo ' vmlinux.ecoff - ECOFF boot image'
739 756 echo ' vmlinux.bin - Raw binary boot image'
740 757 echo ' vmlinux.srec - SREC boot image'
  758 + echo ' vmlinuz - Compressed boot(zboot) image'
  759 + echo ' vmlinuz.ecoff - ECOFF zboot image'
  760 + echo ' vmlinuz.bin - Raw binary zboot image'
  761 + echo ' vmlinuz.srec - SREC zboot image'
741 762 echo
742 763 echo ' These will be default as apropriate for a configured platform.'
743 764 endef
744 765  
745 766 CLEAN_FILES += vmlinux.32 \
746 767 vmlinux.64 \
747   - vmlinux.ecoff
  768 + vmlinux.ecoff \
  769 + vmlinuz \
  770 + vmlinuz.ecoff \
  771 + vmlinuz.bin \
  772 + vmlinuz.srec
arch/mips/boot/compressed/Makefile
  1 +#
  2 +# This file is subject to the terms and conditions of the GNU General Public
  3 +# License.
  4 +#
  5 +# Adapted for MIPS Pete Popov, Dan Malek
  6 +#
  7 +# Copyright (C) 1994 by Linus Torvalds
  8 +# Adapted for PowerPC by Gary Thomas
  9 +# modified by Cort (cort@cs.nmt.edu)
  10 +#
  11 +# Copyright (C) 2009 Lemote Inc. & DSLab, Lanzhou University
  12 +# Author: Wu Zhangjin <wuzj@lemote.com>
  13 +#
  14 +
  15 +# compressed kernel load addr: VMLINUZ_LOAD_ADDRESS > VMLINUX_LOAD_ADDRESS + VMLINUX_SIZE
  16 +VMLINUX_SIZE := $(shell wc -c $(objtree)/$(KBUILD_IMAGE) 2>/dev/null | cut -d' ' -f1)
  17 +VMLINUX_SIZE := $(shell [ -n "$(VMLINUX_SIZE)" ] && echo $$(($(VMLINUX_SIZE) + (65536 - $(VMLINUX_SIZE) % 65536))))
  18 +VMLINUZ_LOAD_ADDRESS := 0x$(shell [ -n "$(VMLINUX_SIZE)" ] && printf %x $$(($(VMLINUX_LOAD_ADDRESS) + $(VMLINUX_SIZE))))
  19 +
  20 +# set the default size of the mallocing area for decompressing
  21 +BOOT_HEAP_SIZE := 0x400000
  22 +
  23 +# Disable Function Tracer
  24 +KBUILD_CFLAGS := $(shell echo $(KBUILD_CFLAGS) | sed -e "s/-pg//")
  25 +
  26 +KBUILD_CFLAGS := $(LINUXINCLUDE) $(KBUILD_CFLAGS) -D__KERNEL__ \
  27 + -DBOOT_HEAP_SIZE=$(BOOT_HEAP_SIZE) -D"VMLINUX_LOAD_ADDRESS_ULL=$(VMLINUX_LOAD_ADDRESS)ull" \
  28 +
  29 +KBUILD_AFLAGS := $(LINUXINCLUDE) $(KBUILD_AFLAGS) -D__ASSEMBLY__ \
  30 + -DKERNEL_ENTRY=0x$(shell $(NM) $(objtree)/$(KBUILD_IMAGE) 2>/dev/null | grep " kernel_entry" | cut -f1 -d \ ) \
  31 + -DBOOT_HEAP_SIZE=$(BOOT_HEAP_SIZE)
  32 +
  33 +obj-y := $(obj)/head.o $(obj)/decompress.o $(obj)/dbg.o
  34 +
  35 +obj-$(CONFIG_SYS_SUPPORTS_ZBOOT_UART16550) += $(obj)/uart-16550.o
  36 +
  37 +OBJCOPYFLAGS_vmlinux.bin := $(OBJCOPYFLAGS) -O binary -R .comment -S
  38 +$(obj)/vmlinux.bin: $(KBUILD_IMAGE)
  39 + $(call if_changed,objcopy)
  40 +
  41 +suffix_$(CONFIG_KERNEL_GZIP) = gz
  42 +suffix_$(CONFIG_KERNEL_BZIP2) = bz2
  43 +suffix_$(CONFIG_KERNEL_LZMA) = lzma
  44 +tool_$(CONFIG_KERNEL_GZIP) = gzip
  45 +tool_$(CONFIG_KERNEL_BZIP2) = bzip2
  46 +tool_$(CONFIG_KERNEL_LZMA) = lzma
  47 +$(obj)/vmlinux.$(suffix_y): $(obj)/vmlinux.bin
  48 + $(call if_changed,$(tool_y))
  49 +
  50 +$(obj)/piggy.o: $(obj)/vmlinux.$(suffix_y) $(obj)/dummy.o
  51 + $(Q)$(OBJCOPY) $(OBJCOPYFLAGS) \
  52 + --add-section=.image=$< \
  53 + --set-section-flags=.image=contents,alloc,load,readonly,data \
  54 + $(obj)/dummy.o $@
  55 +
  56 +LDFLAGS_vmlinuz := $(LDFLAGS) -Ttext $(VMLINUZ_LOAD_ADDRESS) -T
  57 +vmlinuz: $(src)/ld.script $(obj-y) $(obj)/piggy.o
  58 + $(call if_changed,ld)
  59 + $(Q)$(OBJCOPY) $(OBJCOPYFLAGS) -R .comment -R .stab -R .stabstr -R .initrd -R .sysmap $@
  60 +
  61 +#
  62 +# Some DECstations need all possible sections of an ECOFF executable
  63 +#
  64 +ifdef CONFIG_MACH_DECSTATION
  65 + E2EFLAGS = -a
  66 +else
  67 + E2EFLAGS =
  68 +endif
  69 +
  70 +# elf2ecoff can only handle 32bit image
  71 +
  72 +ifdef CONFIG_32BIT
  73 + VMLINUZ = vmlinuz
  74 +else
  75 + VMLINUZ = vmlinuz.32
  76 +endif
  77 +
  78 +vmlinuz.32: vmlinuz
  79 + $(Q)$(OBJCOPY) -O $(32bit-bfd) $(OBJCOPYFLAGS) $< $@
  80 +
  81 +vmlinuz.ecoff: $(obj)/../elf2ecoff $(VMLINUZ)
  82 + $(Q)$(obj)/../elf2ecoff $(VMLINUZ) vmlinuz.ecoff $(E2EFLAGS)
  83 +
  84 +$(obj)/../elf2ecoff: $(src)/../elf2ecoff.c
  85 + $(Q)$(HOSTCC) -o $@ $^
  86 +
  87 +drop-sections = .reginfo .mdebug .comment .note .pdr .options .MIPS.options
  88 +strip-flags = $(addprefix --remove-section=,$(drop-sections))
  89 +
  90 +OBJCOPYFLAGS_vmlinuz.bin := $(OBJCOPYFLAGS) -O binary $(strip-flags)
  91 +vmlinuz.bin: vmlinuz
  92 + $(call if_changed,objcopy)
  93 +
  94 +OBJCOPYFLAGS_vmlinuz.srec := $(OBJCOPYFLAGS) -S -O srec $(strip-flags)
  95 +vmlinuz.srec: vmlinuz
  96 + $(call if_changed,objcopy)
  97 +
  98 +clean:
  99 +clean-files += *.o \
  100 + vmlinu*
arch/mips/boot/compressed/dbg.c
  1 +/*
  2 + * MIPS-specific debug support for pre-boot environment
  3 + *
  4 + * NOTE: putc() is board specific, if your board have a 16550 compatible uart,
  5 + * please select SYS_SUPPORTS_ZBOOT_UART16550 for your machine. othewise, you
  6 + * need to implement your own putc().
  7 + */
  8 +
  9 +#include <linux/init.h>
  10 +#include <linux/types.h>
  11 +
  12 +void __attribute__ ((weak)) putc(char c)
  13 +{
  14 +}
  15 +
  16 +void puts(const char *s)
  17 +{
  18 + char c;
  19 + while ((c = *s++) != '\0') {
  20 + putc(c);
  21 + if (c == '\n')
  22 + putc('\r');
  23 + }
  24 +}
  25 +
  26 +void puthex(unsigned long long val)
  27 +{
  28 +
  29 + unsigned char buf[10];
  30 + int i;
  31 + for (i = 7; i >= 0; i--) {
  32 + buf[i] = "0123456789ABCDEF"[val & 0x0F];
  33 + val >>= 4;
  34 + }
  35 + buf[8] = '\0';
  36 + puts(buf);
  37 +}
arch/mips/boot/compressed/decompress.c
  1 +/*
  2 + * Misc. bootloader code for many machines.
  3 + *
  4 + * Copyright 2001 MontaVista Software Inc.
  5 + * Author: Matt Porter <mporter@mvista.com> Derived from
  6 + * arch/ppc/boot/prep/misc.c
  7 + *
  8 + * Copyright (C) 2009 Lemote, Inc. & Institute of Computing Technology
  9 + * Author: Wu Zhangjin <wuzj@lemote.com>
  10 + *
  11 + * This program is free software; you can redistribute it and/or modify it
  12 + * under the terms of the GNU General Public License as published by the
  13 + * Free Software Foundation; either version 2 of the License, or (at your
  14 + * option) any later version.
  15 + */
  16 +
  17 +#include <linux/types.h>
  18 +#include <linux/kernel.h>
  19 +
  20 +#include <asm/addrspace.h>
  21 +
  22 +/* These two variables specify the free mem region
  23 + * that can be used for temporary malloc area
  24 + */
  25 +unsigned long free_mem_ptr;
  26 +unsigned long free_mem_end_ptr;
  27 +char *zimage_start;
  28 +
  29 +/* The linker tells us where the image is. */
  30 +extern unsigned char __image_begin, __image_end;
  31 +extern unsigned char __ramdisk_begin, __ramdisk_end;
  32 +unsigned long initrd_size;
  33 +
  34 +/* debug interfaces */
  35 +extern void puts(const char *s);
  36 +extern void puthex(unsigned long long val);
  37 +
  38 +void error(char *x)
  39 +{
  40 + puts("\n\n");
  41 + puts(x);
  42 + puts("\n\n -- System halted");
  43 +
  44 + while (1)
  45 + ; /* Halt */
  46 +}
  47 +
  48 +/* activate the code for pre-boot environment */
  49 +#define STATIC static
  50 +
  51 +#ifdef CONFIG_KERNEL_GZIP
  52 +void *memcpy(void *dest, const void *src, size_t n)
  53 +{
  54 + int i;
  55 + const char *s = src;
  56 + char *d = dest;
  57 +
  58 + for (i = 0; i < n; i++)
  59 + d[i] = s[i];
  60 + return dest;
  61 +}
  62 +#include "../../../../lib/decompress_inflate.c"
  63 +#endif
  64 +
  65 +#ifdef CONFIG_KERNEL_BZIP2
  66 +void *memset(void *s, int c, size_t n)
  67 +{
  68 + int i;
  69 + char *ss = s;
  70 +
  71 + for (i = 0; i < n; i++)
  72 + ss[i] = c;
  73 + return s;
  74 +}
  75 +#include "../../../../lib/decompress_bunzip2.c"
  76 +#endif
  77 +
  78 +#ifdef CONFIG_KERNEL_LZMA
  79 +#include "../../../../lib/decompress_unlzma.c"
  80 +#endif
  81 +
  82 +void decompress_kernel(unsigned long boot_heap_start)
  83 +{
  84 + int zimage_size;
  85 +
  86 + /*
  87 + * We link ourself to an arbitrary low address. When we run, we
  88 + * relocate outself to that address. __image_beign points to
  89 + * the part of the image where the zImage is. -- Tom
  90 + */
  91 + zimage_start = (char *)(unsigned long)(&__image_begin);
  92 + zimage_size = (unsigned long)(&__image_end) -
  93 + (unsigned long)(&__image_begin);
  94 +
  95 + /*
  96 + * The zImage and initrd will be between start and _end, so they've
  97 + * already been moved once. We're good to go now. -- Tom
  98 + */
  99 + puts("zimage at: ");
  100 + puthex((unsigned long)zimage_start);
  101 + puts(" ");
  102 + puthex((unsigned long)(zimage_size + zimage_start));
  103 + puts("\n");
  104 +
  105 + if (initrd_size) {
  106 + puts("initrd at: ");
  107 + puthex((unsigned long)(&__ramdisk_begin));
  108 + puts(" ");
  109 + puthex((unsigned long)(&__ramdisk_end));
  110 + puts("\n");
  111 + }
  112 +
  113 + /* this area are prepared for mallocing when decompressing */
  114 + free_mem_ptr = boot_heap_start;
  115 + free_mem_end_ptr = boot_heap_start + BOOT_HEAP_SIZE;
  116 +
  117 + /* Display standard Linux/MIPS boot prompt for kernel args */
  118 + puts("Uncompressing Linux at load address ");
  119 + puthex(VMLINUX_LOAD_ADDRESS_ULL);
  120 + puts("\n");
  121 + /* Decompress the kernel with according algorithm */
  122 + decompress(zimage_start, zimage_size, 0, 0,
  123 + (void *)VMLINUX_LOAD_ADDRESS_ULL, 0, error);
  124 + /* FIXME: is there a need to flush cache here? */
  125 + puts("Now, booting the kernel...\n");
  126 +}
arch/mips/boot/compressed/dummy.c
  1 +int main(void)
  2 +{
  3 + return 0;
  4 +}
arch/mips/boot/compressed/head.S
  1 +/*
  2 + * This file is subject to the terms and conditions of the GNU General Public
  3 + * License. See the file "COPYING" in the main directory of this archive
  4 + * for more details.
  5 + *
  6 + * Copyright (C) 1994, 1995 Waldorf Electronics
  7 + * Written by Ralf Baechle and Andreas Busse
  8 + * Copyright (C) 1995 - 1999 Ralf Baechle
  9 + * Copyright (C) 1996 Paul M. Antoine
  10 + * Modified for DECStation and hence R3000 support by Paul M. Antoine
  11 + * Further modifications by David S. Miller and Harald Koerfgen
  12 + * Copyright (C) 1999 Silicon Graphics, Inc.
  13 + */
  14 +
  15 +#include <asm/asm.h>
  16 +#include <asm/regdef.h>
  17 +
  18 + .set noreorder
  19 + .cprestore
  20 + LEAF(start)
  21 +start:
  22 + /* Save boot rom start args */
  23 + move s0, a0
  24 + move s1, a1
  25 + move s2, a2
  26 + move s3, a3
  27 +
  28 + /* Clear BSS */
  29 + PTR_LA a0, _edata
  30 + PTR_LA a2, _end
  31 +1: sw zero, 0(a0)
  32 + bne a2, a0, 1b
  33 + addiu a0, a0, 4
  34 +
  35 + PTR_LA a0, (.heap) /* heap address */
  36 + PTR_LA sp, (.stack + 8192) /* stack address */
  37 +
  38 + PTR_LA ra, 2f
  39 + PTR_LA k0, decompress_kernel
  40 + jr k0
  41 + nop
  42 +2:
  43 + move a0, s0
  44 + move a1, s1
  45 + move a2, s2
  46 + move a3, s3
  47 + PTR_LI k0, KERNEL_ENTRY
  48 + jr k0
  49 + nop
  50 +3:
  51 + b 3b
  52 + nop
  53 + END(start)
  54 +
  55 + .comm .heap,BOOT_HEAP_SIZE,4
  56 + .comm .stack,4096*2,4
arch/mips/boot/compressed/ld.script
  1 +OUTPUT_ARCH(mips)
  2 +ENTRY(start)
  3 +SECTIONS
  4 +{
  5 + /* Read-only sections, merged into text segment: */
  6 + .init : { *(.init) } =0
  7 + .text :
  8 + {
  9 + _ftext = . ;
  10 + *(.text)
  11 + *(.rodata)
  12 + *(.rodata1)
  13 + /* .gnu.warning sections are handled specially by elf32.em. */
  14 + *(.gnu.warning)
  15 + } =0
  16 + .kstrtab : { *(.kstrtab) }
  17 +
  18 + . = ALIGN(16); /* Exception table */
  19 + __start___ex_table = .;
  20 + __ex_table : { *(__ex_table) }
  21 + __stop___ex_table = .;
  22 +
  23 + __start___dbe_table = .; /* Exception table for data bus errors */
  24 + __dbe_table : { *(__dbe_table) }
  25 + __stop___dbe_table = .;
  26 +
  27 + __start___ksymtab = .; /* Kernel symbol table */
  28 + __ksymtab : { *(__ksymtab) }
  29 + __stop___ksymtab = .;
  30 +
  31 + _etext = .;
  32 +
  33 + . = ALIGN(8192);
  34 + .data.init_task : { *(.data.init_task) }
  35 +
  36 + /* Startup code */
  37 + . = ALIGN(4096);
  38 + __init_begin = .;
  39 + .text.init : { *(.text.init) }
  40 + .data.init : { *(.data.init) }
  41 + . = ALIGN(16);
  42 + __setup_start = .;
  43 + .setup.init : { *(.setup.init) }
  44 + __setup_end = .;
  45 + __initcall_start = .;
  46 + .initcall.init : { *(.initcall.init) }
  47 + __initcall_end = .;
  48 + . = ALIGN(4096); /* Align double page for init_task_union */
  49 + __init_end = .;
  50 +
  51 + . = ALIGN(4096);
  52 + .data.page_aligned : { *(.data.idt) }
  53 +
  54 + . = ALIGN(32);
  55 + .data.cacheline_aligned : { *(.data.cacheline_aligned) }
  56 +
  57 + .fini : { *(.fini) } =0
  58 + .reginfo : { *(.reginfo) }
  59 + /* Adjust the address for the data segment. We want to adjust up to
  60 + the same address within the page on the next page up. It would
  61 + be more correct to do this:
  62 + . = .;
  63 + The current expression does not correctly handle the case of a
  64 + text segment ending precisely at the end of a page; it causes the
  65 + data segment to skip a page. The above expression does not have
  66 + this problem, but it will currently (2/95) cause BFD to allocate
  67 + a single segment, combining both text and data, for this case.
  68 + This will prevent the text segment from being shared among
  69 + multiple executions of the program; I think that is more
  70 + important than losing a page of the virtual address space (note
  71 + that no actual memory is lost; the page which is skipped can not
  72 + be referenced). */
  73 + . = .;
  74 + .data :
  75 + {
  76 + _fdata = . ;
  77 + *(.data)
  78 +
  79 + /* Put the compressed image here, so bss is on the end. */
  80 + __image_begin = .;
  81 + *(.image)
  82 + __image_end = .;
  83 + /* Align the initial ramdisk image (INITRD) on page boundaries. */
  84 + . = ALIGN(4096);
  85 + __ramdisk_begin = .;
  86 + *(.initrd)
  87 + __ramdisk_end = .;
  88 + . = ALIGN(4096);
  89 +
  90 + CONSTRUCTORS
  91 + }
  92 + .data1 : { *(.data1) }
  93 + _gp = . + 0x8000;
  94 + .lit8 : { *(.lit8) }
  95 + .lit4 : { *(.lit4) }
  96 + .ctors : { *(.ctors) }
  97 + .dtors : { *(.dtors) }
  98 + .got : { *(.got.plt) *(.got) }
  99 + .dynamic : { *(.dynamic) }
  100 + /* We want the small data sections together, so single-instruction offsets
  101 + can access them all, and initialized data all before uninitialized, so
  102 + we can shorten the on-disk segment size. */
  103 + .sdata : { *(.sdata) }
  104 + . = ALIGN(4);
  105 + _edata = .;
  106 + PROVIDE (edata = .);
  107 +
  108 + __bss_start = .;
  109 + _fbss = .;
  110 + .sbss : { *(.sbss) *(.scommon) }
  111 + .bss :
  112 + {
  113 + *(.dynbss)
  114 + *(.bss)
  115 + *(COMMON)
  116 + . = ALIGN(4);
  117 + _end = . ;
  118 + PROVIDE (end = .);
  119 + }
  120 +
  121 + /* Sections to be discarded */
  122 + /DISCARD/ :
  123 + {
  124 + *(.text.exit)
  125 + *(.data.exit)
  126 + *(.exitcall.exit)
  127 + }
  128 +
  129 + /* This is the MIPS specific mdebug section. */
  130 + .mdebug : { *(.mdebug) }
  131 + /* These are needed for ELF backends which have not yet been
  132 + converted to the new style linker. */
  133 + .stab 0 : { *(.stab) }
  134 + .stabstr 0 : { *(.stabstr) }
  135 + /* DWARF debug sections.
  136 + Symbols in the .debug DWARF section are relative to the beginning of the
  137 + section so we begin .debug at 0. It's not clear yet what needs to happen
  138 + for the others. */
  139 + .debug 0 : { *(.debug) }
  140 + .debug_srcinfo 0 : { *(.debug_srcinfo) }
  141 + .debug_aranges 0 : { *(.debug_aranges) }
  142 + .debug_pubnames 0 : { *(.debug_pubnames) }
  143 + .debug_sfnames 0 : { *(.debug_sfnames) }
  144 + .line 0 : { *(.line) }
  145 + /* These must appear regardless of . */
  146 + .gptab.sdata : { *(.gptab.data) *(.gptab.sdata) }
  147 + .gptab.sbss : { *(.gptab.bss) *(.gptab.sbss) }
  148 + .comment : { *(.comment) }
  149 + .note : { *(.note) }
  150 +}
arch/mips/boot/compressed/uart-16550.c
  1 +/*
  2 + * 16550 compatible uart based serial debug support for zboot
  3 + */
  4 +
  5 +#include <linux/types.h>
  6 +#include <linux/serial_reg.h>
  7 +#include <linux/init.h>
  8 +
  9 +#include <asm/addrspace.h>
  10 +
  11 +#if defined(CONFIG_MACH_LOONGSON) || defined(CONFIG_MIPS_MALTA)
  12 +#define UART_BASE 0x1fd003f8
  13 +#define PORT(offset) (CKSEG1ADDR(UART_BASE) + (offset))
  14 +#endif
  15 +
  16 +#ifdef CONFIG_AR7
  17 +#include <ar7.h>
  18 +#define PORT(offset) (CKSEG1ADDR(AR7_REGS_UART0) + (4 * offset))
  19 +#endif
  20 +
  21 +#ifndef PORT
  22 +#error please define the serial port address for your own machine
  23 +#endif
  24 +
  25 +static inline unsigned int serial_in(int offset)
  26 +{
  27 + return *((char *)PORT(offset));
  28 +}
  29 +
  30 +static inline void serial_out(int offset, int value)
  31 +{
  32 + *((char *)PORT(offset)) = value;
  33 +}
  34 +
  35 +void putc(char c)
  36 +{
  37 + int timeout = 1024;
  38 +
  39 + while (((serial_in(UART_LSR) & UART_LSR_THRE) == 0) && (timeout-- > 0))
  40 + ;
  41 +
  42 + serial_out(UART_TX, c);
  43 +}