Gentoo on ODROID C2

Published on Author Artem Butusov1 Comment


Unfortunately only Ubuntu is officially supported on ODROID C2.
There are some other unofficial images available but not Gentoo.

Here we will fill the gap and install Gentoo Linux on ODROID C2.
The instruction should be relatively easy to update for other ODROID boxes,
like, ODROID C4 etc.

Inspired by a short but a bit outdated instruction located here:

Instruction below is tuned to my use case:

  • ODROID C2 box (aarch64) – target environment (target host)
  • Gentoo Linux
  • 16GB eMMC with eMMC to USB 3 adapter
  • macOS x86_64 with Linux running in VirtualBox – provisioning environment (compile host)

Initial Installation

1) Get your provisioning environment ready

Get any Linux host where you can provision eMMC/SD that will be used to boot ODROID C2.

Unfortunately, Gentoo minimal ISO can’t be used because it doesn’t allow to install qemu-user-static on the fly, however, if you have aarch64 Linux host, then you can do chroot right from your .

I will be using Debian Live Standard ISO as provisioning environment here.

Preapare virtual machine:

  • create VirtualBox virtual machine with defaults
  • install VirtualBox extension pack that has USB 3 support
  • switch USB controller for machine to USB 3
  • connect eMMC using USB 3 adapter
  • add USB filter for eMMC adapter
  • ensure that eMMC is unmounted in macOS Disk Utility
  • run virtual machine
  • pick Debian Live Standard ISO x86_64 when asked
  • boot into first entry in boot menu

Type in VirtualBox console to get ssh working:

# update list of packages
sudo apt-get update

# install and run ssh server
sudo apt-get install ssh
sudo systemctl start ssh

# change password to any known value, for example, "gentoo"
sudo passwd user

Then connect from macOS terminal over SSH (enables copy/paste!):

# then from macOS terminal and use previously used password
ssh user@localhost -p 2222

# switch to root shell session
sudo bash

# install some tools
sudo apt-get install curl

2) Flash official Ubuntu image to eMMC/SD

  • Obtain download link to official Ubuntu minimal image:
  • Confirm eMMC/SD device name
  • Download, decompress and flash on the fly
  • Reread partitions
  • Extend root partition
  • Create swap partition (compilation of heavy packages could require a lot of RAM)


# get know device disk name

# download, extract and write the image
curl --fail --silent \ \
  | xzcat \
  | dd bs=1M iflag=fullblock of=/dev/sdX status=progress

# flush buffers after dd

# extend root partition to 13GB
echo "- 13G" | sfdisk -N 2 /dev/sdX
# create swap partition in remaining space (~1.5GB)
echo "- +" | sfdisk -N 3 /dev/sdX

# resize partition
e2fsck -f /dev/sdX2
resize2fs /dev/sdX2

# create swap and label it
mkswap /dev/sdX3
swaplabel -L swap /dev/sdX3

# confirm labels for partitions: boot, rootfs, swap

# reread partitions
blockdev --rereadpt -v /dev/sdX

3) Mount eMMC/SD card

mkdir -p /mnt/gentoo

mount /dev/sdX2 /mnt/gentoo/
mount /dev/sdX1 /mnt/gentoo/boot

cd /mnt/gentoo

4) Backup vanilla ODROID C2 kernel and configuration

mkdir -p opt/odroid-c2-backup

cp -rfa lib/modules opt/odroid-c2-backup
cp -rfa lib/firmware opt/odroid-c2-backup
cp -rfa boot opt/odroid-c2-backup
cp -a etc/fstab opt/odroid-c2-backup

5) Remove not needed stuff

find . -maxdepth 1 \
  | while read file; do \
    [ "$file" != "./boot" ] \
    && [ "$file" != "./opt" ] \
    && [ "$file" != "./lost+found" ] \
    && [ "$file" != "." ] \
    && rm -rf "$file"; \

6) Install aarch64 stage3

curl -O
tar xvpf stage3-* --xattrs-include='*.*' --numeric-owner
rm -f stage3-*

7) Enable target arch emulation

The host CPU arch in my case is x86_64 (amd64) and target is aarch64 (arm64), so chroot won’t work.

If you are installing Gentoo aarch64 from another aarch64 Linux, then you can skip this step.

Install and configure qemu-user-static:

apt-get install qemu-user-static binfmt-support
update-binfmts --display

Make qemu-user-static available inside chroot as well with the same path relative to new root:

cp -v /usr/bin/qemu-*-static usr/bin

Since qemu-user-static is slow, we will offload as much heavy steps as possible to be executed after reboot from odroid c2.

8) Chroot

The rest of installation will continue inside /mnt/gentoo chroot env.

Copy required network configuration:

cp /etc/resolv.conf /mnt/gentoo/etc/

Mount /proc, /sys, /dev:

mount -t proc none /mnt/gentoo/proc
mount -o bind /sys /mnt/gentoo/sys
mount -o bind /dev /mnt/gentoo/dev
mount -o bind /dev/pts /mnt/gentoo/dev/pts
mount -o bind /dev/shm /mnt/gentoo/dev/shm


chroot /mnt/gentoo /bin/bash

Reload environment inside chroot:

source /etc/profile

9) Configure wired network

I will have ODROID C2 connected to wired network so don’t need to setup wireless network.

Enable wired ethernet interface:

ln -s /etc/init.d/net.lo /etc/init.d/net.eth0
rc-update add net.eth0 default

Without additional configuration netifrc will use dhcp by default.

10) Configure fstab

Edit fstab nano /etc/fstab:

LABEL=boot      /boot   vfat    noauto                          0 0
LABEL=rootfs    /       ext4    noatime,errors=remount-ro       0 1
LABEL=swap      none    swap    sw                              0 0

11) Install kernel modules/firmware

cp -rfa /opt/odroid-c2-backup/modules lib/
cp -rfa /opt/odroid-c2-backup/firmware lib/

12) Set root password

sed -e 's/^password.*pam_passwdqc/#\0/' -e 's/use_authtok//' -i /etc/pam.d/system-auth
echo "root:gentoo" | chpasswd

13) Enable ssh

rc-update add sshd default

Edit ssh config nano /etc/ssh/sshd_config and replace default
#PermitRootLogin prohibit-password with PermitRootLogin yes, otherwise you
won’t be able to ssh as root even with right password:

sed 's/^#PermitRootLogin.*$/PermitRootLogin yes/' -i /etc/ssh/sshd_config

14) Enable serial console

If you have serial adapter then make this change to be able to login using serial console.

Edit inittab nano /etc/inittab.

Find and edit agetty ttyS0 and replace

#s0:12345:respawn:/sbin/agetty -L 9600 ttyS0 vt100


s0:12345:respawn:/sbin/agetty -L 115200 ttyS0 vt100

You can also disable agetty ttyAMA0 (RPi4 related) to avoid warnings like “INIT: Id “f0″ respawning too fast: disabled for 5 minutes” on console – replace

f0:12345:respawn:/sbin/agetty 9600 ttyAMA0 vt100


#f0:12345:respawn:/sbin/agetty 9600 ttyAMA0 vt100

Gentoo’s OpenRC can’t output to both serial and primary terminal in the same time,
so you might want to tune line below:

setenv condev "console=ttyS0,115200n8 console=tty0"

to be

setenv condev "console=tty0 console=ttyS0,115200n8"

if your preference is to see OpenRC boot over serial rather than on primary terminal.

15) Fix bootloader configuration

Ensure that boot.ini has correct device name set for root block device when
actual odroid c2 will boot with this eMMC/SD card.

eMMC device is named as /dev/mmcblk0 and second partition will be /dev/mmcblk0p2.

SD card device will be named as /dev/sda and second partition will be /dev/sda2.

Keep in mind, only /dev/* syntax works for ODROID C2 bootloader:

nano /boot/boot.ini

setenv bootargs "root=/dev/mmcblk0p2 ..."

A note regarding SD fusing. It can be needed if you create partition from the
scratch. We didn’t do that here. But if you would like to read read more about it then follow Arch Linux wiki:

16) Done

Exit chroot and power off VirtualBox instance.

# exit chroot

# remove temporarily installed qemu stuff
rm -v usr/bin/qemu-*-static

# turn of Linux and unmount all stuff

Post-reboot Installation

Disconnect eMMC/SD card and attach to ODROID C2, connect power and ethernet cord.

After boot:

1) SSH into ODROID C2

Wait for some time and find new IP in the router settings and try to ssh using
username “root” and password “gentoo”.

You can also find an IP using network scanner nmap:

nmap -p 22 | grep open -B 4

SSH using know IP address:

ssh root@A.B.C.D

If you have serial console cable, you can connect using it and track the boot
process from macOS:

screen /dev/tty.SLAB_USBtoUART 115200

2) Set time

ODROID C2 doesn’t have RTC so every time it reboots it will forget current time.

We will install later ntp to address this issue but for now we need to manually
set the clock, otherwise, nothing will work well.

You can run date on macOS and copy paste into terminal like below:

date -s "Sat Dec 19 21:04:49 EST 2020"

3) Install portage

mkdir -p /etc/portage/repos.conf
cp -f /usr/share/portage/config/repos.conf /etc/portage/repos.conf/gentoo.conf

4) Install ntp server

ODROID-C2 doesn’t have RTC so every time it reboots it will forget current time.

Classical ntp doesn’t play well for systems without RTC (like ODROID C2), so
lets install chrony instead that has support for systems without RTC.

emerge chrony

nano /etc/conf.d/chronyd
ARGS="... -s -r"

rc-update add chronyd default

/etc/init.d/chronyd start

Default hwclock init script is useless without RTC:

rc-update delete hwclock boot

Reboot and confirm that clock is properly set.

5) Done

Okay, the minimal Gentoo installation is completed. It boots and new packages
can be installed.

Please follow official Gentoo instruction to change defaults like locale,
timezone, make.conf etc:


One Response to Gentoo on ODROID C2

  1. Interesting take on the install. I also use gentoo on the C2, and it works really great.

    Did you know about this overlay?

    The instructions on how to use the official sys-kernel/gentoo-sources kernel are there, in case you want the ability to easily upgrade and customize it.

    It’s also possible to install without a virtual machine, or even a second computer. I used arch linux on the c2 running on an sd card to create a gentoo install from scratch on a second sd card via a usb sd adapter. It took a day to compile gcc, and an another day to (re)compile everything else. Having swap space isn’t strictly necessary, although gcc can only compile this way using 1 thread and no “-pipe” CFLAG.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.