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 kernel.org. 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.
TIMEOUT 30
DEFAULT linux
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 fsck.repair=yes 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/ld.so.conf
and /etc/ld.so.conf.d/*
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
c
videodev 184320 9 s5p_g2d,v4l2_fwnode,videobuf2_common,s5p_jpeg,s5p_csis,s5p_m
fc,v4l2_mem2mem,videobuf2_v4l2,s5p_fimc
exynos_rng 20480 0
mc 45056 7 videobuf2_common,videodev,s5p_csis,exynos4_is_common,v4l2_me
m2mem,videobuf2_v4l2,s5p_fimc
s5p_cec 20480 0
ip_tables 28672 0
x_tables 28672 1 ip_tables
lima 53248 0
gpu_sched 28672 1 lima