A Docker image to run an old version of Buildroot (buildroot-2014-02) based on Debian Wheezy
1.1K
This is a work in progress, it is fully usable and runs correctly, but documentation is still incomplete.
Buildroot-armv7 is a Docker image (in wich Buildroot is not included), a set of scripts, configuration files and Buildroot external tree to easily setup an emulation environment where to run, debug and reverse engineer the Netgear DVA 5592 router executables. This environment uses Docker, Buildroot and Qemu to build a root file system and emulate a board with an ARMv7 Cortex A9 processor, a quite old Linux kernel, version 3.4.11-rt19 with appropriate patches, uClibc 0.9.33.2, and old versions of other libraries.
sig_verify
sig_verify library callsgdbserver on the emulated Machinegdb in the host machinesig_verifymysig_verify: a script that does the same job as sig_verifysig_verifyOn a Linux box, the only OS supported:
$ sudo adduser *yourusername* docker
$ sudo apt-get install qemu qemu-block-extra qemu-kvm qemu-slof qemu-system \
qemu-system-arm qemu-system-common qemu-system-mips qemu-system-misc \
qemu-system-ppc qemu-system-s390x qemu-system-sparc qemu-system-x86 \
qemu-user qemu-user-binfmt qemu-utils
$ sudo apt-get install binwalk
valerio@ubuntu-hp:~$ mkdir br # configuration script will create folders here
valerio@ubuntu-hp:~$ cd br
valerio@ubuntu-hp:~/br$ git clone https://github.com/digiampietro/buildroot-armv7.git buildroot-armv7
br-armv7-config.sh script will download Buildroot, Linux kernel, router firmware and will configure the environment
valerio@ubuntu-hp:~/br$ cd buildroot-armv7
valerio@ubuntu-hp:~/br/buildroot-armv7$ ./br-armv7-config.sh
valerio@ubuntu-hp:~/br/buildroot-armv7$ docker pull digiampietro/buildroot-armv7
valerio@ubuntu-hp:~/br/buildroot-armv7$ cd docker/
valerio@ubuntu-hp:~/br/buildroot-armv7/docker$ ./dockrun.sh
valerio@BRHOST:~$ cd ~/br/buildroot-armv7
valerio@BRHOST:~/br/buildroot-armv7$ ./brmake dvaemu-emu_arm_vexpress_defconfig
valerio@BRHOST:~/br/buildroot-armv7$ ./brmake # takes a loooong time
valerio@BRHOST:~/br/buildroot-armv7$ exit
root@BRHOST:/src/misc# exit
valerio@ubuntu-hp:~/br/buildroot-armv7/docker$ cd ../qemu-run/
valerio@ubuntu-hp:~/br/buildroot-armv7/qemu-run$ ./qr
...
reeing init memory: 160K
smsc911x 4e000000.ethernet: eth0: SMSC911x/921x identified at 0xc08c0000, IRQ: 47
Welcome to Buildroot
buildroot login: root
root@buildroot:~# uname -a
Linux buildroot 3.4.11-rt19 #1 SMP PREEMPT Fri Sep 28 18:46:38 UTC 2018 armv7l GNU/Linux
root@buildroot:~#
/dva-root, the firmware files and file system images are included in the folder /dva-firm:
root@buildroot:~# ls /dva-root/
bin dev.tar.gz mnt sbin usr
data etc proc sys var
dev lib root tmp www
root@buildroot:~# ls /dva-firm/
DVA-5592_A1_WI_20180405.sig root-fs.bin
boot-fs.bin set-nandsim.sh
# halt and then press Ctrl-A followed by the key XThe purpose of the emulation environment is to run, as much as possible, router executables in a Qemu virtual machine. This means not only that the machine must have an ARM v7 Cortex-A9 processor, but that the kernel and the libraries should be the same version, or compatible versions, used in the router.
The emulated environment should have:
libgcrypt.so.11)The root file system can be built with a cross compilation toolchain able to generate binaries for the ARM architecture on an Intel based Linux PC; but building the kernel, the libraries and the needed packages can be very challenging and time consuming because of the various version dependency that each package can have with other packages and standard libraries (the so called dependency hell). For this reason it is better to select a build tool able to manage this dependency hell, the most popular building tools for embedded devices are:
Buildroot has been the tool chosen for this reverse engineering project. It has been easy to learn ed effective in building the required root file system.
Initial idea was using the latest Buildroot version available (buildroot-2018-05) on the last Ubuntu version (18.04.1 LTS, Bionic Beaver), but this buildroot version doesn't have the option to use uClibc, it has uClibc-ng that is not fully compatible with the router's binaries compiled with uClibc; the Gnu libgcrypt crypto library is a newer version, not fully compatible wth the router's binaries. It is practically impossible to downgrade these two libraries and others because of the dependency hell.
Another idea was to use an older Buildroot version (buildroot-2014-02) that has the same router's uClibc version, compatible version of Gnu libgcrypt crypto library and similar versions of other libraries. The problem is that this buildroot version, on Ubuntu 18.04, gives multiple compilation errors, almost impossible to fix; changing gcc version doesn't help to solve all the issues.
The solution has been to use a Docker image, based on Debian Wheezy released in 2013, to run buildroot-2014-02; this docker image is able to run this version of buildroot without any issues.
During the setup of this environment many other issues have arisen, described below in the description of various configurations.
The main purpose of the Docker image is to have a Linux environment able to run buildroot-214.02 without issues, for this reason the image is based on Debian Wheezy (released in 2013) with additional packages needed to run buildroot-2014.02, including packages and QT libraries to do a make xconfig with a GUI. The Docekerfile is quite simple and doesn't include Buildroot.
Buildroot is installed in the user's home directory because both the user and his home directory are mapped inside the Docker image using the following shell script, docker/dockrun.sh, to run the Docker image:
#!/bin/sh
export GDISPLAY=unix/$DISPLAY # forward X11 display to the host machine
export GUSERNAME=`id -u -n` # current user's username
export GUID=`id -u` # current user's user id
export GGROUP=`id -g -n` # current user's primary group name
export GGID=`id -g` # current user's primary group id
export GHOME=$HOME # current user's home directory
export GSHELL=$SHELL # current user's shell
export GRUNXTERM=0 # flag start lxterminal, useful in windows
export GPWD=`pwd` # current working directory
docker run -h BRHOST \
--rm \
-v /tmp/.X11-unix:/tmp/.X11-unix \
-v $HOME:$HOME \
-e DISPLAY=$GDISPLAY \
-e GUSERNAME=$GUSERNAME \
-e GUID=$GUID \
-e GGROUP=$GGROUP \
-e GGID=$GGID \
-e GHOME=$GHOME \
-e GSHELL=$SHELL \
-e GRUNXTERM=$GRUNXTERM \
-e GPWD=$GPWD \
-it digiampietro/buildroot-armv7
In this script:
-v, inside the running image at exactly the same path-v /tmp/.X11-unix:/tmp/.X11-unix option has the purpose do display, on the host, X11 applications running inside the Docker image--rm options terminate the Docker image process after exiting from the interactive shell; This is needed to prevent having a lot of unused stopped images-v) are passed from the host to the docker image with the purpose to create, on the fly, inside the image, the same user existing on the host with exact same attributes (username, uid, primary group, shell, home dir). This job is accomplished by the following entrypoint script docekr/startup.sh:#!/bin/sh
#
# add current user and user's primary group
#
groupadd -g $GGID $GGROUP
useradd -u $GUID -s $GSHELL -c $GUSERNAME -g $GGID -M -d $GHOME $GUSERNAME
usermod -a -G sudo $GUSERNAME
echo $GUSERNAME:docker | chpasswd
if [ "$GRUNXTERM" = "1" ]
then
# become the current user and start a shell
su -l -c lxterminal $GUSERNAME
# another root shel
lxterminal
else
# become the current user and start a shell
su -l $GUSERNAME
# another root shell
/bin/bash
fi
This Docker usage pattern allows to transparently share the user's home directory between the host and the Docker image and can be used every time there is a need to use a Docker image to transparently run software that cannot be run on the host and that will use and/or modify files in user's home directory.
In this case the Buildroot folder is not installed inside the Docker image, but will be installed in user's home directory and, in this way, the Buildroot folder will remain persistent across Docker image invocations.
The Buildroot configuration is stored in an external tree in the folder ext-tree, Buildroot itself can be launched with the shell script brmake that, basically, change directory in the Buildroot directory and execute a make BR2_EXTERNAL=<path to ext-tree>.
The ext-tree folder has the following content:
ext-tree/
├── board
│ └── dvaemu
│ ├── kernel-defconfig
│ ├── overlay
│ │ └── etc
│ │ └── profile.d
│ │ └── set-prompt.sh
│ └── post-build.sh
├── Config.in
├── configs
│ ├── dvaemu-emu_arm_vexpress_defconfig
│ └── uClibc-0.9.33.config
├── external.desc
├── external.mk
├── package
│ └── klish
│ ├── 0001-klish-help-param-optional.patch
│ ├── Config.in
│ └── klish.mk
└── patches
└── linux
├── 0002-module.h-remove-p2v8-from-module-id-string.patch
├── 0004-jffs2_make_lzma_available.patch
├── 0005-jffs2_eofdetect.patch
└── 0006-jffs2_make_lzma_high_priority.patch
ext-tree/board/dvaemu contains files for the fictitious board called dvaemu (for DVA 5592 router emulation)
ext-tree/board/dvaemu/kernel-defconfig contains the kernel configuration, saved in a defconfig file; main differences, compared with the default kernel configuration, have been introduced to be more similar to the router's kernel and to run it in QEMU:
ext-tree/board/dvaemu/overlay in this path's subfolder there is the set-prompt.sh script used to setup the prompt inside the QEMU emulated machine
ext-tree/board/dvaemu/post-build.sh this is the Buildroot post-build script, used mainly to copy router's root file system and firmware to the root image of the emulated machine
ext-tree/Config.in, external.desc, external.mk are files needed by Buildroot to use the external tree
ext-tree/configs/dvaemu-emu_arm_vexpress_defconfig contains the buildroot configuration, it is based on the qemu_arm_vexpress_defconfig, included in buildroot, to emulate a Versatile Express ARM board with an ARMv7 Cortex-A9 processor. The most important modified options are:
ext-tree/configs/uClibc-0.9.33.config this is the uClibc configuration, the main differences, compared with the default, have been introduced to be compatible with the router's binaries and to include debugging symbols in the library files. The inclusion of debugging symbols has been problematic: uClibc don't obey to the general option included in the Buildroot configuration, has his own flag for this purpose; the problem is that enabling his own flag the compilation gives impossible to fix errors, for this reason a workaround, described below, has been used:
ext-tree/package, in this directory is included the klish package, but, unfortunately, it is not compatible with the router's klish configuration files, probably the klish application in the router has been modified in incompatible ways
ext-tree/patches/linux: linux patches to have the kernel more similar to the router's kernel, the patches are:
The Buildroot User's Manual is a very good guide on how to configure and run Buildroot; in this environment Buildroot make commands should be executed using the brmake script inside the buildroot-armv7 folder, the most useful commands are:
./brmake xconfig (or ./brmake menu-config) to configure Buildroot options;
./brmake linux-xconfig (or ./brmake linux-menuconfig) to configure the Linux Kernel
./brmake uclibc-menuconfig (the xconfig version is not available for uClibc) to configure the uClibc library
./brmake savedefconfig to save the Buildroot configuration in the external tree, on the file ext-tree/configs/dvaemu-emu_arm_vexpress_defconfig
./brmake linux-update-defconfig to save the Linux Kernel configuration in the external tree, on the file ext-tree/board/dvaemu/kernel-defconfig
./brmake uclibc-update-defconfig to save the uClibc configuration in the external tree, on the file ext-tree/configs/uClibc-0.9.33.config
./brmake clean to delete all build products (including build directories, host, staging and target trees, the images and the toolchain)
./brmake distclean to delete everything, including configuration files; needed to build for a new target, should not be needed with this environment;
./brmake linux-dirclean removes the whole kernel build directory, to be used when kernel configuration changes are made;
./brmake -s printvars to dump all the variables known to make;
./brmake to build the kernel and the root file system.To run QEMU there is the qr script inside the qemu-run folder, this script runs QEMU using the root file system built by Buildroot. The script is the following:
#!/bin/bash
MYDIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
. $MYDIR/../set-env.sh
cd $MYDIR
export QEMU_AUDIO_DRV="none"
qemu-system-arm -M vexpress-a9 \
-cpu cortex-a9 \
-m 1024 \
-nographic \
-kernel $BRIMAGES/zImage \
-drive file=$BRIMAGES/rootfs.ext2,index=0,media=disk,format=raw,if=sd \
-dtb $BRIMAGES/vexpress-v2p-ca9.dtb \
-net nic \
-net user,hostfwd=tcp::2222-:22,hostfwd=tcp::9000-:9000 \
-append "rw console=ttyAMA0 console=tty root=/dev/mmcblk0"
The first three lines set environment variables and change directory to that of the script, the fourth line disables the audio driver (the emulated board doesn't emulate audio hardware), the qemu-system-arm options select:
Content type
Image
Digest
Size
226.2 MB
Last updated
about 7 years ago
docker pull digiampietro/buildroot-armv7