Debugging ESP32 with JTAG Adapter on Linux
Although Espressif’s website provides detailed instructions, this post offers a quick overview on steps required to setup a JTAG debugger adapter for ESP32 NodeMCU development board on Linux platform.
Why JTAG
JTAG (Joint Test Action Group) is a useful interface for debugging and programming electronic devices such as microcontrollers and digital signal processors for several reasons:
- Non-Intrusive: JTAG is a non-intrusive interface, meaning it can be used to test and debug a device without affecting its normal operation. It provides a way to access the internal circuitry of a device, which is typically not accessible through other interfaces.
- Boundary Scan: JTAG includes a feature called boundary scan that allows designers to test and debug connections on printed circuit boards (PCBs). The boundary scan feature allows to test and diagnose problems with individual components or connection.
- In-System Programming: JTAG can be used to program a device while it is still mounted on a PCB or other system, which is known as in-system programming. This can be useful for updating firmware or debug device without needing to remove it from the system.
- Standardized Protocol: JTAG uses a standardized protocol defined by the IEEE 1149.1 standard, which ensures compatibility between devices and tools from different manufacturers.
- Semi-hosting: Provides a access to Host Resources, redirect “printf” or access to files on the host system as if they were on the local device, making it easier to test and debug software that relies on file input/output.
- Low-Cost: JTAG is a low-cost interface that is widely available on many microcontrollers and other electronic devices. This makes it a popular choice for developers and engineers who need to test and debug electronic systems.
Prerequisites
- Linux host machine, in my case Linux Mint 21.1 distribution is adopted, but any modern Linux distribution should work.
- OpenOCD compatible JTAG debugger hadware, in my case FT2232D that was left over from a previous plug computer project. https://globalscaletechnologies.com/product/gti-jtag-probe/
Reference design for this JTAG interface and connection schematics: https://www.netquote.it/nqmain/wp-content/uploads/SheevaPlug.pdf - Esp32 NodeMCU development board: https://wiki.geekworm.com/NodeMCU-32S
https://www.espressif.com/sites/default/files/documentation/esp32-wroom-32_datasheet_en.pdf
Setup OpenOCD
Because the version of OpenOCD available in this Linux release is outdated and lacks Xtensa support, install the latest release from the official repository: https://openocd.org/pages/getting-openocd.html
For detailed instruction on howto build and install OpenOCD: https://openocd.org/doc-release/README
~/esp32$ git clone https://git.code.sf.net/p/openocd/code openocd-code
Cloning into 'openocd-code'...
remote: Enumerating objects: 77625, done.
...
Resolving deltas: 100% (64682/64682), done.
Run “./bootstrap” when building from the git repository
~/esp32$ cd openocd-code/
~/esp32/openocd-code$ ./bootstrap
+ aclocal --warnings=all
+ libtoolize --automake --copy
+ autoconf --warnings=all
...
libjaylink/Makefile.am: installing 'build-aux/depcomp'
Bootstrap complete. Quick build instructions:
./configure ....
Now we can set some build options like hardware interface support, verbosity, installation directories and disable/enable other features.
~/esp32/openocd-code$ ./configure --enable-ftdi
checking for makeinfo... no
configure: WARNING: Info documentation will not be built.
checking for a BSD-compatible install... /usr/bin/install -c
checking whether build environment is sane... yes
...
OpenOCD configuration summary
--------------------------------------------------
MPSSE mode of FTDI based devices yes
ST-Link Programmer yes (auto)
TI ICDI JTAG Programmer yes (auto)
Keil ULINK JTAG Programmer yes (auto)
Altera USB-Blaster II Compatible yes (auto)
Bitbang mode of FT232R based devices yes (auto)
Versaloon-Link JTAG Programmer yes (auto)
TI XDS110 Debug Probe yes (auto)
CMSIS-DAP v2 Compliant Debugger yes (auto)
OSBDM (JTAG only) Programmer yes (auto)
eStick/opendous JTAG Programmer yes (auto)
Olimex ARM-JTAG-EW Programmer yes (auto)
Raisonance RLink JTAG Programmer yes (auto)
USBProg JTAG Programmer yes (auto)
Espressif JTAG Programmer yes (auto)
CMSIS-DAP Compliant Debugger no
Nu-Link Programmer no
Cypress KitProg Programmer no
Altera USB-Blaster Compatible yes (auto)
ASIX Presto Adapter yes (auto)
OpenJTAG Adapter yes (auto)
Linux GPIO bitbang through libgpiod no
SEGGER J-Link Programmer no
Bus Pirate yes (auto)
Use Capstone disassembly framework yes (auto)
Then make and install as usual, be careful about conflicts with existing OpenOCD installation, remove or add prefix/suffix to the new OpenOCD executable.
~/esp32/openocd-code$ make -j16
...
~/esp32/openocd-code$ sudo make install
...
Add udev rules:
~/esp32/openocd-code$ nano /etc/udev/rules.d/10-ft2322D_jtag.rules
UBSYSTEMS=="usb", ATTRS{idVendor}=="9e88", ATTRS{idProduct}=="9e8f", MODE="0666"
Add user to dialout group:
~/esp32/openocd-code$ sudo usermod -aG dialout $USER
JTAG connections:
| ESP32 pin | JTAG pin | #J6 |
|---|---|---|
| 3V3 | VTRef (3.3V) | 1 |
| EN | JT_SRSTn | 3 |
| GPIO12 | JT_TDI | 5 |
| GPIO14 | JT_TMS_CPU | 7 |
| GPIO13 | JT_CLK | 9 |
| GPIO15 | JT_TDO | 13 |
| GND | GND | 20 |

Detailed description for JTAG configuration can be found on this page: https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-guides/jtag-debugging/configure-other-jtag.html
For ESP32 pinout refer to this page: https://www.studiopieters.nl/esp32-pinout/
OpenOCD Configuration and Testing
Now if we run openocd binary we will se somethink like this:
~/esp32/bare_v1$ openocd
Open On-Chip Debugger v0.11.0-esp32-20221026 (2022-10-26-14:47)
Licensed under GNU GPL v2
For bug reports, read
http://openocd.org/doc/doxygen/bugs.html
embedded:startup.tcl:28: Error: Can't find openocd.cfg
in procedure 'script'
at file "embedded:startup.tcl", line 28
Info : Listening on port 6666 for tcl connections
Info : Listening on port 4444 for telnet connections
Error: Debug Adapter has to be specified, see "adapter driver" command
embedded:startup.tcl:28: Error:
in procedure 'script'
at file "embedded:startup.tcl", line 28
This error, because of unknown adapter. We need to instruct OpenOCD about our hardware interface and target. This can be done by creating a configuration file named ‘esp32_jtag.cfg’ with next settings:
# FT2232D JTAG Adapter Configuration
adapter driver ftdi
ftdi device_desc "SheevaPlug JTAGKey FT2232D B"
ftdi vid_pid 0x9e88 0x9e8f
ftdi channel 0
ftdi layout_init 0x0608 0x0f1b
ftdi layout_signal nTRST -data 0x0200 -noe 0x0100
ftdi layout_signal nSRST -data 0x0800 -noe 0x0400
# The speed of the JTAG interface, in kHz. If you get DSR/DIR errors (and they
# do not relate to OpenOCD trying to read from a memory range without physical
# memory being present there), you can try lowering this.
#
# On DevKit-J, this can go as high as 20MHz if CPU frequency is 80MHz, or 26MHz
# if CPU frequency is 160MHz or 240MHz.
adapter speed 1000
# flash 3.3 V for ESP32-WROOM-32
set ESP32_FLASH_VOLTAGE 3.3
# Load esp32 target configuration
source [find target/esp32.cfg]
You can find a list of available interfaces and targets in the ‘openocd-code/tcl’ folder.
Running JTAG debugger
After launching the debugger, we should see something like this:
~/esp32$ openocd -f esp32_jtag.cfg
Open On-Chip Debugger 0.12.0+dev-00078-gfc30feb51 (2023-03-11-15:26)
Licensed under GNU GPL v2
For bug reports, read
http://openocd.org/doc/doxygen/bugs.html
force hard breakpoints
Info : Listening on port 6666 for tcl connections
Info : Listening on port 4444 for telnet connections
Info : clock speed 1000 kHz
Info : JTAG tap: esp32.cpu0 tap/device found: 0x120034e5 (mfg: 0x272 (Tensilica), part: 0x2003, ver: 0x1)
Info : JTAG tap: esp32.cpu1 tap/device found: 0x120034e5 (mfg: 0x272 (Tensilica), part: 0x2003, ver: 0x1)
Info : starting gdb server for esp32.cpu0 on 3333
Info : Listening on port 3333 for gdb connections
Info : Set GDB target to 'esp32.cpu0'
Open your favorite telnet console on localhost at port 4444
~$ telnet localhost 4444
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
Open On-Chip Debugger
> help
...
Brief command list:
| Command | Description |
| help [command_name] | Show full command help; command can be multiple tokens. (command valid any time) |
| version | show program version (command valid any time) |
| reset [run|halt|init] | Reset all targets into the specified mode. Default reset mode is run, if not given. |
| halt [milliseconds] | request target to halt, then wait up to the specified number of milliseconds (default 5000) for it to complete |
| targets [target] | change current default target (one parameter) or prints table of all targets (no parameters) (command valid any time) |
| flash banks | Display table with information about flash banks. (command valid any time) |
| reg [(number|name)] reg [(value|’force’)] | display (reread from target with “force”) or set a register; with no arguments, displays all registers and their values |
| resume [address] | resume target execution from current PC or address |
| scan_chain | print current scan chain configuration (command valid any time) script |
| shutdown | Close the OpenOCD server, disconnecting all clients (GDB, telnet, other). If option error is used, OpenOCD will return a non-zero exit code to the parent process. If user types CTRL-C or kills OpenOCD, the command shutdown will be automati- cally executed to cause OpenOCD to exit. |
| arm semihosting [‘enable’|’disable’] | Set the base directory for semihosting I/O.DEPRECATED! use arm activate support for semihosting operations |
| arm semihosting_basedir [dir] | set the base directory for semihosting I/O operations |
| arm semihosting_fileio [‘enable’|’disable’] | activate support for semihosting fileio operations |
| arm semihosting_redirect (disable | tcp [‘debug’|’stdio’|’all’]) | redirect semihosting IO |
| init | Initializes configured targets and servers. Changes command mode from CONFIG to EXEC. Unless ‘noinit’ is called, this command is called automatically at the end of startup. (command valid any time) |
RTL-SDR decoding digital voice
Another great tool for RTL dongle is “Digital Speech Decoder”: https://github.com/szechyjs/dsd
Installation instructions: https://github.com/szechyjs/dsd/wiki/Installation
# Save to wave file
$ socat stdout udp-listen:7355 | dsd -i - -w voice.wav
# Real-time voice decoding
$ socat stdout udp-listen:7355 | padsp dsd -i -
# Command line variant
rtl_fm -f 430.785M -M fm -s 70K -r 48K -E dc | padsp dsd -fr -i -
Tutorial: https://www.rtl-sdr.com/rtl-sdr-radio-scanner-tutorial-decoding-digital-voice-p25-with-dsd/
Rewritten decoder library: https://github.com/f4exb/dsdcc
Siglent oscilloscope USB connection Linux and Python
Simple way to connect Siglent Oscilloscope to your Linux PC is PyVisa package and USB interface.
Install PyVisa lib for python: https://pyvisa.readthedocs.io/en/latest/introduction/getting.html
Add permission for USB oscilloscope device:
$ sudo nano /etc/udev/rules.d/99-siglent.rules
SUBSYSTEM=="usb", ATTR{idVendor}=="f4ed", ATTR{idProduct}=="ee3a", MODE="0666"
Python code to list connected devices and query for name:
import pyvisa
rm = pyvisa.ResourceManager('@py')
res_list = rm.list_resources()
for res in res_list:
print(res)
dev = rm.open_resource(res)
print(dev.query("*IDN?"))
Output looks like this:
USB0::62701::60986::SDS1EDED3R1234::0::INSTR
Siglent Technologies,SDS1202X-E,SDS1EDED3R1234,1.3.2
Screen capture command “SCDP” fall into some sort of packet structure error in “pyvisa-py” implementation.
Issue on this thread: https://github.com/pyvisa/pyvisa/issues/458
And this one: https://github.com/pyvisa/pyvisa-py/issues/20
Hmm…. not fully compatible USB interface. Similar issue for RIGOL oscilloscopes.
Low cost Logic Level Analyzer on Linux.
FT232R USB UART IC provides really cheap device, capable to sample about 10Mhz for 8 digital channels. This FTDI IC can be found on many embedded solutions like Arduino boards and many other development boards, primary acts as USB to serial UART converter. Another way to use this IC is Logic Signal Analyzer. Linux OS is required for control GUI and signal visualization / decoding. For this purpose install https://sigrok.org/wiki/PulseView developed by sigrok.
List of supported hardware can be found at this link: https://sigrok.org/wiki/Supported_hardware

For example connecting IR receiver, taken from old set-top box to the FTDI module permits infrared signal visualization from any TV remote controller.
FT232R datasheet: https://www.ftdichip.com/Support/Documents/DataSheets/ICs/DS_FT232R.pdf
IR receiver datasheet: https://www.vishay.com/docs/82491/tsop382.pdf
Find more details on Bit-Bang operating mode: https://hackaday.com/2009/09/22/introduction-to-ftdi-bitbang-mode/
Libftdi programming documentation: https://www.intra2net.com/en/developer/libftdi/documentation/
Python libftdi programming example: https://github.com/adafruit/Adafruit_Python_GPIO/blob/master/Adafruit_GPIO/FT232H.py
Arduino ATMega and PulseView solution works with 2Mhz or 4Mhz samplerate: https://github.com/gillham/logic_analyzer
More about Logic Sniffers: http://dangerousprototypes.com/docs/Open_Bench_Logic_Sniffer
Linux from scratch
How to easily cross-build custom Linux Distribution entirely from source code. Normally it is not an easy task, because you have to deal with lot of different aspects of software development and integration; from infinite configuration options to the strange compiler errors. From hardware specifications to the device drivers and file-systems, I/O console, Task scheduler and almost everything is involved. So, all of this is not simple, but buildroot project may help us. This fantastic tool is able to solve many really complex and boring tasks.
https://buildroot.org – “Buildroot is a simple, efficient and easy to use tool to generate embedded Linux systems through cross-compilation.”
# My host build system is:
$ lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description: Ubuntu 18.04.3 LTS
Release: 18.04
Codename: bionic
This is an example on how to build LinuxOS for Olimex low cost board with 64MB RAM and 450Mhz CPU.
$ git clone git://git.buildroot.net/buildroot buildroot_mx23
Cloning into 'buildroot_mx23'...
remote: Enumerating objects: 351177, done.
remote: Counting objects: 100% (351177/351177), done.
remote: Compressing objects: 100% (111770/111770), done.
remote: Total 351177 (delta 245634), reused 342867 (delta 237974)
Receiving objects: 100% (351177/351177), 74.68 MiB | 1.50 MiB/s, done.
Resolving deltas: 100% (245634/245634), done.
Get the list of all configured boards:
$ make list-defconfigs
Built-in configs:
aarch64_efi_defconfig - Build for aarch64_efi
acmesystems_aria_g25_128mb_defconfig - Build for acmesystems_aria_g25_128mb
acmesystems_aria_g25_256mb_defconfig - Build for acmesystems_aria_g25_256mb
acmesystems_arietta_g25_128mb_defconfig - Build for acmesystems_arietta_g25_128mb
acmesystems_arietta_g25_256mb_defconfig - Build for acmesystems_arietta_g25_256mb
amarula_a64_relic_defconfig - Build for amarula_a64_relic
amarula_vyasa_rk3288_defconfig - Build for amarula_vyasa_rk3288
andes_ae3xx_defconfig - Build for andes_ae3xx
arcturus_ucls1012a_defconfig - Build for arcturus_ucls1012a
arcturus_ucp1020_defconfig - Build for arcturus_ucp1020
armadeus_apf27_defconfig - Build for armadeus_apf27
armadeus_apf28_defconfig - Build for armadeus_apf28
armadeus_apf51_defconfig - Build for armadeus_apf51
arm_foundationv8_defconfig - Build for arm_foundationv8
arm_juno_defconfig - Build for arm_juno
asus_tinker_rk3288_defconfig - Build for asus_tinker_rk3288
at91sam9260eknf_defconfig - Build for at91sam9260eknf
at91sam9g20dfc_defconfig - Build for at91sam9g20dfc
at91sam9g45m10ek_defconfig - Build for at91sam9g45m10ek
at91sam9rlek_defconfig - Build for at91sam9rlek
at91sam9x5ek_defconfig - Build for at91sam9x5ek
at91sam9x5ek_dev_defconfig - Build for at91sam9x5ek_dev
at91sam9x5ek_mmc_defconfig - Build for at91sam9x5ek_mmc
at91sam9x5ek_mmc_dev_defconfig - Build for at91sam9x5ek_mmc_dev
atmel_sama5d27_som1_ek_mmc_dev_defconfig - Build for atmel_sama5d27_som1_ek_mmc_dev
atmel_sama5d2_xplained_mmc_defconfig - Build for atmel_sama5d2_xplained_mmc
atmel_sama5d2_xplained_mmc_dev_defconfig - Build for atmel_sama5d2_xplained_mmc_dev
atmel_sama5d3xek_defconfig - Build for atmel_sama5d3xek
atmel_sama5d3_xplained_defconfig - Build for atmel_sama5d3_xplained
atmel_sama5d3_xplained_dev_defconfig - Build for atmel_sama5d3_xplained_dev
atmel_sama5d3_xplained_mmc_defconfig - Build for atmel_sama5d3_xplained_mmc
atmel_sama5d3_xplained_mmc_dev_defconfig - Build for atmel_sama5d3_xplained_mmc_dev
atmel_sama5d4_xplained_defconfig - Build for atmel_sama5d4_xplained
atmel_sama5d4_xplained_dev_defconfig - Build for atmel_sama5d4_xplained_dev
atmel_sama5d4_xplained_mmc_defconfig - Build for atmel_sama5d4_xplained_mmc
atmel_sama5d4_xplained_mmc_dev_defconfig - Build for atmel_sama5d4_xplained_mmc_dev
bananapi_m1_defconfig - Build for bananapi_m1
bananapi_m2_plus_defconfig - Build for bananapi_m2_plus
bananapi_m2_ultra_defconfig - Build for bananapi_m2_ultra
bananapi_m64_defconfig - Build for bananapi_m64
bananapro_defconfig - Build for bananapro
beagleboardx15_defconfig - Build for beagleboardx15
beagleboneai_defconfig - Build for beagleboneai
beaglebone_defconfig - Build for beaglebone
beaglebone_qt5_defconfig - Build for beaglebone_qt5
beelink_gs1_defconfig - Build for beelink_gs1
chromebook_snow_defconfig - Build for chromebook_snow
ci20_defconfig - Build for ci20
csky_gx6605s_defconfig - Build for csky_gx6605s
cubieboard2_defconfig - Build for cubieboard2
engicam_imx6qdl_icore_defconfig - Build for engicam_imx6qdl_icore
engicam_imx6qdl_icore_qt5_defconfig - Build for engicam_imx6qdl_icore_qt5
engicam_imx6qdl_icore_rqs_defconfig - Build for engicam_imx6qdl_icore_rqs
engicam_imx6ul_geam_defconfig - Build for engicam_imx6ul_geam
engicam_imx6ul_isiot_defconfig - Build for engicam_imx6ul_isiot
freescale_imx28evk_defconfig - Build for freescale_imx28evk
freescale_imx6dlsabreauto_defconfig - Build for freescale_imx6dlsabreauto
freescale_imx6dlsabresd_defconfig - Build for freescale_imx6dlsabresd
freescale_imx6qsabreauto_defconfig - Build for freescale_imx6qsabreauto
freescale_imx6qsabresd_defconfig - Build for freescale_imx6qsabresd
freescale_imx6sxsabresd_defconfig - Build for freescale_imx6sxsabresd
freescale_imx7dsabresd_defconfig - Build for freescale_imx7dsabresd
freescale_imx8mmevk_defconfig - Build for freescale_imx8mmevk
freescale_imx8mqevk_defconfig - Build for freescale_imx8mqevk
freescale_imx8qxpmek_defconfig - Build for freescale_imx8qxpmek
freescale_p1025twr_defconfig - Build for freescale_p1025twr
freescale_t1040d4rdb_defconfig - Build for freescale_t1040d4rdb
freescale_t2080_qds_rdb_defconfig - Build for freescale_t2080_qds_rdb
friendlyarm_nanopi_a64_defconfig - Build for friendlyarm_nanopi_a64
friendlyarm_nanopi_neo2_defconfig - Build for friendlyarm_nanopi_neo2
friendlyarm_nanopi_neo_plus2_defconfig - Build for friendlyarm_nanopi_neo_plus2
galileo_defconfig - Build for galileo
grinn_chiliboard_defconfig - Build for grinn_chiliboard
grinn_liteboard_defconfig - Build for grinn_liteboard
hifive_unleashed_defconfig - Build for hifive_unleashed
imx23evk_defconfig - Build for imx23evk
imx6-sabreauto_defconfig - Build for imx6-sabreauto
imx6-sabresd_defconfig - Build for imx6-sabresd
imx6-sabresd_qt5_defconfig - Build for imx6-sabresd_qt5
imx6slevk_defconfig - Build for imx6slevk
imx6sx-sdb_defconfig - Build for imx6sx-sdb
imx6ulevk_defconfig - Build for imx6ulevk
imx6ulpico_defconfig - Build for imx6ulpico
imx7dpico_defconfig - Build for imx7dpico
imx7d-sdb_defconfig - Build for imx7d-sdb
imx8mmpico_defconfig - Build for imx8mmpico
imx8mpico_defconfig - Build for imx8mpico
lafrite_defconfig - Build for lafrite
lego_ev3_defconfig - Build for lego_ev3
licheepi_zero_defconfig - Build for licheepi_zero
linksprite_pcduino_defconfig - Build for linksprite_pcduino
minnowboard_max_defconfig - Build for minnowboard_max
minnowboard_max-graphical_defconfig - Build for minnowboard_max-graphical
mx25pdk_defconfig - Build for mx25pdk
mx51evk_defconfig - Build for mx51evk
mx53loco_defconfig - Build for mx53loco
mx6cubox_defconfig - Build for mx6cubox
mx6sx_udoo_neo_defconfig - Build for mx6sx_udoo_neo
mx6udoo_defconfig - Build for mx6udoo
nanopi_m1_defconfig - Build for nanopi_m1
nanopi_m1_plus_defconfig - Build for nanopi_m1_plus
nanopi_neo_defconfig - Build for nanopi_neo
nexbox_a95x_defconfig - Build for nexbox_a95x
nitrogen6sx_defconfig - Build for nitrogen6sx
nitrogen6x_defconfig - Build for nitrogen6x
nitrogen7_defconfig - Build for nitrogen7
nitrogen8m_defconfig - Build for nitrogen8m
odroidxu4_defconfig - Build for odroidxu4
olimex_a10_olinuxino_lime_defconfig - Build for olimex_a10_olinuxino_lime
olimex_a13_olinuxino_defconfig - Build for olimex_a13_olinuxino
olimex_a20_olinuxino_lime2_defconfig - Build for olimex_a20_olinuxino_lime2
olimex_a20_olinuxino_lime_defconfig - Build for olimex_a20_olinuxino_lime
olimex_a20_olinuxino_micro_defconfig - Build for olimex_a20_olinuxino_micro
olimex_a33_olinuxino_defconfig - Build for olimex_a33_olinuxino
olimex_a64_olinuxino_defconfig - Build for olimex_a64_olinuxino
olimex_imx233_olinuxino_defconfig - Build for olimex_imx233_olinuxino
openblocks_a6_defconfig - Build for openblocks_a6
orangepi_lite2_defconfig - Build for orangepi_lite2
orangepi_lite_defconfig - Build for orangepi_lite
orangepi_one_defconfig - Build for orangepi_one
orangepi_one_plus_defconfig - Build for orangepi_one_plus
orangepi_pc2_defconfig - Build for orangepi_pc2
orangepi_pc_defconfig - Build for orangepi_pc
orangepi_pc_plus_defconfig - Build for orangepi_pc_plus
orangepi_plus_defconfig - Build for orangepi_plus
orangepi_prime_defconfig - Build for orangepi_prime
orangepi_r1_defconfig - Build for orangepi_r1
orangepi_win_defconfig - Build for orangepi_win
orangepi_zero_defconfig - Build for orangepi_zero
orangepi_zero_plus2_defconfig - Build for orangepi_zero_plus2
pandaboard_defconfig - Build for pandaboard
pc_x86_64_bios_defconfig - Build for pc_x86_64_bios
pc_x86_64_efi_defconfig - Build for pc_x86_64_efi
pine64_defconfig - Build for pine64
pine64_sopine_defconfig - Build for pine64_sopine
qemu_aarch64_virt_defconfig - Build for qemu_aarch64_virt
qemu_arm_versatile_defconfig - Build for qemu_arm_versatile
qemu_arm_versatile_nommu_defconfig - Build for qemu_arm_versatile_nommu
qemu_arm_vexpress_defconfig - Build for qemu_arm_vexpress
qemu_arm_vexpress_tz_defconfig - Build for qemu_arm_vexpress_tz
qemu_csky610_virt_defconfig - Build for qemu_csky610_virt
qemu_csky807_virt_defconfig - Build for qemu_csky807_virt
qemu_csky810_virt_defconfig - Build for qemu_csky810_virt
qemu_csky860_virt_defconfig - Build for qemu_csky860_virt
qemu_m68k_mcf5208_defconfig - Build for qemu_m68k_mcf5208
qemu_m68k_q800_defconfig - Build for qemu_m68k_q800
qemu_microblazebe_mmu_defconfig - Build for qemu_microblazebe_mmu
qemu_microblazeel_mmu_defconfig - Build for qemu_microblazeel_mmu
qemu_mips32r2el_malta_defconfig - Build for qemu_mips32r2el_malta
qemu_mips32r2_malta_defconfig - Build for qemu_mips32r2_malta
qemu_mips32r6el_malta_defconfig - Build for qemu_mips32r6el_malta
qemu_mips32r6_malta_defconfig - Build for qemu_mips32r6_malta
qemu_mips64el_malta_defconfig - Build for qemu_mips64el_malta
qemu_mips64_malta_defconfig - Build for qemu_mips64_malta
qemu_mips64r6el_malta_defconfig - Build for qemu_mips64r6el_malta
qemu_mips64r6_malta_defconfig - Build for qemu_mips64r6_malta
qemu_nios2_10m50_defconfig - Build for qemu_nios2_10m50
qemu_or1k_defconfig - Build for qemu_or1k
qemu_ppc64_e5500_defconfig - Build for qemu_ppc64_e5500
qemu_ppc64le_pseries_defconfig - Build for qemu_ppc64le_pseries
qemu_ppc64_pseries_defconfig - Build for qemu_ppc64_pseries
qemu_ppc_g3beige_defconfig - Build for qemu_ppc_g3beige
qemu_ppc_mac99_defconfig - Build for qemu_ppc_mac99
qemu_ppc_mpc8544ds_defconfig - Build for qemu_ppc_mpc8544ds
qemu_ppc_virtex_ml507_defconfig - Build for qemu_ppc_virtex_ml507
qemu_riscv32_virt_defconfig - Build for qemu_riscv32_virt
qemu_riscv64_virt_defconfig - Build for qemu_riscv64_virt
qemu_sh4eb_r2d_defconfig - Build for qemu_sh4eb_r2d
qemu_sh4_r2d_defconfig - Build for qemu_sh4_r2d
qemu_sparc64_sun4u_defconfig - Build for qemu_sparc64_sun4u
qemu_sparc_ss10_defconfig - Build for qemu_sparc_ss10
qemu_x86_64_defconfig - Build for qemu_x86_64
qemu_x86_defconfig - Build for qemu_x86
qemu_xtensa_lx60_defconfig - Build for qemu_xtensa_lx60
qemu_xtensa_lx60_nommu_defconfig - Build for qemu_xtensa_lx60_nommu
raspberrypi0_defconfig - Build for raspberrypi0
raspberrypi0w_defconfig - Build for raspberrypi0w
raspberrypi2_defconfig - Build for raspberrypi2
raspberrypi3_64_defconfig - Build for raspberrypi3_64
raspberrypi3_defconfig - Build for raspberrypi3
raspberrypi3_qt5we_defconfig - Build for raspberrypi3_qt5we
raspberrypi4_defconfig - Build for raspberrypi4
raspberrypi_defconfig - Build for raspberrypi
riotboard_defconfig - Build for riotboard
rock64_defconfig - Build for rock64
roseapplepi_defconfig - Build for roseapplepi
s6lx9_microboard_defconfig - Build for s6lx9_microboard
sheevaplug_defconfig - Build for sheevaplug
snps_aarch64_vdk_defconfig - Build for snps_aarch64_vdk
snps_arc700_axs101_defconfig - Build for snps_arc700_axs101
snps_archs38_axs103_defconfig - Build for snps_archs38_axs103
snps_archs38_haps_defconfig - Build for snps_archs38_haps
snps_archs38_hsdk_defconfig - Build for snps_archs38_hsdk
snps_archs38_vdk_defconfig - Build for snps_archs38_vdk
socrates_cyclone5_defconfig - Build for socrates_cyclone5
solidrun_clearfog_defconfig - Build for solidrun_clearfog
solidrun_clearfog_gt_8k_defconfig - Build for solidrun_clearfog_gt_8k
solidrun_macchiatobin_mainline_defconfig - Build for solidrun_macchiatobin_mainline
solidrun_macchiatobin_marvell_defconfig - Build for solidrun_macchiatobin_marvell
stm32f429_disco_defconfig - Build for stm32f429_disco
stm32f469_disco_defconfig - Build for stm32f469_disco
stm32mp157c_dk2_defconfig - Build for stm32mp157c_dk2
toradex_apalis_imx6_defconfig - Build for toradex_apalis_imx6
ts4900_defconfig - Build for ts4900
ts5500_defconfig - Build for ts5500
ts7680_defconfig - Build for ts7680
wandboard_defconfig - Build for wandboard
warp7_defconfig - Build for warp7
warpboard_defconfig - Build for warpboard
zynq_microzed_defconfig - Build for zynq_microzed
zynqmp_zcu106_defconfig - Build for zynqmp_zcu106
zynq_zc706_defconfig - Build for zynq_zc706
zynq_zed_defconfig - Build for zynq_zed
Select Olimex i.mx233 board configuration:
$ make olimex_imx233_olinuxino_defconfig
...
#
# configuration written to /home/iwi/Documents/buildroot_mx23/.config
#
Now just build and wait. That’s all.
$ make
...
INFO: hdimage(sdcard.img): adding partition 'u-boot' (in MBR) from 'u-boot.sd' ...
INFO: hdimage(sdcard.img): adding partition 'kernel' (in MBR) from 'boot.vfat' ...
INFO: hdimage(sdcard.img): adding partition 'rootfs' (in MBR) from 'rootfs.ext2' ...
INFO: hdimage(sdcard.img): writing MBR
Successful build looks like this, otherwise please check carefully your host system pre-requisites: https://buildroot.org/downloads/manual/manual.html#requirement
The first build may take some time to download all the required source code, build cross-compiler and all host system tools and libraries, than you can build just newly selected packages, but hacking with tool-chain options, requires clean rebuild of everything.
# Insert SD card and unmount all auto-mounted partitions
$ umount /dev/sdX2
$ umount /dev/sdX3
# Write image file to SD card
$ sudo dd if=output/images/sdcard.img of=/dev/sdX bs=1M
97517568 bytes (98 MB, 93 MiB) copied, 12.0944 s, 8.1 MB/s
# Flush all disks buffers
sync
Default board configuration provides Linux OS with minimal set of features and programs tailored for embedded systems. This lightweight Linux system provides excellent starting point for any smart IoT device.
U-Boot 2017.11 (Dec 07 2019 - 04:29:38 +0100)
CPU: Freescale i.MX23 rev1.4 at 454 MHz
BOOT: SSP SD/MMC #0
DRAM: 64 MiB
No arch specific invalidate_icache_all available!
__led_init: failed requesting GPIO59!
MMC: MXS MMC: 0
*** Warning - bad CRC, using default environment
In: serial
Out: serial
Err: serial
Net: Net Initialization Skipped
No ethernet found.
Hit any key to stop autoboot: 0
switch to partitions #0, OK
mmc0 is current device
** Unable to read file boot.scr **
reading uImage
5292296 bytes read in 1640 ms (3.1 MiB/s)
Booting from mmc ...
reading imx23-olinuxino.dtb
10286 bytes read in 29 ms (345.7 KiB/s)
## Booting kernel from Legacy Image at 42000000 ...
Image Name: Linux-4.19.2
Image Type: ARM Linux Kernel Image (uncompressed)
Data Size: 5292232 Bytes = 5 MiB
Load Address: 42000000
Entry Point: 42000000
Verifying Checksum ... OK
## Flattened Device Tree blob at 41000000
Booting using the fdt blob at 0x41000000
Loading Kernel Image ... OK
Loading Device Tree to 43b75000, end 43b7a82d ... OK
Starting kernel ...
[ 0.000000] Booting Linux on physical CPU 0x0
[ 0.000000] Linux version 4.19.2 (iwi@nqdev) (gcc version 8.3.0 (Buildroot 2020.02-git-00204-g2ca0accc21)) #1 Sat Dec 7 04:31:14 CET 2019
[ 0.000000] CPU: ARM926EJ-S [41069265] revision 5 (ARMv5TEJ), cr=0005317f
[ 0.000000] CPU: VIVT data cache, VIVT instruction cache
[ 0.000000] OF: fdt: Machine model: i.MX23 Olinuxino Low Cost Board
[ 0.000000] Memory policy: Data cache writeback
[ 0.000000] random: get_random_bytes called from start_kernel+0x84/0x474 with crng_init=0
[ 0.000000] Built 1 zonelists, mobility grouping on. Total pages: 16256
[ 0.000000] Kernel command line: console=ttyAMA0,115200 root=/dev/mmcblk0p3 rw rootwait
[ 0.000000] Dentry cache hash table entries: 8192 (order: 3, 32768 bytes)
[ 0.000000] Inode-cache hash table entries: 4096 (order: 2, 16384 bytes)
[ 0.000000] Memory: 46644K/65536K available (7200K kernel code, 633K rwdata, 2364K rodata, 364K init, 7454K bss, 18892K reserved, 0K cma-reserved)
[ 0.000000] Virtual kernel memory layout:
[ 0.000000] vector : 0xffff0000 - 0xffff1000 ( 4 kB)
[ 0.000000] fixmap : 0xffc00000 - 0xfff00000 (3072 kB)
[ 0.000000] vmalloc : 0xc4800000 - 0xff800000 ( 944 MB)
[ 0.000000] lowmem : 0xc0000000 - 0xc4000000 ( 64 MB)
[ 0.000000] modules : 0xbf000000 - 0xc0000000 ( 16 MB)
[ 0.000000] .text : 0x(ptrval) - 0x(ptrval) (7202 kB)
[ 0.000000] .init : 0x(ptrval) - 0x(ptrval) ( 364 kB)
[ 0.000000] .data : 0x(ptrval) - 0x(ptrval) ( 634 kB)
[ 0.000000] .bss : 0x(ptrval) - 0x(ptrval) (7455 kB)
[ 0.000000] SLUB: HWalign=32, Order=0-3, MinObjects=0, CPUs=1, Nodes=1
[ 0.000000] Running RCU self tests
[ 0.000000] NR_IRQS: 16, nr_irqs: 16, preallocated irqs: 16
[ 0.000000] clocksource: mxs_timer: mask: 0xffff max_cycles: 0xffff, max_idle_ns: 911346093 ns
[ 0.000000] Console: colour dummy device 80x30
[ 0.000000] Lock dependency validator: Copyright (c) 2006 Red Hat, Inc., Ingo Molnar
[ 0.000000] ... MAX_LOCKDEP_SUBCLASSES: 8
[ 0.000000] ... MAX_LOCK_DEPTH: 48
[ 0.000000] ... MAX_LOCKDEP_KEYS: 8191
[ 0.000000] ... CLASSHASH_SIZE: 4096
[ 0.000000] ... MAX_LOCKDEP_ENTRIES: 32768
[ 0.000000] ... MAX_LOCKDEP_CHAINS: 65536
[ 0.000000] ... CHAINHASH_SIZE: 32768
[ 0.000000] memory used by lock dependency info: 4655 kB
[ 0.000000] per task-struct memory footprint: 1536 bytes
[ 0.000000] sched_clock: 32 bits at 100 Hz, resolution 10000000ns, wraps every 21474836475000000ns
[ 0.070000] Calibrating delay loop... 226.09 BogoMIPS (lpj=1130496)
[ 0.070000] pid_max: default: 32768 minimum: 301
[ 0.070000] Mount-cache hash table entries: 1024 (order: 0, 4096 bytes)
[ 0.070000] Mountpoint-cache hash table entries: 1024 (order: 0, 4096 bytes)
[ 0.080000] CPU: Testing write buffer coherency: ok
[ 0.090000] Setting up static identity map for 0x40008400 - 0x40008458
[ 0.100000] devtmpfs: initialized
[ 0.140000] clocksource: jiffies: mask: 0xffffffff max_cycles: 0xffffffff, max_idle_ns: 19112604462750000 ns
[ 0.140000] futex hash table entries: 256 (order: 1, 11264 bytes)
[ 0.150000] pinctrl core: initialized pinctrl subsystem
[ 0.160000] NET: Registered protocol family 16
[ 0.170000] DMA: preallocated 256 KiB pool for atomic coherent allocations
[ 0.320000] Serial: AMBA PL011 UART driver
[ 0.320000] 80070000.serial: ttyAMA0 at MMIO 0x80070000 (irq = 17, base_baud = 0) is a PL011 rev2
[ 0.530000] console [ttyAMA0] enabled
[ 0.640000] mxs-dma 80004000.dma-apbh: initialized
[ 0.660000] mxs-dma 80024000.dma-apbx: initialized
[ 0.670000] SCSI subsystem initialized
[ 0.680000] usbcore: registered new interface driver usbfs
[ 0.690000] usbcore: registered new interface driver hub
[ 0.690000] usbcore: registered new device driver usb
[ 0.700000] pps_core: LinuxPPS API ver. 1 registered
[ 0.710000] pps_core: Software ver. 5.3.6 - Copyright 2005-2007 Rodolfo Giometti <giometti@linux.it>
[ 0.710000] PTP clock support registered
[ 0.720000] Advanced Linux Sound Architecture Driver Initialized.
[ 0.740000] clocksource: Switched to clocksource mxs_timer
[ 1.790000] NET: Registered protocol family 2
[ 1.800000] tcp_listen_portaddr_hash hash table entries: 128 (order: 0, 5120 bytes)
[ 1.810000] TCP established hash table entries: 1024 (order: 0, 4096 bytes)
[ 1.820000] TCP bind hash table entries: 1024 (order: 3, 36864 bytes)
[ 1.820000] TCP: Hash tables configured (established 1024 bind 1024)
[ 1.830000] UDP hash table entries: 256 (order: 2, 20480 bytes)
[ 1.840000] UDP-Lite hash table entries: 256 (order: 2, 20480 bytes)
[ 1.850000] NET: Registered protocol family 1
[ 1.860000] RPC: Registered named UNIX socket transport module.
[ 1.870000] RPC: Registered udp transport module.
[ 1.870000] RPC: Registered tcp transport module.
[ 1.880000] RPC: Registered tcp NFSv4.1 backchannel transport module.
[ 1.910000] Initialise system trusted keyrings
[ 1.910000] workingset: timestamp_bits=30 max_order=14 bucket_order=0
[ 2.020000] NFS: Registering the id_resolver key type
[ 2.030000] Key type id_resolver registered
[ 2.030000] Key type id_legacy registered
[ 2.040000] jffs2: version 2.2. (NAND) © 2001-2006 Red Hat, Inc.
[ 2.100000] jitterentropy: Initialization failed with host not compliant with requirements: 2
[ 2.110000] Key type asymmetric registered
[ 2.120000] Asymmetric key parser 'x509' registered
[ 2.120000] Block layer SCSI generic (bsg) driver version 0.4 loaded (major 248)
[ 2.130000] io scheduler noop registered (default)
[ 2.140000] io scheduler mq-deadline registered
[ 2.140000] io scheduler kyber registered
[ 2.160000] 8006c000.serial: ttyAPP0 at MMIO 0x8006c000 (irq = 147, base_baud = 1500000) is a 8006c000.serial
[ 2.170000] mxs-auart 8006c000.serial: Found APPUART 3.0.0
[ 2.210000] libphy: Fixed MDIO Bus: probed
[ 2.220000] usbcore: registered new interface driver asix
[ 2.230000] usbcore: registered new interface driver ax88179_178a
[ 2.240000] usbcore: registered new interface driver cdc_ether
[ 2.240000] usbcore: registered new interface driver smsc95xx
[ 2.250000] usbcore: registered new interface driver net1080
[ 2.260000] usbcore: registered new interface driver cdc_subset
[ 2.260000] usbcore: registered new interface driver zaurus
[ 2.270000] usbcore: registered new interface driver cdc_ncm
[ 2.280000] ehci_hcd: USB 2.0 'Enhanced' Host Controller (EHCI) Driver
[ 2.280000] usbcore: registered new interface driver usb-storage
[ 2.300000] imx_usb 80080000.usb: Linked as a consumer to regulator.1
[ 2.310000] ci_hdrc ci_hdrc.0: EHCI Host Controller
[ 2.320000] ci_hdrc ci_hdrc.0: new USB bus registered, assigned bus number 1
[ 2.360000] ci_hdrc ci_hdrc.0: USB 2.0 started, EHCI 1.00
[ 2.380000] hub 1-0:1.0: USB hub found
[ 2.390000] hub 1-0:1.0: 1 port detected
[ 2.410000] stmp3xxx-rtc 8005c000.rtc: rtc core: registered 8005c000.rtc as rtc0
[ 2.420000] i2c /dev entries driver
[ 2.440000] stmp3xxx_rtc_wdt stmp3xxx_rtc_wdt: initialized watchdog with heartbeat 19s
[ 2.450000] mxs-mmc 80010000.ssp: 80010000.ssp supply vmmc not found, using dummy regulator
[ 2.460000] mxs-mmc 80010000.ssp: Linked as a consumer to regulator.0
[ 2.500000] mxs-mmc 80010000.ssp: initialized
[ 2.510000] random: fast init done
[ 2.530000] imx23-pinctrl 80018000.pinctrl: pin SSP1_DETECT already requested by 80010000.ssp; cannot claim for leds
[ 2.540000] imx23-pinctrl 80018000.pinctrl: pin-65 (leds) status -22
[ 2.540000] imx23-pinctrl 80018000.pinctrl: could not request pin 65 (SSP1_DETECT) from group led_gpio2_1.0 on device 80018000.pinctrl
[ 2.560000] leds-gpio leds: Error applying setting, reverse things back
[ 2.560000] leds-gpio: probe of leds failed with error -22
[ 2.580000] mxs-dcp 80028000.dcp: Failed to register sha1 hash!
[ 2.590000] mxs-dcp: probe of 80028000.dcp failed with error -22
[ 2.610000] usbcore: registered new interface driver usbhid
[ 2.610000] usbhid: USB HID core driver
[ 2.630000] mmc0: host does not support reading read-only switch, assuming write-enable
[ 2.650000] mmc0: new high speed SDHC card at address aaaa
[ 2.680000] NET: Registered protocol family 17
[ 2.690000] mmcblk0: mmc0:aaaa SU16G 14.8 GiB
[ 2.700000] Key type dns_resolver registered
[ 2.720000] registered taskstats version 1
[ 2.730000] Loading compiled-in X.509 certificates
[ 2.750000] mmcblk0: p1 p2 p3
[ 2.840000] stmp3xxx-rtc 8005c000.rtc: setting system clock to 1970-01-01 00:00:51 UTC (51)
[ 2.850000] cfg80211: Loading compiled-in X.509 certificates for regulatory database
[ 2.890000] cfg80211: Loaded X.509 cert 'sforshee: 00b28ddf47aef9cea7'
[ 2.900000] ALSA device list:
[ 2.900000] No soundcards found.
[ 2.910000] uart-pl011 80070000.serial: no DMA platform data
[ 2.920000] platform regulatory.0: Direct firmware load for regulatory.db failed with error -2
[ 2.930000] cfg80211: failed to load regulatory.db
[ 2.950000] EXT4-fs (mmcblk0p3): mounting ext2 file system using the ext4 subsystem
[ 3.000000] EXT4-fs (mmcblk0p3): mounted filesystem without journal. Opts: (null)
[ 3.010000] VFS: Mounted root (ext2 filesystem) on device 179:3.
[ 3.020000] devtmpfs: mounted
[ 3.040000] Freeing unused kernel memory: 364K
[ 3.040000] This architecture does not have kernel memory protection.
[ 3.050000] Run /sbin/init as init process
[ 3.350000] EXT4-fs (mmcblk0p3): re-mounted. Opts: block_validity,barrier,user_xattr
Starting syslogd: OK
Starting klogd: OK
Running sysctl: OK
Starting mdev... OK
Initializing random number generator: OK
Saving random seed: [ 12.930000] random: dd: uninitialized urandom read (512 bytes read)
OK
Starting network: OK
Welcome to Buildroot
buildroot login:
Login is “root”, without password.
# Customize user prompt, save to "~/.profile"
$ nano ~/.profile
PS1="\\u@\\h:\\w$ "
Directory listing for binaries
root@buildroot:/bin$ ls
arch dnsdomainname linux64 nuke sh
ash dumpkmap ln pidof sleep
base64 echo login ping stty
busybox egrep ls pipe_progress su
cat false lsattr printenv sync
chattr fdflush mkdir ps tar
chgrp fgrep mknod pwd touch
chmod getopt mktemp resume true
chown grep more rm umount
cp gunzip mount rmdir uname
cpio gzip mountpoint run-parts usleep
date hostname mt sed vi
dd kill mv setarch watch
df link netstat setpriv zcat
dmesg linux32 nice setserial
root@buildroot:/sbin$ ls
arp init makedevs setconsole
blkid insmod mdev start-stop-daemon
devmem ip mkdosfs sulogin
fdisk ipaddr mke2fs swapoff
freeramdisk iplink mkswap swapon
fsck ipneigh modprobe switch_root
fstrim iproute nameif sysctl
getty iprule pivot_root syslogd
halt iptunnel poweroff tc
hdparm klogd reboot udhcpc
hwclock ldconfig rmmod uevent
ifconfig loadkmap route vconfig
ifdown losetup run-init watchdog
ifup lsmod runlevel
root@buildroot:/usr/bin$ ls
[ du killall nproc sha512sum unlink
[[ eject last nslookup shred unlzma
ar env ldd od sort unlzop
awk expr less openvt strings unxz
basename factor logger passwd svc unzip
bc fallocate logname paste svok uptime
bunzip2 find lsof patch tail uudecode
bzcat flock lspci printf tee uuencode
chrt fold lsscsi readlink telnet vlock
chvt free lsusb realpath test w
cksum fuser lzcat renice tftp wc
clear getconf lzma reset time wget
cmp head lzopcat resize top which
crontab hexdump md5sum seq tr who
cut hexedit mesg setfattr traceroute whoami
dc hostid microcom setkeycodes truncate xargs
deallocvt id mkfifo setsid ts xxd
diff install mkpasswd sha1sum tty xz
dirname ipcrm nl sha256sum uniq xzcat
dos2unix ipcs nohup sha3sum unix2dos yes
root@buildroot:/usr/sbin$ ls
addgroup delgroup fdformat i2cset nologin ubirename
adduser deluser fsfreeze i2ctransfer partprobe
arping dnsd i2cdetect inetd rdate
chroot ether-wake i2cdump killall5 readprofile
crond fbset i2cget loadfont setlogcons
Disk and RAM reports:
root@buildroot:/$ df -h
Filesystem Size Used Available Use% Mounted on
/dev/root 58.1M 5.6M 49.5M 10% /
devtmpfs 22.8M 0 22.8M 0% /dev
tmpfs 23.0M 0 23.0M 0% /dev/shm
tmpfs 23.0M 20.0K 22.9M 0% /tmp
tmpfs 23.0M 20.0K 22.9M 0% /run
root@buildroot:/$ cat /proc/meminfo
MemTotal: 47008 kB
MemFree: 26812 kB
MemAvailable: 36784 kB
Buffers: 232 kB
Cached: 2004 kB
SwapCached: 0 kB
Active: 2072 kB
Inactive: 684 kB
Active(anon): 544 kB
Inactive(anon): 16 kB
Active(file): 1528 kB
Inactive(file): 668 kB
Unevictable: 0 kB
Mlocked: 0 kB
SwapTotal: 0 kB
SwapFree: 0 kB
Dirty: 28 kB
Writeback: 0 kB
AnonPages: 536 kB
Mapped: 1068 kB
Shmem: 40 kB
Slab: 14296 kB
SReclaimable: 11204 kB
SUnreclaim: 3092 kB
KernelStack: 280 kB
PageTables: 88 kB
NFS_Unstable: 0 kB
Bounce: 0 kB
WritebackTmp: 0 kB
CommitLimit: 23504 kB
Committed_AS: 1780 kB
VmallocTotal: 966656 kB
VmallocUsed: 0 kB
VmallocChunk: 0 kB
Percpu: 32 kB
Disk space is not a big issue, but RAM memory is really limiting factor for this system. Also CPU is low profile ARM926 Running at 454 MHz. This computational power is just enough for mp3 player or light web server or something like photo frame, also because current linux support for this architecture is incomplete and can’t take full advantages of all available peripherals. Anyhow, fast or slow is your system, everything depends on what you intent to do with this system.
root@buildroot:/$ cat /proc/cpuinfo
processor : 0
model name : ARM926EJ-S rev 5 (v5l)
BogoMIPS : 226.09
Features : swp half thumb fastmult edsp java
CPU implementer : 0x41
CPU architecture: 5TEJ
CPU variant : 0x0
CPU part : 0x926
CPU revision : 5
Hardware : Freescale MXS (Device Tree)
Revision : 0000
Serial : 0000000000000000
Back to buildroot configuration. This setup lacks of wifi support and some useful tools like nano and mc. Moreover if you want to adapt kernel configuration to your hardware, add extra drivers and packages:
# Buildroot configuration
$ make menuconfig
# For kernel and drivers configuration
$ make linux-menuconfig
# For busybox configuration
$ make busybox-menuconfig
Useful tool-chain and system settings:
# Select full featured GNU stdc library
Toolchain ---> C library (glibc) ---> (X) glibc
# Enable c++ compiler
[*] Enable C++ support
# Select kernel version
Custom kernel headers series (5.4.x) ---> (X) 5.4.x
# Remote system debugging
[*] Build cross gdb for the host
Select Python, c++, gdb, sudo, mc, ecc...
Network connecction:
# Wifi network
root@mx23:~$ wpa_passphrase ESSID_NAME ESSID_PASS > /root/home_conn.conf
# Connect to home network
root@mx23:~$ wpa_supplicant -B -i wlan0 -c /root/home_conn.conf
# Run DHCP client
root@mx23:~$ udhcpc -i wlan0
# Enable root login for open SSH server
root@mx23:~$ nano /etc/ssh/sshd_config
PermitRootLogin yes
Finally, set swap file:
# Make 128 MB swapfile
root@mx23:~$ fallocate -l 128M /swapfile
root@mx23:~$ chmod 600 /swapfile
root@mx23:~$ mkswap /swapfile
root@mx23:~$ swapon /swapfile
# Add swap info to fstab
root@mx23:~$ nano /etc/fstab
/swapfile none swap defaults 0 0
Next:
Code::blocks IDE and Remote debugging
OpenOCD and Serial JTAG
Serial UART console
Most simple and common way to connect almost any embedded device is serial UART port. You can find one inside any Smart TV or Media Center, WiFi Router and almost any kind of complex electronic device provides this port. The reason to expose this port may be different, but usually is used for maintenance, debug and diagnostics. Be careful with [un] authorized accesses to any device: please check device documentation and contact support first.
For everything you would like to know about serial communication please refer to this article: https://www.freebsd.org/doc/en_US.ISO8859-1/articles/serial-uart/index.html
Original specification for DB9 and DB25 connectors defines a lot of control and synchronization signals like DTR – “Data Terminal Ready”, DSR – “Data Set Ready” or RI – “Ring Indicator”. Signals used especially for synchronization with ancient and slow terminals with small buffers. Currently many devices successfully use only TX and RX pins for serial communication and all other pins are simply useless.
Actually there are many ways to connect to the serial port, for example you can use “USB to Serial” converter or “Serial Bluetooth” module; almost any embedded development kit should support UART / USART connection. Before selecting your converter, check signal levels, is common to find 5v and 3.3v devices. Do not mix unless your 3.3Volt device is specifically tolerant to 5volt signals, otherwise signal level converter is required. Some old devices or also special purpose serial devices may use +/-12 volt signal.
This kind of serial connection is not intended for high bandwidth or long range communications. Rather that it’s simple and robust enough to fulfill most of the basic but essential communication tasks.
Common baud-rates and maximum theoretical data throughput:
| 7bit data No parity | 8bit data No parity | 8bit data 1bit parity | |
| Baud-rate | CPS | CPS | CPS |
| 300 | 33 | 30 | 27 |
| 600 | 67 | 60 | 55 |
| 1200 | 133 | 120 | 109 |
| 1800 | 200 | 180 | 164 |
| 2400 | 267 | 240 | 218 |
| 4800 | 533 | 480 | 436 |
| 7200 | 800 | 720 | 655 |
| 9600 | 1067 | 960 | 873 |
| 14400 | 1600 | 1440 | 1309 |
| 19200 | 2133 | 1920 | 1745 |
| 38400 | 4267 | 3840 | 3491 |
| 57600 | 6400 | 5760 | 5236 |
| 115200 | 12800 | 11520 | 10473 |
| 128000 | 14222 | 12800 | 11636 |
| 153600 | 17067 | 15360 | 13964 |
| 230400 | 25600 | 23040 | 20945 |
| 256000 | 28444 | 25600 | 23273 |
| 460800 | 51200 | 46080 | 41891 |
| 921600 | 102400 | 92160 | 83782 |
| 1382400 | 153600 | 138240 | 125673 |
Although simple serial console I/O is powerful enough for many tasks where the error is negligible, big data transfer requires error handling and synchronization, like XON / XOFF or parity bit. Is also a good practice to add CRC to the transmitted data block, over then simple parity check. Because this type of communication may suffer of erasures and multi bit errors.
A lot of software and protocols was developed to support serial communication remote console and file transfer, like “[X|Y|Z]MODEM” or “Kermit”, “minicom” and “Putty” and many others more or less famous.
A simple and elegant way to connect router’s serial console is through HC-06 Slave bluetooth module.
This module exposes the SPP (Serial Port Profile) protocol for remote devices. Then, any Bluetooth Master near the router can connect it, obviously knowing the correct pin.

TL-MR3220 serial port connected to bluetooth HC-06 module. Supply of 3.3v is provided by router board red wire. Black is ground, TX and RX (Green and White) for serial I/O.

First, configure HC-06 module for 115200 bps 8 bit data, no parity bit and one stop bit, then connect it to the router. If provided power supply is sufficient to power-up bluetooth module, we will see blinking red led. Module consumption under 3.3v is around 4mA – 8mA for idle state and 20mA – 40mA for normal operation.
Python setup script for HC-06 serial bluetooth module: https://github.com/netquote/hc_utils

$ python3 hc_setup.py /dev/ttyUSB0 -p N --set-pin 1234 --set-name BTS00 --set-rate 115200 --set-parity N
Guessing bit-rate and parity on /dev/ttyUSB0 …
Rate: 1200, parity: N
Rate: 2400, parity: N
Rate: 4800, parity: N
Rate: 9600, parity: N
Rate: 19200, parity: N
Rate: 38400, parity: N
Rate: 57600, parity: N
Rate: 115200, parity: N
AT device detected.
Open serial port: /dev/ttyUSB0, bit-rate: 115200, parity: N
Device version: linvorV1.8
Set name OK
Set pin OK
Set baud 115200
Set parity None
Deal with serial ports from source code is pretty straightforward, like write and read any simple file except seek function which is not applicable. Other things, like serial port name and configuration procedures are OS and language specific.
Example Python script for basic serial I/O:
#!/usr/bin/env python
# Import pySerial library
from serial import *
# Open serial port at "115200,8,N,1", timeout 3s
ser = Serial(port='/dev/ttyUSB0',
baudrate=115200,
bytesize=EIGHTBITS,
parity=PARITY_NONE,
stopbits=STOPBITS_ONE,
timeout=3)
# Write a string
ser.write(b'Hello!\n')
# Read 30 bytes
print(ser.read(30))
# Close port
ser.close()
This Python demo script should work on both, Linux and Windows platforms, just change device name to “COM1” on Windows.
Another way to deal with serial communication is “kermit” from: http://www.kermitproject.org
Old-school scriptable tool for almost any modem communication related tasks.
; Kermit script for router firmware update via serial line
; Router: TL-MR3220 v1.2 (original bootloader)
; File: "wrt_ser_upload.ksc"
set line /dev/rfcomm3
set speed 115200
set carrier-watch off
set flow-control none
set handshake none
set prefixing all
; Echo serial line to console
SET INPUT ECHO ON
; Clear console input buffer
LINEOUT \21
; Wait for console prompt
INPUT 3 :/#
; System reboot request
LINEOUT reboot
; Wait for U-Boot prompt
INPUT 180 Autobooting in 1 seconds
; Login into u-boot console
OUTPUT tpl
; Wait for u-boot prompt
INPUT 3 ar7240>
; Prepare U-Boot for incomming file
LINEOUT loadb 0x81000000
; Wait for u-boot ACK
INPUT 3 Ready for binary (kermit) download
; Send new firmware file
SEND ~/openwrt-18.06/bin/targets/ar71xx/tiny/openwrt-ar71xx-tiny-tl-mr3220-v1-squashfs-factory.bin
; Wait for u-boot prompt
INPUT 3 ar7240>
; Erase target flash memory
LINEOUT erase 0x9f020000 +0x3c0000
; Erase completed
INPUT 60 Erased 60 sectors
; Wait for u-boot prompt
INPUT 3 ar7240>
; Write new firmware to flash
LINEOUT cp.b 0x81000000 0x9f020000 0x3c0000
; Wait for done
INPUT 60 done
; Wait for u-boot prompt
INPUT 3 ar7240>
; Boot into new system
LINEOUT bootm 0x9f020000
; Quit
QUIT 0
This Kermit script updates OpenWRT firmware for TL-MR3220 router v1.2

Router documentation:
https://openwrt.org/toh/tp-link/tl-mr3420
Kermit documentation:
http://www.kermitproject.org
http://www.columbia.edu/kermit/ek.html
https://www.emcraft.com/stm32f429discovery/loading-linux-images-over-uart
HC-06 bluetooth module documentation:
http://www.martyncurrey.com/bluetooth-modules/
http://wiki.pinguino.cc/index.php/SPP_Bluetooth_Modules
https://mcuoneclipse.com/2014/03/30/getting-bluetooth-working-with-jy-mcu-bt_board-v1-06/
HC-06 Firmware reference:
https://www.instructables.com/id/Upgrade-Your-3-Bluetooth-Module-to-Have-HID-Firmwa/
http://dangerousprototypes.com/blog/2012/10/05/open-source-bluetooth-module-firmware/
http://elasticsheep.com/2012/06/bluetooth-module-firmware-dump/
https://github.com/pfalcon/blutunode
http://byron76.blogspot.com/search/label/bluetooth
TP-Link MR3420 setup OpenWRT v18.06
OpenWrt is a powerful Linux distribution for embedded devices. Especially for routers with reduced memory and performance. This objective has contributed to an extreme level of optimization of this distribution, allowing also a high margin of flexibility and really easy setup.
This distribution usually fits on many embedded devices, the complete list can be found at this link: http://wiki.openwrt.org/toh/start
Don’t expect magics from this configuration, you can’t install all the available software, simply because we don’t have enough RAM / ROM memory. Sometimes it is possible to overcome some limitations, for example extending the RAM memory with the ZRAM or SWAP file, extending the root filesystem with a USB flash memory device. However, a stable and robust configuration requires a careful evaluation of the installed services and their impact on system resources. Software as imagemagick or ffmpeg, which tries to allocate a large amount of memory, will likely fail with the segmentation error.
However, everything comes from source and everything is customizable. You can even avoid to install web interface and configure everything by ssh console and UCI command line tool, or build your own web GUI or Service supported by a solid and flexible cross-build system.
Thanks to the excellent work of all OpenWrt team, time to time, we have a new and fresh release to build.
Check your system requirements first: http://wiki.openwrt.org/doc/howto/buildroot.exigence
This new release includes linux kernel updates, different security and bug fixes.
Clone v18.06 branche:
git clone -b openwrt-18.06 git://git.openwrt.org/openwrt/openwrt.git openwrt-18.06
Or master branche:
git clone git://git.openwrt.org/openwrt/openwrt.git openwrt
Next, update feeds:
cd openwrt-18.06/
./scripts/feeds update -a
Configure build system:
make menuconfig
Select router options:
Install LUCI web interface:
./scripts/feeds install luci
Select Luci web interface from menuconfig:
LuCI ---> 1. Collections ---> <*> luci
Choose packages carefully, because we have only 4mb of storage. This amount of memory is enough for many specialized device with a limited set of features like a router or AP. In order to take advantage of many of the packages provided by OpenWrt, it is essential to extend the memory with external USB storage. Blockmount package and root overlay filesystem can do this trick: https://openwrt.org/docs/techref/block_mount
Select block-mount:
Base system ---> <*> block-mount
Kernel modules ---> USB Support ---> <*> kmod-usb-storage
Kernel modules ---> Filesystems ---> <*> kmod-fs-ext4
Another solution is to remove all ip-v6 support. Is configured by default and also supported from kernel side. Hacking on Kernel configuration is especially useful when support for specific hardware is required or simply to enable debugging features or disable something to save space.
Linux kernel configuration:
make kernel_menuconfig
Careful with kernel settings, most of them are unsafe. Don’t touch things, if you are not aware about what are they really doing. At best, you’ll get a slow kernel with a lot of useless code.
Build firmware:
make -j8
Finally, we can find all binary files in “bin/targets/ar71xx/tiny/”
1,2K giu 13 12:04 config.seed
2,8K giu 13 12:07 openwrt-ar71xx-tiny-device-tl-mr3420-v1.manifest
2,7M giu 13 12:07 openwrt-ar71xx-tiny-root.squashfs
3,8M giu 13 12:07 openwrt-ar71xx-tiny-tl-mr3420-v1-squashfs-factory.bin
3,6M giu 13 12:07 openwrt-ar71xx-tiny-tl-mr3420-v1-squashfs-sysupgrade.bin
1,2M giu 13 12:07 openwrt-ar71xx-tiny-uImage-lzma.bin
3,5M giu 13 12:07 openwrt-ar71xx-tiny-vmlinux.bin
3,5M giu 13 12:07 openwrt-ar71xx-tiny-vmlinux.elf
1,2M giu 13 12:07 openwrt-ar71xx-tiny-vmlinux.lzma
1,2M giu 13 12:07 openwrt-ar71xx-tiny-vmlinux-lzma.elf
4,0K giu 13 12:07 packages
1,1K giu 13 12:07 sha256sums
To program the device for the first time is sufficient to upload “factory.bin” to the router, from it’s own classic web interface as usual. For subsequent upgrades from LUCI web interface use “sysupgrade.bin”.
Next topics:
1) Serial debug console
2) Customize your build
3) Remote development
Reference:
All documentation and howto: http://wiki.openwrt.org/doc/start
Multiple builds in one single checkout: http://wiki.openwrt.org/doc/devel/env
Detailed build instructions: http://wiki.openwrt.org/doc/howto/build
Easy patch management: http://wiki.openwrt.org/doc/devel/patches
Creating packages: http://wiki.openwrt.org/doc/devel/packages
TP-LINK MR3420 hardware
TL-MR3420 is Wireless N Router with USB 2.0 Port for UMTS/HSPA/EVDO USB Modem.
Model NameTL-MR3420 |
Dimensions6.9 x 4.4 x 1.2 in. (174 x 111 x 30 mm) |
Power9VDC / 0.85A |
Ports#1 – USB 2.0 #1 – Ethernet WAN 10/100Mbps #4 – Ethernet LAN 10/100Mbps |
Antennas#2 – 3dBi Detachable Omni Directional Antennas |
Wireless Transmit Power20dBm (Max. EIRP) |
CPUAtheros AR7241@400MHz |
RAM32 MB |
Flash4 MB |
Arduino Nano v3 internal temperature sensor
Calibration data:

Download data & formulas in excel.
Atmega documentation says:
The voltage sensitivity is approximately 1 mV/°C and the accuracy of the temperature measurement is +/- 10°C.
Measured temperature is a sum of ambient temperature and chip’s TDP.
In fact it rises up for few minutes after the chip is powered and may change in base of load.
// Read Atmega328P internal temperature sensor // long read_temp() { // Read temperature sensor against 1.1V reference ADMUX = _BV(REFS1) | _BV(REFS0) | _BV(MUX3); // Start AD conversion ADCSRA |= _BV(ADEN) | _BV(ADSC); // Detect end-of-conversion while (bit_is_set(ADCSRA,ADSC)); // return raw data return ADCL | (ADCH << 8); } // Convert raw temperature data to °C double conv_temp(long raw_temp) { // f(x) = (raw - offset) / coeff return((raw_temp - 324.31) / 1.22); } void setup() { Serial.begin(115200); } void loop() { Serial.println(conv_temp(read_temp()), 1); delay(500); }Datasheet Atmega 328P – https://www.microchip.com/wwwproducts/en/ATmega328p
It is a curious fact that putting chips in the freezer, after a few minutes when the temperature drops below zero, the chip stops working.




