Installing Debian on Odroid-HC1

Debian does not support installation on the device as of today (May 2019). Installing requires U-Boot and several firmware BLOB from Hardkernel/Samsung.

Creating an SD Card based on the daily Debian Installer worked fine, however after boot the kernel did not recognize the USB Host controller it seemed - neither the network card not the USB2Sata bridge were found. The root cause for this is not known.

/!\ If your USB2Sata bridge does not work reliably (i.e. only after cold boot), try flashing the firmware for the JMicron USB to ATA/ATAPI bridge. Especially enabling SATA hot plug functionality (Example 5 with -u 0) seems to have fixed the problems.

Debian Installer (TFTP netboot)

A netboot-installation of buster (TFTP with DebianInstaller/NetbootAssistant and latest u-boot, SD-card prepared with blobs/sd_fusing.sh) worked fine here for both, HC1 and HC2 (2020-02). The only modification needed: Prepare a link exynos5422-odroid.dtb -> exynos5422-odroidxu4.dtb with ln -s exynos5422-odroidxu4.dtb exynos5422-odroid.dtb in the installer's directory buster/armhf/dtbs/ (If unsure, watch the TFTP-server's log to see what the board tries to fetch.)

Manual installation

Lets install straight to a SD Card. This procedure can be done on a normal desktop or laptop computer, the SD Card will contain a ready Debian Installation.

First step: Partitioning

The SD Card must be set up to contain 2MB of unused space at the start, then a boot partition (readable by U-Boot), then the root filesystem.

I used a 16GB SD card and chose 400MB for the /boot partition.

SDCARD=/dev/sdd
parted --script ${SDCARD} \
  mklabel msdos \
  mkpart primary 2MiB 412MiB \
  mkpart primary 412MiB 100%

Next create filesystems on both partitions. For the second partition is the root filesystem, you can choose your preferred filesysstem. For the first partition however you should stick with vfat or ext4, as u-boot supports those two.

mkfs.ext4 ${SDCARD}1 -E discard
mkfs.ext4 ${SDCARD}2 -E discard

Next mount the filesystems:

mount ${SDCARD}2 /mnt/
mkdir /mnt/boot /mnt/dev /mnt/proc /mnt/sys
mount ${SDCARD}1 /mnt/boot

multistrap is a new tool similar to debootstrap, but without using a tar.gz file. It fits the purpose nicely. First install this tool and other supporting packages:

apt install multistrap apt-transport-https qemu binfmt-support qemu-user-static

Then create a config file and run the tool. Feel free to customize the list of packages below to your need:

cat <<EOF > debian-odroid-hc1-multistrap.conf
[General]
arch=armhf
directory=/mnt/
# same as --tidy-up option if set to true
cleanup=true
# same as --no-auth option if set to true
# keyring packages listed in each bootstrap will
# still be installed.
noauth=false
# extract all downloaded archives (default is true)
unpack=true
# enable MultiArch for the specified architectures
# default is empty
#multiarch=
# aptsources is a list of sections to be used for downloading packages
# and lists and placed in the /etc/apt/sources.list.d/multistrap.sources.list
# of the target. Order is not important
aptsources=Debian
# the order of sections is not important.
# the bootstrap option determines which repository
# is used to calculate the list of Priority: required packages.
bootstrap=Debian

[Debian]
packages=task-ssh-server u-boot-exynos u-boot u-boot-tools linux-image-armmp-lpae firmware-linux firmware-linux-nonfree sudo vim less systemd systemd-sysv iproute2 isc-dhcp-client ca-certificates iputils-ping net-tools iperf3 man-db ifupdown flash-kernel
source=https://deb.debian.org/debian/
keyring=debian-archive-keyring
suite=buster
components=main contrib non-free
addimportant=false

EOF

multistrap -f debian-odroid-hc1-multistrap.conf

On that device, the kernel and initramfs links (vmlinuz and initrd.img) are expected to be found in the boot partition. Let's tell update-initramfs to generate them there:

echo 'link_in_boot = Yes' > /mnt/etc/kernel-img.conf

Next we need to configure all debian packages. This requires the use of qemu as emulator, if this step is run on a normal computer:

cp /usr/bin/qemu-arm-static  /mnt/usr/bin/

mount --bind /dev /mnt/dev
mount --bind /proc /mnt/proc

chroot /mnt/ env DEBIAN_FRONTEND=noninteractive dpkg --configure -a

Likely this last step failed with some problems, we will run configure once again later.

Third step: General system config

Configure a password for root:

chroot /mnt passwd root

Enable the serial console:

chroot /mnt systemctl enable serial-getty@ttySAC2.service

Configure a hostname:

echo debian-odroid-h1 > /mnt/etc/hostname
echo 127.0.0.1 debian-odroid-hc1 localhost > /mnt/etc/hosts

Configure the network to dhcp:

cat << EOF > /mnt/etc/network/interfaces
auto lo
iface lo inet loopback

auto eth0
iface eth0 inet dhcp
EOF

Modify the SSH daemon config to allow login by root:

sed -e "s/^#PermitRootLogin.*/PermitRootLogin Yes/g" -i /mnt/etc/ssh/sshd_config

Fourth step: Boot loader, including Vendor firmware (BLOB)

Find the UUID for each filesystem:

BOOT_UUID="$(lsblk -n -o UUID ${SDCARD}1)"
ROOT_UUID="$(lsblk -n -o UUID ${SDCARD}2)"

Create the fstab for mounting partitions on boot:

cat << EOF > /mnt/etc/fstab
proc              /proc   proc    defaults
UUID=${ROOT_UUID} /       ext4    noatime,errors=remount-ro,discard
UUID=${BOOT_UUID} /boot   ext4    defaults,discard
EOF

With the fstab in place we should be able to configure the remaining packages:

chroot /mnt/ dpkg --configure -a

Download the vendor git tree for the boot loader with required firmware:

git clone https://github.com/hardkernel/u-boot -b odroidxu3-v2012.07

And install the required files to the boot partitin:

mkdir /mnt/boot/hardkernel/
cp u-boot/sd_fuse/hardkernel_1mb_uboot//{bl1.bin.hardkernel,bl2.bin.hardkernel.1mb_uboot,sd_fusing.1M.sh,tzsw.bin.hardkernel} /mnt/boot/hardkernel/
cp /mnt/usr/lib/u-boot/odroid-xu3/u-boot.bin /mnt/boot/hardkernel/

Install the firmware and the u-boot boot loader into the 2MB unpartitioned space at the start of the SD card:

chroot /mnt bash -c "cd /boot/hardkernel; ./sd_fusing.1M.sh ${SDCARD}"

Configure u-boot to load the kernel

cat <<EOF >> /mnt/etc/default/flash-kernel
LINUX_KERNEL_CMDLINE="console=ttySAC2,115200n8 consoleblank=0 loglevel=8  rootwait rw net.ifnames=0 biosdevname=0  governor=performance root=UUID=${ROOT_UUID} rootfstype=ext4"
LINUX_KERNEL_CMDLINE_DEFAULTS=""
EOF

chroot /mnt env FK_MACHINE="Hardkernel Odroid HC1" flash-kernel

Almost done, now unmount all partitions and sync data to disk:

umount /mnt/boot
umount /mnt/dev
umount /mnt/proc
umount /mnt
sync

All done - remove the SD Card, plug into the Odroid HC1 and start using it.