Forums » Software Development »
U-Boot with large uImage containing initramfs
Added by Nicholas Crast about 10 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:
- 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 - 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 about 10 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 about 10 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
vmlinux.lds.S (6.79 KB) vmlinux.lds.S |
RE: U-Boot with large uImage containing initramfs - Added by Nicholas Crast about 10 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 about 10 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
kerneldump.txt (11.7 KB) kerneldump.txt | |||
build_ramdisk_image.sh (2.39 KB) build_ramdisk_image.sh | |||
defconfig (70 KB) defconfig |
RE: U-Boot with large uImage containing initramfs - Added by Michael Williamson about 10 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