Ondrej Famera - top logo

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
  • 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 password odroid and then change into root account using same password odroid.
      ...
      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:~#
      
  • 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
        
    • (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
        
  • 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
      
  • 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)
  • 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
      
  • Mount the (future) Gentoo / into /mnt for installation.
    • (eMMC)
      # mount /dev/mmcblk0p2 /mnt
      
    • (SD card)
      # mount /dev/mmcblk1p2 /mnt
      
    • (NVMe)
      # mount /dev/nvme0n1p2 /mnt
      
  • 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), (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), (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
      
  • 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"
    
  • (eMMC), (SD card), (NVMe) - Temporarily mount 3 GB tmpfs into /var/tmp/portage - this will greatly speed up installation of gentoo-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 disable firmware 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 need dev-embedded/u-boot-tools that provides mkimage 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
    ...
    
  • (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
    
  • (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"
    ...
    
  • (eMMC), (SD card), (NVMe) - Generate the binary version (boot.scr) from boot.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
      
  • 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
      
  • (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), (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), (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

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.

Last change .