diff options
Diffstat (limited to 'recipes/linux/linux/simpad/export_atags-r2.patch')
-rw-r--r-- | recipes/linux/linux/simpad/export_atags-r2.patch | 320 |
1 files changed, 320 insertions, 0 deletions
diff --git a/recipes/linux/linux/simpad/export_atags-r2.patch b/recipes/linux/linux/simpad/export_atags-r2.patch new file mode 100644 index 0000000000..e6fd85cf20 --- /dev/null +++ b/recipes/linux/linux/simpad/export_atags-r2.patch @@ -0,0 +1,320 @@ +[PATCH] Export atags to userspace and allow kexec to use customised atags + +Currently, the atags used by kexec are fixed to the ones originally used +to boot the kernel. This is less than ideal as changing the commandline, +initrd and other options would be a useful feature. + +This patch exports the atags used for the current kernel to userspace +through an "atags" file in procfs. The presence of the file is +controlled by its own Kconfig option and cleans up several ifdef blocks +into a separate file. The tags for the new kernel are assumed to be at +a fixed location before the kernel image itself. The location of the +tags used to boot the original kernel is unimportant and no longer +saved. + +Based on a patch from Uli Luckas <u.luckas@road.de> + +Signed-off-by: Richard Purdie <rpurdie@rpsys.net> + +--- + arch/arm/Kconfig | 7 +++ + arch/arm/kernel/Makefile | 1 + arch/arm/kernel/atags.c | 86 ++++++++++++++++++++++++++++++++++++++ + arch/arm/kernel/atags.h | 5 ++ + arch/arm/kernel/machine_kexec.c | 2 + arch/arm/kernel/relocate_kernel.S | 30 +------------ + arch/arm/kernel/setup.c | 32 -------------- + include/asm-arm/kexec.h | 3 + + 8 files changed, 110 insertions(+), 56 deletions(-) + +Index: linux-2.6.23/arch/arm/kernel/atags.c +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-2.6.23/arch/arm/kernel/atags.c 2008-01-20 15:56:02.000000000 +0000 +@@ -0,0 +1,86 @@ ++#include <linux/slab.h> ++#include <linux/kexec.h> ++#include <linux/proc_fs.h> ++#include <asm/setup.h> ++#include <asm/types.h> ++#include <asm/page.h> ++ ++struct buffer { ++ size_t size; ++ char *data; ++}; ++static struct buffer tags_buffer; ++ ++static int ++read_buffer(char* page, char** start, off_t off, int count, ++ int* eof, void* data) ++{ ++ struct buffer *buffer = (struct buffer *)data; ++ ++ if (off >= buffer->size) { ++ *eof = 1; ++ return 0; ++ } ++ ++ count = min((int) (buffer->size - off), count); ++ ++ memcpy(page, &buffer->data[off], count); ++ ++ return count; ++} ++ ++ ++static int ++create_proc_entries(void) ++{ ++ struct proc_dir_entry* tags_entry; ++ ++ tags_entry = create_proc_read_entry("atags", 0400, &proc_root, read_buffer, &tags_buffer); ++ if (!tags_entry) ++ return -ENOMEM; ++ ++ return 0; ++} ++ ++ ++static char __initdata atags_copy_buf[KEXEC_BOOT_PARAMS_SIZE]; ++static char __initdata *atags_copy; ++ ++void __init save_atags(const struct tag *tags) ++{ ++ atags_copy = atags_copy_buf; ++ memcpy(atags_copy, tags, KEXEC_BOOT_PARAMS_SIZE); ++} ++ ++ ++static int __init init_atags_procfs(void) ++{ ++ struct tag *tag; ++ int error; ++ ++ if (!atags_copy) { ++ printk(KERN_WARNING "Exporting ATAGs: No saved tags found\n"); ++ return -EIO; ++ } ++ ++ for (tag = (struct tag *) atags_copy; tag->hdr.size; tag = tag_next(tag)) ++ ; ++ ++ tags_buffer.size = ((char *) tag - atags_copy) + sizeof(tag->hdr); ++ tags_buffer.data = kmalloc(tags_buffer.size, GFP_KERNEL); ++ if (tags_buffer.data == NULL) ++ return -ENOMEM; ++ memcpy(tags_buffer.data, atags_copy, tags_buffer.size); ++ ++ error = create_proc_entries(); ++ if (error) { ++ printk(KERN_ERR "Exporting ATAGs: not enough memory\n"); ++ kfree(tags_buffer.data); ++ tags_buffer.size = 0; ++ tags_buffer.data = NULL; ++ } ++ ++ return error; ++} ++ ++arch_initcall(init_atags_procfs); +Index: linux-2.6.23/arch/arm/kernel/atags.h +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-2.6.23/arch/arm/kernel/atags.h 2008-01-20 15:56:02.000000000 +0000 +@@ -0,0 +1,5 @@ ++#ifdef CONFIG_ATAGS_PROC ++extern void save_atags(struct tag *tags); ++#else ++static inline void save_atags(struct tag *tags) { } ++#endif +Index: linux-2.6.23/arch/arm/kernel/Makefile +=================================================================== +--- linux-2.6.23.orig/arch/arm/kernel/Makefile 2007-10-09 21:31:38.000000000 +0100 ++++ linux-2.6.23/arch/arm/kernel/Makefile 2008-01-20 15:56:02.000000000 +0000 +@@ -19,6 +19,7 @@ obj-$(CONFIG_ISA_DMA) += dma-isa.o + obj-$(CONFIG_PCI) += bios32.o isa.o + obj-$(CONFIG_SMP) += smp.o + obj-$(CONFIG_KEXEC) += machine_kexec.o relocate_kernel.o ++obj-$(CONFIG_ATAGS_PROC) += atags.o + obj-$(CONFIG_OABI_COMPAT) += sys_oabi-compat.o + + obj-$(CONFIG_CRUNCH) += crunch.o crunch-bits.o +Index: linux-2.6.23/arch/arm/kernel/setup.c +=================================================================== +--- linux-2.6.23.orig/arch/arm/kernel/setup.c 2008-01-20 15:55:43.000000000 +0000 ++++ linux-2.6.23/arch/arm/kernel/setup.c 2008-01-20 15:56:02.000000000 +0000 +@@ -24,7 +24,6 @@ + #include <linux/interrupt.h> + #include <linux/smp.h> + #include <linux/fs.h> +-#include <linux/kexec.h> + + #include <asm/cpu.h> + #include <asm/elf.h> +@@ -39,6 +38,7 @@ + #include <asm/mach/time.h> + + #include "compat.h" ++#include "atags.h" + + #ifndef MEM_SIZE + #define MEM_SIZE (16*1024*1024) +@@ -784,23 +784,6 @@ static int __init customize_machine(void + } + arch_initcall(customize_machine); + +-#ifdef CONFIG_KEXEC +- +-/* Physical addr of where the boot params should be for this machine */ +-extern unsigned long kexec_boot_params_address; +- +-/* Physical addr of the buffer into which the boot params are copied */ +-extern unsigned long kexec_boot_params_copy; +- +-/* Pointer to the boot params buffer, for manipulation and display */ +-unsigned long kexec_boot_params; +-EXPORT_SYMBOL(kexec_boot_params); +- +-/* The buffer itself - make sure it is sized correctly */ +-static unsigned long kexec_boot_params_buf[(KEXEC_BOOT_PARAMS_SIZE + 3) / 4]; +- +-#endif +- + void __init setup_arch(char **cmdline_p) + { + struct tag *tags = (struct tag *)&init_tags; +@@ -819,18 +802,6 @@ void __init setup_arch(char **cmdline_p) + else if (mdesc->boot_params) + tags = phys_to_virt(mdesc->boot_params); + +-#ifdef CONFIG_KEXEC +- kexec_boot_params_copy = virt_to_phys(kexec_boot_params_buf); +- kexec_boot_params = (unsigned long)kexec_boot_params_buf; +- if (__atags_pointer) { +- kexec_boot_params_address = __atags_pointer; +- memcpy((void *)kexec_boot_params, tags, KEXEC_BOOT_PARAMS_SIZE); +- } else if (mdesc->boot_params) { +- kexec_boot_params_address = mdesc->boot_params; +- memcpy((void *)kexec_boot_params, tags, KEXEC_BOOT_PARAMS_SIZE); +- } +-#endif +- + /* + * If we have the old style parameters, convert them to + * a tag list. +@@ -846,6 +817,7 @@ void __init setup_arch(char **cmdline_p) + if (tags->hdr.tag == ATAG_CORE) { + if (meminfo.nr_banks != 0) + squash_mem_tags(tags); ++ save_atags(tags); + parse_tags(tags); + } + +Index: linux-2.6.23/arch/arm/Kconfig +=================================================================== +--- linux-2.6.23.orig/arch/arm/Kconfig 2008-01-20 15:55:43.000000000 +0000 ++++ linux-2.6.23/arch/arm/Kconfig 2008-01-20 15:58:52.000000000 +0000 +@@ -865,6 +865,13 @@ config KEXEC + initially work for you. It may help to enable device hotplugging + support. + ++config ATAGS_PROC ++ bool "Export atags in procfs" ++ default n ++ help ++ Should the atags used to boot the kernel be exported in an "atags" ++ file in procfs. Useful with kexec. ++ + endmenu + + if (ARCH_SA1100 || ARCH_INTEGRATOR || ARCH_OMAP || ARCH_IMX ) +Index: linux-2.6.23/arch/arm/kernel/machine_kexec.c +=================================================================== +--- linux-2.6.23.orig/arch/arm/kernel/machine_kexec.c 2007-10-09 21:31:38.000000000 +0100 ++++ linux-2.6.23/arch/arm/kernel/machine_kexec.c 2008-01-20 15:56:03.000000000 +0000 +@@ -21,6 +21,7 @@ extern void setup_mm_for_reboot(char mod + extern unsigned long kexec_start_address; + extern unsigned long kexec_indirection_page; + extern unsigned long kexec_mach_type; ++extern unsigned long kexec_boot_atags; + + /* + * Provide a dummy crash_notes definition while crash dump arrives to arm. +@@ -62,6 +63,7 @@ void machine_kexec(struct kimage *image) + kexec_start_address = image->start; + kexec_indirection_page = page_list; + kexec_mach_type = machine_arch_type; ++ kexec_boot_atags = image->start - KEXEC_ARM_ZIMAGE_OFFSET + KEXEC_ARM_ATAGS_OFFSET; + + /* copy our kernel relocation code to the control code page */ + memcpy(reboot_code_buffer, +Index: linux-2.6.23/arch/arm/kernel/relocate_kernel.S +=================================================================== +--- linux-2.6.23.orig/arch/arm/kernel/relocate_kernel.S 2008-01-20 15:55:43.000000000 +0000 ++++ linux-2.6.23/arch/arm/kernel/relocate_kernel.S 2008-01-20 15:56:03.000000000 +0000 +@@ -7,23 +7,6 @@ + .globl relocate_new_kernel + relocate_new_kernel: + +- /* Move boot params back to where the kernel expects them */ +- +- ldr r0,kexec_boot_params_address +- teq r0,#0 +- beq 8f +- +- ldr r1,kexec_boot_params_copy +- mov r6,#KEXEC_BOOT_PARAMS_SIZE/4 +-7: +- ldr r5,[r1],#4 +- str r5,[r0],#4 +- subs r6,r6,#1 +- bne 7b +- +-8: +- /* Boot params moved, now go on with the kernel */ +- + ldr r0,kexec_indirection_page + ldr r1,kexec_start_address + +@@ -67,7 +50,7 @@ relocate_new_kernel: + mov lr,r1 + mov r0,#0 + ldr r1,kexec_mach_type +- ldr r2,kexec_boot_params_address ++ ldr r2,kexec_boot_atags + mov pc,lr + + .globl kexec_start_address +@@ -82,14 +65,9 @@ kexec_indirection_page: + kexec_mach_type: + .long 0x0 + +- /* phy addr where new kernel will expect to find boot params */ +- .globl kexec_boot_params_address +-kexec_boot_params_address: +- .long 0x0 +- +- /* phy addr where old kernel put a copy of orig boot params */ +- .globl kexec_boot_params_copy +-kexec_boot_params_copy: ++ /* phy addr of the atags for the new kernel */ ++ .globl kexec_boot_atags ++kexec_boot_atags: + .long 0x0 + + relocate_new_kernel_end: +Index: linux-2.6.23/include/asm-arm/kexec.h +=================================================================== +--- linux-2.6.23.orig/include/asm-arm/kexec.h 2008-01-20 15:55:57.000000000 +0000 ++++ linux-2.6.23/include/asm-arm/kexec.h 2008-01-20 15:56:03.000000000 +0000 +@@ -16,6 +16,9 @@ + + #define KEXEC_BOOT_PARAMS_SIZE 1536 + ++#define KEXEC_ARM_ATAGS_OFFSET 0x1000 ++#define KEXEC_ARM_ZIMAGE_OFFSET 0x8000 ++ + #ifndef __ASSEMBLY__ + + struct kimage; |