Walnut boottime issues
Simon Winwood
sjw at cse.unsw.edu.au
Thu Nov 22 05:44:37 EST 2001
On Tue, Nov 20, 2001 at 05:35:02PM -0700, Tom Rini wrote:
> On Wed, Nov 21, 2001 at 10:45:17AM +1100, Simon Winwood wrote:
>
> > Hi, the latest bitkeeper linuxppc_2_4_devel kernel is broken
> > for walnut (and any other board using misc-embedded.c in arch/ppc/boot/simple)
> >
> > Specifically, the ZIMAGE_START and ZIMAGE_SIZE macros are wrong (0)
> > and have been replaced by {__image}_{begin, end}.
> >
> > The command line stuff also appears to be broken (the kernel doesn't
> > get the command line properly)
> >
> > Is there a fix pending, or should I do it?
>
> Does the following work for you? I thought I could do the changes
> easily w/o breaking 8xx/4xx, but...
After some slight hacking --- basically, I added
#include <asm/bootmem.h>
and
avail_ram = 0x600000
end_avail = 0x800000
The only problem is that you can only boot with an empty command line,
otherwise it locks up after 'Now booting the kernel' (as far as I can tell)
Simon
>
> --
> Tom Rini (TR1265)
> http://gate.crashing.org/~trini/
>
> ===== arch/ppc/boot/simple/misc-embedded.c 1.21 vs edited =====
> --- 1.21/arch/ppc/boot/simple/misc-embedded.c Tue Nov 13 14:37:01 2001
> +++ edited/arch/ppc/boot/simple/misc-embedded.c Tue Nov 20 14:17:38 2001
> @@ -1,11 +1,11 @@
> /*
> * BK Id: %F% %I% %G% %U% %#%
> - */
> -/*
> - * Adapted for PowerPC by Gary Thomas
> *
> - * Rewritten by Cort Dougan (cort at cs.nmt.edu)
> - * One day to be replaced by a single bootloader for chrp/prep/pmac. -- Cort
> + * Originally adapted by Gary Thomas. Much additional work by
> + * Cort Dougan <cort at fsmlabs.com>. On top of that still more work by
> + * Dan Malek <dmalek at jlc.net>.
> + *
> + * Currently maintained by: Tom Rini <trini at kernel.crashing.org>
> */
>
> #include <linux/config.h>
> @@ -22,29 +22,22 @@
>
> #include "nonstdio.h"
>
> -/*
> - * Please send me load/board info and such data for hardware not
> - * listed here so I can keep track since things are getting tricky
> - * with the different load addrs with different firmware. This will
> - * help to avoid breaking the load/boot process.
> - * -- Cort
> - */
> -char *avail_ram;
> -char *end_avail;
> +/* The linker tells us where the image is. */
> +extern char __image_begin, __image_end;
> +extern char __ramdisk_begin, __ramdisk_end;
>
> /* Because of the limited amount of memory on embedded, it presents
> * loading problems. The biggest is that we load this boot program
> * into a relatively low memory address, and the Linux kernel Bss often
> * extends into this space when it get loaded. When the kernel starts
> * and zeros the BSS space, it also writes over the information we
> - * save here and pass to the kernel (command line and board info).
> + * save here and pass to the kernel (usually board info).
> * On these boards, we grab some known memory holes to hold this information.
> */
> char cmd_buf[256];
> char *cmd_line = cmd_buf;
>
> -/* Serial port to use.
> -*/
> +/* Serial port to use. */
> unsigned long com_port;
>
> /* This is the default cmdline that will be given to the user at boot time..
> @@ -63,9 +56,11 @@
>
> bd_t hold_resid_buf;
> bd_t *hold_residual = &hold_resid_buf;
> -unsigned long initrd_start = 0, initrd_end = 0;
> char *zimage_start;
>
> +extern unsigned long start;
> +
> +extern void flush_instruction_cache(void);
> extern void gunzip(void *, int, unsigned char *, int *);
> extern void embed_config(bd_t **bp);
> extern unsigned long serial_init(int chan, bd_t *bp);
> @@ -75,8 +70,7 @@
> {
> int timer, zimage_size = ZIMAGE_SIZE;
> char *cp, ch;
> - extern unsigned long start;
> - extern void flush_instruction_cache(void);
> + unsigned long initrd_size;
>
> /* First, capture the embedded board information. Then
> * initialize the serial console port.
> @@ -102,16 +96,12 @@
> #else
> cmd_line = (char *)(0x200000);
> #endif
> +
> hold_residual = (bd_t *)(cmd_line + sizeof(cmd_buf));
> /* copy board data */
> if (bp)
> memcpy(hold_residual,bp,sizeof(bd_t));
>
> - /* Set end of memory available to us. It is always the highest
> - * memory address provided by the board information.
> - */
> - end_avail = (char *)(bp->bi_memsize);
> -
> puts("loaded at: "); puthex(load_addr);
> puts(" "); puthex((unsigned long)(load_addr + (4*num_words))); puts("\n");
> if ( (unsigned long)load_addr != (unsigned long)&start )
> @@ -135,86 +125,52 @@
> puts("\n");
> }
>
> - /* we have to subtract 0x10000 here to correct for objdump including the
> - size of the elf header which we strip -- Cort */
> - zimage_start = (char *)(load_addr - 0x10000 + ZIMAGE_OFFSET);
> + /*
> + * We link ourself to 0x00800000. When we run, we relocate
> + * ourselves there. So we just need __image_begin for the
> + * start. -- Tom
> + */
> + zimage_start = (char *)(unsigned long)(&__image_begin);
> + zimage_size = (unsigned long)(&__image_end) -
> + (unsigned long)(&__image_begin);
>
> - if ( INITRD_OFFSET )
> - initrd_start = load_addr - 0x10000 + INITRD_OFFSET;
> - else
> - initrd_start = 0;
> - initrd_end = INITRD_SIZE + initrd_start;
> + initrd_size = (unsigned long)(&__ramdisk_end) -
> + (unsigned long)(&__ramdisk_begin);
>
> /*
> - * setup avail_ram - this is the first part of ram usable
> - * by the uncompress code. -- Cort
> + * The zImage and initrd will be between start and _end, so they've
> + * already been moved once. We're good to go now. -- Tom
> */
> - avail_ram = (char *)PAGE_ALIGN((unsigned long)zimage_start+zimage_size);
> - if ( ((load_addr+(num_words*4)) > (unsigned long) avail_ram)
> - && (load_addr <= 0x01000000) )
> - avail_ram = (char *)(load_addr+(num_words*4));
> - if ( (((unsigned long)&start+(num_words*4)) > (unsigned long) avail_ram)
> - && (load_addr <= 0x01000000) )
> - avail_ram = (char *)((unsigned long)&start+(num_words*4));
> -
> - /* relocate zimage */
> puts("zimage at: "); puthex((unsigned long)zimage_start);
> - puts(" "); puthex((unsigned long)(zimage_size+zimage_start)); puts("\n");
> - /*
> - * There is no reason (yet) to relocate zImage for embedded boards.
> - * To support boot from flash rom on 8xx embedded boards, I
> - * assume if zimage start is over 16M we are booting from flash.
> - * In this case, avilable ram will start just above the space we
> - * have allocated for the command buffer and board information.
> - */
> - if ((unsigned long)zimage_start > 0x01000000)
> - avail_ram = (char *)PAGE_ALIGN((unsigned long)hold_residual + sizeof(bd_t));
> -
> - /* relocate initrd */
> - if ( initrd_start )
> - {
> - puts("initrd at: "); puthex(initrd_start);
> - puts(" "); puthex(initrd_end); puts("\n");
> + puts(" "); puthex((unsigned long)(zimage_size+zimage_start));
> + puts("\n");
>
> - /* We only have to relocate initrd if we find it is in Flash
> - * rom. This is because the kernel thinks it can toss the
> - * pages into the free memory pool after it is done. Use
> - * the same 16M test.
> - */
> - if ((unsigned long)initrd_start > 0x01000000) {
> - memcpy ((void *)PAGE_ALIGN(-PAGE_SIZE+(unsigned long)end_avail-INITRD_SIZE),
> - (void *)initrd_start,
> - INITRD_SIZE );
> - initrd_start = PAGE_ALIGN(-PAGE_SIZE+(unsigned long)end_avail-INITRD_SIZE);
> - initrd_end = initrd_start + INITRD_SIZE;
> - end_avail = (char *)initrd_start;
> - puts("relocated to: "); puthex(initrd_start);
> - puts(" "); puthex(initrd_end); puts("\n");
> - }
> - else {
> - avail_ram = (char *)PAGE_ALIGN((unsigned long)initrd_end);
> - }
> + if ( initrd_size ) {
> + puts("initrd at: ");
> + puthex((unsigned long)(&__ramdisk_begin));
> + puts(" "); puthex((unsigned long)(&__ramdisk_end));puts("\n");
> }
>
> -
> - puts("avail ram: "); puthex((unsigned long)avail_ram); puts(" ");
> - puthex((unsigned long)end_avail); puts("\n");
> puts("\nLinux/PPC load: ");
> timer = 0;
> cp = cmd_line;
> - /* This is where we try and pick the right command line for booting.
> +
> + /*
> + * This is where we try and pick the right command line for booting.
> * If we were given one at compile time, use it. It Is Right.
> * If we weren't, see if we have a ramdisk. If so, thats root.
> - * When in doubt, give them the netroot (root=/dev/nfs rw) -- Tom */
> + * When in doubt, give them the netroot (root=/dev/nfs rw) -- Tom
> + */
> #ifdef CONFIG_CMDLINE_BOOL
> memcpy (cmd_line, compiled_string, sizeof(compiled_string));
> #else
> - if (initrd_start)
> + if (initrd_size)
> memcpy (cmd_line, ramroot_string, sizeof(ramroot_string));
> else
> memcpy (cmd_line, netroot_string, sizeof(netroot_string));
> #endif
> - while ( *cp ) putc(*cp++);
> + while ( *cp )
> + putc(*cp++);
> while (timer++ < 5*1000) {
> if (tstc()) {
> while ((ch = getc()) != '\n' && ch != '\r') {
> @@ -244,6 +200,35 @@
> gunzip(0, 0x400000, zimage_start, &zimage_size);
> flush_instruction_cache();
> puts("done.\n");
> + {
> + struct bi_record *rec;
> +
> + rec = (struct bi_record *)_ALIGN((unsigned long)(zimage_size) +
> + (1 << 20) - 1, (1 << 20));
> +
> + rec->tag = BI_FIRST;
> + rec->size = sizeof(struct bi_record);
> + rec = (struct bi_record *)((unsigned long)rec + rec->size);
> +
> + rec->tag = BI_CMD_LINE;
> + memcpy( (char *)rec->data, cmd_line, strlen(cmd_line)+1);
> + rec->size = sizeof(struct bi_record) + strlen(cmd_line) + 1;
> + rec = (struct bi_record *)((unsigned long)rec + rec->size);
> +
> + if ( initrd_size ) {
> + rec->tag = BI_INITRD;
> + rec->data[0] = (unsigned long)(&__ramdisk_begin);
> + rec->data[1] = initrd_size;
> + rec->size = sizeof(struct bi_record) + 2 *
> + sizeof(unsigned long);
> + rec = (struct bi_record *)((unsigned long)rec +
> + rec->size);
> + }
> +
> + rec->tag = BI_LAST;
> + rec->size = sizeof(struct bi_record);
> + rec = (struct bi_record *)((unsigned long)rec + rec->size);
> + }
> puts("Now booting the kernel\n");
> return (unsigned long)hold_residual;
> }
-------------- next part --------------
===== arch/ppc/boot/simple/misc-embedded.c 1.21 vs edited =====
--- 1.21/arch/ppc/boot/simple/misc-embedded.c Tue Nov 13 16:37:01 2001
+++ edited/arch/ppc/boot/simple/misc-embedded.c Wed Nov 21 14:12:29 2001
@@ -1,11 +1,11 @@
/*
* BK Id: %F% %I% %G% %U% %#%
- */
-/*
- * Adapted for PowerPC by Gary Thomas
*
- * Rewritten by Cort Dougan (cort at cs.nmt.edu)
- * One day to be replaced by a single bootloader for chrp/prep/pmac. -- Cort
+ * Originally adapted by Gary Thomas. Much additional work by
+ * Cort Dougan <cort at fsmlabs.com>. On top of that still more work by
+ * Dan Malek <dmalek at jlc.net>.
+ *
+ * Currently maintained by: Tom Rini <trini at kernel.crashing.org>
*/
#include <linux/config.h>
@@ -19,32 +19,29 @@
#include <asm/mpc8xx.h>
#include <asm/mpc8260.h>
#include <asm/ibm4xx.h>
+#include <asm/bootinfo.h>
#include "nonstdio.h"
-/*
- * Please send me load/board info and such data for hardware not
- * listed here so I can keep track since things are getting tricky
- * with the different load addrs with different firmware. This will
- * help to avoid breaking the load/boot process.
- * -- Cort
- */
char *avail_ram;
char *end_avail;
+/* The linker tells us where the image is. */
+extern char __image_begin, __image_end;
+extern char __ramdisk_begin, __ramdisk_end;
+
/* Because of the limited amount of memory on embedded, it presents
* loading problems. The biggest is that we load this boot program
* into a relatively low memory address, and the Linux kernel Bss often
* extends into this space when it get loaded. When the kernel starts
* and zeros the BSS space, it also writes over the information we
- * save here and pass to the kernel (command line and board info).
+ * save here and pass to the kernel (usually board info).
* On these boards, we grab some known memory holes to hold this information.
*/
char cmd_buf[256];
char *cmd_line = cmd_buf;
-/* Serial port to use.
-*/
+/* Serial port to use. */
unsigned long com_port;
/* This is the default cmdline that will be given to the user at boot time..
@@ -63,9 +60,11 @@
bd_t hold_resid_buf;
bd_t *hold_residual = &hold_resid_buf;
-unsigned long initrd_start = 0, initrd_end = 0;
char *zimage_start;
+extern unsigned long start;
+
+extern void flush_instruction_cache(void);
extern void gunzip(void *, int, unsigned char *, int *);
extern void embed_config(bd_t **bp);
extern unsigned long serial_init(int chan, bd_t *bp);
@@ -75,8 +74,7 @@
{
int timer, zimage_size = ZIMAGE_SIZE;
char *cp, ch;
- extern unsigned long start;
- extern void flush_instruction_cache(void);
+ unsigned long initrd_size;
/* First, capture the embedded board information. Then
* initialize the serial console port.
@@ -102,16 +100,12 @@
#else
cmd_line = (char *)(0x200000);
#endif
+
hold_residual = (bd_t *)(cmd_line + sizeof(cmd_buf));
/* copy board data */
if (bp)
memcpy(hold_residual,bp,sizeof(bd_t));
- /* Set end of memory available to us. It is always the highest
- * memory address provided by the board information.
- */
- end_avail = (char *)(bp->bi_memsize);
-
puts("loaded at: "); puthex(load_addr);
puts(" "); puthex((unsigned long)(load_addr + (4*num_words))); puts("\n");
if ( (unsigned long)load_addr != (unsigned long)&start )
@@ -135,86 +129,55 @@
puts("\n");
}
- /* we have to subtract 0x10000 here to correct for objdump including the
- size of the elf header which we strip -- Cort */
- zimage_start = (char *)(load_addr - 0x10000 + ZIMAGE_OFFSET);
+ /*
+ * We link ourself to 0x00800000. When we run, we relocate
+ * ourselves there. So we just need __image_begin for the
+ * start. -- Tom
+ */
+ zimage_start = (char *)(unsigned long)(&__image_begin);
+ zimage_size = (unsigned long)(&__image_end) -
+ (unsigned long)(&__image_begin);
- if ( INITRD_OFFSET )
- initrd_start = load_addr - 0x10000 + INITRD_OFFSET;
- else
- initrd_start = 0;
- initrd_end = INITRD_SIZE + initrd_start;
+ initrd_size = (unsigned long)(&__ramdisk_end) -
+ (unsigned long)(&__ramdisk_begin);
+
+ avail_ram = (char *)0x00600000;
+ end_avail = (char *)0x00800000;
/*
- * setup avail_ram - this is the first part of ram usable
- * by the uncompress code. -- Cort
+ * The zImage and initrd will be between start and _end, so they've
+ * already been moved once. We're good to go now. -- Tom
*/
- avail_ram = (char *)PAGE_ALIGN((unsigned long)zimage_start+zimage_size);
- if ( ((load_addr+(num_words*4)) > (unsigned long) avail_ram)
- && (load_addr <= 0x01000000) )
- avail_ram = (char *)(load_addr+(num_words*4));
- if ( (((unsigned long)&start+(num_words*4)) > (unsigned long) avail_ram)
- && (load_addr <= 0x01000000) )
- avail_ram = (char *)((unsigned long)&start+(num_words*4));
-
- /* relocate zimage */
puts("zimage at: "); puthex((unsigned long)zimage_start);
- puts(" "); puthex((unsigned long)(zimage_size+zimage_start)); puts("\n");
- /*
- * There is no reason (yet) to relocate zImage for embedded boards.
- * To support boot from flash rom on 8xx embedded boards, I
- * assume if zimage start is over 16M we are booting from flash.
- * In this case, avilable ram will start just above the space we
- * have allocated for the command buffer and board information.
- */
- if ((unsigned long)zimage_start > 0x01000000)
- avail_ram = (char *)PAGE_ALIGN((unsigned long)hold_residual + sizeof(bd_t));
-
- /* relocate initrd */
- if ( initrd_start )
- {
- puts("initrd at: "); puthex(initrd_start);
- puts(" "); puthex(initrd_end); puts("\n");
+ puts(" "); puthex((unsigned long)(zimage_size+zimage_start));
+ puts("\n");
- /* We only have to relocate initrd if we find it is in Flash
- * rom. This is because the kernel thinks it can toss the
- * pages into the free memory pool after it is done. Use
- * the same 16M test.
- */
- if ((unsigned long)initrd_start > 0x01000000) {
- memcpy ((void *)PAGE_ALIGN(-PAGE_SIZE+(unsigned long)end_avail-INITRD_SIZE),
- (void *)initrd_start,
- INITRD_SIZE );
- initrd_start = PAGE_ALIGN(-PAGE_SIZE+(unsigned long)end_avail-INITRD_SIZE);
- initrd_end = initrd_start + INITRD_SIZE;
- end_avail = (char *)initrd_start;
- puts("relocated to: "); puthex(initrd_start);
- puts(" "); puthex(initrd_end); puts("\n");
- }
- else {
- avail_ram = (char *)PAGE_ALIGN((unsigned long)initrd_end);
- }
+ if ( initrd_size ) {
+ puts("initrd at: ");
+ puthex((unsigned long)(&__ramdisk_begin));
+ puts(" "); puthex((unsigned long)(&__ramdisk_end));puts("\n");
}
-
- puts("avail ram: "); puthex((unsigned long)avail_ram); puts(" ");
- puthex((unsigned long)end_avail); puts("\n");
puts("\nLinux/PPC load: ");
timer = 0;
cp = cmd_line;
- /* This is where we try and pick the right command line for booting.
+
+ /*
+ * This is where we try and pick the right command line for booting.
* If we were given one at compile time, use it. It Is Right.
* If we weren't, see if we have a ramdisk. If so, thats root.
- * When in doubt, give them the netroot (root=/dev/nfs rw) -- Tom */
+ * When in doubt, give them the netroot (root=/dev/nfs rw) -- Tom
+ */
#ifdef CONFIG_CMDLINE_BOOL
memcpy (cmd_line, compiled_string, sizeof(compiled_string));
#else
- if (initrd_start)
+ if (initrd_size)
memcpy (cmd_line, ramroot_string, sizeof(ramroot_string));
else
memcpy (cmd_line, netroot_string, sizeof(netroot_string));
#endif
- while ( *cp ) putc(*cp++);
+ while ( *cp )
+ putc(*cp++);
while (timer++ < 5*1000) {
if (tstc()) {
while ((ch = getc()) != '\n' && ch != '\r') {
@@ -244,6 +207,35 @@
gunzip(0, 0x400000, zimage_start, &zimage_size);
flush_instruction_cache();
puts("done.\n");
+ {
+ struct bi_record *rec;
+
+ rec = (struct bi_record *)_ALIGN((unsigned long)(zimage_size) +
+ (1 << 20) - 1, (1 << 20));
+
+ rec->tag = BI_FIRST;
+ rec->size = sizeof(struct bi_record);
+ rec = (struct bi_record *)((unsigned long)rec + rec->size);
+
+ rec->tag = BI_CMD_LINE;
+ memcpy( (char *)rec->data, cmd_line, strlen(cmd_line)+1);
+ rec->size = sizeof(struct bi_record) + strlen(cmd_line) + 1;
+ rec = (struct bi_record *)((unsigned long)rec + rec->size);
+
+ if ( initrd_size ) {
+ rec->tag = BI_INITRD;
+ rec->data[0] = (unsigned long)(&__ramdisk_begin);
+ rec->data[1] = initrd_size;
+ rec->size = sizeof(struct bi_record) + 2 *
+ sizeof(unsigned long);
+ rec = (struct bi_record *)((unsigned long)rec +
+ rec->size);
+ }
+
+ rec->tag = BI_LAST;
+ rec->size = sizeof(struct bi_record);
+ rec = (struct bi_record *)((unsigned long)rec + rec->size);
+ }
puts("Now booting the kernel\n");
return (unsigned long)hold_residual;
}
More information about the Linuxppc-embedded
mailing list