Skip to content

Commit

Permalink
Merge branch 'depends/rmk/devel-stable' into next/cleanup
Browse files Browse the repository at this point in the history
  • Loading branch information
Arnd Bergmann committed Oct 8, 2011
2 parents 8efc59a + c825dda commit 71f2c15
Show file tree
Hide file tree
Showing 405 changed files with 7,167 additions and 1,547 deletions.
33 changes: 33 additions & 0 deletions arch/arm/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ config ARM
select HAVE_GENERIC_HARDIRQS
select HAVE_SPARSE_IRQ
select GENERIC_IRQ_SHOW
select CPU_PM if (SUSPEND || CPU_IDLE)
help
The ARM series is a line of low-power-consumption RISC chip designs
licensed by ARM Ltd and targeted at embedded applications and
Expand Down Expand Up @@ -1794,6 +1795,38 @@ config ZBOOT_ROM_SH_MOBILE_SDHI

endchoice

config ARM_APPENDED_DTB
bool "Use appended device tree blob to zImage (EXPERIMENTAL)"
depends on OF && !ZBOOT_ROM && EXPERIMENTAL
help
With this option, the boot code will look for a device tree binary
(DTB) appended to zImage
(e.g. cat zImage <filename>.dtb > zImage_w_dtb).

This is meant as a backward compatibility convenience for those
systems with a bootloader that can't be upgraded to accommodate
the documented boot protocol using a device tree.

Beware that there is very little in terms of protection against
this option being confused by leftover garbage in memory that might
look like a DTB header after a reboot if no actual DTB is appended
to zImage. Do not leave this option active in a production kernel
if you don't intend to always append a DTB. Proper passing of the
location into r2 of a bootloader provided DTB is always preferable
to this option.

config ARM_ATAG_DTB_COMPAT
bool "Supplement the appended DTB with traditional ATAG information"
depends on ARM_APPENDED_DTB
help
Some old bootloaders can't be updated to a DTB capable one, yet
they provide ATAGs with memory configuration, the ramdisk address,
the kernel cmdline string, etc. Such information is dynamically
provided by the bootloader and can't always be stored in a static
DTB. To allow a device tree enabled kernel to be used with such
bootloaders, this option allows zImage to extract the information
from the ATAG list and store it at run time into the appended DTB.

config CMDLINE
string "Default kernel command string"
default ""
Expand Down
6 changes: 6 additions & 0 deletions arch/arm/Kconfig.debug
Original file line number Diff line number Diff line change
Expand Up @@ -129,4 +129,10 @@ config DEBUG_S3C_UART
The uncompressor code port configuration is now handled
by CONFIG_S3C_LOWLEVEL_UART_PORT.

config ARM_KPROBES_TEST
tristate "Kprobes test module"
depends on KPROBES && MODULES
help
Perform tests of kprobes API and instruction set simulation.

endmenu
9 changes: 9 additions & 0 deletions arch/arm/boot/compressed/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,12 @@ piggy.lzo
piggy.lzma
vmlinux
vmlinux.lds

# borrowed libfdt files
fdt.c
fdt.h
fdt_ro.c
fdt_rw.c
fdt_wip.c
libfdt.h
libfdt_internal.h
32 changes: 28 additions & 4 deletions arch/arm/boot/compressed/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,10 @@ HEAD = head.o
OBJS += misc.o decompress.o
FONTC = $(srctree)/drivers/video/console/font_acorn_8x8.c

# string library code (-Os is enforced to keep it much smaller)
OBJS += string.o
CFLAGS_string.o := -Os

#
# Architecture dependencies
#
Expand Down Expand Up @@ -89,21 +93,41 @@ suffix_$(CONFIG_KERNEL_GZIP) = gzip
suffix_$(CONFIG_KERNEL_LZO) = lzo
suffix_$(CONFIG_KERNEL_LZMA) = lzma

# Borrowed libfdt files for the ATAG compatibility mode

libfdt := fdt_rw.c fdt_ro.c fdt_wip.c fdt.c
libfdt_hdrs := fdt.h libfdt.h libfdt_internal.h

libfdt_objs := $(addsuffix .o, $(basename $(libfdt)))

$(addprefix $(obj)/,$(libfdt) $(libfdt_hdrs)): $(obj)/%: $(srctree)/scripts/dtc/libfdt/%
$(call cmd,shipped)

$(addprefix $(obj)/,$(libfdt_objs) atags_to_fdt.o): \
$(addprefix $(obj)/,$(libfdt_hdrs))

ifeq ($(CONFIG_ARM_ATAG_DTB_COMPAT),y)
OBJS += $(libfdt_objs) atags_to_fdt.o
endif

targets := vmlinux vmlinux.lds \
piggy.$(suffix_y) piggy.$(suffix_y).o \
font.o font.c head.o misc.o $(OBJS)
lib1funcs.o lib1funcs.S font.o font.c head.o misc.o $(OBJS)

# Make sure files are removed during clean
extra-y += piggy.gzip piggy.lzo piggy.lzma lib1funcs.S
extra-y += piggy.gzip piggy.lzo piggy.lzma lib1funcs.S $(libfdt) $(libfdt_hdrs)

ifeq ($(CONFIG_FUNCTION_TRACER),y)
ORIG_CFLAGS := $(KBUILD_CFLAGS)
KBUILD_CFLAGS = $(subst -pg, , $(ORIG_CFLAGS))
endif

ccflags-y := -fpic -fno-builtin
ccflags-y := -fpic -fno-builtin -I$(obj)
asflags-y := -Wa,-march=all

# Supply kernel BSS size to the decompressor via a linker symbol.
KBSS_SZ = $(shell size $(obj)/../../../../vmlinux | awk 'END{print $$3}')
LDFLAGS_vmlinux = --defsym _kernel_bss_size=$(KBSS_SZ)
# Supply ZRELADDR to the decompressor via a linker symbol.
ifneq ($(CONFIG_AUTO_ZRELADDR),y)
LDFLAGS_vmlinux += --defsym zreladdr=$(ZRELADDR)
Expand All @@ -123,7 +147,7 @@ LDFLAGS_vmlinux += -T
# For __aeabi_uidivmod
lib1funcs = $(obj)/lib1funcs.o

$(obj)/lib1funcs.S: $(srctree)/arch/$(SRCARCH)/lib/lib1funcs.S FORCE
$(obj)/lib1funcs.S: $(srctree)/arch/$(SRCARCH)/lib/lib1funcs.S
$(call cmd,shipped)

# We need to prevent any GOTOFF relocs being used with references
Expand Down
97 changes: 97 additions & 0 deletions arch/arm/boot/compressed/atags_to_fdt.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
#include <asm/setup.h>
#include <libfdt.h>

static int node_offset(void *fdt, const char *node_path)
{
int offset = fdt_path_offset(fdt, node_path);
if (offset == -FDT_ERR_NOTFOUND)
offset = fdt_add_subnode(fdt, 0, node_path);
return offset;
}

static int setprop(void *fdt, const char *node_path, const char *property,
uint32_t *val_array, int size)
{
int offset = node_offset(fdt, node_path);
if (offset < 0)
return offset;
return fdt_setprop(fdt, offset, property, val_array, size);
}

static int setprop_string(void *fdt, const char *node_path,
const char *property, const char *string)
{
int offset = node_offset(fdt, node_path);
if (offset < 0)
return offset;
return fdt_setprop_string(fdt, offset, property, string);
}

static int setprop_cell(void *fdt, const char *node_path,
const char *property, uint32_t val)
{
int offset = node_offset(fdt, node_path);
if (offset < 0)
return offset;
return fdt_setprop_cell(fdt, offset, property, val);
}

/*
* Convert and fold provided ATAGs into the provided FDT.
*
* REturn values:
* = 0 -> pretend success
* = 1 -> bad ATAG (may retry with another possible ATAG pointer)
* < 0 -> error from libfdt
*/
int atags_to_fdt(void *atag_list, void *fdt, int total_space)
{
struct tag *atag = atag_list;
uint32_t mem_reg_property[2 * NR_BANKS];
int memcount = 0;
int ret;

/* make sure we've got an aligned pointer */
if ((u32)atag_list & 0x3)
return 1;

/* if we get a DTB here we're done already */
if (*(u32 *)atag_list == fdt32_to_cpu(FDT_MAGIC))
return 0;

/* validate the ATAG */
if (atag->hdr.tag != ATAG_CORE ||
(atag->hdr.size != tag_size(tag_core) &&
atag->hdr.size != 2))
return 1;

/* let's give it all the room it could need */
ret = fdt_open_into(fdt, fdt, total_space);
if (ret < 0)
return ret;

for_each_tag(atag, atag_list) {
if (atag->hdr.tag == ATAG_CMDLINE) {
setprop_string(fdt, "/chosen", "bootargs",
atag->u.cmdline.cmdline);
} else if (atag->hdr.tag == ATAG_MEM) {
if (memcount >= sizeof(mem_reg_property)/4)
continue;
mem_reg_property[memcount++] = cpu_to_fdt32(atag->u.mem.start);
mem_reg_property[memcount++] = cpu_to_fdt32(atag->u.mem.size);
} else if (atag->hdr.tag == ATAG_INITRD2) {
uint32_t initrd_start, initrd_size;
initrd_start = atag->u.initrd.start;
initrd_size = atag->u.initrd.size;
setprop_cell(fdt, "/chosen", "linux,initrd-start",
initrd_start);
setprop_cell(fdt, "/chosen", "linux,initrd-end",
initrd_start + initrd_size);
}
}

if (memcount)
setprop(fdt, "/memory", "reg", mem_reg_property, 4*memcount);

return fdt_pack(fdt);
}
121 changes: 114 additions & 7 deletions arch/arm/boot/compressed/head.S
Original file line number Diff line number Diff line change
Expand Up @@ -216,22 +216,118 @@ restart: adr r0, LC0
mov r10, r6
#endif

mov r5, #0 @ init dtb size to 0
#ifdef CONFIG_ARM_APPENDED_DTB
/*
* r0 = delta
* r2 = BSS start
* r3 = BSS end
* r4 = final kernel address
* r5 = appended dtb size (still unknown)
* r6 = _edata
* r7 = architecture ID
* r8 = atags/device tree pointer
* r9 = size of decompressed image
* r10 = end of this image, including bss/stack/malloc space if non XIP
* r11 = GOT start
* r12 = GOT end
* sp = stack pointer
*
* if there are device trees (dtb) appended to zImage, advance r10 so that the
* dtb data will get relocated along with the kernel if necessary.
*/

ldr lr, [r6, #0]
#ifndef __ARMEB__
ldr r1, =0xedfe0dd0 @ sig is 0xd00dfeed big endian
#else
ldr r1, =0xd00dfeed
#endif
cmp lr, r1
bne dtb_check_done @ not found

#ifdef CONFIG_ARM_ATAG_DTB_COMPAT
/*
* OK... Let's do some funky business here.
* If we do have a DTB appended to zImage, and we do have
* an ATAG list around, we want the later to be translated
* and folded into the former here. To be on the safe side,
* let's temporarily move the stack away into the malloc
* area. No GOT fixup has occurred yet, but none of the
* code we're about to call uses any global variable.
*/
add sp, sp, #0x10000
stmfd sp!, {r0-r3, ip, lr}
mov r0, r8
mov r1, r6
sub r2, sp, r6
bl atags_to_fdt

/*
* If returned value is 1, there is no ATAG at the location
* pointed by r8. Try the typical 0x100 offset from start
* of RAM and hope for the best.
*/
cmp r0, #1
sub r0, r4, #(TEXT_OFFSET - 0x100)
mov r1, r6
sub r2, sp, r6
blne atags_to_fdt

ldmfd sp!, {r0-r3, ip, lr}
sub sp, sp, #0x10000
#endif

mov r8, r6 @ use the appended device tree

/*
* Make sure that the DTB doesn't end up in the final
* kernel's .bss area. To do so, we adjust the decompressed
* kernel size to compensate if that .bss size is larger
* than the relocated code.
*/
ldr r5, =_kernel_bss_size
adr r1, wont_overwrite
sub r1, r6, r1
subs r1, r5, r1
addhi r9, r9, r1

/* Get the dtb's size */
ldr r5, [r6, #4]
#ifndef __ARMEB__
/* convert r5 (dtb size) to little endian */
eor r1, r5, r5, ror #16
bic r1, r1, #0x00ff0000
mov r5, r5, ror #8
eor r5, r5, r1, lsr #8
#endif

/* preserve 64-bit alignment */
add r5, r5, #7
bic r5, r5, #7

/* relocate some pointers past the appended dtb */
add r6, r6, r5
add r10, r10, r5
add sp, sp, r5
dtb_check_done:
#endif

/*
* Check to see if we will overwrite ourselves.
* r4 = final kernel address
* r9 = size of decompressed image
* r10 = end of this image, including bss/stack/malloc space if non XIP
* We basically want:
* r4 - 16k page directory >= r10 -> OK
* r4 + image length <= current position (pc) -> OK
* r4 + image length <= address of wont_overwrite -> OK
*/
add r10, r10, #16384
cmp r4, r10
bhs wont_overwrite
add r10, r4, r9
ARM( cmp r10, pc )
THUMB( mov lr, pc )
THUMB( cmp r10, lr )
adr r9, wont_overwrite
cmp r10, r9
bls wont_overwrite

/*
Expand Down Expand Up @@ -285,14 +381,16 @@ wont_overwrite:
* r2 = BSS start
* r3 = BSS end
* r4 = kernel execution address
* r5 = appended dtb size (0 if not present)
* r7 = architecture ID
* r8 = atags pointer
* r11 = GOT start
* r12 = GOT end
* sp = stack pointer
*/
teq r0, #0
orrs r1, r0, r5
beq not_relocated

add r11, r11, r0
add r12, r12, r0

Expand All @@ -307,12 +405,21 @@ wont_overwrite:

/*
* Relocate all entries in the GOT table.
* Bump bss entries to _edata + dtb size
*/
1: ldr r1, [r11, #0] @ relocate entries in the GOT
add r1, r1, r0 @ table. This fixes up the
str r1, [r11], #4 @ C references.
add r1, r1, r0 @ This fixes up C references
cmp r1, r2 @ if entry >= bss_start &&
cmphs r3, r1 @ bss_end > entry
addhi r1, r1, r5 @ entry += dtb size
str r1, [r11], #4 @ next entry
cmp r11, r12
blo 1b

/* bump our bss pointers too */
add r2, r2, r5
add r3, r3, r5

#else

/*
Expand Down
Loading

0 comments on commit 71f2c15

Please sign in to comment.