Onion Omega2 Kernel Compilation

Onion is probably the only company who manages MT7688AN SoC firmware otherwise completely abandoned by MediaTek. Without their effort, either you have to stick with OpenWrt 15.05 or you have to struggle with the issues of porting current version of OpenWrt on this platform.

Among other things, sub-optimal performance and instability of the open source MT76 WiFi driver should be addressed. Onion version of OpenWrt not only solves this issue, it comes with tons of useful additions, not to mention their impressive documentation and online community support. This is my personal exercise to build Omega 2 flavour of OpenWrt 18 using their source.

Clone the source from the Onion’s repository. The github repository has three branches and by default openwrt-18.06 branch will be selected. As of this writing however current official build is still based on lede-17.01 branch. This is not correct. New version are based on openwrt-18.06 and official built images and packages are hosted in a new location.

Thus to work on the OpenWrt 18.06 version:

git clone https://github.com/OnionIoT/source.git
cd source
git log --grep "b218:"
git checkout adfead5c -b build218
sh scripts/onion-feed-setup.sh
git checkout .config
sh scripts/onion-minimal-build.sh
make -j

To work on the most recent official previous build (lede 17 – b202 or older) instead:

git clone https://github.com/OnionIoT/source.git
cd source
git checkout lede-17.01 -b build202
sh scripts/onion-feed-setup.sh
git checkout .config
sh scripts/onion-minimal-build.sh
make -j

This build is based on LEDE 17. Thus if your host system is Ubuntu 18.04 then it is not recommended to recover the .config file, which is likely to introduce compilation errors.

I2C Bit Banging Driver for LinkIt Smart 7688

I2C peripheral in LinkIt Smart 7688 works most of the cases. But it has some issues with devices that respond with NACK frequently. In such cases, you can replace the kernel driver that utilises internal I2C peripheral with a bitbanging driver that emulates I2C using GPIOs.

LinkIt Smart 7688 has most of the GPIOs allocated for peripherals such as I2C, SPI, UARTs. So let’s switch the ports allocated to I2C to GPIOs first. This can be done by directly manipulating the corresponding multiplexer.

Linux DEVMEN (/dev/mem) virtual driver allows this manipulation by exposing memory mapped port control registers. Run make menuconfig and select: Global build settings > Kernel build options > /dev/mem virtual device support.

This will create a /dev/mem driver at the target machine. You can write a simple script or you can use omega2-ctrl utility to control the multiplexers. Usage of the utility can be found here. What you want to is to set the GPIO4 pin and GPIO5 pin under the control of GPIO logic.

# omega2-ctrl gpiomux set i2c gpio

Nex, you need a set of drivers for the bitbanging of I2C. Run make menuconfig and select followings under Kernel modules > I2C support >

  • kmod-i2c-core
  • kmod-i2c-algo-bit
  • kmod-i2c-gpio
  • kmod-i2c-gpio-custom

Due to the dependencies, you choose the last one then all the others should follow. You can install them as separate kernel modules or you can select all the modules to be included in the kernel except the last one. You have to specify the GPIO pins for the I2C bitbanging by manually calling insmod

# insmod i2c-gpio-custom bus0=0,5,4

Note that actual driver (/dev/i2c-0) won’t be populated until the above driver is loaded. After that you can use i2cdetect command to check if it is actually working.

Connecting LinkIt Smart 7688 to internet via Wi-Fi

In this post, we will assume that you want to use Wi-Fi to connect your device to the internet. This can be the situation when you build a WiFi enabled IoT device using LinkIt Smart 7688.

Alternatively you can use this mode to create a device that connects to your main AP through WiFi, while provides an internet access to other devices through Ethernet. This is the reverse configuration of the dumb AP mode discussed before.

In OpenWrt term, this is WiFi Extender or Repeater or Bridge Configuration. This mode is not supported by the default settings of OpenWrt. Main reason is that WiFi driver does not support bridging when it is in client (station) mode. Thus you need an additional service from the package named relayd. Please check previous post for the instruction how to install this package and others (luci-proto-relay).

In this page, you can find detailed instruction for setting up this mode, both using LuCI and CLI. Here again we summarise the process using CLI. There are some differences as well.

First change the subnet address of lan, which might be optional but just for the sake of safety.

# uci set network.lan.ipaddr='192.168.2.1'

Create a relay network for the bridging between lan and the WiFi (wwan) which will be in station mode. This will bind lan and wwan.

# uci set network.repeater_bridge=interface
# uci set network.repeater_bridge.proto='relay'
# uci set network.repeater_bridge.network='lan wwan'

Then create a network wwan and run DHCP on it, so that the device can connect to the main AP via WiFi.

# uci set network.wwan=interface
# uci set network.wwan.proto='dhcp'

Add all network to the firewall zone

# uci set firewall.@zone[0].network='lan repeater_bridge wwan'

But prevent DHCP from running on lan network.

# uci set dhcp.lan.ignore='1'

Now, according to the OpenWrt document, you need to create a new wireless interface for wwan and set it to station mode. However for some reason creating a second interface is not allowed in MT7688. So we turn the first interface into this role instead.

# uci set wireless.default_radio0.mode='sta'
# uci set wireless.default_radio0.network='wwan'
# uci set wireless.default_radio0.ssid='your AP SSID'
# uci set wireless.default_radio0.bssid='your AP BSSID'
# uci set wireless.default_radio0.encryption='psk2'
# uci set wireless.default_radio0.key='your super secret key'

Do not forget to activate radio0 device if not done already.

# uci set wireless.radio0.disabled='0'

You may need BSSID of the target AP in the above step. To check it run following commands

# iw dev wlan0 scan > /root/ap_list
# vi /root/ap_list

Connecting LinkIt Smart 7688 to internet via Ethernet

If you want to set up the LinkIt Smart 7688 as an IoT device, and if you want to use its Ethernet port for the uplink connection, i.e., connection to the main router or to the modem, then this is the setting you will have.

Alternatively if you have an Ethernet only router and want to have an AP (access point) to the router then this is the setting as its name means. OpenWrt keeps a very good document for this setting.

In this mode the device receives its IPv4 address from the main routher through Ethernet port (eth0), while the WiFi (wlan0) creates an AP of its own. Relation between eth0 and wlan0 is direct and transparent to any WiFi devices that are attached to the AP. So the dumb AP.

Let us assume that a subnet 192.160.0.x is created by the main router. When the MT7688 device is connected to the router, it receives an IP address, say 192.168.0.24 through eth0, becomes the address of the lan. This address will be advertised as the address of the AP by wlan0 as well.

Setting up process can be done via LuCI. But here we use uci, whose documentation can be found here. Just follow the procedure here. Followings are the summary.

First change the network protocol for lan to dhcp.

# uci set network.lan.proto=dhcp

Disable and stop dnsmasq service.

# /etc/init.d/dnsmasq disable
# /etc/init.d/dnsmasq stop

We do not need DHCPv6 on lan either. After the change, commit it.

# uci set dhcp.lan.dhcpv6=disabled
# uci set dhcp.lan.ra=disabled
# uci commit

Further disable and stop firewall.

# /etc/init.d/firewall diable
# /etc/init.d/firewall stop

Apply the change and restart network. If necessary reboot the device

# /etc/init.d/network reload

At this point, if you plug the device into the main router. It works as an Ethernet enabled device, while WiFi is disabled by default. Thus it is the desired state as an IoT device with Ethernet.

If you want instead to set it as a AP, then just bring up the wlan0.

# uci set wireless.radio0.disabled=0
# wifi

Install OpenWrt v.18.06 on LinkIt Smart 7688

LinkIt Smart 7688 is an affordable platform that runs OpenWrt. Original firmware released by MediaTek is based on OpenWrt v15. Many of packages such as node or npm are not very useful. Besides it is quite bloated.

Until recently upgrading OpenWrt version of this device was not easy due to lack of support from MediaTek especially in the Wi-Fi driver. That has been changed recently as new OpenWrt v18 is announced.

Building firmware is painless and fast. And it comes with an open source Wi-Fi driver (mt76) replacing out-dated MediaTek driver, which works quite well.

Start with cloning the source and check out one of the tagged version:

git clone https://github.com/openwrt/openwrt.git
git checkout v18.06.2 -b testing

You can choose to work with the most recent checkout. However if you chose to use one of the versions for which OpenWrt maintains package repositories then you can simply download the precompiled packages from the repository.

Process of firmware building is well documented here. You may need to install some libraries and utilities. After the initial setup (installing feeds) is done, run menuconfig. Then choose following options for the target system:

  • Target System: MediaTek Ralink MIPS
  • Subtarget: MT76x8 based board
  • Target Profile: MediaTek LinkIt Smart 7688

For the other settings, you may want to include LuCI at least. Other default settings may fit your purpose or may not. In my case, I choose following components additionally:

  • Kernel modules -> I2C support -> kmod-i2c-mt7628
  • Language -> Perl -> perl
  • Libraries -> libavahi-client
  • LuCI -> collections -> luci
  • LuCI -> Protocols -> luci-proto-relay
  • Network -> Routing and Redirection -> relayd

Build speed is a lot faster than v15. For the latter, you need to install Ubuntu 14.04 first as a host system, otherwise the process will break at many points.

To update the firmware you can use Web interface (LuCI) or USB thumb drive. Check this page for the instruction when you are upgrading from old MediaTek firmware. After the upgrade, it depends on the new firmware, which may be different from the old one. Likewise if you upgraded the bootloader, your booting process and firmware upgrade method via bootloader may change as well.

Bear in mind that when you use the USB drive to update, the file name must be lks7688.img for the firmware and lks7688.ldr for the bootloader. Otherwise it is not recognised.

You may find it useful to have a terminal on a UART channel until network setup is finished, baudrate of which is set to 57600 not 115200.

By default, WiFi interface is not activated. You can bring it up by:

# uci set wireless.radio0.disabled=0
# wifi

If you for some reason want to do factory reset, run commands below. If console is not working then perform fail-safe boot by clicking the MPU reset button then entering ‘f’ key followed by ‘enter’ key when asked during the boot process.

firstboot
reboot