summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorH. Peter Anvin <hpa@zytor.com>2010-05-28 20:50:39 -0700
committerH. Peter Anvin <hpa@zytor.com>2010-05-28 20:50:39 -0700
commitabd6fcebc99212122cff37e55b82df65163b5494 (patch)
tree971d0313d0d73ffba8f49e10fa043f04785e71d6
parentc25bbd8d020855c32c5f54966da742c5777435d2 (diff)
downloadwraplinux-abd6fcebc99212122cff37e55b82df65163b5494.tar.gz
wraplinux-abd6fcebc99212122cff37e55b82df65163b5494.tar.xz
wraplinux-abd6fcebc99212122cff37e55b82df65163b5494.zip
highmove: handle zImage and setup separately
It doesn't really work to try to combine the zImage PM code and the setup code into a single copy unit. Separate them into two. Signed-off-by: H. Peter Anvin <hpa@zytor.com>
-rw-r--r--highmove/highmove.S19
-rw-r--r--linux.c15
-rw-r--r--setup.h10
3 files changed, 29 insertions, 15 deletions
diff --git a/highmove/highmove.S b/highmove/highmove.S
index ac1cc2a..231c743 100644
--- a/highmove/highmove.S
+++ b/highmove/highmove.S
@@ -34,10 +34,10 @@
*/
/* Parameters */
.section ".startupinfo","a",@progbits
-mv_src: .long 0
-mv_dst: .long 0
-mv_len: .long 0
mv_entry: .long 0
+mv_move: .long 0, 0, 0 /* Setup code */
+ .long 0, 0, 0 /* zImage kernel code */
+ .long 0, 0, 0 /* Null terminator */
/* We will be entered in flat 32-bit protected mode... */
.section ".start","ax",@progbits
@@ -56,15 +56,22 @@ _start:
movl mv_entry(%ebx), %ecx
movl %ecx, (5*4)(%esp) /* Where to go next */
- movl mv_src(%ebx), %esi
- movl mv_dst(%ebx), %edi
- movl mv_len(%ebx), %ecx
+ addl $mv_move, %ebx
+2:
+ movl (%ebx), %edi
+ movl 4(%ebx), %esi
+ movl 8(%ebx), %ecx
addl $3, %ecx
shrl $2, %ecx
+ jz 3f /* Zero length = we're done */
cld
rep ; movsl
+ addl $12, %ebx
+ jmp 2b
+
+3:
popl %edi
popl %esi
popl %ebx
diff --git a/linux.c b/linux.c
index 9aab786..385bf2e 100644
--- a/linux.c
+++ b/linux.c
@@ -317,11 +317,13 @@ int wrap_kernel(const char *kernel_file, const char *cmdline,
if (opt.loadhigh) {
uint32_t rm_base, rm_len, delta;
- rm_base = ssup.address;
if (skrn.address < 0x100000) {
- rm_base = skrn.address;
+ /* zImage, need to move the kernel as well */
+ wrle32(skrn.address, &hmv->mv[1].dst);
+ wrle32(skrn.length, &hmv->mv[1].len);
skrn.address = 0x100000;
- initrd_addr = 0x100000 + skrn.length;
+ wrle32(skrn.address, &hmv->mv[1].src);
+ initrd_addr = skrn.address + skrn.length;
}
shmv.next = skrn.next;
@@ -334,9 +336,10 @@ int wrap_kernel(const char *kernel_file, const char *cmdline,
shmv.name = "highmove";
shmv.data = highmove;
+ rm_base = ssup.address;
rm_len = scmd.address + scmd.length - rm_base;
- wrle32(rm_base, &hmv->mv_dst);
- wrle32(rm_len, &hmv->mv_len);
+ wrle32(rm_base, &hmv->mv[0].dst);
+ wrle32(rm_len, &hmv->mv[0].len);
wrle32(entry, &hmv->mv_entry);
entry = shmv.address + sizeof *hmv;
@@ -344,7 +347,7 @@ int wrap_kernel(const char *kernel_file, const char *cmdline,
initrd_addr = shmv.address + shmv.length;
initrd_addr = align_up(initrd_addr, 4);
- wrle32(initrd_addr, &hmv->mv_src);
+ wrle32(initrd_addr, &hmv->mv[0].src);
delta = initrd_addr - ssup.address;
diff --git a/setup.h b/setup.h
index 4313bc7..460585a 100644
--- a/setup.h
+++ b/setup.h
@@ -12,11 +12,15 @@ struct startup_info {
uint32_t reloc_size;
};
+struct highmove {
+ uint32_t dst;
+ uint32_t src;
+ uint32_t len;
+};
+
struct highmove_info {
- uint32_t mv_src;
- uint32_t mv_dst;
- uint32_t mv_len;
uint32_t mv_entry;
+ struct highmove mv[3];
};
#define LINUX_MAGIC ('H' + ('d' << 8) + ('r' << 16) + ('S' << 24))