About
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:
https://forum.odroid.com/viewtopic.php?t=21675
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: https://wiki.odroid.com/odroid-c2/odroid-c2
- 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)
Example:
# get know device disk name
lsblk
# download, extract and write the image
curl --fail --silent \
https://odroid.in/ubuntu_20.04lts/c2/ubuntu-20.04-3.16-minimal-odroid-c2-20200617.img.xz \
| xzcat \
| dd bs=1M iflag=fullblock of=/dev/sdX status=progress
# flush buffers after dd
sync
# 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
blkid
# 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"; \
done
6) Install aarch64 stage3
curl -O http://distfiles.gentoo.org/releases/arm64/autobuilds/current-stage3/stage3-arm64-20201216T203511Z.tar.xz
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
chroot /mnt/gentoo /bin/bash
Reload environment inside chroot:
env-update
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
with
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
with
#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: https://archlinuxarm.org/platforms/armv8/amlogic/odroid-c2
16) Done
Exit chroot and power off VirtualBox instance.
# exit chroot
exit
# remove temporarily installed qemu stuff
rm -v usr/bin/qemu-*-static
# turn of Linux and unmount all stuff
poweroff
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 192.168.50.1/24 | 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
emerge-webrsync
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: https://wiki.gentoo.org/wiki/Handbook:AMD64/Full/Installation
Interesting take on the install. I also use gentoo on the C2, and it works really great.
Did you know about this overlay?
https://github.com/nxmyoz/c2-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.