Improved HLK-RM04 bootloader

HLK-RM04 moduleAbout the module

RT5350 based HLK-RM04 board is a small and cheap embedded module which can run OpenWrt. As it contains GPIOs, UART, I2C, USB host, WiFi and 100BASE-TX it's a good option for Internet of Things (IoT) devices.

Updating firmware

The most common method to transfer new firmware to the board is to use TFTP protocol over ethernet connection. But when the module is used in projects without Ethernet sockets it's firmware can be updated only through serial line. You should enter the bootloader console and issue several commands, providing correct addresses and sizes. Example:

erase 0xXXXXXXXX +0xXXXX
loadb 0xXXXXXXX
bootm 0xXXXXXXXX

Any mistake can make the module bricked.

Improved bootloader

I've been using the HLK-RM04 board in several home automation projects and created improved version of bootloader for it.
There is now new shortcut in the boot menu - "Load system code then write to Flash via Serial". Just press "0" when prompted and upload new firmware using kermit protocol.
See the boot log for details (New option highlighted with red color):

U-Boot 1.1.3 (Dec  7 2014 - 00:31:38)

Board: Ralink APSoC DRAM:  32 MB
relocate_code Pointer at: 81fb4000
spi_wait_nsec: 21 
spi device id: ef 40 18 0 0 (40180000)
find flash: W25Q128
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:Dec  7 2014  Time:00:31:38
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 =32 Mbytes

Please choose the operation: 
   0: Load system code then write to Flash via Serial. 
   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. 

You choosed 0

raspi_read: from:40028 len:6 
0: System Load Linux Kernel then write to Flash via Serial. 
## Ready for binary (kermit) download to 0x80100000 at 57600 bps...

And after kermit upload is done (transfer rate is about 4-5Kb/s, so uploading 3.5Mb firmware takes 10-15 minutes):

Load address: 0x80100000
Write address: 0x50000
Size: 3407876
Max system size: 16449536
raspi_erase_write: offs:50000, count:340004
raspi_erase: offs:50000 len:340000
raspi_write: to:50000 len:340000 
raspi_read: from:50000 len:10000 
.raspi_read: from:60000 len:10000 
.raspi_read: from:70000 len:10000 
.raspi_read: from:80000 len:10000 
.raspi_read: from:90000 len:10000 
.raspi_read: from:a0000 len:10000 
.raspi_read: from:b0000 len:10000 
.raspi_read: from:c0000 len:10000 
.raspi_read: from:d0000 len:10000 
.raspi_read: from:e0000 len:10000 
.raspi_read: from:f0000 len:10000 
.raspi_read: from:100000 len:10000 
.raspi_read: from:110000 len:10000 
.raspi_read: from:120000 len:10000 
.raspi_read: from:130000 len:10000 
.raspi_read: from:140000 len:10000 
.raspi_read: from:150000 len:10000 
.raspi_read: from:160000 len:10000 
.raspi_read: from:170000 len:10000 
.raspi_read: from:180000 len:10000 
.raspi_read: from:190000 len:10000 
.raspi_read: from:1a0000 len:10000 
.raspi_read: from:1b0000 len:10000 
.raspi_read: from:1c0000 len:10000 
.raspi_read: from:1d0000 len:10000 
.raspi_read: from:1e0000 len:10000 
.raspi_read: from:1f0000 len:10000 
.raspi_read: from:200000 len:10000 
.raspi_read: from:210000 len:10000 
.raspi_read: from:220000 len:10000 
.raspi_read: from:230000 len:10000 
.raspi_read: from:240000 len:10000 
.raspi_read: from:250000 len:10000 
.raspi_read: from:260000 len:10000 
.raspi_read: from:270000 len:10000 
.raspi_read: from:280000 len:10000 
.raspi_read: from:290000 len:10000 
.raspi_read: from:2a0000 len:10000 
.raspi_read: from:2b0000 len:10000 
.raspi_read: from:2c0000 len:10000 
.raspi_read: from:2d0000 len:10000 
.raspi_read: from:2e0000 len:10000 
.raspi_read: from:2f0000 len:10000 
.raspi_read: from:300000 len:10000 
.raspi_read: from:310000 len:10000 
.raspi_read: from:320000 len:10000 
.raspi_read: from:330000 len:10000 
.raspi_read: from:340000 len:10000 
.raspi_read: from:350000 len:10000 
.raspi_read: from:360000 len:10000 
.raspi_read: from:370000 len:10000 
.raspi_read: from:380000 len:10000 
.raspi_read: from:390000 len:10000 
.raspi_erase: offs:390000 len:10000
raspi_write: to:390000 len:10000 
raspi_read: from:390000 len:10000 
## Booting image at bc050000 ...
raspi_read: from:50000 len:40 
.   Image Name:   HLK-RM02
   Created:      2014-10-02   7:21:50 UTC
   Image Type:   MIPS Linux Kernel Image (lzma compressed)
   Data Size:    1054882 Bytes =  1 MB
   Load Address: 80000000
   Entry Point:  80000000
raspi_read: from:50040 len:1018a2 
.................   Verifying Checksum ... OK
   Uncompressing Kernel Image ... OK
No initrd
## Transferring control to Linux (at address 80000000) ...
## Giving linux memsize in MB, 32

Starting kernel ...

[    0.000000] Linux version 3.10.49 (bb@builder1) (gcc version 4.8.3 (OpenWrt/Linaro GCC 4.8-2014.04 r42625) ) #3 Wed Oct 1 16:33:08 CEST 2014


Precompiled bootloader download

md5 checksum 24807933492b5a1b85d060fb33f173b8
For installation tips and tricks read the HLK-RM04 OpenWrt Wiki page.

How to compile the code

MIPS gcc toolchain version 3.42 is required to build this bootloader. Newer versions of toolchain will produce errors and are not recommended.

Obtaining toolchain

Go to the, select DCS 933L model and download "GPL Source Code" archive. The toolchain is in "toolchain/buildroot-gcc342.tar.bz2". Unpack the "buildroot-gcc342.tar.bz2" into "/opt" (easy way) or anywhere else.


First checkout sources

git clone

If you installed the toolchain in /opt/buildroot-gcc342/ just run


The resulting image is placed in the root directory and is called uboot.img

To adjust build settings including toolchain location run

make menuconfig

Notes on RAM

The bootloader supports boards with both 16M and 32M of RAM. Installed amount of RAM is detected automatically and this value is passed to OpenWrt kernel.

Supported flash chips

Current build of the bootloader supports the following flash chips:

Vendor Chip ID, JEDEC ID Size
Atmel AT25DF321 0x1f, 0x47000000 4M
  AT26DF161 0x1f, 0x46000000 2M
Spansion FL016AIF 0x01, 0x02140000 2M
  FL064AIF 0x01, 0x02160000 8M
Macronix MX25L1605D 0xc2, 0x2015c220 2M
  MX25L3205D 0xc2, 0x2016c220 4M
  MX25L6405D 0xc2, 0x2017c220 8M
  MX25L12805D 0xc2, 0x2018c220 16M
 Spansion S25FL128P 0x01, 0x20180301 16M
  S25FL129P 0x01, 0x20184D01 16M
  S25FL032P 0x01, 0x02154D00 4M
  S25FL064P 0x01, 0x02164D00 8M
Eon EN25F16 0x1c, 0x31151c31 2M
  EN25F32 0x1c, 0x31161c31 4M
Winbond W25Q32BV 0xef, 0x40160000 4M
  W25X16 0xef, 0x30150000 2M
  W25X32 0xef, 0x30160000 4M
  W25Q32DW 0xef, 0x60160000 4M
  W25X64 0xef, 0x30170000 8M
  W25Q64 0xef, 0x40170000 8M
  W25Q128 0xef, 0x40180000 16M

How to add support for more flash chips

Append the appropriate entry to the "chip_data" array in the source file "drivers/spi_flash.c" and recompile the bootloader.


Build and update the bootloader at your own risk! If the bootloader gets broken your board will not boot at all. In this case the only option is to desolder the flash chip and use external programmer to restore the original bootloader from backup.




i hava an hlk rm04 i have used at once with the openwrt from u r site of installation guide lines. its working good.

now i need to boot and add a new firmware to my hlkrm04 module its get bricked on
i need a help to overcome this scenario of bricking please help me to upgrade my firm ware.

Add new comment