Adding new device support

This article assumes your device is based on a platform already supported by OpenWrt. If you need to add a new platform, see →

General Approach

  1. Make a detailed list of chips on the device and find into about support for them. Focus on processor, flash, ethernet and wireless. Some helpful tips are available on hw.hacking.first.steps
  2. Make sure you have working serial console and access to the bootloader.
  3. Prepare and install firmware, watch the bootlog for problems and errors.
  4. Verify flash partitioning, LEDs and buttons.


Most of devices use GPIOs for controlling LEDs and buttons. There aren't any generic GPIOs numbers, so OpenWrt has to use device specific mappings. It means we need to find out GPIOs for every controllable LED and button on every supported device.


If LED is controlled by GPIO, direction has to be set to out. Polarity on the other hand may vary, some LEDs may be activated with "0" value, some with "1". It means info about polarity has also to be part of OpenWrt GPIOs database.

A single GPIO can be tested in the following way:

cd /sys/class/gpio
echo $GPIO > export
echo "out" > gpio$GPIO/direction
echo 0 > gpio$GPIO/value
sleep 1s
echo 1 > gpio$GPIO/value
sleep 1s
echo $GPIO > unexport

Of course every GPIO (starting with 0) has to be tested, not only a GPIO 3 as in the example above.

If LED state changes (turns ON or OFF) after changing value, it means it's controlled by the currently tested GPIO.

  • If LED turns on for value 1, it's active high
  • If LED turns on for value 0, it's active low

So basically you need to create a table like:

Name GPIO Polarity
Power 0 Active high
WLAN 7 Active high
USB 12 Active low

To speed up testing all GPIOs one by one you can use following bash script:

NGPIO=$(cat /sys/class/gpio/gpiochip0/ngpio)
while [ $GPIO -lt $NGPIO ] ; do
	echo $GPIO > /sys/class/gpio/export
	echo out > /sys/class/gpio/gpio$GPIO/direction

	echo "[GPIO$GPIO] Trying value 0"
	echo 0 > /sys/class/gpio/gpio$GPIO/value
	sleep 3s

	echo "[GPIO$GPIO] Trying value 1"
	echo 1 > /sys/class/gpio/gpio$GPIO/value
	sleep 3s

	echo $GPIO > /sys/class/gpio/unexport

GPIO buttons

In case of GPIO controlled buttons value changes during button press. So the best idea to find out which GPIO is connected to some hardware button is to:

  1. Dump values of all GPIOs
  2. Push button and keep it pushed
  3. Dump values of all GPIOs
  4. Find out which GPIO changed its value

For dumping GPIO values following script can be used:

NGPIO=$(cat /sys/class/gpio/gpiochip0/ngpio)
while [ $GPIO -lt $NGPIO ] ; do
	echo $GPIO > /sys/class/gpio/export
	echo in > /sys/class/gpio/gpio$GPIO/direction
	echo "[GPIO$GPIO] value $(cat /sys/class/gpio/gpio$GPIO/value)"
	echo $GPIO > /sys/class/gpio/unexport


Brcm63xx Platform

If you have the OEM sourcecode for your bcm63xx specific device, it may be useful some things for later adding the OpenWrt support:

  • Look for your Board Id at shared/opensource/boardparms/boardparms.c
  • Adapt the imagetag.c to create a different tag (see shared/opensource/inlude/bcm963xx/bcmTag.h in the GPL tar for the layout)
  • Finally xor the whole image with '12345678' (the ascii string, not hex).


For creating the OpenWrt firmware your bcm63xx device, you can follow the following steps:

  1. Obtain the source and follow the compile procudure with the make menuconfig as last step.
  2. During menuconfig select the correct target system.
  3. Next generate the board_bcm963xx.c file for the selected platform with all board parameters execute the following command:
    make kernel_menuconfig
  4. Add the board-id to the ./target/linux/brcm63xx/image/Makefile.
    	# Davolink DV2020	
    	$(call Image/Build/CFE,$(1),DV2020,6348)
  5. add the board-id with the parameters to ./build_dir/linux-brcm63xx/linux-
    static struct board_info __initdata board_DV2020 = {
            .name                           = "DV2020",
            .expected_cpu_id                = 0x6348,
            .has_uart0                      = 1,
            .has_pci                        = 1,
            .has_ohci0                      = 1,
            .has_enet0                      = 1,
            .has_enet1                      = 1,
            .enet0 = {
                    .has_phy                = 1,
                    .use_internal_phy       = 1,
            .enet1 = {	
                    .force_speed_100        = 1,	
                    .force_duplex_full      = 1,	
    static const struct board_info __initdat
  6. Finish the compile instructions according the procedure from the make step.

Ramips Platform

As long as you are adding support for an ramips board with an existing chipset, this is rather straightforward. You need to create a new board definition, which will generate an image file specifically for your device and runs device-specific code. Then you write various board-specific hacks to initialize devices and set the correct default configuration.

Your board identifier will be passed in the following sequence:

 (Image Generator puts it in the kernel command line)
 (Kernel command line is executed with BOARD=MY_BOARD)
 (Kernel code for ramips finds your board and loads machine-specific code)
 (/lib/ reads the board name from /proc/cpuinfo)
 (Several userspace scripts use ramips_board_name() for board-specific setup)

At a minimum, you need to make the following changes to make a basic build, all under target/linux/ramips/:

  • Add a new machine image in image/Makefile
  • Create a new machine file in arch/mips/ralink/$CHIP/mach-myboard.c where you register:
    • GPIO pins for LEDs and buttons
    • Port layout for the device (vlan configuration)
    • Flash memory configuration
    • Wifi
    • USB
    • Watchdog timer
    • And anything else specific to your board
  • Reference the new machine file in arch/mips/ralink/$CHIP/{Kconfig,Makefile}
  • Reference the new machine name in files/arch/mips/include/asm/mach-ralink/machine.h
  • Add your board to base-files/lib/ for userspace scripts to read the board name

Then you'll want to modify some of these files depending on your board's features:

  • base-files/etc/ to set a LED which OpenWRT should blink on bootup
  • base-files/lib/upgrade/ to allow sysupgrade to work on your board
  • base-files/etc/uci-defaults/network to configure default network interface settings, particularly MAC addresses
  • base-files/etc/uci-defaults/leds if you have configurable LEDs which should default to a behavior, like a WLAN activity LED
  • base-files/etc/hotplug.d/firmware/10-rt2x00-eeprom to extract the firmware image for the wireless module
  • base-files/lib/preinit/06_set_iface_mac to set the MAC addresses of any other interfaces

Example commits:


After add a new board, you may should clean the tmp folder first.

 cd trunk
 rm -rf tmp
 make menuconfig 

Back to top

doc/devel/ · Last modified: 2014/09/01 03:51 by sunny