Quick guide for odroidxu4

From Tizen Wiki
Jump to: navigation, search

Odroid-XU4 for Tizen 3.0

Booting media

Although Odroid-XU4 can boot off of an eMMC as well as a MicroSD, the booting process is slightly different in both cases and requires different setup. Unlike MicroSD cards eMMC chips comprise several hardware partitions which are supposed to hold the bootloader. Unfortunately these partitions cannot be accessed with a USB card reader. To make a brand new eMMC chip bootable you need to boot from a MicroSD card and follow the steps described in the #booting with eMMC section.

Prepare Binary

To make a bootable card, you will need to get the files listed before and put them in the same directory.

Name Type
bl1.bin.hardkernel binary
bl2.bin.hardkernel.1mb_uboot binary
tzsw.bin.hardkernel binary
u-boot-mmc.bin binary
sd_fusing_xu4.sh shell script

1-1. Download the pre bootloader binaries (which binaries are supported by hardkernel)

$ wget https://github.com/hardkernel/u-boot/raw/odroidxu3-v2012.07/sd_fuse/hardkernel_1mb_uboot/bl1.bin.hardkernel
$ wget https://github.com/hardkernel/u-boot/raw/odroidxu3-v2012.07/sd_fuse/hardkernel_1mb_uboot/bl2.bin.hardkernel.1mb_uboot
$ wget https://github.com/hardkernel/u-boot/raw/odroidxu3-v2012.07/sd_fuse/hardkernel_1mb_uboot/tzsw.bin.hardkernel

1-2. Download the latest u-boot and kernel (tizen-tv_xxxxxxxx.x_tv-boot-armv7l-odroidxu3.tar.gz)

http://download.tizen.org/snapshots/tizen/tv/latest/images/arm-wayland/tv-boot-armv7l-odroidxu3/

1-3. Extract the contents of the image tarball and change the u-boot binary names

$ tar xvf tizen-tv_xxxxxxxx.x_tv-boot-armv7l-odroidxu3.tar.gz

1-4. Save this listing into file "sd_fusing_xu4.sh" Download "sd_fusing_xu4.sh" from u-boot git

#!/bin/bash

declare FORMAT=""
declare DEVICE=""

# Binaires array for fusing
declare -a FUSING_BINARY_ARRAY
declare -i FUSING_BINARY_NUM=0

declare CONV_ASCII=""
declare -i FUS_ENTRY_NUM=0

# binary name | part number | offset | bs
declare -a PART_TABLE=(
	"bl1.bin.hardkernel"		""	1	512
	"bl2.bin.hardkernel.1mb_uboot"	""	31	512
	"u-boot-mmc.bin"		""	63	512
	"tzsw.bin.hardkernel"		""	2111	512
	"params.bin"			""	6272	512
	"boot.img"			1	0	512
	"ramdisk.img"			1	0	512
	"rootfs.img"			2	0	4M
	"system-data.img"		3	0	4M
	"user.img"			5	0	4M
	"modules.img"			6	0	512
	)

declare -r -i PART_TABLE_COL=4
declare -r -i PART_TABLE_ROW=${#PART_TABLE[*]}/${PART_TABLE_COL}

# partition table support
function get_index_use_name () {
	local -r binary_name=$1

	for ((idx=0;idx<$PART_TABLE_ROW;idx++)); do
		if [ ${PART_TABLE[idx * ${PART_TABLE_COL} + 0]} == $binary_name ]; then
			return $idx
		fi
	done

	# return out of bound index
	return $idx
}

# fusing feature
function convert_num_to_ascii () {
	local number=$1

	CONV_ASCII=$(printf \\$(printf '%03o' $number))
}

function print_message () {
	local color=$1
	local message=$2

	tput setaf $color
	tput bold
	echo ""
	echo $message
	tput sgr 0
}

function add_fusing_entry () {
	local name=$1
	local offset=$2
	local size=$3

	FUS_ENTRY_NUM=$((FUS_ENTRY_NUM + 1))

	echo -n "$name" > entry_name
	cat entry_name /dev/zero | head -c 32 >> entry

	echo -n "" > entry_offset
	for ((i=0; i < 4; i++))
	do
		declare -i var;
		var=$(( ($offset >> (i*8)) & 0xFF ))
		convert_num_to_ascii $var
		echo -n $CONV_ASCII > tmp
		cat tmp /dev/zero | head -c 1 >> entry_offset
	done
	cat entry_offset /dev/zero | head -c 4 >> entry

	echo -n "" > entry_size
	for ((i=0; i < 4; i++))
	do
		declare -i var;
		var=$(( ($size >> (i*8)) & 0xFF ))
		convert_num_to_ascii $var
		echo -n $CONV_ASCII > tmp
		cat tmp /dev/zero | head -c 1 >> entry_size
	done
	cat entry_size /dev/zero | head -c 4 >> entry

	rm tmp
	rm entry_name
	rm entry_offset
	rm entry_size
}

function fusing_image () {
	local -r fusing_img=$1

	# get binary info using basename
	get_index_use_name $(basename $fusing_img)
	local -r -i part_idx=$?

	if [ $part_idx -ne $PART_TABLE_ROW ];then
		local -r device=$DEVICE${PART_TABLE[${part_idx} * ${PART_TABLE_COL} + 1]}
		local -r seek=${PART_TABLE[${part_idx} * ${PART_TABLE_COL} + 2]}
		local -r bs=${PART_TABLE[${part_idx} * ${PART_TABLE_COL} + 3]}
	else
		echo "Not supported binary: $fusing_img"
		return
	fi

	local -r input_size=`du -b $fusing_img | awk '{print $1}'`

	print_message 2 "[Fusing $1]"

	if [ "$(basename $fusing_img)" == "ramdisk.img" ]; then
		umount $device
		mkdir mnt_tmp
		mount -t vfat $device ./mnt_tmp
		cp -f $fusing_img ./mnt_tmp
		sync
		umount ./mnt_tmp
		rmdir mnt_tmp
		echo "fusing $fusing_img is done."
	else
		dd if=$fusing_img | pv -s $input_size | dd of=$device seek=$seek bs=$bs
	fi

	if [ $(basename $fusing_img) == "u-boot-mmc.bin" ];then
		add_fusing_entry "u-boot" $seek 2048
	fi
}

function fuse_image_tarball () {
	local -r filepath=$1
	local -r temp_dir="tar_tmp"

	mkdir -p $temp_dir
	tar xvf $filepath -C $temp_dir
	cd $temp_dir

	for file in *
	do
		fusing_image $file
	done

	cd ..
	rm -rf $temp_dir
}

function check_binary_format () {
	local -r binary=$1

	case "$binary" in
	*.tar | *.tar.gz)
		fuse_image_tarball $binary
		eval sync
		;;
	*)
		fusing_image $binary
		eval sync
		;;
	esac
}

function fuse_image () {
	if [ "$FUSING_BINARY_NUM" == 0 ]; then
		return
	fi

	# NOTE: to ensure ramdisk booting, ramdisk image should be copied after
	# boot image is flashed into boot partition.
	#
	# This code guarantees that ramdisk image is flashed in the end of binaries.
	local -i tmpval=$FUSING_BINARY_NUM-1
	for ((fuse_idx = 0 ; fuse_idx < $FUSING_BINARY_NUM ; fuse_idx++))
	do
		local filename=${FUSING_BINARY_ARRAY[fuse_idx]}
		local tmpname=""

		case "$filename" in
		*.tar | *.tar.gz)
			if [ $fuse_idx -lt $tmpval ]; then
				local tar_contents=`tar tvf $filename | awk 'BEGIN {FS=" "} {print $6}'`

				for content in $tar_contents
				do
					if [ "$content" == "ramdisk.img" ]; then
						tmpname=$filename
						filename=${FUSING_BINARY_ARRAY[$tmpval]}
						FUSING_BINARY_ARRAY[$tmpval]=$tmpname
						break
					fi
				done
			fi
			check_binary_format $filename
			;;
		*)
			if [ $fuse_idx -lt $tmpval ]; then
				if [ "$filename" == "ramdisk.img" ]; then
					tmpname=$filename
					filename=${FUSING_BINARY_ARRAY[$tmpval]}
					FUSING_BINARY_ARRAY[$tmpval]=$tmpname
				fi
			fi
			check_binary_format $filename
			;;
		esac
	done
	echo ""
}

# partition format
function mkpart_3 () {
	# NOTE: if your sfdisk version is less than 2.26.0, then you should use following sfdisk command:
	# sfdisk --in-order --Linux --unit M $DISK <<-__EOF__
	#
	# NOTE: sfdisk 2.26 doesn't support units other than sectors and marks --unit option as deprecated.
	# The input data needs to contain multipliers (MiB) instead.
	local version=`sfdisk -v | awk '{print $4}'`
	local major=${version%%.*}
	local version=${version:`expr index $version .`}
	local minor=${version%%.*}
	local sfdisk_new=0

	if [ $major -gt 2 ];  then
		sfdisk_new=1
	else
		if [ $major -eq 2 -a $minor -ge 26 ];  then
			sfdisk_new=1
		fi
	fi

	local -r DISK=$DEVICE
	local -r SIZE=`sfdisk -s $DISK`
	local -r SIZE_MB=$((SIZE >> 10))

	local -r BOOT_SZ=64
	local -r ROOTFS_SZ=3072
	local -r DATA_SZ=512
	local -r MODULE_SZ=32
	if [ $sfdisk_new == 1 ]; then
		local -r EXTEND_SZ=8
	else
		local -r EXTEND_SZ=4
	fi

	let "USER_SZ = $SIZE_MB - $BOOT_SZ - $ROOTFS_SZ - $DATA_SZ - $MODULE_SZ - $EXTEND_SZ"

	local -r BOOT=boot
	local -r ROOTFS=rootfs
	local -r SYSTEMDATA=system-data
	local -r USER=user
	local -r MODULE=modules

	if [[ $USER_SZ -le 100 ]]
	then
		echo "We recommend to use more than 4GB disk"
		exit 0
	fi

	echo "========================================"
	echo "Label          dev           size"
	echo "========================================"
	echo $BOOT"		" $DISK"1  	" $BOOT_SZ "MB"
	echo $ROOTFS"		" $DISK"2  	" $ROOTFS_SZ "MB"
	echo $SYSTEMDATA"	" $DISK"3  	" $DATA_SZ "MB"
	echo "[Extend]""	" $DISK"4"
	echo " "$USER"		" $DISK"5  	" $USER_SZ "MB"
	echo " "$MODULE"		" $DISK"6  	" $MODULE_SZ "MB"

	local MOUNT_LIST=`mount | grep $DISK | awk '{print $1}'`
	for mnt in $MOUNT_LIST
	do
		umount $mnt
	done

	echo "Remove partition table..."
	dd if=/dev/zero of=$DISK bs=512 count=16 conv=notrunc

	if [ $sfdisk_new == 1 ]; then
		sfdisk $DISK <<-__EOF__
		4MiB,${BOOT_SZ}MiB,0xE,*
		8MiB,${ROOTFS_SZ}MiB,,-
		8MiB,${DATA_SZ}MiB,,-
		8MiB,,E,-
		,${USER_SZ}MiB,,-
		,${MODULE_SZ}MiB,,-
		__EOF__
	else
		sfdisk --in-order --Linux --unit M $DISK <<-__EOF__
		4,$BOOT_SZ,0xE,*
		,$ROOTFS_SZ,,-
		,$DATA_SZ,,-
		,,E,-
		,$USER_SZ,,-
		,$MODULE_SZ,,-
		__EOF__
	fi

	mkfs.vfat -F 16 ${DISK}1 -n $BOOT
	mkfs.ext4 -q ${DISK}2 -L $ROOTFS -F
	mkfs.ext4 -q ${DISK}3 -L $SYSTEMDATA -F
	mkfs.ext4 -q ${DISK}5 -L $USER -F
	mkfs.ext4 -q ${DISK}6 -L $MODULE -F
}

function show_usage () {
	echo "- Usage:"
	echo "	sudo ./sd_fusing_xu4.sh -d <device> [-b <path> <path> ..] [--format]"
}

function check_partition_format () {
	if [ "$FORMAT" != "2" ]; then
		echo "-----------------------"
		echo "Skip $DEVICE format"
		echo "-----------------------"
		return 0
	fi

	echo "-------------------------------"
	echo "Start $DEVICE format"
	echo ""
	mkpart_3
	echo "End $DEVICE format"
	echo "-------------------------------"
	echo ""
}

function check_args () {
	if [ "$DEVICE" == "" ]; then
		echo "$(tput setaf 1)$(tput bold)- Device node is empty!"
		show_usage
		tput sgr 0
		exit 0
	fi

	if [ "$DEVICE" != "" ]; then
		echo "Device: $DEVICE"
	fi

	if [ "$FUSING_BINARY_NUM" != 0 ]; then
		echo "Fusing binary: "
		for ((bid = 0 ; bid < $FUSING_BINARY_NUM ; bid++))
		do
			echo "  ${FUSING_BINARY_ARRAY[bid]}"
		done
		echo ""
	fi

	if [ "$FORMAT" == "1" ]; then
		echo ""
		echo "$(tput setaf 3)$(tput bold)$DEVICE will be formatted, Is it OK? [y/n]"
		tput sgr 0
		read input
		if [ "$input" == "y" ] || [ "$input" == "Y" ]; then
			FORMAT=2
		else
			FORMAT=0
		fi
	fi
}

function print_logo () {
	echo ""
	echo "[Odroid-XU3/4 downloader]"
	echo "This version also supports Tizen 4.0."
	echo ""
}

print_logo

function add_fusing_binary() {
	local declare binary_name=$1
	FUSING_BINARY_ARRAY[$FUSING_BINARY_NUM]=$binary_name

	FUSING_BINARY_NUM=$((FUSING_BINARY_NUM + 1))
}

declare -i binary_option=0

while test $# -ne 0; do
	option=$1
	shift

	case $option in
	--f | --format)
		FORMAT="1"
		binary_option=0
		;;
	-d)
		DEVICE=$1
		binary_option=0
		shift
		;;
	-b)
		add_fusing_binary $1
		binary_option=1
		shift
		;;
	*)
		if [ $binary_option == 1 ];then
			add_fusing_binary $option
		else
			echo "Unkown command: $option"
			exit
		fi
		;;
	esac
done

check_args
check_partition_format
fuse_image

1-5. Make the file executable

$ chmod u+x sd_fusing_xu4.sh

1-6. Prepare to use fusing script

Install the pv tools

$ sudo apt-get install pv

Download bootloader on Micro SD

2-1. Connect the Micro SD to Desktop using Card Reader and check device node

Desktop$ sudo fdisk -l

..........
Partition table entries are not in disk order
Disk /dev/sdb: 32.0 GB, 32010928128 bytes
64 heads, 32 sectors/track, 30528 cylinders, total 62521344 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x00000000
Device Boot Start End Blocks Id System
/dev/sdb1 * 8192 139263 65536 e W95 FAT16 (LBA)
..........

2-2. run "sd_fusing_xu4.sh" with device node

※ Replace /dev/sdX with the proper device name, e.g. /dev/sdb

※ This can take a few minutes so wait for the script to finish

Desktop$ sudo ./sd_fusing_xu4.sh -d /dev/sdX -b bl1.bin.hardkernel bl2.bin.hardkernel.1mb_uboot tzsw.bin.hardkernel u-boot-mmc.bin

2-3. Insert your Micro SD card into Odroid and select boot mode to SD

Xu4 boot mode.jpg

2-4. Turn on the power

Now, You can boot the odroid xu4 with the Micro SD

Partitioning for Tizen 3.0

3-1. Connect the eMMC to Desktop using Card Reader and check device node

Desktop$ sudo fdisk -l
..........
Partition table entries are not in disk order
Disk /dev/sdb: 7948 MB, 7948206080 bytes
245 heads, 62 sectors/track, 1021 cylinders, total 15523840 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x00000000
Device Boot Start End Blocks Id System
/dev/sdb1 * 8192 139263 65536 e W95 FAT16 (LBA).......

3-2. Run "sd_fusing_xu4.sh" script with device node

※ Replace /dev/sdX with the proper device name, e.g. /dev/sdb

Desktop$ sudo ./sd_fusing_xu4.sh -d /dev/sdX --format
Press 'y' key to format (It can take a few minutes so wait for the script to finish)
Device: /dev/sdb
/dev/sdb will be formatted, Is it OK? [y/n]
y
-------------------------------
Start /dev/sdb format
..........

Download boot and platform image for Tizen 3.0

4-1. Download Latest boot and platform image

https://download.tizen.org/snapshots/tizen/tv/latest/images/arm-wayland/tv-boot-armv7l-odroidxu3/
https://download.tizen.org/snapshots/tizen/tv/latest/images/arm-wayland/tv-wayland-armv7l-odroidu3/

4-2. Connect the eMMC to Desktop using Card Reader and check device node

Desktop$ sudo fdisk -l
..........
Partition table entries are not in disk order
Disk /dev/sdb: 7948 MB, 7948206080 bytes
245 heads, 62 sectors/track, 1021 cylinders, total 15523840 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x00000000
Device Boot Start End Blocks Id System
/dev/sdb1 * 8192 139263 65536 e W95 FAT16 (LBA).......

4-3. Run "sd_fusing_xu4.sh" script with device node

※ Replace /dev/sdX with the proper device name, e.g. /dev/sdb

$ sudo ./sd_fusing_xu4.sh -d /dev/sdX -b tizen-tv_20150824.1_tv-boot-armv7l-odroidxu3.tar.gz tizen-tv_20150824.1_tv-wayland-armv7l-odroidu3.tar.gz

booting with eMMC

5-1. Insert your Micro SD card and eMMC into Odroid and select boot mode to SD

5-2. Turn on the power and enter u-boot prompt

5-3. run this command

ODROID-XU3 # mmc dev 0
ODROID-XU3 # mmc read 0x50000000 0x1 0xa3e
ODROID-XU3 # mmc dev 1 1
ODROID-XU3 # mmc write 0x50000000 0x0 0xa3e
ODROID-XU3 # mmc dev 1 0

Copy-paste friendly version of above follows:

mmc dev 0; mmc read 0x50000000 0x1 0xa3e; mmc dev 1 1; mmc write 0x50000000 0x0 0xa3e; mmc dev 1 0

5-4. Change boot mode to eMMC

5-5. Reboot

Now, you can use the eMMC for development, So. you can change binary just follow [Download_boot_and_platform_image_for_Tizen_3.0]

Links