PeterChan

i.MX28: Enable initramfs step by step

Discussion created by PeterChan Employee on Mar 13, 2013
Latest reply on Nov 28, 2014 by Zongbiao Liao

1. Prepare initramfs image

 

First of all, please follow the i.MX28 linux BSP user guide to build the LTIB once to make sure the u-boot, kernel, boot streams and rootfs are built successfully.

Then run the following command in LTIB for configuration setup.

 

./ltib -m config

 

Pick "initramfs" in the Target Image Generation.

 

--- Target Image Generation
   Options --->
        --- Choose your root filesystem image type
        Target image: (initramfs) --->

 

Exit and save this configuration. Run the following command to build the LTIB again.

 

./ltib -f

 

After a successful build, the initramfs image "initramfs.cpio.gz" will be created under the "ltib" directory.

 

 

2. Integrate initramfs into SB file

 

In the building steps, when the following command is run

 

./ltib -p boot_stream.spec -f

 

power_prep, boot_prep, linux_prep will be built and then these boot streams will be combined with zImage and u-boot to form the SD files. These SD files can be found at directory rootfs/boot. In imx28_(ivt_)linux.sb, the boot sequence is power_prep, boot_prep, linux_prep and then zImage. In imx28_(ivt_)uboot.sb, the boot sequence is power_prep, boot_prep and then u-boot.

The boot and load sequence is actually controlled by the BD files linux(_ivt).bd and uboot(_ivt).bd. To integrate the initramfs into SB, simply apply the mx28_initramfs_imx-bootlets-src-10.12.01.patch to modify linux(_ivt).bd and run the build boot streams command again.

 

./ltib -p boot_stream.spec -f

 

After the build, the initramfs image will be integrated into the SB. You can check this from the imx28_(ivt_)linux.sb file size.

 

In linux_prep, function setup_initrd_tag() setup a ATAG_INITRD2 memory tag to inform the kernel where the compressed initramfs iamge is located and its size. It is the the developer's responsibility to ensure that the size of the initrd.size is large enough to hold the initramfs.cpio.gz. If initrd.size is smaller than the initramfs.cpio.gz file size, please increase the initrd.size value. Otherwise, the kernel will find this is a corrupted image and skip mounting the initramfs.

In this example, the patch reserves 32MB for initramfs.cpio.gz. Reserving 32MB may be too luxury but don't worry, this piece of memory will free after decompression complete and the initramfs has mounted.

 

Program the imx28_(ivt_)linux.sb to your booting media and power up the board. You should see the kernel will mount the initramfs as roofs after boot up.

 

 

3. Load initramfs from bootloader (Optional)

 

In the previous section, the boot stream linux_prep helps to load the kernel and initramfs image and run the kernel automatically. Optionally, you can also make use of the bootloader to load the kernel and initramfs.

 

To use the u-boot as bootloader, please apply the mx28_initramfs_u-boot-2009.08.patch and build the imx28_(ivt_)uboot.sb by the following commands

 

./ltib -p u-boot -f
./ltib -p boot_stream.spec -f

 

After a successful build, the initramfs image "initramfs.cpio.gz" is created. Use the following command to insert the u-boot header to this image for u-boot to load.


mkimage -A arm -O linux -T ramdisk -C none -a 0x40800000 -n "Root Filesystem" -d ./initramfs.cpio.gz ./initramfs.cpio.gz.uboot

 

The mkimage utility can be found under the u-boot directory "u-boot-2009.08/tools/".

Here the address 0x40800000 is the address where initramfs will be located. For i.MX28, the kernel will be always loaded at 0x40008000. Unless the kernel size is getting very large, usually there is no need to move the initramfs address.

 

Let us take the SD card boot as an example to continue. Use fdisk command and create the follow partitions on an SD card.


Command (m for help): p

Disk /dev/sdc: 255 MB, 255066112 bytes
64 heads, 32 sectors/track, 243 cylinders
Units = cylinders of 2048 * 512 = 1048576 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0xb3f32f78

   Device Boot      Start         End      Blocks   Id  System
/dev/sdc1              16          64       50176   53  OnTrack DM6 Aux3
/dev/sdc2              65         127       64512    b  W95 FAT32
/dev/sdc3             128         243      118784   83  Linux

Command (m for help):


Here the beginning 16MB of the SD card is reserved for storing the master boot record, u-boot environment, uImage and initramfs.cpio.gz.uboot.
The first partition is used to store the imx28_(ivt_)uboot.sb. Partition 2 & 3 are optional for custom use.

Let's define the uImage to be stored at 128KB physical offset in the SD and the initramfs.cpio.gz.uboot is stored at 4MB offset to the SD.
Run the following to program the firmware images into the SD card.


## Clean up u-boot env
dd if=/dev/zero of=/dev/sdx bs=512 seek=2 count=254; sync
## Write u-boot
./sdimage -f rootfs/boot/imx28_ivt_uboot.sb -d /dev/sdx; sync
dd if=rootfs/boot/uImage of=/dev/sdx bs=512 seek=256; sync
dd if=initramfs.cpio.gz.uboot of=/dev/sdx bs=512 seek=8192; sync


Power up your board with the SD and you will see the autoboot countdown at the serial debug console. Hit any key to stop it. Review the boot environment by the "printenv" command.

 

MX28 U-Boot > printenv
bootargs=console=ttyAM0,115200n8
bootcmd=run bootcmd_SD; bootm ${loadaddr} ${rd_loadaddr}
bootdelay=3
baudrate=115200
ipaddr=192.168.1.103
serverip=192.168.1.101
netmask=255.255.255.0
bootfile="uImage"
loadaddr=0x42000000
nfsroot=/home/notroot/nfs/rootfs
bootargs_nfs=setenv bootargs ${bootargs} root=/dev/nfs ip=dhcp nfsroot=${serverip}:${nfsroot},v3,tcp fec_mac=${ethaddr}
bootcmd_net=run bootargs_nfs; dhcp; bootm
bootargs_mmc=setenv bootargs ${bootargs} root=/dev/mmcblk0p3 rw rootwait ip=dhcp fec_mac=${ethaddr}
bootcmd_mmc=run bootargs_mmc; mmc read 0 ${loadaddr} 100 3000; bootm
loadaddr=0x42000000
rd_loadaddr=0x42300000
bootargs_SD=setenv bootargs ${bootargs} rw gpmi
bootcmd_SD=run bootargs_SD; mmc read 0 ${loadaddr} 0x100 0x1800; mmc read 0 ${rd_loadaddr} 0x2000 0x4000
stdin=serial
stdout=serial
stderr=serial
ethact=FEC0
ver=U-Boot 2009.08-dirty (Mar 13 2013 - 18:43:19)

Environment size: 886/130044 bytes
MX28 U-Boot >


"bootargs_SD" simply setup the kernel command line.

"bootcmd_SD" run the "bootargs_SD" and read uImage from SD physical offset 128KB to address "loadaddr" and then read initramfs.cpio.gz.uboot from the SD physical offset 4MB to "rd_loadaddr".

"loadaddr" is 0x42000000 and "rd_loadaddr" is 0x42300000. These memory areas are generally not used by i.MX28 u-boot and are used here to hold the uImage and initramfs.cpio.gz.uboot. "loadaddr" and "rd_loadaddr" must be far apart enough so that the loaded images will not overlap.

The "bootcmd" run "bootcmd_SD", and use "bootm" commnad to boot the kernel. The first argument is the address where the kernel uImage is stored. The second argument is the initramfs u-image. This second argument can be omitted if initramfs is not used and in this case, kernel will expect a correct "root=" option in the kernel command line.

 

You can manually edit the boot environment or hardcode it in the include/configs/mx28_evk.h.

 

Reset your board and let it autoboot. You should see the initramfs will be mounted as rootfs as in section 2.

Original Attachment has been moved to: mx28_initramfs_imx-bootlets-src-10.12.01.patch.zip

Original Attachment has been moved to: mx28_initramfs_u-boot-2009.08.patch.zip

Outcomes