OpenWrt on HLK-RM04

This is about compiling and installing OpenWRT on a cheap Wifi module.

Status du project
Date de début Juin 2014
Status work in progress
Initiateur Magnus

The Wifi module should be able to steer GPIO, I2C and UART peripherals.

  • Install splash screen on OpenWRT to popup its own page

After following somehow the steps on OpenWrt, I did not manage to upload the firmware image (perhaps this only works via ethernet and not via Wifi), but I managed to upload the boot loader (see BUT then the device would not boot any longer…

Connecting a serial terminal (baudrate: 57800) revealed that the kernel image has a problem, but at least the bootloader is alive. Now there is an option to upload the firmware via tftp, but this required wired ethernet – for which I did not have a cable/connector (magnetics!).

Another option would be to upload the firmware via the serial link, which ended with the following endeavour: to be continued…

Another attempt of compiling the kernel with all the relevant modules (and logging the steps):

svn co svn://
svn info
Path: .
Working Copy Root Path: /home/ptl/magnus/openwrt/trunk
URL: svn://
Repository Root: svn://
Repository UUID: 3c298f89-4303-0410-b956-a3cf2f4a3e73
Revision: 42163
Node Kind: directory
Schedule: normal
Last Changed Author: jogo
Last Changed Rev: 42162
Last Changed Date: 2014-08-13 22:49:56 +0200 (Wed, 13 Aug 2014)

NB: the version is not 38333, as suggested by JiapengLi

git clone
cd trunk
patch -p0 <../OpenWrt-HiLink-HLK-RM04/openwrt-add-support-for-hilink-hlk-rm04.patch
patch -p0 <../OpenWrt-HiLink-HLK-RM04/openwrt-hlk-rm04-firmware-tool.patch
patch -p0 <../OpenWrt-HiLink-HLK-RM04/openwrt-fix-enable-uartf-kernel-panic.patch
patch -p0 <../OpenWrt-HiLink-HLK-RM04/openwrt-rt5350-add-AP+STA-support.patch

… ignore all not accepted packages (using wrong version)

make menuconfig

OK, need another Linux machine (“Raring is EOL and no longer supported.”)…

Thanks to Erik for updating the machines (already last week, where I was busy with lua-stick). Seems that the latest OpenWRT does not need the patches anymore. It's compiling… let's see.

It compiled. This is the version:

svn info
Path: .
Working Copy Root Path: /home/ptl/magnus/openwrt/trunk
URL: svn://
Relative URL: ^/trunk
Repository Root: svn://
Repository UUID: 3c298f89-4303-0410-b956-a3cf2f4a3e73
Revision: 42305
Node Kind: directory
Schedule: normal
Last Changed Author: blogic
Last Changed Rev: 42305
Last Changed Date: 2014-08-26 15:12:12 +0200 (Tue, 26 Aug 2014)

… and this the firmware image:

 ls -l bin/ramips/openwrt-ramips-rt305x-hlk-rm04-squashfs-sysupgrade.bin 
-rw-r--r-- 1 ptl ptl 3145732 Aug 29 18:37 bin/ramips/openwrt-ramips-rt305x-hlk-rm04-squashfs-sysupgrade.bin

(note down its size)

Time to connect using kermit (apt-get install ckermit is your friend). But before set up the kermit config:

set line /dev/ttyUSB0
set speed 57600
set carrier-watch off
set handshake none
set flow-control none
set file type bin
set file name lit
set rec pack 1000
set send pack 1000
set window 5
set transmit linefeed on

Now connect:

C-Kermit 9.0.302 OPEN SOURCE:, 20 Aug 2011, for Linux+SSL+KRB5
 Copyright (C) 1985, 2011,
  Trustees of Columbia University in the City of New York.
Type ? or HELP for help.
(/home/ptl/magnus/openwrt/trunk/) C-Kermit>

Type connect <ENTER> and switch on the HLK:

(/home/ptl/magnus/openwrt/trunk/) C-Kermit>connect
Connecting to /dev/ttyUSB0, speed 57600
 Escape character: Ctrl-\ (ASCII 28, FS): enabled
Type the escape character followed by C to get back,
or followed by ? to see other options.
U-Boot 1.1.3 (Jan  9 2014 - 18:11:05)
Board: Ralink APSoC DRAM:  16 MB
relocate_code Pointer at: 80fb4000
spi_wait_nsec: 42 
spi device id: ef 40 16 0 0 (40160000)
find flash: W25Q32BV
raspi_read: from:30000 len:1000 
.*** Warning - bad CRC, using default environment
Ralink UBoot Version:
ASIC 5350_MP (Port5<->None)
DRAM_CONF_FROM: Boot-Strapping 
DRAM_SIZE: 256 Mbits
DRAM_WIDTH: 16 bits
Flash component: SPI Flash
Date:Jan  9 2014  Time:18:11:05
icache: sets:256, ways:4, linesz:32 ,total:32768
dcache: sets:128, ways:4, linesz:32 ,total:16384 
 ##### The CPU freq = 360 MHZ #### 
 estimate memory size =16 Mbytes
Please choose the operation: 
   1: Load system code to SDRAM via TFTP. 
   2: Load system code then write to Flash via TFTP. 
   3: Boot system code via Flash (default).
   4: Entr boot command line interface.
   7: Load Boot Loader code then write to Flash via Serial. 
   9: Load Boot Loader code then write to Flash via TFTP. 

… and a countdown starts. Press 4:

You choosed 4

raspi_read: from:40028 len:6 
4: System Enter Boot Command Line Interface.

U-Boot 1.1.3 (Jan  9 2014 - 18:11:05)
RT5350 # 

… and, voila, we are in the uboot shell.

Now, first erase linux:

RT5350 # erase linux

 Erase linux kernel block !!
From 0x50000 length 0x3B0000
raspi_erase: offs:50000 len:3b0000

Time for magic: change byte at address 0x207f94 to 0x3c10HHHH, and byte at address 0x207fa4 to 0x3610LLLL, where 0xHHHHLLLL is the firmware size in bytes (here: 0x00300004, see above). This is achieved by the nm command. You need to answer with y:

RT5350 # nm 207f94
00207f94: 8f8200c4 ? 3c100030
00207f94: 3c100030 ? y
RT5350 # nm 207fa4
00207fa4: 8c500000 ? 36100004
00207fa4: 36100004 ? y

Time to restart uboot:

go 00200000
## Starting application at 0x00200000 ...

… and press 4 again.

Now, upload the image:

RT5350 # loadb
## Ready for binary (kermit) download to 0x80100000 at 57600 bps...

Press Ctrl-\ c to enter kermit command mode:

(Back at saldator)
(/home/ptl/magnus/openwrt/trunk/) C-Kermit>

… and send the file…

(/home/ptl/magnus/openwrt/trunk/) C-Kermit>send bin/ramips/openwrt-ramips-rt305x-hlk-rm04-squashfs-sysupgrade.bin

a screen with transfer statistics opens to entertain you for the next some 10-15 minutes.

connect again and cp.linux the image to the flash and reset:

(/home/ptl/magnus/openwrt/trunk/) C-Kermit>connect
Connecting to /dev/ttyUSB0, speed 57600
 Escape character: Ctrl-\ (ASCII 28, FS): enabled
Type the escape character followed by C to get back,
or followed by ? to see other options.
## Total Size      = 0x00300004 = 3145732 Bytes
## Start Addr      = 0x80100000
RT5350 # cp.linux

 Copy linux image[3145732 byte] to SPI Flash[0x00050000].... 
raspi_write: to:50000 len:300004 
RT5350 # reset

… don't press 4 anymore.

Configured new system; config: TODO

Booting into the brand-new system, you may now do:

root@OpenWrt:/# i2cget -y 1 9

Connected a custom 7-segment display on the I2c and set up the HLK as access point with simple CGI script to show messages:

<header><title>OpenDisplay @ PTL</title></header>
<h1>OpenDisplay @ PTL</h1>
Enter your message here:
<form name="input" action="submit.cgi" method="post">
<tr><th colspan="8">Digit</th></tr>
  <td><input type="text" maxlength="1" size="1" name="digit1"></input></td>
  <td><input type="text" maxlength="1" size="1" name="digit2"></input></td>
  <td><input type="text" maxlength="1" size="1" name="digit3"></input></td>
  <td><input type="text" maxlength="1" size="1" name="digit4"></input></td>
  <td><input type="text" maxlength="1" size="1" name="digit5"></input></td>
  <td><input type="text" maxlength="1" size="1" name="digit6"></input></td>
  <td><input type="text" maxlength="1" size="1" name="digit7"></input></td>
  <td><input type="text" maxlength="1" size="1" name="digit8"></input></td>
<input type="submit" value="Submit"/>
echo "Content-type: text/html
  <title>Bash CGI test</title>
  Updated display... <a href="/">go back!</a>
# From:
if [ "$REQUEST_METHOD" = "POST" ]; then
    if [ "$CONTENT_LENGTH" -gt 0 ]; then
        read -n $CONTENT_LENGTH POST_DATA <&0
digit1=$(echo $POST_DATA | grep digit1 | sed 's/.*digit1=\(.\)/\1/')
digit2=$(echo $POST_DATA | grep digit2 | sed 's/.*digit2=\(.\)/\1/')
digit3=$(echo $POST_DATA | grep digit3 | sed 's/.*digit3=\(.\)/\1/')
digit4=$(echo $POST_DATA | grep digit4 | sed 's/.*digit4=\(.\)/\1/')
digit5=$(echo $POST_DATA | grep digit5 | sed 's/.*digit5=\(.\)/\1/')
digit6=$(echo $POST_DATA | grep digit6 | sed 's/.*digit6=\(.\)/\1/')
digit7=$(echo $POST_DATA | grep digit7 | sed 's/.*digit7=\(.\)/\1/')
digit8=$(echo $POST_DATA | grep digit8 | sed 's/.*digit8=\(.\)/\1/')
digit1=$(printf "%d" "'$digit1")
digit2=$(printf "%d" "'$digit2")
digit3=$(printf "%d" "'$digit3")
digit4=$(printf "%d" "'$digit4")
digit5=$(printf "%d" "'$digit5")
digit6=$(printf "%d" "'$digit6")
digit7=$(printf "%d" "'$digit7")
digit8=$(printf "%d" "'$digit8")
i2cset -y 1 16 $digit1
i2cset -y 1 17 $digit2
i2cset -y 1 18 $digit3
i2cset -y 1 19 $digit4
i2cset -y 1 20 $digit5
i2cset -y 1 21 $digit6
i2cset -y 1 22 $digit7
i2cset -y 1 23 $digit8

Some config stuff in /etc/config/uhttpd write at the appropriate place:

  list interpreter ".cgi=/bin/sh"

And this is for (widely open) WiFi:

config wifi-device  radio0
        option type     mac80211
        option channel  11
        option hwmode   11g
        option path     '10180000.wmac'
        option htmode   HT20
config wifi-iface
        option device   radio0
        option network  lan
        option mode     ap
        option ssid     OpenDisplay
        option encryption none

In action:

  1. Connect to the OpenDisplay WiFi network:
  2. Open in your browser and enter message:
  3. Et voila!

The display now features a “captive portal” (see for instructions) as well as a jquery mobile jQuery Mobile UI.

A few captures with an USBSeeAX PRO (not yet updated) show the 8 characters being transmitted on the I2C: As well as a detail of the first transaction: (still at “only” 24 MSPS) ;-)

“Installation” in the space: Feel free to use it! It's an open WiFi hotspot called “OpenDisplay”.

<doodle |[openwrt_on_hlk-rm04] Interested in joining this project>

participation active participation passive suivre de loins


  • projects/openwrt_on_hlk-rm04.txt
  • Dernière modification: 2014/11/05 17:48
  • de magnustron