
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