This demonstrates that the relocatable kernel doesn't have to run at
real address 0.  It only copies the interrupt vectors down and leaves
the rest of the kernel where it was loaded, and runs it there.

This is mostly just a proof of concept, since it doesn't do anything
to ensure that the kernel base address is 16kB-aligned, and we
probably want to move the kernel down to 0 in most cases (except for
kdump kernels) anyway.

Signed-off-by: Paul Mackerras <[EMAIL PROTECTED]>
---
diff --git a/arch/powerpc/kernel/head_64.S b/arch/powerpc/kernel/head_64.S
index abb3bfe..fdb8565 100644
--- a/arch/powerpc/kernel/head_64.S
+++ b/arch/powerpc/kernel/head_64.S
@@ -1377,6 +1377,7 @@ _STATIC(__after_prom_start)
        /* process relocations for the final address of the kernel */
        lis     r25,[EMAIL PROTECTED]   /* compute virtual base of kernel */
        sldi    r25,r25,32
+       add     r25,r25,r26
        mr      r3,r25
        bl      .relocate
 #endif
@@ -1391,10 +1392,13 @@ _STATIC(__after_prom_start)
        li      r3,0                    /* target addr */
        mr.     r4,r26                  /* In some cases the loader may  */
        beq     9f                      /* have already put us at zero */
-       lis     r5,(copy_to_here - _stext)@ha
-       addi    r5,r5,(copy_to_here - _stext)@l /* # bytes of memory to copy */
        li      r6,0x100                /* Start offset, the first 0x100 */
                                        /* bytes were copied earlier.    */
+#ifdef CONFIG_RELOCATABLE
+       li      r5,__end_interrupts - _stext    /* just copy interrupts */
+#else
+       lis     r5,(copy_to_here - _stext)@ha
+       addi    r5,r5,(copy_to_here - _stext)@l /* # bytes of memory to copy */
 
        bl      .copy_and_flush         /* copy the first n bytes        */
                                        /* this includes the code being  */
@@ -1404,15 +1408,16 @@ _STATIC(__after_prom_start)
        mtctr   r8
        bctr
 
+p_end: .llong  _end - _stext
+
 4:     /* Now copy the rest of the kernel up to _end */
        addis   r5,r26,(p_end - _stext)@ha
        ld      r5,(p_end - _stext)@l(r5)       /* get _end */
+#endif
        bl      .copy_and_flush         /* copy the rest */
 
 9:     b       .start_here_multiplatform
 
-p_end: .llong  _end - _stext
-
 /*
  * Copy routine used to copy the kernel to start at physical address 0
  * and flush and invalidate the caches as needed.
_______________________________________________
Linuxppc-dev mailing list
Linuxppc-dev@ozlabs.org
https://ozlabs.org/mailman/listinfo/linuxppc-dev

Reply via email to