How to create a bootable microSD card (XELK)

From DAVE Developer's Wiki
Revision as of 15:33, 15 April 2019 by U0007 (talk | contribs)

(diff) ← Older revision | Approved revision (diff) | Latest revision (diff) | Newer revision → (diff)
Jump to: navigation, search
Info Box
Axel-lite 02.png Applies to Axel Lite


200px-Emblem-important.svg.png The procedure described here was tested with a physical machine. In case of a virtual machine such as the MVM, it might not work properly. Also, it is worth remembering that USB controller of the MVM is disabled by default. See also this section. 200px-Emblem-important.svg.png


This article shows how to create a bootable microSD for the XELK-4.0.0 kit by using a simple bash script.
Note: Starting from this release the support for the SPL has been introduced in Uboot. Previous versions of this script will no longer produce a fully functional and bootable microSD card.
Please use this script for older releases.

The procedure has been tested on a Linux PC running Ubuntu LTS (>=16.04) distribution with

  • a 16 GB microSD card [1]
  • the binary files delivered along with the XELK 4.0.0.

The resulting card is partitioned as depicted here.

The script - named mksd.sh - looks like this:

#!/bin/bash

if [[ -z $1 || -z $2 || -z $3 || -z $4 || -z $5 ]]
then
	echo "$0 Usage:"
	echo "	$0 <device> <u-boot.img> <SPL> <binaries directory> <rootfs tar.bz2>"
	echo "	Example: $0 /dev/sdc u-boot.img SPL binaries/ rootfs.tar.bz2"
	exit
fi

if [ "$(whoami)" != "root" ]
then
	echo "you must be root to run this script!"
	exit
fi

if ! [[ -b $1 ]]
then
	echo "$1 is not a valid block device!"
	exit
fi

if ! [[ -e $2 ]]
then
	echo "Incorrect u-boot.img location!"
	exit
fi

if ! [[ -e $3 ]]
then
	echo "Incorrect SPL location!"
	exit
fi

if ! [[ -d $4 ]]
then
	echo "Incorrect Binaries location!"
	exit
fi

if ! [[ -f $5 ]]
then
	echo "Incorrect rootfs location!"
	exit
fi

DRIVE=$1
if [[ "$DRIVE" == *"mmcblk"* ]]
then
	echo "You're using a mmc device, I need to fix partition names"
	PART="p"
else
	PART=""
fi
UBOOT=$2
SPL=$3
BINARIES=$4
RFS=$5

echo "All data on "$DRIVE" now will be destroyed! Continue? [y/n]"
read ans
if ! [ $ans == 'y' ]
then
	exit
fi

echo "[Partitioning $1...]"

dd if=/dev/zero of=$DRIVE bs=1024 count=1024

SIZE=`fdisk -l $DRIVE | grep Disk | awk '{print $5}'`

echo DISK SIZE - $SIZE bytes

CYLINDERS=`echo $SIZE/255/63/512 | bc`

# check if we're running an old (e.g. 2.20.x) or new (e.g. 2.24.x) sfdisk
sfdisk --help | grep -- -H

if [ "$?" -eq "0" ]
then
	{
		echo 10,1380,0x0c,*
		echo 1390,,83,-
	} | sfdisk -D -H 255 -S 63 -C $CYLINDERS $DRIVE
else
{
    echo 10,4086M,0x0c,*
    echo 4096M,,83,-
} | sfdisk $DRIVE
fi

partprobe


echo "[Making filesystems...]"
mkfs.vfat -F 32 -n BOOT "$DRIVE$PART"1 #> /dev/null
mkfs.ext3 -L ROOTFS "$DRIVE$PART"2 #> /dev/null

echo "[Copying files...]"

binaries_dir=${BINARIES%/}
mount "$DRIVE$PART"1 /mnt
cp -av --no-preserve=ownership $binaries_dir/* /mnt/
umount "$DRIVE$PART"1

echo "[Extracting rfs (this may take a while...)]"
mount "$DRIVE$PART"2 /mnt
tar jxf $RFS -C /mnt > /dev/null
chmod 755 /mnt
umount "$DRIVE$PART"2

echo "[Programming SPL]"
dd if=$SPL of=$DRIVE bs=512 seek=2 conv=fsync

echo "[Programming u-boot.img]"
dd if=$UBOOT of=$DRIVE bs=1k seek=69 conv=fsync

echo "[Done]"

Here is an example that shows how to use this script. Let's assume that the binary files were downloaded in the xuelk-4.0.0 subdirectory of the working directory. Before invoking the script, the following files has to be renamed in order to make them compatible with the default U-Boot environment variables:

  • bootscript: boot.scr
  • Linux kernel: uImage
  • Device tree blob: imx6ul-sbcx.dtb.

This is the list of the binary files that will be used by the script:

# ll 
total 362M
drwxr-xr-x 2 dave dave 4.0K Jun 25 17:09 binaries
-rw-r--r-- 1 dave dave 362M Jun  8 15:53 dave-image-devel.rootfs.tar.bz2
-rwxr-xr-x 1 dave dave 2.0K Jun 21 10:57 mksd.sh
-rw-r--r-- 1 dave dave  47K Jun 25 17:12 SPL.mmc
-rw-r--r-- 1 dave dave 480K Jun 25 17:12 u-boot.img.mmc

You can now run the script, by passing the following parameters:

  • Device file of the microSD card (/dev/sdc in the example)
  • U-Boot image
  • SPL
  • Path of the directory containing the bootscript file, the Linux kernel image, and the device tree blob files
  • Archive of the target's root file system (compressed as .tar.bz2 file).
# ./mksd.sh /dev/sdc u-boot.img.mmc SPL.mmc binaries/ dave-image-devel.rootfs.tar.bz2
All data on /dev/sdc now will be destroyed! Continue? [y/n]
y
[Partitioning /dev/sdc...]
1024+0 records in
1024+0 records out
1048576 bytes (1.0 MB) copied, 0.60321 s, 1.7 MB/s
DISK SIZE - 15987638272 bytes
 -H, --heads <number>      set the number of heads to use
sfdisk: Checking that no-one is using this disk right now ...
sfdisk: OK

Disk /dev/sdc: 1943 cylinders, 255 heads, 63 sectors/track
sfdisk:  /dev/sdc: unrecognized partition table type
Old situation:
sfdisk: No partitions found
New situation:
Units: cylinders of 8225280 bytes, blocks of 1024 bytes, counting from 0

   Device Boot Start     End   #cyls    #blocks   Id  System
/dev/sdc1   *     10    1389    1380   11084850    c  W95 FAT32 (LBA)
/dev/sdc2       1390    1942     553    4441972+  83  Linux
/dev/sdc3          0       -       0          0    0  Empty
/dev/sdc4          0       -       0          0    0  Empty
Successfully wrote the new partition table

Re-reading the partition table ...

sfdisk: If you created or changed a DOS partition, /dev/foo7, say, then use dd(1)
to zero the first 512 bytes:  dd if=/dev/zero of=/dev/foo7 bs=512 count=1
(See fdisk(8).)
Error: The backup GPT table is corrupt, but the primary appears OK, so that will be used.
[Making filesystems...]
mkfs.fat 3.0.27 (2014-11-12)
mke2fs 1.42.12 (29-Aug-2014)
/dev/sdc2 contains a ext3 file system labelled 'ROOTFS'
	last mounted on /mnt on Mon Jun 25 17:18:17 2018
Proceed anyway? (y,n) y
Creating filesystem with 1110493 4k blocks and 277984 inodes
Filesystem UUID: 9876db93-deb5-48e9-ba5c-3bd81a3fb510
Superblock backups stored on blocks: 
	32768, 98304, 163840, 229376, 294912, 819200, 884736

Allocating group tables: done                            
Writing inode tables: done                            
Creating journal (32768 blocks): done
Writing superblocks and filesystem accounting information: done 

[Copying files...]
‘binaries/boot.scr’ -> ‘/mnt/boot.scr’
‘binaries/imx6dl-sbcx-cb0012.dtb’ -> ‘/mnt/imx6dl-sbcx-cb0012.dtb’
‘binaries/imx6dl-sbcx-cb0013.dtb’ -> ‘/mnt/imx6dl-sbcx-cb0013.dtb’
‘binaries/imx6dl-xelk-l.dtb’ -> ‘/mnt/imx6dl-xelk-l.dtb’
‘binaries/imx6q-sbcx-cb0012.dtb’ -> ‘/mnt/imx6q-sbcx-cb0012.dtb’
‘binaries/imx6q-xelk-l-2.0.0.dtb’ -> ‘/mnt/imx6q-xelk-l-2.0.0.dtb’
‘binaries/SPL.mmc’ -> ‘/mnt/SPL.mmc’
‘binaries/SPL.nand’ -> ‘/mnt/SPL.nand’
‘binaries/SPL.spi’ -> ‘/mnt/SPL.spi’
‘binaries/u-boot.img.mmc’ -> ‘/mnt/u-boot.img.mmc’
‘binaries/u-boot.img.nand’ -> ‘/mnt/u-boot.img.nand’
‘binaries/u-boot.img.spi’ -> ‘/mnt/u-boot.img.spi’
‘binaries/uImage’ -> ‘/mnt/uImage’
[Extracting rfs (this may take a while...)]
[Programming SPL]
94+0 records in
94+0 records out
48128 bytes (48 kB) copied, 0.0464824 s, 1.0 MB/s
[Programming u-boot.img]
479+1 records in
479+1 records out
490896 bytes (491 kB) copied, 0.638593 s, 769 kB/s
[Done]


[1] In case you have a different size, you'll need to change the sfdisk parameters accordingly.