Exynos 4412 Source Build

Template:Infobox Device


The board name "ODROID-X2" including the revision number is clearly printed on the top side of the board (the side where the SoC cooler is located).


This feature matrix shows hardware support of the ODROID-X2 when using the kernel fork by Tobias Jakobi (currently based on vanilla-4.9.y).

Feature Forked Linux Kernel
Serial Yes
Network Yes
eMMC Yes
Audio Yes
CPUFreq Yes (including Boost)
G2D (2D acceleration) Yes
Mali (3D Acceleration) Yes (r5p0)
MFC (Video encoding/decoding) Needs testing
Crypto engine Yes
IOMMU runtime PM working
clocks runtime PM semi-working

It is recommended to use a recent upstream u-boot build to boot the kernel.

u-boot build

Clone the stable branch of this u-boot repository:

   git clone -b stable https://github.com/tobiasjakobi/u-boot.git

This branch is an older version of upstream u-boot (at the time of writing, from July 2016) with a minimal amount of patches applied on top. Proceed by following the instructions in u-boot/doc/README.odroid, which explains the installation of the complete bootloader chain and also partitioning of your boot media (which can be either eMMC or SD).

Make sure to actually build a recent u-boot binary and don't just use the binary from the tarball with the bootloader blobs (BL1, BL2 and TrustZone). The tarball comes directly from HardKernel and houses an ancient 2010-based u-boot binary.

Using an upstream u-boot build has one potential disadvantage when comparing it to the vendor u-boot branch. The vendor branch clocks the MPLL with 880MHz, while upstream uses 800MHz. This results in slightly reduced memory bandwidth.

kernel setup and build

Clone the kernel fork and fetch a minimal kernel config. We assume that you do these steps on the actual device (probabaly using one of the vendor-provided images as bootstrap platform).

   git clone -b odroid-4.9.y https://github.com/tobiasjakobi/linux-odroid-public.git && cd linux-odroid-public
   curl https://raw.githubusercontent.com/tobiasjakobi/odroid-environment/master/sourcecode/system/vanilla-4.9.conf > .config

Proceed by building the kernel (you can of course modify the kernel config first).

   make -j5 && make zImage

Next we put the kernel image and the devicetree blob (DTB) on the boot filesystem. We assume that the filesystem is correctly mounted in /boot. Depending on your current user's rights you might have to become root for that.

   cp arch/arm/boot/zImage /boot/zImage-4.9-odroid
   cp arch/arm/boot/dts/exynos4412-odroidx2.dtb /boot/odroid-x2-4.9.dtb

u-boot setup

These instructions assume that your boot media is an SD card. You might have to adjust instructions if you're using an eMMC to boot. In particular an eMMC has a dedicated boot area, which is not writable by default (you need to unlock it first).

u-boot stores its configuration data (the u-boot environment, shortened to u-boot env) in the first few blocks of the boot media. For the ODROID-X2 the config region starts at 0x140000 and is 0x1000 bytes long. The default u-boot env that u-boot writes if it doesn't find one is very complex. It is recommend to replace it with a simpler version and provide most of the configuration through the u-boot script.

To prepare the script we store these commands as /boot/boot.cmd.

   if test -n ${oneshot}; then
     setenv oneshot
     setenv filesize
     setenv experimental "4.10"
   # kernel versions
   setenv stable_ver "4.9"
   # kernel image and dtb load addresses
   setenv zimg_addr "0x40008000"
   setenv fdt_addr "0x41f00000"
   setenv fdt_high "0xffffffff"
   # video config: 1280x720M@50, 1920x1080M@60
   # console config
   # rootfs config
   setenv vid_config "video=HDMI-A-1:1280x720M@60"
   setenv con_config "console=ttySAC1,115200n8"
   setenv rfs_config "root=PARTUUID=<partition UUID of the rootfs> rootfstype=ext4 rootwait ro"
   if test -n ${experimental}; then
     setenv zimg_file "zImage-${experimental}-odroid"
     setenv fdt_file "odroid-x2-${experimental}.dtb"
     setenv bootargs "${vid_config} ${con_config} ${rfs_config} earlyprintk"
     setenv zimg_file "zImage-${stable_ver}-odroid"
     setenv fdt_file "odroid-x2-${stable_ver}.dtb"
     setenv bootargs "${vid_config} ${con_config} ${rfs_config}"
   setenv uloadcmd "fatload mmc 0:1 ${zimg_addr} ${zimg_file}; fatload mmc 0:1 ${fdt_addr} ${fdt_file}"
   setenv bootcmd "run uloadcmd; fdt addr ${fdt_addr}; fdt resize; bootz ${zimg_addr} - ${fdt_addr}"

You have to put the correct partition UUID of your rootfs in the script above. You can use blkid to find out the UUID.

   blkid /dev/root

You might want to adjust the other options as well. It currently selects a 720p (60Hz) mode on boot and assumes that the root filesystem is ext4. Also it allows for booting a different kernel (based on Linux 4.10 here) when requested, something which we won't use at the moment. If you use an eMMC then you have to change uloadcmd to point to the correct partition (see below for information about how u-boot indexes them).

Proceed by creating the u-boot script from the input commands (mkimage is part of the u-boot tools package).

   cd /boot && mkimage -A arm -T script -C none -n "Boot script for ODROID-X2" -d boot.cmd boot.scr

Next we configure the u-boot env, where we want to use the u-boot env utilities (fw_printenv/fw_setenv) for. We start by fetching the utility config, storing it in /etc. Another file is going to be used to actually setup the env.

   curl https://gist.githubusercontent.com/tobiasjakobi/f533bb8bcba75cc76bb3/raw/5407dcd554d2efe46064c95ce8acd1d69c021857/fw_env.config > /etc/fw_env.config
   curl -O https://gist.githubusercontent.com/tobiasjakobi/3bfd36eb540c5e246489b3998089d6e0/raw/70a1c7a2d3bdc0a0ac1a9e361929749c9744f0e4/uboot.env.base64
   base64 -d uboot.env.base64 | unxz > uboot.env

We proceed by writing uboot.env into the designated area. Beware that this is potentially dangerous, so make sure that no critical data is stored in that region on this particular block device (here /dev/mmcblk0).

   dd if=uboot.env of=/dev/mmcblk0 bs=1 seek=1310720 count=4096

Check the u-boot env by using fw_printenv. It should look something like this.

   bootcmd=run loadscript
   loadscript=fatload mmc 0:1 ${scriptaddr} boot.scr; source ${scriptaddr}

You can fine-tune the env with fw_setenv, e.g. changing the boot delay. If you use an eMMC you have to change the position from which boot.scr is loaded. Position 0:1 is the first partition on the storage device with index 0, which should be the SD card. The eMMC should have index 1.

This concludes the u-boot setup. A serial/UART adapter is now recommended. Reboot and monitor logging output on the UART.

Additional guides