Recently, the Wi-Fi router stopped working for me and after some thought I ordered the Asus RT-N16. I wanted to finally get acquainted with alternative firmware. Characteristics of this ruter were already described on Habré. So, DD-WRT is installed (v2.24), a samba is running, a system flash drive is plugged into the first port, and an external hard drive is inserted into the second one. And then I became interested: can I run my programs on this router? I did not find online manuals for building programs under the router and I hope to fill the gap with this article. Let me give you a step by step guide with a description of the small problems encountered on the way.
As an experimental program, I wanted to run Easysync, which I recently wrote about . I repeat that this is an open program for synchronizing files in the dropbox style. The program is written using Qt 4, and Unison is used as the synchronization engine. So, this article describes how to compile Qt, Unison, Easysync for MIPS architecture and talks about running Easysync on your home router.
Mistress on the note.
Routers use non-standard processors.Home users are used to x86 architecture, Intel and AMD processors.The Asus RT-N16 uses a Broadcom BCM4718 processor with MIPS architecture.There may not be enough resources on the router itself to build the program, and therefore programs are usually compiled on a big brother (for example, a familiar desktop computer), but under the desired architecture.This process is called cross-compiling.
Instruments.
We will need a working computer with Linux on board. I used Ubuntu;
Compilers (gcc, g ++);
Standard libraries C, C ++;
Utilities in the form of GNU make, TAR, GZIP, GIT, and so on;). In the case of Ubuntu, most are already installed.
Steps
The first thing we need is to understand how DD-WRT programs are assembled at all. A page in their wiki introduces up to date. Particularly interesting section Instructions . There is a link to the toolchain (hereinafter - toolchain), which is used to build DD-WRT from source. The tool in this case is the Uclibc library compiled for the desired architecture, as well as the compiler. So, the toolchain is swinging from the DD-WRT site. It is not written there, but everything is built under the x86_64 architecture. Therefore, if you do not see something with a value of 64 (x86_64 or amd64) in the terminal, typing the command uname -m , then you will have to install a new version of Linux. An alternative method is to build the toolchain myself, but I preferred to install the system I need. After waiting for the download to complete (and this is currently 716 MB), we proceed to the next item.
We open archive, in it folders with toolchains under different architectures. We need toolchain-mipsel_gcc4.1.2. I unpacked this folder in / home / fralik /. Why toolchain-mipsel_gcc4.1.2? Mipsel, because I saw that optware is placed on the router from mipsel packets, which means that the order of bytes from the youngest to the oldest (little-endian) is used. The rest of the folders containing mipsel in the name, in my opinion, are used to assemble the components of the core DD-WRT.
Pay attention to the first line! Without it, the program will not build and an error will be issued:
/home/fralik/toolchain-mipsel_gcc4.1.2/bin/../lib/gcc/mipsel-linux-uclibc/4.1.2/../../../../include/c++/4.1.2/ cstdio: 126: error: ':: printf' has not been declared
We collect, check that everything works on the router.
Go to the terminal in the folder with Qt. It is necessary to pay attention to the mkspecs / qws folder. It stores Make files for different architectures. For example, mkspecs / qws / linux-mips-g ++ / qmake.conf . Copy the linux-mips-g ++ folder into linux-mipsel-g ++ :
Edit the mkspecs / qws / linux-mipsesl-g ++ / qmake.conf file so that it uses the mipsel-linux- * commands instead of the mips-linux- * command. I use as flags
-mel -march = mips32r2
Next, proceed to the Qt configuration. But first, install libxext-dev, otherwise we get an error:
Qt is now configured for building. Just run 'make'.
Once everything is built, you must run 'make install'.
Qt will be installed into /usr/local/Trolltech/Qt-4.7.2
The first time we configured Qt for the current architecture, the second for MIPS. In the second command, the xplatform argument points to the folder that we created in step 6. I removed the support for unnecessary things: no-qt3support, no-phonon, no-audio-backend, -nomake example, etc. As a result, we see the following message:
Qt is now configured for building. Just run 'make'.
Once everything is built, you must run 'make install'.
Qt will be installed into /usr/local/Trolltech/QtEmbedded-4.7.2-mips
Run make . You can go for a smoke or brew tea. =) At this step, I have another problem:
.obj / release-shared-emb-mips / qrect.o: In function `QRectF :: toAlignedRect () const ':
qrect.cpp :(. text + 0x1468): undefined reference to `ceilf '
qrect.cpp :(. text + 0x1488): undefined reference to `ceilf '
The fact is that in the uclibc library the ceilf function is not enabled by default. You can, of course, rebuild the library and add this function there, but we still use the toolchain from DD-WRT and this means there is also a library on the router without the ceilf function. In this step, I danced a long time with a tambourine, trying to turn the ceilf challenge into a ceil . But Qt was unmoved. I had to tackle the scalpel, especially considering that I would not need the QRect class. Open the file ~ / qt-everywhere-opensource-src-4.7.2 / src / corelib / tools / qrect.cpp , find the line 2379. Change to:
int xmax = int ((float) ((int) xp + w));
that is, we replace the call
qCeil (xp + y)
on
(float) ((int) xp + y)
We perform a similar operation on line 2381, and also in line 640 of the ~ / qt-everywhere-opensource-src-4.7.2 / src / corelib / tools / qtimeline.cpp file Call make again, this time the process should complete successfully.
We carry out
sudo make install
We check that we now have a Qt library under MIPS (despite Qt’s assurances that the installation will take place in the /usr/local/Trolltech/QtEmbedded-4.7.2-mips folder, I have everything installed in / usr / local / Trolltech / Qt -4.7.2 ):
/usr/local/Trolltech/Qt-4.7.2/lib/libQtCore.so.4.7.2: ELF 32-bit LSB shared object, MIPS, MIPS32 version 1 (SYSV), dynamically linked (shared shared libs), not stripped
Moving on to the Easysync build.
# Go to some directory, for example, cd ~ git clone git: // github.com/fralik/ Easysync.git cd Easysync / server / usr / local / Trolltech / Qt-4.7.2 / bin / qmake easysync-server.pro make # check: file build / easysync-server
Now we need Unison. Despite its usefulness, it is not in optware. We will collect it directly on the router. Go to the router via ssh or telnet.
ipkg-opt install buildroot ocaml mkdir / mnt / unison cd / mnt / unison wget http: // www.seas.upenn.edu / ~ bcpierce / unison // download / releases / stable / unison-2.40.61.tar.gz tar xvfz unison-2.40.61.tar.gz ocaml mkProjectInfo.ml > Makefile.ProjectInfo # Before collecting unison, you need to make a symbolic link from libncurses to libcurses ln -s / opt / lib / libncurses.so.5.7 / opt / lib / libcurses.so.5.7 ln -s / opt / lib / libcurses.so.5.7 / opt / lib / libcurses.so.5 ln -s / opt / lib / libcurses.so.5 / opt / lib / libcurses.so make NATIVE = false UISTYLE = text . / unison -version cp . / unison / opt / bin / unison
Here the key point is ocaml mkProjectInfo.ml> Makefile.ProjectInfo . Without this, it will not gather.
Now we need to run all that we have collected. Suppose the router address is 192.168.2.1 and the / mnt directory is accessible to us
scp / usr / local / Trolltech / Qt-4.7.2 / lib / libQtCore.so.4.7.2 root @ 192.168.2.1: / opt / lib scp / usr / local / Trolltech / Qt-4.7.2 / lib / libQtNetwork.so.4.7.2 root @ 192.168.2.1: / opt / lib scp / usr / local / Trolltech / Qt-4.7.2 / lib / libQtSql.so.4.7.2 root @ 192.168.2.1: / opt / lib / cd < Easysync / server > # Packing Easysync-server in one file to make it easier to transfer to the router: . / build_package_dd-wrt.sh scp dd-wrt_bundle.tar.gz root @ 192.168.2.1: / mnt
Go to the router, in the folder / mnt , unpack easysync-server-mipsel32.tar.gz
Then it makes sense to check the work of the unison without Easysync (you can refer both to the documentation of the unison itself and to the Easysync install files ). After setting up the unison, go back to the router, edit the file config.ini.sample and run:
./setup_dd-wrt.sh
That's it, now we have a synchronization server on our home router. If you can connect to the router from outside, then the synchronization will work from anywhere.
Brief squeeze
You can build programs for DD-WRT using the toolchain from their site. For C ++ programs, you must use #define NEED_PRINTF .
Despite the lack of unison in the assembly of optware, it can be assembled on a router. You can, in principle, do cross-compilation, but I did not understand this.
Qt almost seamlessly builds under MIPS: +1 to the cross-platform nature of your programs.
Easysync is now on home routers! It is worth noting that after rebooting the service will not be started automatically. Most likely, it will not even be marked as checked (because the installation flag is stored in / tmp ). You can install it again using the / opt / bin / easysync-server -i command or you can start it without installing it using the /opt/etc/init.d/easysync-server start command . For those who are interested in Easysync, but do not want to build it from source, an already compiled version is available .
Update 05/30/2016
User Nabytovych suggests that some links are outdated with time. Updated links to toolchain and Qt.