Running OpenWRT on the Odroid N2 — And pretty much any other unsupported ARM device that can run Linux

Why?
People usually run OpenWRT in home routers, however, it’s not every router that is supported by it, also, the majority of the routers destined for home usage don’t have potent hardware, so they are not a good fit for processing-intensive tasks, like encryption of a big amount of data if you intend to put all your network traffic behind a VPN running on it for example.
Routing your network with more robust hardware, like the Odroid N2, you will have sufficient power for putting all your network traffic behind a VPN while still maintaining your download/upload speed to the maximum that is provided by your ISP (unless you have insanely fast internet, hehe).
Say that, like me, you have a good home router with great Wi-Fi capabilities but that lacks OpenWRT support. You can, for example, run OpenWRT into your SBC and then turn your router into a Dumb AP, leveraging its gigabit ports and also its Wireless Radio, so you get the best of both worlds. You have a potent router running OpenWRT while also maintaining your great Wireless capabilities.
Requirements
- A working Linux distro for the ARM device with kernel ≥ 4.14
- If you want to do actual routing you will need 2 network interfaces, e.g. 2 ethernet ports or 1 ethernet port + 1 wifi device. I use 2 ethernet ports, the one embedded in the device and a USB3->1GB Ethernet adapter from Ugreen.
- Some Linux knowledge
How?
TLDR; get the boot partition, kernel modules, and firmware from the working Linux distro and merge it with OpenWrt's armvirt rootfs, either 64 or 32 bits depending on your device.
The process consists of getting the kernel modules, boot partition and firmware from a working Linux distro for your Arm device and merging it with openwrt’s armvirt rootfs and it should work just fine. I’ve tested it with both Linux kernel 4.9 and also the newer kernel 5.9, they worked just fine.
I’ll be using Armbian’s last distro containing 5.9 kernel, which can be downloaded from Armbian’s page here.
Now, Let’s begin!
1. Flash the working Linux distro image to an SD card or eMMC module
Armbian’s tutorial suggests that we use etcher for flashing the image to the sd/eMMC, I’ve used it a couple of times now and it works very well, so I suggest you do the same. Verify that the flashed module boots on your device, if so, continue to the next step, if not, continue trying step 1 until you manage to get a bootable device.
2. Backup boot, Linux modules, and firmware
In this section, this cd /path/to/rootfs
means entering the SD/eMMC root, the one you just flashed with the Linux distro.
To start, let’s organize the Linux modules. Generally, the /lib/modules
directory structure of a Linux distribution looks like this:
/lib/modules/<kernel-version>/
├── kernel
│ ├── arch
│ ├── crypto
│ ├── drivers
│ ├── fs
│ ├── lib
│ ├── mm
│ ├── net
│ ├── security
│ ├── sound
│ └── virt
├── modules.alias
├── modules.alias.bin
├── modules.builtin
├── modules.builtin.bin
├── modules.dep
├── modules.dep.bin
├── modules.devname
├── modules.order
├── modules.softdep
├── modules.symbols
└── modules.symbols.bin
In contrast, OpenWrt expects that we store all the modules directly into the /lib/modules/<kernel-version>
directory, so let’s move them manually with the following commands:
# you will probably need root going forward
cd /path/to/rootfs
# enter the modules dir
cd ./lib/modules/<kernel-version>/
# exclude everything apart from the kernel directory
sudo rm -f * 2>/dev/null
# recursivelly move all modules to the current directory
sudo mv $(find kernel -type f) .
# remove the kernel dir
sudo rm -r kernel
Now that we dealt with the modules, lets backup the stuff we will need before deleting everything and extracting OpenWrt’s rootfs.
In armbian’s image, there’s only one partition and boot is a directory inside it, for some other distros you’ll have a boot partition instead, which is fine, just don’t touch it as you’ll be extracting the rootfs to the other partition.
We will be creating a backup dir and then copying all the necessary stuff there with the following commands:
# create the backup dir
mkdir -p /tmp/backup
# enter the rootfs path in your sd or emmc
cd /path/to/rootfs
# copy boot dir to backup dir, not necessary if boot partition
cp -ra ./boot /tmp/backup/boot
# backup modules and firmware
cp -ra ./lib/modules /tmp/backup/
cp -ra ./lib/firmware /tmp/backup/# backup run dir (needed in latest versions of armbian+openwrt I tried)cp -ra ./run /tmp/backup/# remove everything since we backed-up the necessary already
sudo rm -rf *
# extract openwrt's rootfs to the sd
sudo tar -xvf /path/to/openwrt/rootfs.tar.gz
# remove openwrt's boot dir
sudo rm -rf ./boot
# restore the backup
sudo mv -f /tmp/backup/boot .
sudo mv -f /tmp/backup/modules/<kernel-version> ./lib/modules
sudo mv -f /tmp/backup/firmware ./lib
sudo mv -f /tmp/backup/run .
You must end up with the following tree:
sd-root
- boot (copied from backup)
- lib
- modules (copied from backup)
- kernel version
- bunch of .ko files (copied from working distro)
- firmware (copied from backup)
- ... (all the other directoried from openwrt rootfs)
By now you should already have a bootable OpenWrt distro for your device, however, we need to configure networking first so that you’re able to access it and configure it.
3. Configure network
Edit or create the file /etc/config/network and insert the following:
For finishing up configuring your device, you now have 2 options, configuring a new LAN already, or, using DHCP for connecting the odroid into an existing router that has DHCP enabled.
Option 1: New Lan (This is my preferred one, I’ll tell you why soon)
config interface 'lan'
option type 'bridge'
option ifname 'eth0'
option proto 'static'
option ipaddr '10.0.0.1'
option netmask '255.255.255.0'
Option 2: DHCP
config interface 'lan'
option ifname 'eth0'
option proto 'dhcp'
The reason I prefer creating the new LAN is because of predictability, I already know the IP my device will be listing to, I don’t need to go to the issuing DHCP device and figure out what IP was assigned to it.
You may have noticed that I configured only one LANinterface, the embedded one, we still need to configure the second one, we will make it work soon, for now, bear with me.
4. Booting
You may now try to boot your device, you will have no image display but you must have networking working by now.
If you did the new LAN option, connect a PC directly to it using an ethernet cable and configure the PC IP settings manually as follows:
ip 10.0.0.2
netmask 255.255.255.0
gateway 10.0.0.1
You should be able to access your device now on the IP addr 10.0.0.1.
If you did the DHCP option you need to figure out what IP was issued to your device.
Either way, you then should be able to either access Luci on a web browser or ssh to it using root user.
If you have used DHCP you should have internet access working already, try to opkg update. If it’s not possible to access the internet, try to ping something, say 8.8.8.8 (Google’s DNS), if it’s working you have working connectivity so it might have failed because you have wrong DNS config, check /etc/resolv.conf file.
If you did Lan option, let’s move forward now and configure your second eth interface as your Wan interface, move to the next section.
5. Talking about kmods and making final adjustments
If you have experience with openwrt you know that a kmod is a kernel module and that they’re usually installed using opkg, we need to load one for example to make our USB Ethernet adapter usable.
Here I have 2 news for you, a good one and a bad one.
The bad one is, because you’re not using OpenWRT’s supported kernel, you will not be able to install kmod packages using the default OpenWRT opkg repository. You might now be asking yourself what was the point of all this if you would not be able to use kmods, again, bear with me, I would not make you go through all that if using kernel modules would not be possible, continue reading.
The good news is you are able to use all the kernel modules that came with the Linux distribution you based your build in, and not only it probably contain 98% of the kmods available to be downloaded through OpenWRT repository, it also contain much more, also, please note that apart from kmods, every other package in the official OpenWRT repo is still usable! You can install and start using them!
Let’s make your second ethernet usable (if it’s not already). Here, I’m using a Gigabit Ethernet to USB3 adapter, the ax88179_178a one. I needed to load a kernel module containing it’s driver to use it.
How do you do it? As simple as that:
modprobe ax88179_178a
I’m able to do so because inside my /lib/modules/<kernel-version> directory, there’s a kernel module named ax88179_178a.ko.
Let’s make the module load in boot time, one way to do it is to create a file inside the directory /etc/modules.d/, for example, /etc/modules.d/ax88179 in the content you put the name of the kernel module, without the .ko extension. In my case, only: ax88179_178a.
So I end up with a file, /etc/modules.d/ax88179 with the content:
ax88179_178a
With the kernel module loaded, I will now configure my eth1, then I end up with the following in /etc/config/network:
config interface 'lan'
option type 'bridge'
option ifname 'eth0'
option proto 'static'
option ipaddr '10.0.0.1'
option netmask '255.255.255.0'config interface 'wan'
option ifname 'eth1'
option proto 'dhcp'
Restart network with /etc/init.d/network restart and everything should now be working! You have made your SCB into a fully working OpenWRT router!
6. Enjoy!
That’s it, thanks for reading! If you have any question feel free to leave it in the comments.
Best!