Gentoo on Odroid-M1S (aarch64) with upstream 6.6.x kernel
Guide for installing Gentoo on Odroid-M1S board (8GB version) into eMMC/NVMe/SD card.
If you prefer to use pre-build Gentoo image instead of typical Gentoo installation check the Pre-build Gentoo image on Odroid-M1S (aarch64) post.
Odroid-M1S boot sequence
Odroid-M1S at the time of writing (2024-08-20) features onboard eMMC memory, SD card slot and M.2 slot for NVMe drives. Odroid-M1S Boot sequence is looking first into eMMC and then into SD card to find SPL and subsequently the U-Boot both located in the beginning of eMMC or SD card as described in Odroid-M1S partition table. Note that it is NOT looking onto NVMe or other places before SPL+U-Boot are loaded.
Odroid-M1S U-Boot
At time of writing (2024-08-20) Odroid-M1S is shipped with Hardkernels custom u-boot ‘2017.09’. Additionally there is also Hardkernels custom u-boot ‘2024.01’ that features very brand new version of U-Boot but feature wise is less supported as the stock 2017.09 one according to the (forum.odroid.com) Mainline U-Boot for ODROID-M1S.
This guide will be using the ‘2024.01’ version of U-Boot where needed and appropriate as its one major advantage is ability to boot from NVMe without need for additional bootloader such as petitboot after U-Boot (which is needed with stock 2017.09 U-Boot version).
Gentoo installation checklist
Procedure to get Gentoo running will take around 3-4 hours to complete (2 longest steps are package compilation ~25 minutes and later kernel compilation ~102 minutes). I assume you are starting at Linux computer that is NOT the Odroid-M1S (where the Gentoo is going to be installed).
- Odroid-M1S board (tested on 8GB version, should work on 4GB as well)
- SD card (tested on 32G one, at least 16GB one is needed)
- Hardkernels ubuntu-20.04-server image (255 MB) or the functional Linux system on Odroid-M1S eMMC
- U-Boot 2024.1 binary - required for NVMe installation, optional (but recommended) for eMMC/SD card installation
Installing Gentoo for Odroid-M1S
Based on your decision on where to install the Gentoo follow only the steps that have marking for your chosen destination. For example if you want to install Gentoo on SD card, then follow steps with (SD card)
markings, for installation on internal eMMC follow (eMMC)
markings and for the installation on NVMe follow the (NVMe)
markings in the steps below.
- This manual will assume following naming for storage devices:
- eMMC -
/dev/mmcblk0
- SD card -
/dev/mmcblk1
- NVMe -
/dev/nvme0n1
- eMMC -
- First lets download the ubuntu-2024-server for Odroid-M1S image so we have OS from which we can install OS.
- (SD card) - You can skip this step IF you have functional OS (that can boot) on Odroid-M1S eMMC.
- (eMMC), (NVMe) - Download Hardkernels ubuntu-2024-server image.
# curl -O https://dn.odroid.com/RK3566/ODROID-M1S/Ubuntu/ubuntu-20.04-server-odroidm1s-20231030.img.xz # curl -O https://dn.odroid.com/RK3566/ODROID-M1S/Ubuntu/ubuntu-20.04-server-odroidm1s-20231030.img.xz.md5sum
- Verify the integrity of downloaded file.
- (SD card) - You can skip this step IF you have functional OS (that can boot) on Odroid-M1S eMMC.
- (eMMC), (NVMe) - Verify integrity of Hardkernels ubuntu-2024-server image.
# md5sum -c ubuntu-20.04-server-odroidm1s-20231030.img.xz.md5sum ubuntu-20.04-server-odroidm1s-20231030.img.xz: OK
- Decompress the image.
- (SD card) - You can skip this step IF you have functional OS (that can boot) on Odroid-M1S eMMC.
- (eMMC), (NVMe) - Decompress Hardkernels ubuntu-2024-server image.
# unxz ubuntu-20.04-server-odroidm1s-20231030.img.xz
# du -BM ubuntu-20.04-server-odroidm1s-20231030.img 1246M ubuntu-20.04-server-odroidm1s-20231030.img
- Write the uncompressed image to SD card - below examples assumes your Linux system presents the SD card as
/dev/mmcblk1
device to you (adjust that accordingly to your system). WARNING: This will overwrite existing data on SD card!- (SD card) - You can skip this step IF you have functional OS (that can boot) on Odroid-M1S eMMC.
- (eMMC), (NVMe) - Write uncompressed ubuntu-2024-server image onto SD card.
# dd if=ubuntu-20.04-server-odroidm1s-20231030.img of=/dev/mmcblk1 bs=4M oflag=direct status=progress 451+1 records in 451+1 records out 1894343680 bytes (1.9 GB, 1.8 GiB) copied, xxx.xxx s, xx.x MB/s
- Verify that image was written onto SD card where you can see partition table with 2 partitions.
- (SD card) - You can skip this step IF you have functional OS (that can boot) on Odroid-M1S eMMC.
- (eMMC), (NVMe) - ubuntu-2024-server image should be visible on DOS style partition table.
# fdisk -l /dev/mmcblk1 Disk /dev/mmcblk1: 29.45 GiB, 31609323520 bytes, 61736960 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 Disklabel type: dos Disk identifier: 0x8cdbf051 Device Boot Start End Sectors Size Id Type /dev/mmcblk1p1 6144 530431 524288 256M 83 Linux /dev/mmcblk1p2 530432 3699889 3169458 1.5G 83 Linux
-
(SD card), (eMMC), (NVMe) - Disconnect SD card from your Linux computer and insert it into powered off Odroid-M1S.
- Power on Odroid-M1S while SD card is inserted.
- (SD card) Wait for your OS on Odroid-M1S to boot, login and get into
root
account. - (eMMC), (NVMe) Wait for ubuntu-2024-server to start and login as user
odroid
with passwordodroid
and then change intoroot
account using same passwordodroid
.... Booting Debian 5.10.0-odroid-arm64 from mmc 1:1... ... Ubuntu 20.04.6 LTS server ttyFIQ0 server login: odroid Password: odroid Welcome to Ubuntu 20.04.6 LTS (GNU/Linux 5.10.0-odroid-arm64 aarch64) ...
odroid@server:~$ sudo -i [sudo] password for odroid: odroid root@server:~#
- (SD card) Wait for your OS on Odroid-M1S to boot, login and get into
- Make sure that target storage on which we will install Gentoo is clean.
- (eMMC) WARNING: This will destroy all data on
/dev/mmcblk0
!# blkdiscard /dev/mmcblk0 # lsblk /dev/mmcblk0 NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT mmcblk0 179:0 0 58.2G 0 disk
- (SD card) WARNING: This will destroy all data on
/dev/mmcblk1
!# blkdiscard /dev/mmcblk1 # lsblk /dev/mmcblk1 NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT mmcblk1 179:96 0 29.4G 0 disk
- If the partitions are still visible then your SD card may not support TRIM properly, use
dd
to cleanup beginning of it instead.# dd if=/dev/zero of=/dev/mmcblk1 bs=4M count=500 oflag=direct status=progress 500+0 records in 500+0 records out 2097152000 bytes (2.1 GB, 2.0 GiB) copied, xx.xxx s, xxx MB/s
- If the partitions are still visible then your SD card may not support TRIM properly, use
- (NVMe) WARNING: This will destroy all data on
/dev/nvme0n1
!# blkdiscard /dev/nvme0n1 # lsblk /dev/nvme0n1 NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT nvme0n1 259:0 0 13.4G 0 disk
- If the partitions are still visible then your NVMe may not support TRIM properly, use
dd
to cleanup beginning of it instead.# dd if=/dev/zero of=/dev/nvme0n1 bs=4M count=500 oflag=direct status=progress 500+0 records in 500+0 records out 2097152000 bytes (2.1 GB, 2.0 GiB) copied, xx.xxx s, xxx MB/s
- If the partitions are still visible then your NVMe may not support TRIM properly, use
- (eMMC) WARNING: This will destroy all data on
- Storage onto which Gentoo will be installed in examples below will use DOS partition table.
- Initial 8MB will be reserved for fixed-position of bootloader and U-Boot.
- p1 - first partition -
/boot
- 256 MiB - kernel, initramfs, DTB and boot.scr files - p2 - second partition -
/
- 9 GiB - Gentoo root partition
- Partition the storage device using
parted
command and check the resulting partitioning.- (eMMC) Partition eMMC.
# parted /dev/mmcblk0 mklabel msdos # parted /dev/mmcblk0 mkpart primary 8MiB 264MiB # parted /dev/mmcblk0 mkpart primary 264MiB 9GiB
# lsblk /dev/mmcblk0 NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT mmcblk0 179:0 0 58.2G 0 disk ├─mmcblk0p1 179:1 0 256M 0 part └─mmcblk0p2 179:2 0 58G 0 part
# fdisk -l /dev/mmcblk0 |grep -E 'Disklabel|size' Sector size (logical/physical): 512 bytes / 512 bytes I/O size (minimum/optimal): 512 bytes / 512 bytes Disklabel type: dos
- (SD card) Partition SD card.
# parted /dev/mmcblk1 mklabel msdos # parted /dev/mmcblk1 mkpart primary 8MiB 264MiB # parted /dev/mmcblk1 mkpart primary 264MiB 9GiB
# lsblk /dev/mmcblk1 NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT mmcblk1 179:96 0 29.4G 0 disk ├─mmcblk1p1 179:97 0 256M 0 part └─mmcblk1p2 179:98 0 8.8G 0 part
# fdisk -l /dev/mmcblk1 |grep -E 'Disklabel|size' Sector size (logical/physical): 512 bytes / 512 bytes I/O size (minimum/optimal): 512 bytes / 512 bytes Disklabel type: dos
- (NVMe) Partition NVMe.
# parted /dev/nvme0n1 mklabel msdos # parted /dev/nvme0n1 mkpart primary 8MiB 264MiB # parted /dev/nvme0n1 mkpart primary 264MiB 9GiB
# lsblk /dev/nvme0n1 NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT nvme0n1 259:0 0 13.4G 0 disk ├─nvme0n1p1 259:1 0 256M 0 part └─nvme0n1p2 259:2 0 8.8G 0 part
# fdisk -l /dev/nvme0n1 |grep -E 'Disklabel|size' Sector size (logical/physical): 512 bytes / 512 bytes I/O size (minimum/optimal): 512 bytes / 512 bytes Disklabel type: dos
- (eMMC) Partition eMMC.
- Examples below will use following file systems.
- EXT2 for
/boot
(any file system that U-Boot is able to read from can be used) - EXT4 for Gentoo
/
(any file system that Gentoo can mount can be used)
- EXT2 for
- Create the file systems.
- (eMMC)
# mkfs.ext2 /dev/mmcblk0p1 # mkfs.ext4 /dev/mmcblk0p2
- (SD card)
# mkfs.ext2 /dev/mmcblk1p1 # mkfs.ext4 /dev/mmcblk1p2
- (NVMe)
# mkfs.ext2 /dev/nvme0n1p1 # mkfs.ext4 /dev/nvme0n1p2
- (eMMC)
- Mount the (future) Gentoo
/
into/mnt
for installation.- (eMMC)
# mount /dev/mmcblk0p2 /mnt
- (SD card)
# mount /dev/mmcblk1p2 /mnt
- (NVMe)
# mount /dev/nvme0n1p2 /mnt
- (eMMC)
- In examples I will use Gentoo stage3 systemd variant from nearby mirror.
- NOTE: I had issue with openrc on first boot where it got stuck on ‘Starting local [ok]’ forever and I’m not sure still how to resolve it so the systemd installation is therefore recommended for now.
- (eMMC), (SD card), (NVMe) - Download stage3 and unpack it inside
/mnt
(systemd) # cd /mnt # wget http://ftp.kaist.ac.kr/gentoo/releases/arm64/autobuilds/current-stage3-arm64-systemd/stage3-arm64-systemd-20240825T234900Z.tar.xz # wget http://192.168.5.33/tmp/stage3-arm64-systemd-20240825T234900Z.tar.xz # tar xpvf stage3-*.tar.xz --xattrs-include='*.*' --numeric-owner
- Mount
/boot
partition.- (eMMC)
# mount /dev/mmcblk0p1 /mnt/boot
- (SD card)
# mount /dev/mmcblk1p1 /mnt/boot
- (NVMe)
# mount /dev/nvme0n1p1 /mnt/boot
- (eMMC)
- (eMMC), (SD card), (NVMe) - Mount other virtual file systems needed for Gentoo installation.
# mount -t proc none /mnt/proc # mount --rbind /sys /mnt/sys # mount --rbind /dev /mnt/dev
- Checkpoint - Check the mounted file systems and their capacities, you should see output similar to ones below.
- (eMMC)
# df -h /mnt /mnt/boot /mnt/proc /mnt/sys /mnt/dev Filesystem Size Used Avail Use% Mounted on /dev/mmcblk0p2 8.6G 1.4G 6.7G 18% /mnt /dev/mmcblk0p1 248M 24K 236M 1% /mnt/boot none 0 0 0 - /mnt/proc sysfs 0 0 0 - /mnt/sys udev 3.8G 0 3.8G 0% /mnt/dev
- (SD card)
# df -h /mnt /mnt/boot /mnt/proc /mnt/sys /mnt/dev Filesystem Size Used Avail Use% Mounted on /dev/mmcblk1p2 8.6G 1.4G 6.7G 18% /mnt /dev/mmcblk1p1 248M 24K 236M 1% /mnt/boot none 0 0 0 - /mnt/proc sysfs 0 0 0 - /mnt/sys udev 3.8G 0 3.8G 0% /mnt/dev
- (NVMe)
# df -h /mnt /mnt/boot /mnt/proc /mnt/sys /mnt/dev Filesystem Size Used Avail Use% Mounted on /dev/nvme0n1p2 8.6G 1.4G 6.7G 18% /mnt /dev/nvme0n1p1 248M 24K 236M 1% /mnt/boot none 0 0 0 - /mnt/proc sysfs 0 0 0 - /mnt/sys udev 3.8G 0 3.8G 0% /mnt/dev
- (eMMC)
- (eMMC), (SD card), (NVMe) - Chroot into (future) Gentoo
/
.# cp -L /etc/resolv.conf /mnt/etc # chroot /mnt /bin/bash # env-update # source /etc/profile
- Add
/
and/boot
file systems into/etc/fstab
- use the UUIDs from your outputs (NOTE: UUID is not same thing as PARTUUID).- (eMMC)
# blkid /dev/mmcblk0p1 /dev/mmcblk0p2 /dev/mmcblk0p1: UUID="aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa" BLOCK_SIZE="4096" TYPE="ext2" PARTUUID="cccccccc-01" /dev/mmcblk0p2: UUID="bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb" BLOCK_SIZE="4096" TYPE="ext4" PARTUUID="cccccccc-02" # echo 'UUID="aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa" /boot ext2 noauto,noatime 0 0' >> /etc/fstab # echo 'UUID="bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb" / ext4 defaults 0 0' >> /etc/fstab
- (SD card)
# blkid /dev/mmcblk1p1 /dev/mmcblk1p2 /dev/mmcblk1p1: UUID="aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa" BLOCK_SIZE="4096" TYPE="ext2" PARTUUID="cccccccc-01" /dev/mmcblk1p2: UUID="bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb" BLOCK_SIZE="4096" TYPE="ext4" PARTUUID="cccccccc-02" # echo 'UUID="aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa" /boot ext2 noauto,noatime 0 0' >> /etc/fstab # echo 'UUID="bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb" / ext4 defaults 0 0' >> /etc/fstab
- (NVMe)
# blkid /dev/nvme0n1p1 /dev/nvme0n1p2 /dev/nvme0n1p1: UUID="aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa" BLOCK_SIZE="4096" TYPE="ext2" PARTUUID="cccccccc-01" /dev/nvme0n1p2: UUID="bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb" BLOCK_SIZE="4096" TYPE="ext4" PARTUUID="cccccccc-02" # echo 'UUID="aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa" /boot ext2 noauto,noatime 0 0' >> /etc/fstab # echo 'UUID="bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb" / ext4 defaults 0 0' >> /etc/fstab
- (eMMC)
- Download a fresh portage tree.
# emerge-webrsync
- (eMMC), (SD card), (NVMe) - Configure CPU flags for Odroid-M1S CPU (you can get list of CPU flags from
app-portage/cpuid2cpuflags
).# echo '*/* CPU_FLAGS_ARM: edsp neon thumb vfp vfpv3 vfpv4 vfp-d32 aes sha1 sha2 crc32 v4 v5 v6 v7 v8 thumb2' > /etc/portage/package.use/00cpuflags
- (eMMC), (SD card), (NVMe) - Configure
/etc/portage/make.conf
.- Set architecture matching the CPU (you can also use
-march=native
). - Set concurrency so we utilize all (4) CPU cores (+1).
# nano /etc/portage/make.conf ... COMMON_FLAGS="-O2 -pipe -march=armv8.2-a+crypto+fp16+rcpc+dotprod" ... MAKEOPTS="-j5"
- Set architecture matching the CPU (you can also use
- (eMMC), (SD card), (NVMe) - Temporarily mount 3 GB
tmpfs
into/var/tmp/portage
- this will greatly speed up installation ofgentoo-sources
which are mainly limited by performance of storage device.# mount -t tmpfs -o size=3g tmpfs /var/tmp/portage # df -h /var/tmp/portage Filesystem Size Used Avail Use% Mounted on tmpfs 3.0G 0 3.0G 0% /var/tmp/portage
- (eMMC), (SD card), (NVMe) - Configure the USE flags and download files for tools that we will use during installation.
- To boot Gentoo
sys-kernel/linux-firmware
is not needed therefore lets disablefirmware
USE flag to save some space. - To compile kernel and generate initramfs I will use
sys-kernel/genkernel
. - To generate the
boot.scr
file we will needdev-embedded/u-boot-tools
that providesmkimage
command used later.
# echo 'sys-kernel/genkernel -firmware' > /etc/portage/package.use/01_basic_os # emerge -avf sys-kernel/genkernel dev-embedded/u-boot-tools sys-kernel/gentoo-sources:6.6.47 ... Total: 8 packages (8 new), Size of downloads: 361961 KiB ...
- To boot Gentoo
- (eMMC), (SD card), (NVMe) - Emerge tools needed for building kernel and kernel sources (8packages at time of writing, compilation time ~25 minutes when 3 GB tmpfs is used).
# emerge -av sys-kernel/genkernel dev-embedded/u-boot-tools sys-kernel/gentoo-sources:6.6.47
- (eMMC), (SD card), (NVMe) - Select the kernel sources that will be used for compiling kernel - this guide will use 6.6.47 in examples below.
# eselect kernel set 1 # eselect kernel list Available kernel symlink targets: [1] linux-6.6.47-gentoo *
- (eMMC), (SD card), (NVMe) - Download the Device Tree (DT) for Odroid-M1S board and add it to kernel sources.
- NOTE: This steps needs to be repeated each time the new kernel version is selected in future when doing upgrade.
# curl -o /usr/src/linux/arch/arm64/boot/dts/rockchip/rk3566-odroid-m1s.dts https://raw.githubusercontent.com/tobetter/linux/odroid-6.6.y/arch/arm64/boot/dts/rockchip/rk3566-odroid-m1s.dts # echo 'dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3566-odroid-m1s.dtb' >> /usr/src/linux/arch/arm64/boot/dts/rockchip/Makefile
- (eMMC), (SD card), (NVMe) - Get some reasonable kernel
.config
to start with for kernel compilation. For this guide I will use my minimized kernel config for M1S.# curl -o /root/2024-08-odroid-m1s-config.cfg https://www.famera.cz/blog/assets/files/gentoo-odroid-m1s/2024-08-odroid-m1s-config.cfg
- (eMMC), (SD card), (NVMe) - Configure genkernel.
- Disable microcode loading as there is no support for it on ARM CPUs.
- Add callback that will compile DTB file for the Odroid-M1S board that is needed to boot system and that will be copied into
/boot/
automatically same way as kernel and initramfs.
# nano /etc/genkernel.conf ... MICROCODE="no" ... CMD_CALLBACK="make dtbs; copy_image_with_preserve gentoo.dtb arch/arm64/boot/dts/rockchip/rk3566-odroid-m1s.dtb gentoo.dtb" ...
- (eMMC), (SD card), (NVMe) - Run kernel compilation and generate initramfs using
genkernel
. (~102 minutes when using SD card).- (optional) You can customize kernel config by adding
--menuconfig
option. - Subsequent compilations are faster as
genkernel
caches once-build binaries for initramfs.
# genkernel --kernel-config=/root/2024-08-odroid-m1s-config.cfg all
- (optional) You can customize kernel config by adding
- (eMMC), (SD card), (NVMe) - Create
/boot/boot.txt
file.- This guide will use the minimized version
boot.txt
for M1S based on one that came from Hardkernels Ubuntu for Odroid-M1S. - Once downloaded edit UUID of Gentoo
/
to mach it with your system.
# cd /boot # curl -o /boot/boot.txt https://www.famera.cz/blog/assets/files/gentoo-odroid-m1s/boot.txt-6.6.47-m1s.txt
# nano boot.txt ... setenv bootargs " ${bootargs} init=/lib/systemd/systemd root=UUID=bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb" setenv bootargs " ${bootargs} init=/sbin/openrc-init root=UUID=bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb" ... setenv bootlabel "Gentoo 6.6.47" ... setenv fk_kvers "6.6.47-gentoo-arm64" ...
- This guide will use the minimized version
- (eMMC), (SD card), (NVMe) - Generate the binary version (
boot.scr
) fromboot.txt
that is recognized by U-Boot.# mkimage -A arm64 -T script -O linux -n 'boot script' -C none -d boot.txt boot.scr Image Name: boot script Created: Mon Aug 26 15:01:18 2024 Image Type: AArch64 Linux Script (uncompressed) Data Size: 2389 Bytes = 2.33 KiB = 0.00 MiB Load Address: 00000000 Entry Point: 00000000 Contents: Image 0: 2381 Bytes = 2.33 KiB = 0.00 MiB
- Checkpoint - (eMMC), (SD card), (NVMe) - Check the content of
/boot
to confirm that needed files are present as shown below.# ls -l /boot total 27952 -rw-r--r-- 1 root root 3395912 Aug 26 13:58 System.map-6.6.47-gentoo-arm64 -rw-r--r-- 1 root root 2453 Aug 26 15:01 boot.scr -rw-r--r-- 1 root root 2381 Aug 26 15:01 boot.txt -rw-r--r-- 1 root root 57736 Aug 26 14:17 gentoo.dtb -rw-r--r-- 1 root root 3336216 Aug 26 14:40 initramfs-6.6.47-gentoo-arm64.img drwx------ 2 root root 16384 Aug 26 12:15 lost+found -rw-r--r-- 1 root root 21968904 Aug 26 13:58 vmlinuz-6.6.47-gentoo-arm64
- Note - Below is disk usage after compilation of kernel 6.6.47.
(systemd) # df -h Filesystem Size Used Avail Use% Mounted on /dev/mmcblk1p2 8.6G 4.6G 3.6G 57% / /dev/mmcblk1p1 248M 28M 208M 12% /boot tmpfs 3.8G 0 3.8G 0% /sys/fs/cgroup udev 3.8G 0 3.8G 0% /dev tmpfs 3.8G 0 3.8G 0% /dev/shm tmpfs 3.0G 0 3.0G 0% /var/tmp/portage
Installing the U-Boot
There are at least two U-Boot versions that can be used for Odroid-M1S:
- (U-Boot 2017.09) - works for booting from eMMC and SD card
- (U-Boot 2024.01) - works for booting from NVMe, eMMC, SD card
Based on your storage device choose one U-Boot version and complete steps below to obtain it and install it onto storage device.
Getting U-Boot
- (U-Boot 2017.09) extract ‘U-Boot SPL 2017.09’ and ‘U-Boot 2017.09’ from ubuntu-2024-server image file
# dd if=ubuntu-20.04-gnome-desktop-odroidm1s-20231030.img of=idbloader.img skip=64 count=1000 bs=512 1000+0 records in 1000+0 records out 512000 bytes (512 kB, 500 KiB) copied, x.xx s, xxx MB/s
# dd if=ubuntu-20.04-gnome-desktop-odroidm1s-20231030.img of=u-boot.itb skip=2048 count=4000 bs=512 4000+0 records in 4000+0 records out 2048000 bytes (2.0 MB, 2.0 MiB) copied, x.xx s, xxx MB/s
- (U-Boot 2024.01) download archive with ‘U-Boot SPL 2024.01’ and ‘U-Boot 2024.01’ and unpack it from Mainline U-Boot for ODROID-M1S odroids forum post.
# cd /root # curl -o /root/u-boot-2024.01-20240125.zip "https://forum.odroid.com/download/file.php?id=18795&sid=e7418da41d7c89d77922241d74949a2b"
# unzip u-boot-2024.01-20240125.zip Archive: u-boot-2024.01-20240125.zip inflating: idbloader.img inflating: u-boot.itb inflating: md5sumlist
Installing U-Boot onto storage device
- Write U-Boot into appropriate places at the start of storage device (= this is why first partition starts from 8MB, so there is space for these binary files).
- (eMMC), (NVMe) - NOTE: to be able to boot from NVMe the U-Boot is written onto eMMC
# dd if=idbloader.img of=/dev/mmcblk0 conv=fsync seek=64 bs=512 360+0 records in 360+0 records out 184320 bytes (184 kB, 180 KiB) copied, 0.70 s, 260 kB/s
# dd if=u-boot.itb of=/dev/mmcblk0 conv=fsync seek=2048 bs=512 2281+0 records in 2281+0 records out 1167872 bytes (1.2 MB, 1.1 MiB) copied, 0.35 s, 3.3 MB/s
- (SD card)
# dd if=idbloader.img of=/dev/mmcblk1 conv=fsync seek=64 bs=512 360+0 records in 360+0 records out 184320 bytes (184 kB, 180 KiB) copied, 0.70 s, 260 kB/s
# dd if=u-boot.itb of=/dev/mmcblk1 conv=fsync seek=2048 bs=512 2281+0 records in 2281+0 records out 1167872 bytes (1.2 MB, 1.1 MiB) copied, 0.35 s, 3.3 MB/s
- (eMMC), (NVMe) - NOTE: to be able to boot from NVMe the U-Boot is written onto eMMC
- Verify the version of installed U-Boot.
- (eMMC) - U-Boot version 2017.09
# dd if=/dev/mmcblk0 skip=64 count=560 status=none|grep -abE -o ".{0,0}U-Boot SPL 20.{0,24}" 246225:U-Boot SPL 2017.09-g97ab962d1ed-23071
# dd if=/dev/mmcblk0 count=4096 status=none | grep -abE -o ".{0,0}U-Boot 20.{0,24}" 2016497:U-Boot 2017.09-g97ab962d1ed-23071
- (eMMC) - U-Boot version 2024.01
# dd if=/dev/mmcblk0 skip=64 count=560 status=none|grep -abE -o ".{0,0}U-Boot SPL 20.{0,24}" 164458:U-Boot SPL 2024.01-00003-gcd797f0899e
# dd if=/dev/mmcblk0 count=4096 status=none | grep -abE -o ".{0,0}U-Boot 20.{0,24}" 1771651:U-Boot 2024.01-00003-gcd797f0899e
- (SD card) - U-Boot version 2017.09
# dd if=/dev/mmcblk0 skip=64 count=560 status=none|grep -abE -o ".{0,0}U-Boot SPL 20.{0,24}" 246225:U-Boot SPL 2017.09-g97ab962d1ed-23071
# dd if=/dev/mmcblk0 count=4096 status=none | grep -abE -o ".{0,0}U-Boot 20.{0,24}" 2016497:U-Boot 2017.09-g97ab962d1ed-23071
- (SD card) - U-Boot version 2024.01
# dd if=/dev/mmcblk0 skip=64 count=560 status=none|grep -abE -o ".{0,0}U-Boot SPL 20.{0,24}" 164458:U-Boot SPL 2024.01-00003-gcd797f0899e
# dd if=/dev/mmcblk0 count=4096 status=none | grep -abE -o ".{0,0}U-Boot 20.{0,24}" 1771651:U-Boot 2024.01-00003-gcd797f0899e
- (NVMe) - NOTE: to be able to boot from NVMe the U-Boot is written onto eMMC and must be version 2024.01 (2017.09 will NOT work)
# dd if=/dev/mmcblk0 skip=64 count=560 status=none|grep -abE -o ".{0,0}U-Boot SPL 20.{0,24}" 164458:U-Boot SPL 2024.01-00003-gcd797f0899e
# dd if=/dev/mmcblk0 count=4096 status=none | grep -abE -o ".{0,0}U-Boot 20.{0,24}" 1771651:U-Boot 2024.01-00003-gcd797f0899e
- (eMMC) - U-Boot version 2017.09
- (NVMe) IF you plan to boot Gentoo from NVMe, but have working OS on eMMC then you need to make sure that OS on eMMC is “not bootable” to allow boot sequence to try booting from NVMe. The simples way of doing this is renaming the
boot.scr
on eMMC first partition.# mount /dev/mmcblk0p1 /mnt # mv /mnt/boot.scr /mnt/boot.scr-backup # umount /mnt
Finishing the installation
- (eMMC), (SD card), (NVMe) - Configure root password and exit chroot.
# passwd root # exit
- POWEROFF and remove the SD card (in case your Gentoo installation destination was not SD card)
# poweroff
Information about Pre-build image preparation - SKIP to ‘Booting into Gentoo’ if not interested
To replicate the pre-build Gentoo image from Pre-build Gentoo image on Odroid-M1S (aarch64) article, you can boot again into non-Gentoo system used for installation, perform following cleanup steps and copy content of installation storage into image file.
- Mount the root file system of Gentoo.
- (eMMC)
# mount /dev/mmcblk0p2 /mnt
- (SD card)
# mount /dev/mmcblk1p2 /mnt
- (NVMe)
# mount /dev/nvme0n1p2 /mnt
- (eMMC)
- (eMMC), (SD card), (NVMe) - Cleanup the system - Remove bash history, cached files for package installation and stage3 image, cleanup the DNS configuration and issue TRIM command for file system.
# rm -rf /mnt/root/.bash_history /mnt/var/db/repos/gentoo /mnt/var/cache/distfiles/* /mnt/stage3* # echo '#nameserver x.x.x.x' > /mnt/etc/resolv.conf # fstrim -v /mnt
- Copy initial 9.6GB of disk into image file.
- (eMMC)
# dd if=/dev/mmcblk0 of=/root/sd_card_systemd-2024-08-26.img bs=1M count=9600 status=progress
- (SD card)
# dd if=/dev/mmcblk1 of=/root/sd_card_systemd-2024-08-26.img bs=1M count=9600 status=progress
- (NVMe)
# dd if=/dev/nvme0n1 of=/root/sd_card_systemd-2024-08-26.img bs=1M count=9600 status=progress
- (eMMC)
- (eMMC), (SD card), (NVMe) - Compress the image file. (~32 minutes)
# xz -k --best --block-size=16777216 -T 0 /root/sd_card_systemd-2024-08-26.img
# du -BM sd_card_systemd-2024-08-26.img.xz 649M sd_card_systemd-2024-08-26.img.xz
Booting into Gentoo
Connect either HDMI and/or USB-UART kit to Odroid-M1S and power it on to see the boot. If you have installed the U-Boot version 2024.01 there could be some time that screen (on HDMI) will be just blank/black before the login into Gentoo appears.
If you have the USB-UART kit connected, you may see the output similar to following when booting (below example is from NVMe boot).
U-Boot SPL 2024.01-00003-gcd797f0899e (Jan 25 2024 - 17:28:44 +0900)
...
U-Boot 2024.01-00003-gcd797f0899e (Jan 25 2024 - 17:28:44 +0900)
Model: Hardkernel ODROID-M1S
DRAM: 8 GiB (effective 7.7 GiB)
...
** Booting bootflow 'nvme#0.blk#1.bootdev.part_1' with script
Failed to load '/config.ini'
57736 bytes read in 1 ms (55.1 MiB/s)
Working FDT set to a100000
21968904 bytes read in 60 ms (349.2 MiB/s)
Error: Bad gzipped data
21968904 bytes read in 59 ms (355.1 MiB/s)
3336216 bytes read in 10 ms (318.2 MiB/s)
Booting Gentoo 6.6.47-gentoo-arm64 from nvme 0:1...
...
Starting kernel ...
[ 0.000000] Booting Linux on physical CPU 0x0000000000 [0x412fd050]
[ 0.000000] Linux version 6.6.47-gentoo-arm64 (root@gnome-desktop) (aarch64-unknown-linux-gnu-gcc (Gentoo 13.3.1_p20240614 p17) 13.3.1 20240614, GNU ld (Gentoo 2.42 p3) 2.42.0) #1 SMP Mon Aug 26 13:58:30 -00 2024
[ 0.000000] Machine model: Hardkernel ODROID-M1S
...
>> Genkernel 4.3.10 (2024-08-26 14:17:51 UTC). Linux kernel 6.6.47-gentoo-arm64
>> Activating udev ...
>> Determining root device (trying UUID=caac7d37-7ea2-46e8-94fa-7630bbb6f611) ...
>> Root device detected as /dev/nvme0n1p2!
>> Mounting /dev/nvme0n1p2 as root ...
...
[ 15.379569] fbcon: Taking over console
[ 15.392779] Console: switching to colour frame buffer device 320x90
This is localhost (Linux aarch64 6.6.47-gentoo-arm64) 14:59:54
localhost login:
Note for future kernel updates
When compiling new kernel version that doesn’t contain the DTB for Odroid-M1S, you will need to do following steps before trying to compile the kernel.
# curl -o /usr/src/linux/arch/arm64/boot/dts/rockchip/rk3566-odroid-m1s.dts https://raw.githubusercontent.com/tobetter/linux/odroid-6.6.y/arch/arm64/boot/dts/rockchip/rk3566-odroid-m1s.dts
# echo 'dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3566-odroid-m1s.dtb' >> /usr/src/linux/arch/arm64/boot/dts/rockchip/Makefile
Additional resources
- Odroid-M1S wiki: https://wiki.odroid.com/odroid-m1s/odroid-m1s
- Odroid-M1S boot sequence diagram: https://wiki.odroid.com/odroid-m1s/board_support/boot_sequence
- U-boot 2024-01: Mainline U-Boot for ODROID-M1S
Final thoughts
While it took me longer than expected to put whole procedure together I’m happy that in the end this ARM board is well capable of booting from various media, runs reasonably recent Linux kernel and is readily available to buy.
In case you got stuck in the above procedure at some point feel free to drop me an email.