Combining rootfs, u-boot and kernel into one image

Dezember 28, 2019

Wer Linux selbst für ein eigenes Board oder sogar für ein anderes Board erstellen möchte, hat man am Ende meist drei verschiedene Komponenten:

  • U-Boot Bootloader
  • Linux Kernel (zImage, uImage)
  • rootfs (debian, ubuntu etc.)

Normalerweise gibt es Vorgaben, wie man seine SD-Karte richtig formatiert und seine Dateien darauf kopiert. Aber meistens ist es bequemer, nur eine einzige Image-Datei zu haben, die man mit einem Drittanbieter-Tool wie balena etcher auf die Karte flashen kann.

Während der Entwicklung des i.MX6 DevBoards habe wir ein Shell-Skript erstellt, welches genau dies tut.
Es kombiniert all diese drei Teile (rootfs, u-boot und kernel) in einem Image.

Wir stellen dieses Skript hier kostenlos zur Verfügung, ohne weitere Kommentare oder Anweisungen.
Dieses Skript wurde mit einem i.MX6 Controller mit Mainline U-Boot und Mainline Linux getestet.

Das Skript wird ohne jegliche Garantie zur Verfügung gestellt.
Die Verwendung erfolgt auf eigene Gefahr.

 

If you build linux by your self for your own board of even for an other board then you often get three different files.

  • U-Boot Bootloader
  • Linux Kernel (zImage, uImage)
  • rootfs (debian, ubuntu etc.)

Usually you get some advice how to format your SD-Card properly and copy your files onto them. But normally it is more convenient to have only one single image file which you can flash onto your card using some 3rd party tool like balena etcher.

During my development of the i.MX6 DevBoard i have created a shell script which does exactly this. Combining all these three parts into one image.

I provide this script here for free, without any further comments or instructions. This script was tested with an i.MX6 Controller using mainline U-Boot and Mainline Linux.

The script is provided without any warranty. Use it at your own risk.


				
					#!/bin/bash

# Copyright: C. Hediger, 2019
# databyte.ch
# provided without warranty. use it at your own risk!

echo "-------------------------------------------"
echo "-------- SD-Card image generator ----------"
echo "-------------------------------------------"
echo ""

#echo "Please enter the Size of your Image"
read -p 'Size for *.img [MB] default 512MByte: ' imagesize

if [ -z "$imagesize" ]
then
      imagesize="512"
fi

#echo "Please enter the destination of the image"
read -p 'Path to Image default /home/<user>/Desktop/sdcard/sdimage.img: ' imagepath

if [ -z "$imagepath" ]
then
      imagepath="/home/"$USER"/Desktop/sdcard/sdimage.img"
fi

#echo "Please enter the path of the u-boot.imx"
read -p 'Path to u-boot default /home/<user>/Desktop/sdcard/u-boot.imx: ' ubootpath

if [ -z "$ubootpath" ]
then
      ubootpath="/home/"$USER"/Desktop/sdcard/u-boot.imx"
fi

#echo "Please enter the path of the rootfs.tar.gz"
read -p 'Path to rootfs default /home/<user>/Desktop/sdcard/rootfs.tar.gz: ' rootfspath

if [ -z "$rootfspath" ]
then
      rootfspath="/home/"$USER"/Desktop/sdcard/rootfs.tar.gz"
fi

read -p 'Strip output directory? Default 1: ' stripcount

if [ -z "$stripcount" ]
then
      stripcount="1"
fi

#echo "Please enter the path of the kernel"
read -p 'Path to kernel default /home/<user>/Desktop/sdcard/zImage: ' kernelpath

if [ -z "$kernelpath" ]
then
      kernelpath="/home/"$USER"/Desktop/sdcard/zImage"
fi

#echo "Please enter the path of the device tree blob"
read -p 'Path to *.dtb default /home/<user>/Desktop/sdcard/eval1a.dtb: ' dtbpath

if [ -z "$dtbpath" ]
then
      dtbpath="/home/"$USER"/Desktop/sdcard/eval1a.dtb"
fi




ddimagesize=$((imagesize * 2))k
partitionsize=+$((imagesize - 20))M

#echo $imagesize
#echo $imagepath
#echo $partitionsize


dd status=progress if=/dev/zero of=$imagepath bs=512 count=$ddimagesize

(
echo o # Create a new empty DOS partition table
echo p # Add a new partition
#echo u # change units to cylinders
echo x # expert mode
echo h # Partition number
echo 255
echo s
echo 63
echo c
echo
echo r
echo n
echo p
echo 1
echo 4096
echo $partitionsize
echo p
echo w
) | fdisk $imagepath


dd bs=512 seek=2 conv=notrunc if=$ubootpath of=$imagepath

loodevice="$(sudo losetup --partscan --show --find $imagepath)"
loopartition="$loodevice"p1

mountfolder=/mnt/sdcardtmpfolder

echo "Device: "$loodevice
echo "Partition: "$loopartition
sudo mkfs.ext2 $loopartition
sudo mkdir -p $mountfolder
sudo mount $loopartition $mountfolder
sudo cp $rootfspath "$mountfolder"/rootfs.tar.gz
sudo tar xzf "$mountfolder"/rootfs.tar.gz -C $mountfolder --strip-components=$stripcount
sudo cp $kernelpath "$mountfolder"/boot/zImage
sudo cp $dtbpath "$mountfolder"/boot/imx6ull-dtb-eval1a.dtb
sudo rm "$mountfolder"/rootfs.tar.gz


echo " ----- Please extract rootfs -----"
read

sudo umount /mnt/sdcardtmpfolder
sudo fsck.ext4 $loopartition
sudo losetup -d $loodevice
sudo rm -R /mnt/sdcardtmpfolder

sudo gparted $imagepath
				
			
				
					#!/bin/bash

# Copyright: C. Hediger, 2019
# databyte.ch
# provided without warranty. use it at your own risk!

echo "-------------------------------------------"
echo "-------- SD-Card image generator ----------"
echo "-------------------------------------------"
echo ""

#echo "Please enter the Size of your Image"
read -p 'Size for *.img [MB] default 512MByte: ' imagesize

if [ -z "$imagesize" ]
then
      imagesize="512"
fi

#echo "Please enter the destination of the image"
read -p 'Path to Image default /home/<user>/Desktop/sdcard/sdimage.img: ' imagepath

if [ -z "$imagepath" ]
then
      imagepath="/home/"$USER"/Desktop/sdcard/sdimage.img"
fi

#echo "Please enter the path of the u-boot.imx"
read -p 'Path to u-boot default /home/<user>/Desktop/sdcard/u-boot.imx: ' ubootpath

if [ -z "$ubootpath" ]
then
      ubootpath="/home/"$USER"/Desktop/sdcard/u-boot.imx"
fi

#echo "Please enter the path of the rootfs.tar.gz"
read -p 'Path to rootfs default /home/<user>/Desktop/sdcard/rootfs.tar.gz: ' rootfspath

if [ -z "$rootfspath" ]
then
      rootfspath="/home/"$USER"/Desktop/sdcard/rootfs.tar.gz"
fi

read -p 'Strip output directory? Default 1: ' stripcount

if [ -z "$stripcount" ]
then
      stripcount="1"
fi

#echo "Please enter the path of the kernel"
read -p 'Path to kernel default /home/<user>/Desktop/sdcard/zImage: ' kernelpath

if [ -z "$kernelpath" ]
then
      kernelpath="/home/"$USER"/Desktop/sdcard/zImage"
fi

#echo "Please enter the path of the device tree blob"
read -p 'Path to *.dtb default /home/<user>/Desktop/sdcard/eval1a.dtb: ' dtbpath

if [ -z "$dtbpath" ]
then
      dtbpath="/home/"$USER"/Desktop/sdcard/eval1a.dtb"
fi




ddimagesize=$((imagesize * 2))k
partitionsize=+$((imagesize - 20))M

#echo $imagesize
#echo $imagepath
#echo $partitionsize


dd status=progress if=/dev/zero of=$imagepath bs=512 count=$ddimagesize

(
echo o # Create a new empty DOS partition table
echo p # Add a new partition
#echo u # change units to cylinders
echo x # expert mode
echo h # Partition number
echo 255
echo s
echo 63
echo c
echo
echo r
echo n
echo p
echo 1
echo 4096
echo $partitionsize
echo p
echo w
) | fdisk $imagepath


dd bs=512 seek=2 conv=notrunc if=$ubootpath of=$imagepath

loodevice="$(sudo losetup --partscan --show --find $imagepath)"
loopartition="$loodevice"p1

mountfolder=/mnt/sdcardtmpfolder

echo "Device: "$loodevice
echo "Partition: "$loopartition
sudo mkfs.ext2 $loopartition
sudo mkdir -p $mountfolder
sudo mount $loopartition $mountfolder
sudo cp $rootfspath "$mountfolder"/rootfs.tar.gz
sudo tar xzf "$mountfolder"/rootfs.tar.gz -C $mountfolder --strip-components=$stripcount
sudo cp $kernelpath "$mountfolder"/boot/zImage
sudo cp $dtbpath "$mountfolder"/boot/imx6ull-dtb-eval1a.dtb
sudo rm "$mountfolder"/rootfs.tar.gz


echo " ----- Please extract rootfs -----"
read

sudo umount /mnt/sdcardtmpfolder
sudo fsck.ext4 $loopartition
sudo losetup -d $loodevice
sudo rm -R /mnt/sdcardtmpfolder

sudo gparted $imagepath