highmove: handle zImage and setup separately
authorH. Peter Anvin <hpa@zytor.com>
Sat, 29 May 2010 03:50:39 +0000 (20:50 -0700)
committerH. Peter Anvin <hpa@zytor.com>
Sat, 29 May 2010 03:50:39 +0000 (20:50 -0700)
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>
highmove/highmove.S
linux.c
setup.h

index ac1cc2a..231c743 100644 (file)
  */
                /* 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 (file)
--- 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 (file)
--- 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))