Sunday, August 10, 2014

Cross compiling mtd tools

I need to compile mtd-tools for arm, to be precise Xilinx ZynQ z702 which, by the way, a very nice platform for moderately complex projects. The presence of an integrated FPGA is the key aspect of its "all programmable" tag-line. You can find more info on ZynQ HERE


I am currently working on ZynQ derivative and going to test the QSPI flash interface to NOR, and possibly the NAND interface (if the board is wired up). In any case, I need mtd tools because,
  • There is no n/w i/f on the target board to download the linux kernel image
  • Our linux kernel require to be run from flash (jffs2, jffs2 being the better choice?) root file system, not as a ramfs (ext2/3/4)
During the process, I was referring to MTD compilation notes at this TI page. But TI page is not very clear about cross compilation. So, here are my thoughts and steps I took to get it compiled.

Step 0: Get your cross compilation environment ready

Well, on ZynQ (or any other platform requiring cross compilation), setting up the tool chain is a subject by itself. Here I assume that you have (somehow) setup your cross compilation environment and the tool chain is available to you as ${CROSS_COMPILE}<toolchain binary>

Step1 : Get the source code

Mtd-utils require the following dependencies satisfied for compilation
Once download is complete, gunzip/untar the files into respective directories.

Prepare prefix directory

Zlib, lzo and e2fs progs being dependencies for mtd-utils, you want to keep all these in a place accessible by mtd-utils during compilation. That means, you need to install these libraries and header files. By default, the prefix (/usr/local/...) may not be a good idea because you are compiling these libraries for a different architecture (arm in my case). I have chosen a target prefix directory /export/prj/voler/mtd-utils/; you may choose something similar.
$ echo $CROSS_COMPILE
/export/prj/Xilinx/SDK/2014.2/gnu/arm/lin/bin/arm-xilinx-linux-gnueabi-
[om@hexcore /export/prj/voler/zlib-1.2.8]
$ arm-xilinx-linux-gnueabi-gcc
arm-xilinx-linux-gnueabi-gcc: fatal error: no input files
compilation terminated.

Cross compile Zlib

[om@hexcore /export/prj/voler/zlib-1.2.8]
$ ./configure –prefix=/export/prj/voler/mtd-utils/
This configure does not support cross compiling environment. So, we need to make manual changes to generated Makefile like the following
CC={CROSS_COMPILE}gcc
....
LDSHARED={CROSS_COMPILE}gcc -shared -Wl,-soname,libz.so.1,--version-script,zlib.map
CPP={CROSS_COMPILE}gcc -E
$make
....
[om@hexcore /export/prj/voler/zlib-1.2.8]
$ file /export/prj/voler/mtd-utils/lib/libz.so.1.2.8
/export/prj/voler/mtd-utils/lib/libz.so.1.2.8: ELF 32-bit LSB shared object, ARM, EABI5 version 1 (SYSV), dynamically linked, not stripped

Cross compile lzo

[om@hexcore /export/prj/voler/lzo-2.06]
$ ./configure --host=arm-xilinx-linux-gnueabi --prefix=/export/prj/voler/mtd-utils
configure: WARNING: if you wanted to set the --build type, don't use --host.
If a cross compiler is detected then cross compile mode will be used
configure: Configuring LZO 2.06
....
LZO configuration summary
-------------------------
LZO version : 2.06
configured for host : arm-xilinx-linux-gnueabi
source code location : .
compiler : arm-xilinx-linux-gnueabi-gcc
preprocessor definitions : -DLZO_HAVE_CONFIG_H=1
preprocessor flags :
compiler flags : -g -O2
build static library : yes
build shared library : no
enable i386 assembly code : no

LZO 2.06 configured.
[om@hexcore /export/prj/voler/lzo-2.06]
$ make ; make install
make all-am
----------------------------------------------------------------------
Libraries have been installed in:
/export/prj/voler/mtd-utils/lib

Cross compile e2fsprogs

[om@hexcore /export/prj/voler/e2fsprogs-1.42.11]
$ ./configure --host=arm-xilinx-linux-gnueabi –prefix=/export/prj/voler/mtd-utils
[om@hexcore /export/prj/voler/e2fsprogs-1.42.11]
$ make ; make install
cd lib/uuid/
make install

Cross compile mtd-utils

Mtd-utils has no ./configure script. That means, we need to manually change the Makefile for cross compilation related changes.
PREFIX = /home/temp/mtdutils
CROSS=arm-linux-gnueabi-

ZLIBCPPFLAGS = -I$(PREFIX)/include
ZLIBLDFLAGS = -L$(PREFIX)/lib

LZOCPPFLAGS = -I$(PREFIX)/include
LZOLDFLAGS = -L$(PREFIX)/lib

LDFLAGS += $(ZLIBLDFLAGS) $(LZOLDFLAGS)
# if you want the resulting binaries standalone binaries, add -static here
# LDFLAGS += $(ZLIBLDFLAGS) $(LZOLDFLAGS) -static
CFLAGS ?= -O2 -g $(ZLIBCPPFLAGS) $(LZOCPPFLAGS)
Edit the common.mk file and comment out the PREFIX=/usr line. Then make and install:
[om@hexcore /export/prj/voler/mtd-utils-9f10713]
WITHOUT_XATTR=1 make; make install

Precompiled binaries for ZynQ

Download precompiled binaries for ZynQ / ARM v7 from here :
Binary
Size
Md5sum
sha256sum
7676764
622e0d4bc7f3197c9dc0ccf00d93b498
0af126bc948522db9d821
1b9e479f41173c028e105
7bc27a02096957720f6bfb
11847584
f55e42e81a2e6944fa87aa0f97117ee0
f613c70337be8bbe316567
8715930e9cc004c18218d9
d9ed8f83ecf4acf04f56

A sample run here:
root@zynq:~# mtdinfo
Count of MTD devices: 5
Present MTD devices: mtd0, mtd1, mtd2, mtd3, mtd4
Sysfs interface supported: yes
root@zynq:~# mtdinfo /dev/mtd0
mtd0
Name: qspi-fsbl-uboot
Type: nor
Eraseblock size: 65536 bytes, 64.0 KiB
Amount of eraseblocks: 16 (1048576 bytes, 1024.0 KiB)
Minimum input/output unit size: 1 byte
Sub-page size: 1 byte
Character device major/minor: 90:0
Bad blocks are allowed: false
Device is writable: true