Difference between revisions of "Prepare a bootable NAND/eMMC"

From IGEP - ISEE Wiki

Jump to: navigation, search
(Changed categories.)
(No difference)

Latest revision as of 16:20, 17 September 2018

The purpose of this tutorial is to show how to flash a complete linux (u-boot + kernel + rootfs) into the internal storage of the system.

This steps has to be followed inside a board running a Linux from a external interface.

Note: you will need to boot from an SD or NFS in order to use an existing Linux to flash the new one.

Prepare the files

First, it will be needed to prepare the following elements:

  • u-boot or X-loader MLO and .img (in the case of i.mx chips both are together in a .imx file)
  • zImage with the corresponfing kernel
  • Correct .dtb used by this kernel
  • rootfs with the corresponding modules installed all compressed in a .tar.bz2 file.

Flash into NAND (Tesdted with am335x based procesor)

Information.jpg This steps has been followed using a Linux Kernel 4.9 and a IGEP SMARC MODULE AM335x

First, we will start with the case of using a NAND flash as internal storage.

Note: it will be used some special tools collected in the Mtdutils package. More info here: Mtdutils

It is recommendable to test the NAND flash and its partitions:

nandtest -m /dev/mtd0
nandtest -m /dev/mtd1
nandtest -m /dev/mtd2
nandtest -m /dev/mtd3

Then we erase the partitions:

flash_eraseall /dev/mtd0
flash_eraseall /dev/mtd1
flash_eraseall /dev/mtd2
flash_eraseall /dev/mtd3

Now we can flash the MLO in the first partition /dev/mtd0. It important to know that in this case (because it is a NAND flash and we have to record the MLO) we have to flash it four times in the first 4 blocks of this partition. In order to know the exact addresses we can check the documentation of the chip developer (in this case: AM335x U-Boot User's Guide (Texas Documentation) NAND Layout) and will get the offset addresses [0x0 0x20000 0x40000 0x60000] . For each one of this addresses we have to write:

nandwrite -p -s [address] /dev/mtd0 [your_MLO]

For example:

nandwrite -p -s 0x0 /dev/mtd0 /home/root/flash_files/MLO
nandwrite -p -s 0x20000 /dev/mtd0 /home/root/flash_files/MLO
nandwrite -p -s 0x40000 /dev/mtd0 /home/root/flash_files/MLO
nandwrite -p -s 0x60000 /dev/mtd0 /home/root/flash_files/MLO

Then we will flash into the second partition /dev/mtd1 the u-boot.img:

nandwrite -p /dev/mtd1 [your_u-boot.img]

For example:

nandwrite -p /dev/mtd1 /home/root/flash_files/u-boot.img

In order to flash the rootfs we use the UBIFS (filesystem for unmanaged flash memory devices) in the last partition /dev/mtd3. We are using a UBIFS in order to do it:]]

 Note: In this case we skip the third partiton /dev/mtd2 that is prepared to include if it is needed a environment uEnv.txt
ubiformat /dev/mtd3
ubiattach -p /dev/mtd3
ubimkvol /dev/ubi0 -N filesystem -m

Then, we can flash the rootfs:

mkdir /tmp/flashroot
mount -t ubifs ubi0:rootfs /tmp/flashroot/
cd /tmp/flashroot/
tar -xf -C .
cd /
umount /tmp/flashroot
ubidetach -p /dev/mtd3

For example:

mkdir /tmp/flashroot
mount -t ubifs ubi0:rootfs /tmp/flashroot/
cd /tmp/flashroot/
tar -xf /home/root/flash_files/my_rootfs.tar -C .
cd /
umount /tmp/flashroot
ubidetach -p /dev/mtd3

Flash into eMMC (Tested with iMX6-DualLite)

Information.jpg This steps has been followed using a Linux Kernel 4.9 and a IGEP SMARC MODULE iMX6

Flashing into a eMMC is quite similar to flash a SD card. This tutorial is going to be focus in the i.MX chip boards. This chips specifies that the u-boot.imx file (MLO+img) has to be at the beginning without format. Knowing this we have to create the partitions in a different way, leaving 8MB before the beginning of the first partition.

We begin by unmounting and clearing the partition on the eMMC (mmcblk2 in this case)

umount /run/media/mmcblk2*
parted -s /dev/mmcblk2 mklabel msdos

Now we use sfdisk to create the partitions. We are creating two partitions:

Partition 1: boot

  • FAT32 partition.
  • Begin at the 16065 sector (leaving 8MB free before).
  • Has to have the boot flag.
  • It has to be Cylinder alignment. (Use Cylinder alignment to maintain compatibility with operating systems released before the year 2000, such as DOS). This setting aligns partitions to start and end on disk cylinder boundaries).
  • Size of 64MB (approx).

Partition 2: rootfs

  • Starts after partition 1.
  • Default settings
  • Size of the rest of the space

We transform this specifications into a sfdisk command:

sfdisk -D -H 255 -S 63 /dev/mmcblk2 << THEEND

We can check the partitions are correctly set using:

fdisk -l /dev/mmcblk2

The result should be similar to the following:

Flash into eMMC.png

Then we finish the partitions:

mkfs.vfat -F 32 /dev/mmcblk2p1 -n boot
RFS_UUID=`cat /proc/sys/kernel/random/uuid`
mkfs.ext3 -U "$RFS_UUID" "/dev/mmcblk2p2" -L rootfs

Now we can create temporaly folders to work with and mount the partitions there.

mkdir -p /tmp/mmcblk2p1
mkdir -p /tmp/mmcblk2p2
mount -t vfat /dev/mmcblk2p1 /tmp/mmcblk2p1
mount -t ext3 /dev/mmcblk2p2 /tmp/mmcblk2p2

Note: If your system has automatically mounted the partitions you have to umount them again by using:

umount /run/media/mmcblk2*

Now we can flash the rest of the elements (by default the zImage and the dtb are place inside the rootfs boot folder).
First we extract the rootfs we want to flash in the temporary folder of the second partition ()

tar -xf  -C /tmp/mmcblk2p2/
For example:
tar -xf
tar.bz2 -C /tmp/mmcblk2p2/

At this point you can flash the u-boot.imx image using dd command and dissebling the read only protection:

RO_PROTECTION=`cat /sys/block/mmcblk2/force_ro`
echo 0 > /sys/block/mmcblk2/force_ro
dd if= of=/dev/mmcblk2 bs=512 seek=2 2> /dev/null
echo $RO_PROTECTION > /sys/block/mmcblk2/force_ro

For example:

RO_PROTECTION=`cat /sys/block/mmcblk2/force_ro`
echo 0 > /sys/block/mmcblk2/force_ro
dd if=/tmp/mmcblk2p2/boot/u-boot.imx of=/dev/mmcblk2 bs=512 seek=2 2>
echo $RO_PROTECTION > /sys/block/mmcblk2/force_ro

Finally we copy the zImage and the dtb into the first partition (boot partition)

cp  /tmp/mmcblk2p1
cp -f /tmp/mmcblk2p1

For example:

cp /tmp/mmcblk2p2/boot/zImage /tmp/mmcblk2p1
cp -f /tmp/mmcblk2p2/boot/imx6*.dtb /tmp/mmcblk2p1