]> git.neil.brown.name Git - history.git/commitdiff
PPC32: Fix a problem in the bootloader/wrapper where we might
authorTom Rini <trini@kernel.crashing.org>
Tue, 7 Jan 2003 01:56:13 +0000 (18:56 -0700)
committerTom Rini <trini@kernel.crashing.org>
Tue, 7 Jan 2003 01:56:13 +0000 (18:56 -0700)
overwrite part of the initrd.

arch/ppc/boot/prep/misc.c
arch/ppc/boot/simple/misc-embedded.c
arch/ppc/boot/simple/misc-spruce.c
arch/ppc/boot/simple/misc.c

index 66dab65ac9e5a38c8407233e61f558ebda62c2e0..9f84df4c850a527553ba2e22245fbad30a9ee305 100644 (file)
@@ -316,9 +316,31 @@ decompress_kernel(unsigned long load_addr, int num_words, unsigned long cksum,
 
        {
                struct bi_record *rec;
-               
-               rec = (struct bi_record *)_ALIGN((unsigned long)(zimage_size) +
+               unsigned long initrd_loc;
+               unsigned long rec_loc = _ALIGN((unsigned long)(zimage_size) +
                                (1 << 20) - 1, (1 << 20));
+               
+               rec = (struct bi_record *)rec_loc;
+
+               /* We need to make sure that the initrd and bi_recs do not
+                * overlap. */
+               if ( initrd_size ) {
+                       initrd_loc = (unsigned long)(&__ramdisk_begin);
+                       /* If the bi_recs are in the middle of the current
+                        * initrd, move the initrd to the next MB
+                        * boundary. */
+                       if ((rec_loc > initrd_loc) &&
+                                       ((initrd_loc + initrd_size)
+                                        > rec_loc)) {
+                               initrd_loc = _ALIGN((unsigned long)(zimage_size)
+                                               + (2 << 20) - 1, (2 << 20));
+                               memmove((void *)initrd_loc, &__ramdisk_begin,
+                                        initrd_size);
+                               puts("initrd moved:  "); puthex(initrd_loc);
+                               puts(" "); puthex(initrd_loc + initrd_size);
+                               puts("\n");
+                       }
+               }
 
                rec->tag = BI_FIRST;
                rec->size = sizeof(struct bi_record);
@@ -348,7 +370,7 @@ decompress_kernel(unsigned long load_addr, int num_words, unsigned long cksum,
 
                if ( initrd_size ) {
                        rec->tag = BI_INITRD;
-                       rec->data[0] = (unsigned long)(&__ramdisk_begin);
+                       rec->data[0] = initrd_loc;
                        rec->data[1] = initrd_size;
                        rec->size = sizeof(struct bi_record) + 2 *
                                sizeof(unsigned long);
index 72cb63cb4967250e46531ce50acd6d004f7abe73..f4ba6545cfb84a727c389fbb8aa6613ecdcdb31a 100644 (file)
@@ -209,9 +209,30 @@ decompress_kernel(unsigned long load_addr, int num_words, unsigned long cksum, b
        puts("done.\n");
        {
                struct bi_record *rec;
+               unsigned long initrd_loc;
+               unsigned long rec_loc = _ALIGN((unsigned long)(zimage_size) +
+                               (1 << 20) - 1, (1 << 20));
+               rec = (struct bi_record *)rec_loc;
 
-               rec = (struct bi_record *)_ALIGN((unsigned long)zimage_size +
-                               (1 << 20) - 1,(1 << 20));
+               /* We need to make sure that the initrd and bi_recs do not
+                * overlap. */
+               if ( initrd_size ) {
+                       initrd_loc = (unsigned long)(&__ramdisk_begin);
+                       /* If the bi_recs are in the middle of the current
+                        * initrd, move the initrd to the next MB
+                        * boundary. */
+                       if ((rec_loc > initrd_loc) &&
+                                       ((initrd_loc + initrd_size)
+                                        > rec_loc)) {
+                               initrd_loc = _ALIGN((unsigned long)(zimage_size)
+                                               + (2 << 20) - 1, (2 << 20));
+                               memmove((void *)initrd_loc, &__ramdisk_begin,
+                                        initrd_size);
+                               puts("initrd moved:  "); puthex(initrd_loc);
+                               puts(" "); puthex(initrd_loc + initrd_size);
+                               puts("\n");
+                       }
+               }
 
                rec->tag = BI_FIRST;
                rec->size = sizeof(struct bi_record);
@@ -224,7 +245,7 @@ decompress_kernel(unsigned long load_addr, int num_words, unsigned long cksum, b
 
                if ( initrd_size ) {
                        rec->tag = BI_INITRD;
-                       rec->data[0] = (unsigned long)(&__ramdisk_begin);
+                       rec->data[0] = initrd_loc;
                        rec->data[1] = initrd_size;
                        rec->size = sizeof(struct bi_record) + 2 *
                                sizeof(unsigned long);
index d799d183568de582fe3782f47c87708d8be3ef6d..12fa7dbb0ce2c6852cef3ba2052aee386a0780e9 100644 (file)
@@ -396,9 +396,30 @@ decompress_kernel(unsigned long load_addr, int num_words, unsigned long cksum)
 
        {
                struct bi_record *rec;
-
-               rec = (struct bi_record *)_ALIGN((ulong)zimage_size +
-                                                       (1<<20)-1,(1<<20));
+               unsigned long initrd_loc;
+               unsigned long rec_loc = _ALIGN((unsigned long)(zimage_size) +
+                               (1 << 20) - 1, (1 << 20));
+               rec = (struct bi_record *)rec_loc;
+  
+               /* We need to make sure that the initrd and bi_recs do not
+                * overlap. */
+               if ( initrd_size ) {
+                       initrd_loc = (unsigned long)(&__ramdisk_begin);
+                       /* If the bi_recs are in the middle of the current
+                        * initrd, move the initrd to the next MB
+                        * boundary. */
+                       if ((rec_loc > initrd_loc) &&
+                                       ((initrd_loc + initrd_size)
+                                        > rec_loc)) {
+                               initrd_loc = _ALIGN((unsigned long)(zimage_size)
+                                               + (2 << 20) - 1, (2 << 20));
+                               memmove((void *)initrd_loc, &__ramdisk_begin,
+                                        initrd_size);
+                               puts("initrd moved:  "); puthex(initrd_loc);
+                               puts(" "); puthex(initrd_loc + initrd_size);
+                               puts("\n");
+                       }
+               }
 
                rec->tag = BI_FIRST;
                rec->size = sizeof(struct bi_record);
@@ -421,7 +442,7 @@ decompress_kernel(unsigned long load_addr, int num_words, unsigned long cksum)
 
                if ( initrd_size ) {
                        rec->tag = BI_INITRD;
-                       rec->data[0] = (unsigned long)(&__ramdisk_begin);
+                       rec->data[0] = initrd_loc;
                        rec->data[1] = initrd_size;
                        rec->size = sizeof(struct bi_record) + 2 *
                                sizeof(unsigned long);
index 7cae431215a359a54726cc50745ff0189f7a141b..a10a8dd12017bbbf248691fa7a236e4a7cb8af3b 100644 (file)
@@ -76,8 +76,8 @@ decompress_kernel(unsigned long load_addr, int num_words, unsigned long cksum)
 {
        int timer = 0;
        char *cp, ch;
-       struct bi_record *rec, *birecs;
-       unsigned long TotalMemory = 0;
+       struct bi_record *rec;
+       unsigned long TotalMemory = 0, rec_loc, initrd_loc;
 
        serial_fixups();
        com_port = serial_init(0, NULL);
@@ -197,10 +197,29 @@ decompress_kernel(unsigned long load_addr, int num_words, unsigned long cksum)
        /*
         * Create bi_recs for cmd_line and initrds
         */
-       rec = (struct bi_record *)_ALIGN((unsigned long)(zimage_size) +
+       rec_loc = _ALIGN((unsigned long)(zimage_size) +
                        (1 << 20) - 1, (1 << 20));
-       birecs = rec;
+       rec = (struct bi_record *)rec_loc;
 
+       /* We need to make sure that the initrd and bi_recs do not
+        * overlap. */
+       if ( initrd_size ) {
+               initrd_loc = (unsigned long)(&__ramdisk_begin);
+               /* If the bi_recs are in the middle of the current
+                * initrd, move the initrd to the next MB
+                * boundary. */
+               if ((rec_loc > initrd_loc) &&
+                               ((initrd_loc + initrd_size) > rec_loc)) {
+                       initrd_loc = _ALIGN((unsigned long)(zimage_size)
+                                       + (2 << 20) - 1, (2 << 20));
+                       memmove((void *)initrd_loc, &__ramdisk_begin,
+                                initrd_size);
+                       puts("initrd moved:  "); puthex(initrd_loc);
+                       puts(" "); puthex(initrd_loc + initrd_size);
+                       puts("\n");
+               }
+       }
        rec->tag = BI_FIRST;
        rec->size = sizeof(struct bi_record);
        rec = (struct bi_record *)((unsigned long)rec + rec->size);
@@ -219,7 +238,7 @@ decompress_kernel(unsigned long load_addr, int num_words, unsigned long cksum)
 
        if ( initrd_size ) {
                rec->tag = BI_INITRD;
-               rec->data[0] = (unsigned long)(&__ramdisk_begin);
+               rec->data[0] = initrd_loc;
                rec->data[1] = initrd_size;
                rec->size = sizeof(struct bi_record) + 2 *
                        sizeof(unsigned long);
@@ -233,5 +252,5 @@ decompress_kernel(unsigned long load_addr, int num_words, unsigned long cksum)
        puts("Now booting the kernel\n");
        serial_close(com_port);
 
-       return birecs;
+       return (struct bi_record *)rec_loc;
 }