Project

General

Profile

U-Boot with large uImage containing initramfs

Added by Nicholas Crast over 9 years ago

Hi,

I am trying to boot from a uImage containing an initramfs with the mitySOM-5csx devkit. When I use the core-image-minimal-initramfs recipe, I boot up OK for the most part. The boot hangs saying "Waiting for removable media...". If I use init-boot.sh instead of init-live.sh, this problem goes away, but I don't get a login prompt. I get booted into single user mode.

I want to add more packages, so I added core-image-boot and core-image-basic. When I do this, my uImage ramps up from ~3MB to ~50MB compressed. As a result, u-boot seems to choke on it:

  1. Booting kernel from Legacy Image at 00100000 ...
    Image Name: Linux-3.12.0
    Image Type: ARM Linux Kernel Image (uncompressed)
    Data Size: 32600544 Bytes = 31.1 MiB
    Load Address: 00008000
    Entry Point: 00008000
  2. Flattened Device Tree blob at 00000100
    Booting using the fdt blob at 0x00000100
    Loading Kernel Image ... OK
    OK
    Loading Device Tree to 03ff8000, end 03fff702 ... OK

Starting kernel ...

I have tried changing the loadaddr (0x100000), but it makes no difference. Since the dts is loaded at 0x100, the uImage shouldn't be overwriting it in memory.

Questions:
1.) Does the entry point/load address matter? If not, how do I change them? I tried editing the machine.conf, but no matter what I do, u-boot says 0x8000.
2.) Is there some sort of size limit on the uImage? If so, what is the best way to accomplish this type of environment? I want it to be fresh every time I reboot with no persistent storage.

Thanks,
Nick


Replies (5)

RE: U-Boot with large uImage containing initramfs - Added by Michael Williamson over 9 years ago

We've run into this issue before on a different ARM based processor.

The problem is the linker for the kernel is putting the initramfs into the init section, because it is assuming that the initramfs is going to go away (that you'll pivot to a "real" root filesystem) and it can reclaim that memory once initialization is complete. The initramfs causes there to be a large gap in the kernel image, and problems develop because the kernel image is now quite large (probably outside of the reserved space).

If you want to run "forever" out of initramfs and it's going to be big, then you should be able to safely move it out of the init tables and put it at the end of the kernel image. See this patch that we did on another ARM (CORTEX-A8) application. It worked for us. Your mileage may vary.

Have you considered using initrd instead of initramfs? I know that will work for larger RAM-Only filesystems, and it allows you to keep your reference filesystem image separate from your kernel image.

-Mike

RE: U-Boot with large uImage containing initramfs - Added by Nicholas Crast over 9 years ago

Michael Williamson wrote:

We've run into this issue before on a different ARM based processor.

The problem is the linker for the kernel is putting the initramfs into the init section, because it is assuming that the initramfs is going to go away (that you'll pivot to a "real" root filesystem) and it can reclaim that memory once initialization is complete. The initramfs causes there to be a large gap in the kernel image, and problems develop because the kernel image is now quite large (probably outside of the reserved space).

If you want to run "forever" out of initramfs and it's going to be big, then you should be able to safely move it out of the init tables and put it at the end of the kernel image. See this patch that we did on another ARM (CORTEX-A8) application. It worked for us. Your mileage may vary.

Have you considered using initrd instead of initramfs? I know that will work for larger RAM-Only filesystems, and it allows you to keep your reference filesystem image separate from your kernel image.

-Mike

Mike,

Thank you for the fast reply. I have tried your first suggestion. As it seems your vmlinux.lds.S file is different than mine, I went in and manually made the changes indicated in the patch. It would not compile with the #ifdefs in there, so I took them out and ended up with the attached file. With this file compiled into the kernel, I still had the same problem.

I have not considered using initrd instead of initramfs, as we don't want to separate the kernel image from the filesystem. If we have to do that to get it to work though, we will do it. Not sure how to configure yocto, the kernel, and uboot to work with initrd though.

Thanks,
Nick

RE: U-Boot with large uImage containing initramfs - Added by Nicholas Crast over 9 years ago

I have attempted the following:

1.) Create .tar.gz rootfs with yocto
2.) Create ext3 ramdisk image of rootfs
3.) Create uboot image with mkimage

Now my uImage is ~3.3MB and my ramdisk is ~45MB. When I try to boot with the following commands:

setenv loadaddr 0x7fc0; setenv ramdiskaddr 0x10000; 

mmc rescan;${mmcloadcmd} mmc 0:${mmcloadpart} ${loadaddr} ${bootimage};${mmcloadcmd} mmc 0:${mmcloadpart} ${fdtaddr} ${fdtimage}; ${mmcloadcmd} mmc 0:${mmcloadpart} ${ramdiskaddr} /boot/uRamdisk; 

setenv bootargs console=ttyS0,115200 root=/dev/ram rw initrd=${ramdiskaddr};bootm ${loadaddr} ${ramdiskaddr} ${fdtaddr};

I get the following printout:

## Booting kernel from Legacy Image at 00007fc0 ...
   Image Name:   Linux-3.12.0
   Image Type:   ARM Linux Kernel Image (uncompressed)
   Data Size:    3494112 Bytes = 3.3 MiB
   Load Address: 00008000
   Entry Point:  00008000
## Loading init Ramdisk from Legacy Image at 00010000 ...
   Image Name:   Test Ramdisk Image
   Image Type:   ARM Linux RAMDisk Image (gzip compressed)
   Data Size:    46521404 Bytes = 44.4 MiB
   Load Address: 80008000
   Entry Point:  80008000
## Flattened Device Tree blob at 00000100
   Booting using the fdt blob at 0x00000100
   XIP Kernel Image ... OK
OK
   Loading Ramdisk to 3d2dc000, end 3ff39c3c ... OK
   Loading Device Tree to 03ff8000, end 03fff702 ... OK

Starting kernel ...

This leads me to believe that the RAMDISK is in the correct format.

The interesting part is that even if I don't tell linux or uboot about the ramdisk, and use the following command to boot:

setenv bootargs console=ttyS0,115200 root=/dev/ram rw;bootm ${loadaddr} - ${fdtaddr};

I get the same hang. However, if I then omit the command that loads the ramdisk from the SD card into memory, the kernel starts (but panics, of course).

This means that the very act of loading the ramdisk from the SD card into memory is somehow preventing the kernel from booting, or somehow overwriting the kernel image. I have tried playing with the various load addresses, but I cannot get it to get past this Starting kernel prompt.

RE: U-Boot with large uImage containing initramfs - Added by Nicholas Crast over 9 years ago

Michael Williamson wrote:

We've run into this issue before on a different ARM based processor.

The problem is the linker for the kernel is putting the initramfs into the init section, because it is assuming that the initramfs is going to go away (that you'll pivot to a "real" root filesystem) and it can reclaim that memory once initialization is complete. The initramfs causes there to be a large gap in the kernel image, and problems develop because the kernel image is now quite large (probably outside of the reserved space).

If you want to run "forever" out of initramfs and it's going to be big, then you should be able to safely move it out of the init tables and put it at the end of the kernel image. See this patch that we did on another ARM (CORTEX-A8) application. It worked for us. Your mileage may vary.

Have you considered using initrd instead of initramfs? I know that will work for larger RAM-Only filesystems, and it allows you to keep your reference filesystem image separate from your kernel image.

-Mike

Mike,

I still have had no luck with the initramfs, Just can't get it to go past that Starting Kernel message. I've tried several different patches, but nothing seems to work.

Using initrd, I can get the kernel to at least start, using the following u-boot commands:

setenv loadaddr 0x10000; setenv ramdiskaddr 0x1000000; mmc rescan;${mmcloadcmd} mmc 0:${mmcloadpart} ${loadaddr} ${bootimage};${mmcloadcmd} mmc 0:${mmcloadpart} ${fdtaddr} ${fdtimage}; ${mmcloadcmd} mmc 0:${mmcloadpart} ${ramdiskaddr} /initRdUImage; 

setenv bootargs console=ttyS0,115200 root=/dev/ram0 debug rw initrd={$ramdiskaddr};bootm ${loadaddr} ${ramdiskaddr} ${fdtaddr};

The kernel doesn't seem to recognize the ramdisk though, and it crashes. I have attached a kernel dump, the script I use to create the ramdisk from the .tar.gz filesystem generated by YOCTO, as well as my kernel config.

Any comments you might have would be greatly appreciated.

Thanks,
Nick

RE: U-Boot with large uImage containing initramfs - Added by Michael Williamson over 9 years ago

Hi Nicholas,

A little confused. Your build_ramdisk_image.sh appears to be building a 1 GB image for loading an SD card, which contains including multiple partitions, etc.

You want to create a raw ext2 or ext3 image only, not a full disk image, and it needs to be less than 1GB in size.

I did a quick google on "linux how to build an initrd" and the first couple of links have some better instructions you might want to try with your reference filesystem.

http://www.opennet.ru/docs/HOWTO/Kernel-HOWTO-11.html

http://www.ibm.com/developerworks/library/l-initrd/

If I get some time I'll try to publish a how to, but we're a bit busy at the moment....

-Mike

    (1-5/5)
    Go to top
    Add picture from clipboard (Maximum size: 1 GB)