Pages

Sunday, 2 March 2014

VM From Scratch

I have spent a lot of time installing various Linux distributions, automating all the complex things, trying out things like puppet, writing my own management scripts. Well, in the end of the day, the goal was to run a very simple application. Usually these applications run inside a hypervisor, and we don't really want to spend time with the operating system's management. All I want is a Virtual Machine that has my application and I don't want to know more about it. I think I'm even not interested in sshing into that box. I want to build VMs quickly.

There are several tools to build a VM, and I believe all do their job perfectly. But I think it's time for me to try to build a VM from scratch. The components, that I will use are:

  • linux
  • crosstool-ng
  • buildroot

Getting the kernel

At the time of writing the linux version that I picked, is 3.10.32 - I believe, it has a long term support. So let's dive in, and get the source code

cd /data/matelakat/kernel
wget https://www.kernel.org/pub/linux/kernel/v3.x/linux-3.10.32.tar.xz
tar -xJf linux-3.10.32.tar.xz

Now that we have the sources, we can create a cross compiler.

crosstool-ng

This tool will help me to build a cross compiler. At the initial phase, my target architecture is 686 32bit. I picked this one, as I would like to test the VM with nested virtualization (ESXi inside VirtualBox), and you can't run 64 bit guests there. So let's get started:

first, download the tools, and check out a specific revision. This makes it easier for anyone to reproduce.

mkdir /data/matelakat/xtool
cd /data/matelakat/xtool
hg clone http://crosstool-ng.org/hg/crosstool-ng
cd crosstool-ng/
hg checkout 9321d9d7af9b

Now comes the crosstool-ng specific part. First, we need to actually install crosstool-ng:

./bootstrap
./configure --prefix=$(cd .. && pwd)/ctng
make
make install
export PATH=$PATH:$(cd .. && pwd)/ctng/bin

The next step is to generate a configuration for the crosstool. I will start by getting a sample configuration file, and overwriting it with my config:

cd /data/matelakat/xtool/
mkdir configuration
cd configuration/
ct-ng x86_64-unknown-linux-gnu
cp /data/matelakat/vmfromscratch/crosstool-ng/.config .config
ct-ng menuconfig

If you are happy with the config, it's time to build the cross compiler. My config will put the downloaded sources and the built tools to ../src and ../x-tools, so I need to create those directories in advance. Also, as I have a laptop with 4 cores, I will use 6 jobs simultaneously:

mkdir ../src ../x-tools
time ct-ng build.6

I can definitely tell: my CPU cores are busy - some hot air flows out of my good old Lenovo R500. After around an hour, the crosscompiler was ready:

du -shc ../x-tools/
364M../x-tools/
364Mtotal

Build the Kernel

Now that we have a crosscompiler, we can get back to the kernel directory, configure the tool paths, and compile a new kernel:

cd /data/matelakat/kernel/linux-3.10.32/
cp /data/matelakat/vmfromscratch/linux/.config ./
make oldconfig
make menuconfig
make -j 4

Unfortunately, I didn't measure the time it took, but it was quite fast

Build the Root Filesystem

Now that I have a nice kernel I also need a root filesystem. Buildroot will help me to build that:

mkdir /data/matelakat/br
cd /data/matelakat/br
wget -qO - http://buildroot.uclibc.org/downloads/buildroot-2014.02.tar.gz | tar -xzf -
cd buildroot-2014.02/
cp /data/matelakat/vmfromscratch/buildroot/config .config
make menuconfig
make

Putting it all together

Now that I have everything, I only need to create an iso cd with my new system

mkdir isoroot
cp ../br/buildroot-2014.02/output/images/rootfs.cpio.gz isoroot/initrd.img
cp ../kernel/linux-3.10.32/arch/i386/boot/bzImage isoroot/
cp ../br/buildroot-2014.02/output/images/isolinux.bin isoroot/isolinux/
cp isolinux.cfg isoroot/isolinux/
mkisofs -J -o minsys.iso -b isolinux/isolinux.bin -c isolinux/boot.cat -no-emul-boot -boot-load-size 4 -boot-info-table isoroot/
qemu-system-i386 -M pc -cdrom minsys.iso -net nic,model=e1000 -net user

Next steps

My next step will be to automate all these things.

Sunday, 9 February 2014

PDF - Two pages per page to one pages per page

So we had a PDF, it's size was 297 x 215 mm. Each page of this PDF contained two pages, like this:
 Page 1 of the input file                       Page 1 of output   Page 2 of output
    +------------------------------+            +---------------+  +---------------+
    |               |              |            |               |  |               |
    |               |              |            |               |  |               |
    |               |              |            |               |  |               |
    |               |              |            |               |  |               |
    |               |              |            |               |  |               |
    | Page 1        | Page 2       |            |   Page 1      |  |   Page 2      |
    |  of the book  |  of the book |            |    of the book|  |    of the book|
    |               |              |            |               |  |               |
    |               |              |            |               |  |               |
    |               |              |            |               |  |               |
    |               |              |            |               |  |               |
    |               |              |            |               |  |               |
    +------------------------------+            +---------------+  +---------------+
                                     +------->
 Page 2 of the input file            +------->  Page 3 of output   Page 4 of output
    +------------------------------+            +---------------+  +---------------+
    |               |              |            |               |  |               |
    |               |              |            |               |  |               |
    |               |              |            |               |  |               |
    |               |              |            |               |  |               |
    |               |              |            |               |  |               |
    | Page 3        | Page 4       |            |   Page 3      |  |   Page 4      |
    |  of the book  |  of the book |            |    of the book|  |    of the book|
    |               |              |            |               |  |               |
    |               |              |            |               |  |               |
    |               |              |            |               |  |               |
    |               |              |            |               |  |               |
    |               |              |            |               |  |               |
    +------------------------------+            +---------------+  +---------------+
So to do this, I extracted the left sides as page-0.pdf, and the right sides as page-1.pdf to the folder out, and the n joined these together:
#!/bin/bash
set -eux

# Default resolution is 720 dpi
# For points, use 72 dpi

# The actual pdf was 297 x 215 mm --(720 dpi)----> 8418 x 6094 pixels
# I only want to extract half of it -------------> 4209 x 6094
# For the right page, I need an offset -(72 dpi)-> -421.0 0

INPUT_FILE="$1"

rm -rf ./out
mkdir out

ghostscript -o "out/%d-0.pdf" -sDEVICE=pdfwrite -g4209x6094 \
-c "<</PageOffset [0 0]>> setpagedevice" -f "$INPUT_FILE"

ghostscript -o "out/%d-1.pdf" -sDEVICE=pdfwrite -g4209x6094 \
-c "<</PageOffset [-421.0 0]>> setpagedevice" -f "$INPUT_FILE"

ghostscript -o "singlepage-$INPUT_FILE" -sDEVICE=pdfwrite -dPDFSETTINGS=/ebook \
    $(ls out/* | sort -V)

rm -rf ./out
References:
http://superuser.com/questions/54054/convert-pdf-2-sides-per-page-to-1-side-per-page

Sunday, 2 February 2014

Back to school - Coursera - Crypto, Control Theory, Android

After KR told me that he signed up for a Cryptography course on Coursera, I decided to do the same. I learned crypto at Uni, but that was a long time ago, so I thought, it's time to refresh my memories. The story does not end here, as this weekend, I signed up to two more courses: an Android course, and a Robot Control course. I'm a bit behind at the moment for each of the courses. I find this Coursera amazing, and I hope my wife won't kill me before I finish these courses. Should you be interested, here is a list of the courses that I started:

  • https://class.coursera.org/crypto-009
  • https://class.coursera.org/conrob-002
  • https://class.coursera.org/android-001

I just started to watch the video lectures for the Android class, and watching this video atm as recommended by the professor:

Sunday, 25 August 2013

Ubuntu - change dns server for proxychains

This is really a not for myself, so that I don't forget it. So if you are using proxychains to access some servers through a proxy, you might want to use that system's dns server. In that case, presuming that you are running ubuntu, please modify the file:
/usr/lib/proxychains3/proxyresolv
When you open the file, it will be obvious what needs to be changed.

Thursday, 8 August 2013

Cross compiling uwsgi with buildroot

I really like uwsgi, and would like to see it on my raspberry PI, so I decided to create a buildroot environment, and add uwsgi as a package. It means cross compiling uwsgi. In this blog, I will log the process.
One thing to note, that the text was shortened with:
s,/data/matelakat/repa/.workspace/buildroot-2013.05,$BUILDROOT,g
Let's check out a tagged version
git checkout tags/1.9.9 -B build-fixes
And make sure, it builds on the host system:
make
...
############## end of uWSGI configuration #############
*** uWSGI is ready, launch it with ./uwsgi ***

Cross compilation

First, I set the compiler and the precompiler, as suggested by Roberto:
CC="$BUILDROOT/output/host/usr/bin/arm-unknown-linux-gnueabi-gcc" \
CPP="$BUILDROOT/output/host/usr/bin/arm-unknown-linux-gnueabi-cpp" make
I got this error (newlines inserted for readability)
*** uWSGI linking ***
$BUILDROOT/output/host/usr/bin/arm-unknown-linux-gnueabi-gcc -o uwsgi ...
...
plugins/transformation_chunked/chunked.o -lpthread -lm -rdynamic -ldl -lz 
-L/usr/lib/x86_64-linux-gnu -lpcre -luuid -lssl -lcrypto 
-L/usr/lib/x86_64-linux-gnu -lxml2 -lpthread -ldl -lutil 
-lm /usr/lib/python2.7/config/libpython2.7.so -lutil -lcrypt
/data/matelakat/repa/.crosstool/x-tools/arm-unknown-linux-gnueabi/lib/gcc/
arm-unknown-linux-gnueabi/4.8.2/../../../../arm-unknown-linux-gnueabi/bin/
ld: skipping incompatible /usr/lib/x86_64-linux-gnu/libpthread.so when searching for -lpthread
/usr/lib/x86_64-linux-gnu/libpthread.a: could not read symbols: File format not recognized
collect2: error: ld returned 1 exit status
*** error linking uWSGI ***
make: *** [all] Error 1
That seems to be an issue, my host system's libpthread will definitely fail to link with the arm binary. I added a print statement, and an assert False.
*** uWSGI linking ***
['-lpthread', '-lm', '-rdynamic', '-ldl', '-lz', '-L/usr/lib/x86_64-linux-gnu -lpcre',
 '-luuid', '-lssl', '-lcrypto', '-L/usr/lib/x86_64-linux-gnu -lxml2', '-lpthread',
 '-ldl', '-lutil', '-lm', '/usr/lib/python2.7/config/libpython2.7.so', '-lutil', '-lcrypt']
Traceback (most recent call last):
  File "uwsgiconfig.py", line 1220, in 
    build_uwsgi(uConf(bconf))
  File "uwsgiconfig.py", line 401, in build_uwsgi
    assert False
AssertionError
make: *** [all] Error 1
It seems to be using my host's libpython2.7.so. But that's not the point (now). The real point is the '-L/usr/lib/x86_64-linux-gnu -lxml2' part. I need to find out from where does it come. I need to add some additional breakpoints. As my computer has 2 CPU cores, uwsgi build employs a compile queue. For now, as I would like to debug things, I want to run the build sequentially, so that it is easier to follow what's happening. So I cleaned the build, and set the CPUCOUNT environment variable:
CC="$BUILDROOT/output/host/usr/bin/arm-unknown-linux-gnueabi-gcc" \
CPUCOUNT=1 \
CPP="$BUILDROOT/output/host/usr/bin/arm-unknown-linux-gnueabi-cpp" make
I created a shell script with these contents. The libs variable is used to collect the libraries during plugin compilation. Let's add a print statement to see when we modify this array
./doit.sh  | grep ADDING
...
[ADDING LIBRARY] ['-lpthread', '-ldl', '-lutil', '-lm',
 '/usr/lib/python2.7/config/libpython2.7.so', '-lutil']
...
Oh, that doesn't look good, I bet, that's the python plugin. Let's print out the plugin's name as well
./doit.sh  | grep ADDING
...
[ADDING LIBRARY - python] ['-lpthread', '-ldl', '-lutil',
 '-lm', '/usr/lib/python2.7/config/libpython2.7.so', '-lutil']
...
Okay, shelve it for now, and go back to the original problem, see from where does the '-L/usr/lib/x86_64-linux-gnu -lxml2' line come from. That might be lxml. It seems, that xml2-config --libs is called to detect the library path. The host's binary was called this time, instead of the cross tool's. So let's add the crosstool bin path to the path:
#!/bin/bash

set -eux
PATH="$BUILDROOT/output/host/usr/arm-buildroot-linux-gnueabi/sysroot/usr/bin:${PATH}" \
CC="$BUILDROOT/output/host/usr/bin/arm-unknown-linux-gnueabi-gcc" \
CPUCOUNT=1 \
CPP="$BUILDROOT/output/host/usr/bin/arm-unknown-linux-gnueabi-cpp" make
But as I modified my script, I ended up with this error:
python uwsgiconfig.py --build
$BUILDROOT/output/
host/usr/arm-buildroot-linux-gnueabi/sysroot/usr/bin/
python: 1: $BUILDROOT/
output/host/usr/arm-buildroot-linux-gnueabi/sysroot/usr/bin/python: 
Syntax error: word unexpected (expecting ")")
make: *** [all] Error 2
It's not an x86 executable:
file $BUILDROOT/output/host/usr/arm-buildroot-linux-gnueabi/sysroot/usr/bin/python
$BUILDROOT/output/host/usr/arm-buildroot-linux-gnueabi/sysroot/usr/bin/python: symbolic link to `python2'
file $BUILDROOT/output/host/usr/arm-buildroot-linux-gnueabi/sysroot/usr/bin/python2.7
$BUILDROOT/output/host/usr/arm-buildroot-linux-gnueabi/sysroot/usr/bin/python2.7:
 ELF 32-bit LSB executable, ARM, version 1 (SYSV), dynamically linked (uses shared libs),
 for GNU/Linux 3.2.48, not stripped
that's why I have issues with that python. So I modify my shell script to start a host python built by buildroot:
#!/bin/bash

set -eux
PATH="$BUILDROOT/output/host/usr/arm-buildroot-linux-gnueabi/sysroot/usr/bin:${PATH}" \
CC="$BUILDROOT/output/host/usr/bin/arm-unknown-linux-gnueabi-gcc" \
CPUCOUNT=1 \
CPP="$BUILDROOT/output/host/usr/bin/arm-unknown-linux-gnueabi-cpp" \
$BUILDROOT/output/build/host-python-2.7.3/python uwsgiconfig.py --build
Note, that I also left out the make, and am directly calling uwsgiconfig.py. This is the next error that I get:
*** uWSGI linking ***
...
$BUILDROOT/output/host/usr/lib/libz.so: file not recognized: File format not recognized
collect2: error: ld returned 1 exit status
*** error linking uWSGI ***
file $BUILDROOT/output/host/usr/lib/libz.so.1.2.7 
$BUILDROOT/output/host/usr/lib/libz.so.1.2.7:
 ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked,
 BuildID[sha1]=0x5bbf6ecd4880bbbbb73c57e048dba2d36aa299e0, not stripped
well, that's interesting. That file is in the host directory, that's a host module of course. Maybe the library path is wrong?
*** uWSGI linking ***
['-lpthread', '-lm', '-rdynamic', '-ldl', '-lz',
 '-L$BUILDROOT/output/host/usr/arm-buildroot-linux-gnueabi/sysroot/usr/lib -lpcre',
 '-luuid', '-lssl', '-lcrypto', '-lxml2 -lz -lm -ldl', '-lpthread', '-ldl',
 '-lutil', '-lm', '-lpython2.7', '-lcrypt']
There is the pcre library, which looks suspicious. So I added another entry to the path, which will find the target system's pcre config script.
#!/bin/bash

set -eux
PATH="$BUILDROOT/output/build/pcre-8.32:$BUILDROOT/output/host/usr/arm-buildroot-linux-gnueabi/sysroot/usr/bin:${PATH}" \
CC="$BUILDROOT/output/host/usr/bin/arm-unknown-linux-gnueabi-gcc" \
CPUCOUNT=1 \
CPP="$BUILDROOT/output/host/usr/bin/arm-unknown-linux-gnueabi-cpp" \
$BUILDROOT/output/build/host-python-2.7.3/python uwsgiconfig.py --build
The problem is still there. Let's look at the build output again:
** uWSGI linking ***
['-lpthread', '-lm', '-rdynamic', '-ldl', '-lz', '-lpcre', '-luuid',
 '-lssl', '-lcrypto', '-lxml2 -lz -lm -ldl', '-lpthread', '-ldl',
 '-lutil', '-lm', '-lpython2.7', '-lcrypt']
...
$BUILDROOT/output/host/usr/bin/arm-unknown-linux-gnueabi-gcc -o uwsgi -L$BUILDROOT/output/host/usr/lib
...
I need to find out from where does that come. As a first guess, I am printing out ldflags.
LDFLAGS ['-L$BUILDROOT/output/host/usr/lib']
That could be an issue. Let's try to find out which plugin is doing this.
./doit.sh | grep LDFLAG
...
[ADDING LDFLAG - python] ['-L$BUILDROOT/output/host/usr/lib']
...
As I looked at plugins/python/uwsgiplugin.py, found the include issue, and the libs. So I decided to do a really dirty hack to override libs (It's getting late here) That left me with another issue:
plugins/python/python_plugin.o: In function `init_uwsgi_embedded_module':
python_plugin.c:(.text+0x1d6c): undefined reference to `Py_InitModule4_64'
collect2: error: ld returned 1 exit status
Let's hack the include directory as well, maybe that is causing the issue. as I was there, I also hacked the library paths. And this is my reward:
make clean
./doit.sh
...
############## end of uWSGI configuration #############
*** uWSGI is ready, launch it with ./uwsgi ***

Sunday, 9 June 2013

ICS - mexamine

First, start xboard as an ics client:
xboard -ics -icshost freechess.org
I am assuming, that both players, a and b started xboard, and logged in. In order to examine a chess game together with a friend of yours, issue the following commands (The a: part is indicating which player is entering the command):
a: examine
This will print out the game id. In my case, it is 194. Now, the other player needs to observe that game
b: observe 194
Now, we are observing the game with player B. The next step is to enable mexamine:
a: mexamine b
After this, both player are examining the same game. To end the examination:
a: unexamine

Tuesday, 4 June 2013

Direct PCB prints + etch

I printed some sample patterns with my solid ink printer to PCB, and etched them. I am pleased with the results. I think I will need a better etch fluid (more fluid or more concentrated fluid). Here you go:
source for the patterns