[U-Boot] Debugging why my kernel won't start

Rogan Dawes
2010-08-18T16:32:51Z

On 2010/08/18 5:33 PM, Wolfgang Denk wrote:
> Dear Rogan Dawes,
>
> Your kernel may not be able to pick up a ramdisk image in flash.
>
> Mainline ARM cannot do that, for example.
>
> [Patches to support that have been submitted, but rejected.]
>
>> Surely that should be Ok? Besides, U-boot is supposed to copy the data
>> in the image to the specified destination address, isn't it?
>
> No, why should it copy the image? It just verifies that the checksum
> is OK, and then passes the address to the kernel. The kernel will have
> to copy it anyway when uncompressing it, so ther ei no use in U-Boot
> adding another copy operation.

Well, I thought that was the point of the "mkimage" header, with the
Load Address and Entry Point fields. Although, of course, you'll never
actually "enter" a ramdisk image. I had still thought that they would be
copied, regardless. Otherwise, what is the point in specifying those
fields? They might just as well be zero.

But yes, what you say makes sense.

This appears to be the answer, from Marvell's u-boot sources, in
lib_arm/armlinux.c, inside the #ifdef RAMDISK block:

#ifdef DEBUG
if (!data) {
printf ("No initrd\n");
}
#endif

if (data) {
#ifdef RAMDISK
initrd_start = ntohl(hdr->ih_load);
initrd_end = initrd_start + len;
memmove ((void *)initrd_start, (void *)data, len);
#else
initrd_start = data;
initrd_end = initrd_start + len;
#endif
} else {
initrd_start = 0;
initrd_end = 0;
}

and then later:

#ifdef CONFIG_INITRD_TAG
if (initrd_start && initrd_end)
setup_initrd_tag (bd, initrd_start, initrd_end);
#endif

So, clearly, the address that the kernel is expecting MUST be within
RAM, and MUST exclude the header.

So, the question then is, what is current u-boot doing? And why does it
not work when the ramdisk is copied over to memory?

It looks like U-Boot for ARM doesn't handle ramdisks at all? From
common/cmd_bootm.c:

#if defined(CONFIG_PPC) || defined(CONFIG_M68K) || defined(CONFIG_SPARC)
case BOOTM_STATE_RAMDISK:
{
ulong rd_len = images.rd_end - images.rd_start;
char str[17];

ret = boot_ramdisk_high(&images.lmb,
images.rd_start,
rd_len, &images.initrd_start,
&images.initrd_end);
if (ret)
return ret;

sprintf(str, "%lx", images.initrd_start);
setenv("initrd_start", str);
sprintf(str, "%lx", images.initrd_end);
setenv("initrd_end", str);
}
break;
#endif

But this is only enabled for PPC, M68K and SPARC.

Is this the missing functionality that I am looking for?

Rogan