Skip to content

Instantly share code, notes, and snippets.

@Tasssadar
Created January 4, 2013 23:50
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Tasssadar/4458581 to your computer and use it in GitHub Desktop.
Save Tasssadar/4458581 to your computer and use it in GitHub Desktop.
Support copying of atags in the decompressor.
From 9d8b8f75aec0029210fe578f0c95197582d37a67 Mon Sep 17 00:00:00 2001
From: Vojtech Bocek <vbocek@gmail.com>
Date: Thu, 22 Nov 2012 20:45:33 +0100
Subject: [PATCH] UBUNTU: Support copying of atags in the decompressor.
OriginalAuthor: Mike Kasick <mike@kasick.org>
Ported from Jens Andersen <jens.andersen@gmail.com>'s
kernel for Asus TF201 [3].
[1] N7 kernel: http://kernel.ubuntu.com/git?p=hwe/ubuntu-nexus7.git
[2] Hardboot: http://forum.xda-developers.com/showthread.php?t=1266827
[3] Original repository: http://git.io/EXpn2A
https://lists.ubuntu.com/archives/kernel-team/2012-November/023076.html
This is needed if this kernel is booted using kexec-hardboot,
because atags need to be in direct-mapped region, usually
the first 16kB of RAM.
Signed-off-by: Vojtech Bocek <vbocek@gmail.com>
Acked-by: Jani Monoses <jani@ubuntu.com>
Signed-off-by: Tim Gardner <tim.gardner@canonical.com>
---
arch/arm/boot/compressed/Makefile | 3 ++
arch/arm/boot/compressed/head.S | 44 ++++++++++++++++++++++++++++++++++++-
arch/arm/boot/compressed/misc.c | 22 ++++++++++++++++++
3 files changed, 68 insertions(+), 1 deletions(-)
diff --git a/arch/arm/boot/compressed/Makefile b/arch/arm/boot/compressed/Makefile
index 0c74a6f..7643b37 100644
--- a/arch/arm/boot/compressed/Makefile
+++ b/arch/arm/boot/compressed/Makefile
@@ -111,6 +111,9 @@ endif
ifeq ($(CONFIG_CPU_ENDIAN_BE8),y)
LDFLAGS_vmlinux += --be8
endif
+ifneq ($(PARAMS_PHYS),)
+LDFLAGS_vmlinux += --defsym params_phys=$(PARAMS_PHYS)
+endif
# ?
LDFLAGS_vmlinux += -p
# Report unresolved symbol references
diff --git a/arch/arm/boot/compressed/head.S b/arch/arm/boot/compressed/head.S
index 401efb4..99fa555 100644
--- a/arch/arm/boot/compressed/head.S
+++ b/arch/arm/boot/compressed/head.S
@@ -134,7 +134,9 @@ start:
.word _edata @ zImage end address
THUMB( .thumb )
1: mov r7, r1 @ save architecture ID
- mov r8, r2 @ save atags pointer
+ teq r0, #0 @ Check for kexec_boot_atags.
+ movne r8, r0 @ Save kexec_boot_tags.
+ moveq r8, r2 @ save atags pointer
#ifndef __ARM_ARCH_2__
/*
@@ -349,6 +351,44 @@ not_relocated: mov r0, #0
add r2, sp, #0x10000 @ 64k max
mov r3, r7
bl decompress_kernel
+
+/* Copy the kernel tagged list (atags):
+ *
+ * The kernel requires atags to be located in a direct-mapped region,
+ * usually below the kernel in the first 16 kB of RAM. If they're above
+ * (the start of) the kernel, they need to be copied to a suitable
+ * location, e.g., the machine-defined params_phys.
+ *
+ * The assumption is that the tags will only be "out of place" if the
+ * decompressor code is also, so copying is implemented only in the "won't
+ * overwrite" case (which should be fixed). Still need to make sure that
+ * the copied tags don't overwrite either the kernel or decompressor code
+ * (or rather, the remainder of it since everything up to here has already
+ * been executed).
+ *
+ * r4: zreladdr (kernel start)
+ * r8: atags */
+
+ /* No need to copy atags if they're already below kernel */
+ cmp r8, r4
+ blo call_kernel
+
+ /* r1: min(zreladdr, pc) */
+ mov r1, pc
+ cmp r4, r1
+ movlo r1, r4
+
+ /* Compute max space for atags, if max <= 0 don't copy. */
+ ldr r0, =params_phys @ dest
+ subs r2, r1, r0 @ max = min(zreladdr, pc) - dest
+ bls call_kernel
+
+ /* Copy atags to params_phys. */
+ mov r1, r8 @ src
+ bl copy_atags
+ mov r8, r0
+
+call_kernel:
bl cache_clean_flush
bl cache_off
mov r0, #0 @ must be zero
@@ -357,6 +397,8 @@ not_relocated: mov r0, #0
ARM( mov pc, r4 ) @ call kernel
THUMB( bx r4 ) @ entry point is always ARM
+ .ltorg
+
.align 2
.type LC0, #object
LC0: .word LC0 @ r1
diff --git a/arch/arm/boot/compressed/misc.c b/arch/arm/boot/compressed/misc.c
index 832d372..c082769 100644
--- a/arch/arm/boot/compressed/misc.c
+++ b/arch/arm/boot/compressed/misc.c
@@ -25,6 +25,7 @@ unsigned int __machine_arch_type;
#include <linux/stddef.h> /* for NULL */
#include <linux/linkage.h>
#include <asm/string.h>
+#include <asm/setup.h>
static void putstr(const char *ptr);
@@ -192,3 +193,24 @@ decompress_kernel(unsigned long output_start, unsigned long free_mem_ptr_p,
else
putstr(" done, booting the kernel.\n");
}
+
+const struct tag *copy_atags(struct tag *dest, const struct tag *src, size_t max)
+{
+ struct tag *tag;
+ size_t size;
+
+ /* Find the last tag (ATAG_NONE). */
+ for_each_tag(tag, (struct tag *)src)
+ continue;
+
+ /* Include the last tag in copy. */
+ size = (char *)tag - (char *)src + sizeof(struct tag_header);
+
+ /* If there's not enough room, just use original and hope it works. */
+ if (size > max)
+ return src;
+
+ memcpy(dest, src, size);
+
+ return dest;
+}
--
1.7.0.4
From 5cfa09ccacd3722ef4cfe81b7db098d52c584336 Mon Sep 17 00:00:00 2001
From: Vojtech Bocek <vbocek@gmail.com>
Date: Thu, 22 Nov 2012 20:45:32 +0100
Subject: [PATCH] UBUNTU: Enable caching and buffering of whole RAM in the decompressor
OriginalAuthor: Mike Kasick <mike@kasick.org>
Ported from Jens Andersen <jens.andersen@gmail.com>'s
kernel for Asus TF201 [3].
[1] N7 kernel: http://kernel.ubuntu.com/git?p=hwe/ubuntu-nexus7.git
[2] Hardboot: http://forum.xda-developers.com/showthread.php?t=1266827
[3] Original repository: http://git.io/EXpn2A
https://lists.ubuntu.com/archives/kernel-team/2012-November/023076.html
This is to speed-up booting if this kernel is booted using
kexec-hardboot. Without this patch, decompressor is very slow
to decompress, because it is located far above the kernel destination.
Signed-off-by: Vojtech Bocek <vbocek@gmail.com>
Acked-by: Jani Monoses <jani@ubuntu.com>
Signed-off-by: Tim Gardner <tim.gardner@canonical.com>
---
arch/arm/boot/compressed/head.S | 6 ++++++
arch/arm/mach-tegra/include/mach/memory.h | 4 ++++
2 files changed, 10 insertions(+), 0 deletions(-)
diff --git a/arch/arm/boot/compressed/head.S b/arch/arm/boot/compressed/head.S
index 24701d6..401efb4 100644
--- a/arch/arm/boot/compressed/head.S
+++ b/arch/arm/boot/compressed/head.S
@@ -9,6 +9,7 @@
* published by the Free Software Foundation.
*/
#include <linux/linkage.h>
+#include <asm/memory.h>
/*
* Debugging stuff
@@ -467,9 +468,14 @@ __setup_mmu: sub r3, r4, #16384 @ Page directory size
* bits for the RAM area only.
*/
mov r0, r3
+#if defined(PLAT_PHYS_OFFSET) && defined(END_MEM)
+ mov r9, #PLAT_PHYS_OFFSET @ start of RAM
+ ldr r10, =END_MEM @ end of RAM
+#else
mov r9, r0, lsr #18
mov r9, r9, lsl #18 @ start of RAM
add r10, r9, #0x10000000 @ a reasonable RAM size
+#endif
mov r1, #0x12
orr r1, r1, #3 << 10
add r2, r3, #16384
diff --git a/arch/arm/mach-tegra/include/mach/memory.h b/arch/arm/mach-tegra/include/mach/memory.h
index 5f51066..c243a32 100644
--- a/arch/arm/mach-tegra/include/mach/memory.h
+++ b/arch/arm/mach-tegra/include/mach/memory.h
@@ -29,6 +29,10 @@
#define PLAT_PHYS_OFFSET UL(0x80000000)
#endif
+#if defined(CONFIG_MACH_GROUPER)
+#define END_MEM UL(0xBEA00000)
+#endif
+
/*
* Unaligned DMA causes tegra dma to place data on 4-byte boundary after
* expected address. Call to skb_reserve(skb, NET_IP_ALIGN) was causing skb
--
1.7.0.4
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment