Building Linux Kernel on Odroid-U3

This is the year 2020, Odroid-U3 is far from a powerful ARM development board in today’s standard, but it is still more than capable! Quad-core ARMv7 CPU and 2GB RAM, which means I can still run some light services and test my toy projects without paying any fees to AWS or Azure. The year 2020 also means that this little device can be powered by the mainline Linux kernel without many troubles (if any)! Better than that, the process is ridiculously straightforward!

In this post, I put together the steps I did to build the Linux kernel using upstream mainline source code natively on Odroid-U3. If you’re interested in cross-building from your x86 machines, you can find plenty of tutorials on that on the Internet.

It makes things easier if you’re using a mainline kernel and the mainline u-boot already (there are quite a few developers who build images for Odroid-U3 using mainline kernel out there, for example, the one I’m using is from hexdump0815). If not, make sure you’ve at least installed the mainline u-boot (with syslinux/extlinux), otherwise, some steps below may not apply.

First of all, make sure you have the necessary development packages installed (GCC, binutils, etc.), then download the latest stable source code tarball from I’m using linux-5.4.80 as an example below.

tar xf linux-5.4.80.tar.xz
cd linux-5.4.80
make menuconfig  # Time to tailor your kernel
make -j4  # It takes about half an hour
sudo make modules_install
sudo make headers_install
sudo make install
sudo mkdir /boot/dtb-5.4.80
sudo cp arch/arm/boot/dts/exynos4412-odroidu3.dtb /boot/dtb-5.4.80/
sudo cp arch/arm/boot/zImage /boot/zImage-5.4.80
sudo rm /boot/vmlinuz-5.4.80

I don’t have any firmware to install, but if you have them in your config, then you also need to run make firmware_install. After these, make a backup and then edit /boot/extlinux/extlinux.conf with your favourite editor to something like these lines below.

MENU TITLE odroid u3 boot options
LABEL linux
      MENU LABEL linux
      LINUX ../zImage-5.4.80
      INITRD ../initrd.img-5.4.80
      FDT ../dtb-5.4.80/exynos4412-odroidu3.dtb
      APPEND earlycon console=ttySAC1,115200n8 console=tty1 mem=2047M smsc95xx.macaddr=ba:5d:6d:41:68:6f root=PARTUUID=7798e841-03 ro loglevel=8 rootwait net.ifnames=0 video=HDMI-A-1:e

Your root partition’s UID is likely different from what I have (same for the MAC address). It’s only for your reference.

Now reboot your odroid and if all goes well, you should be able to see the new kernel is used:

$ uname -a
Linux odroid.local 5.4.80-librehat #1 SMP PREEMPT Wed Nov 25 16:36:45 GMT 2020 armv7l GNU/Linux

If something went wrong, don’t worry. Use your desktop/laptop and insert your microSD card from Odroid-U3, restore the backup of extlinux.conf to use the old kernel, and try again ;)

ARM Lima Driver

The main reason for me to build my own kernel is to use the open-source lima driver for the Mali-400 GPU. A newer kernel than 5.4 would be even better since there were some patches that got merged more recently. To have a safety killswitch, I have CONFIG_DRM_LIMA=m so it is built as a module. Make sure you have maligpu blacklisted (/etc/modprobe.d/blacklist-maligpu.conf) and check /etc/ and /etc/* to make sure that the GL libraries for maligpu are not loaded.

Lastly, in order to use lima, you probably will have to compile newer libdrm and mesa yourself (mesa >= 20).

Kernel 5.9.11

Subsequently, I have built the latest stable Linux kernel (at the time of writing) with a slimmed-down set of modules and slightly tuned for server use. It’s mostly for my own reference, this configuration file has been aggressively trimmed down to suit my own use case, but you might find it to be a good starting point. The modules loaded on start are:

$ lsmod
Module                  Size  Used by
s5p_csis               20480  0
s5p_fimc               69632  0
exynos4_is_common      16384  1 s5p_fimc
v4l2_fwnode            24576  2 s5p_csis,s5p_fimc
s5p_mfc               135168  0
s5p_jpeg               45056  0
s5p_g2d                20480  0
v4l2_mem2mem           20480  3 s5p_g2d,s5p_jpeg,s5p_fimc
videobuf2_dma_contig    20480  4 s5p_g2d,s5p_jpeg,s5p_mfc,s5p_fimc
videobuf2_memops       20480  1 videobuf2_dma_contig
videobuf2_v4l2         20480  5 s5p_g2d,s5p_jpeg,s5p_mfc,v4l2_mem2mem,s5p_fimc
videobuf2_common       49152  6 s5p_g2d,s5p_jpeg,s5p_mfc,v4l2_mem2mem,videobuf2_v4l2,s5p_fim
videodev              184320  9 s5p_g2d,v4l2_fwnode,videobuf2_common,s5p_jpeg,s5p_csis,s5p_m
exynos_rng             20480  0
mc                     45056  7 videobuf2_common,videodev,s5p_csis,exynos4_is_common,v4l2_me
s5p_cec                20480  0
ip_tables              28672  0
x_tables               28672  1 ip_tables
lima                   53248  0
gpu_sched              28672  1 lima

Author: librehat