Cross-compiling (ES series)


From SamyGO
Revision as of 18:46, 6 January 2013 by E3V3A (talk | contribs) ((X) Installing the Samsung Firmware Sources)
Jump to: navigation, search

This is Work In Progress !!

No answers/solutions can be expected here yet. If you need quick answers Google the forums.

@developers:
Do not change or update this page without first checking/asking on the "Talk" page or support forum thread for latest status/info.


Cross Compiling

This is an introduction to cross-compiling for MST10P (MStar/MediaTek) based TV sets. It is primary intended as a crash course for getting even a novice to be able to quickly compile his/her own programs to run on their TV sets. As such, we will assume that you are using a Windows based PC with a basic installation of Cygwin. The modification for using a Linux based PC will then be minimal and even simpler.

Introduction

If you have never cross-compiled anything before, this is the right place for you. If you already have experience and knowledge with cross compilation, this wiki may still be helpful to get you started. If you are looking for information on how to build your own cross-compiler, this place is not for you. (Look HERE instead.)


What this Wiki will cover and not.

- We will use a popular pre-compiled cross-compiler.
- We will work on a Windows (Intel/AMD) based PC.
- All examples herein are based on a UExxES5700 TV set, and should be reproducable on the same.

- We will not cover the compilation of a cross-compiler!
- We will not cover other cross-compilers, operating systems or processor architectures.


A few Questions and Answers:

Q:  What is a cross-compiler?
A:  Basically it is just a compiler built to run on one type of processor (e.g. Intel x86), 
    but which is built and configured for compiling code for another processor (e.g. ARM).

Q:  Should I get a pre-compiled cross-compiler or compile my own?
A:  We hate to waste our time compiling compilers, so always try to find a pre-compiled one!

Q:  Where can I find help to configure my cross-compiler?
A:  Not here. If it's not already in here or in our forums, we don't know.

Q:  Do I need to install the TV specific platform sources? (Such as UExxES6xxx.zip ?)
A: ** It depends on what you need to compile. (See below.)

Q:  Do I have to install the Samsung platform ARM toolchain? (Such as VDLinux-ARMv7-4.4-202-toolchain-v2r2-20110630.tgz ?)
A:  ** Hopefully not, but it depends on what you need to compile. (See below.)

** = unknown and not fact!


Things you need to get started.

WIP! This need checking and adjustment...

1. Install Cygwin for Windows. (Not necessary, but very helpful for the various *nix tools and file utilities.)
2. Install a good text editor (EditPlus, Notepad++ etc.)
3. Download a suitable pre-compiled cross-compiler. 
4. Download your TV kernel sources.
5. Download your TV firmware sources. (?)
6. 



Steps:

(A) Install & Verify the pre-compiled cross-compiler on your PC.
(B) Verify your TV sets processor / architecture. 
(C) Compile "HelloWorld" and run it on TV.

Extras:

(D) Installing the Samsung cross-compiler.

(E) Installing your TV Kernel sources.   
(F) Installing your TV firmware sources.

(G) Compiling the Kernel
(H) Compiling a Kernel module


...

(A) Installing the Cross-Compiler

Go to the Mentor Graphics website, and download the "Sourcery CodeBench Lite Edition" from HERE. (You'll need to supply an email to get a download link.) There you will get a few different choices based on the platform. You will have choices such as:

arm-2012.09-63-arm-none-eabi.exe
arm-2012.09-63-arm-none-eabi-i686-mingw32.tar.bz2
arm-2012.09-64-arm-none-linux-gnueabi.exe
arm-2012.09-64-arm-none-linux-gnueabi-i686-mingw32.tar.bz2
arm-2012.09-64-arm-none-linux-gnueabi-i686-pc-linux-gnu.tar.bz2

If you use a x86 Windows based system, choose: "arm-2012.09-64-arm-none-linux-gnueabi.exe". Run it, and when asked, change the installation directory to something simple like: C:\zarm\csbench
The rest of the installation procedure is self explanatory.

After installation, verify that the cross-compiler PATH variable is properly set and working:

$ arm-none-linux-gnueabi-gcc --version

arm-none-linux-gnueabi-gcc.exe (Sourcery CodeBench Lite 2012.09-64) 4.7.2
Copyright (C) 2012 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 

Since this is a Windows installer, Cygwin may or may not catch the updated system PATH variable. Open a new Cygwin shell and check:

$ echo $PATH

If it's not working, you'll have to add the following line in your ~/.bash_profile file. (On some systems this file is called ".profile".)

PATH=${PATH}:/cygdrive/path/to/csbench/bin;

This should do it.

*******************************************************************************
If you want to have access to the cross-compiler's man pages you'll have to 
add the following line to /etc/man.conf:

 MANPATH_MAP /path/to/csbench/bin /path/to/csbench/share/doc/arm-arm-none-linux-gnueabi/man

and/or possibly this line to your ~/.bashrc

 MANPATH=${MANPATH}:/path/to/csbench/share/doc/arm-arm-none-linux-gnueabi/man;

*******************************************************************************


If you have more questions, check out the Sourcery ARM FAQ.


(B) Determine the TV processor & architecture

In order to properly compile and run anything, you need to know what processor you're programming for. Here is how to find that information.

1. Root your TV and login to a shell. (Instructions HERE.)

2. Verify your TV's processor type and architecture by executing the following at the shell prompt.


shell> cat /proc/cpuinfo

Processor       : ARMv7 Processor rev 0 (v7l)
processor       : 0
BogoMIPS        : 1794.04
processor       : 1
BogoMIPS        : 1794.04
Features        : swp half thumb fastmult vfp edsp neon vfpv3
CPU implementer : 0x41
CPU architecture: 7
CPU variant     : 0x3
CPU part        : 0xc09
CPU revision    : 0 
Hardware        : amber3
Revision        : 0000
Serial          : 0000000000000000


Now, this is not obvious in any way. Problem is that an "ARM" processor is really only a license to manufacture a processor according to ARM Holding's specifications. Therefore any hardware manufacturer can have a processor with an ARM "core". In addition, and to make it even more confusing, an ARM "core" belong to an ARM "architecture" which belong to an ARM "family", whose numbers are little related...

The only way to get some insight is looking at the WikiPedia entries:

1. "List of ARM microprocessor cores"
2. "ARM architecture"

and compare what you find there with the interpretation of the ARM "Features" above, where:


-----------------------------------------------------------------------------
Feature         Description
-----------------------------------------------------------------------------
swp             SWP (SWaP) instruction, which is used to implement a binary semaphore (mutex)
half            Half-precision (16-bit) floating point, "__fp16" data type in gcc
thumb           Thumb instructions
fastmult        Fast multiplication
vfp             Vector Floating Point instruction extension
edsp            Enhanced DSP instructions
neon            NEON SIMD instructions
vfpv3           Vector Floating Point instruction extension Version 3
-----------------------------------------------------------------------------


So from the above we think we have a dual core processor of the ARMv7-R or ARMv7-A architecture. (Of either the Coretx-R or A families, respectively.) But the only NEON enabled processors with both DSP and VFPV3, are the Cortex-A8 and "Cortex-A9 MPCore". But this is not good enough...for a perfectionist. So we search in the ARM on-line documentation for "Main ID Register":


Main ID Register bit functions:

-----------------------------------------------------------------------------
Bits    Field                   Value   Function
-----------------------------------------------------------------------------
[31:24] Implementor             0x41    implementor: ARM
[23:20] Variant                 0x3     variant number or major revision of the processor
[19:16] Architecture            0x7     architecture is given in the feature registers
[15:4]  Primary part number     0xC09   part number: Cortex-A9
[3:0]   Revision                0x0     revision number or minor revision of the processor
-----------------------------------------------------------------------------


Here is a brief list of ARM primary part numbers.


ARM core       CPU part
------------------------
ARM920         0x920
ARM926         0x926
ARM946         0x946
ARM966         0x966

ARM1136        0xb36
ARM1156        0xb56
ARM1176        0xb76
ARM11 MPCore   0xb02

Cortex A5      0xc05
Cortex A8      0xc08
Cortex A9      0xc09
Cortex A15     0xc0f
Cortex R4      0xc14 
Cortex R5      0xc15
------------------------

We finally conclude that our TV processor contains a dual core Cortex-A9 MPCore from the ARMv7-A architecture.

Done!


(C) Compiling "HelloWorld"

We would like to compile our "Hello World" program for our TV.
So create a file like this:

hellow.c

#include <stdio.h>
int main(void) {
       printf("Hello world\n");
       return (0);
}

We now, need to determine what compiler flags to use with our cross-compiler. There are several dozens of compiler options for the CodeSourcery compiler, but we are only interested in the following.


Here are the most important CodeSorcery ARM Cross Compiler options:

-march=                 Specify the name of the target architecture
-mcpu=                  Specify the name of the target CPU
-mfpu=                  Specify the name of the target FPU hardware/format

-marm                   Generate code in 32 bit ARM state.
-mthumb                 Generate code for Thumb state

-mlittle-endian         Assume target CPU is configured as little endian
-mthumb-interwork       Support calls between Thumb and ARM instruction

-mglibc                 Use GNU C library
-muclibc                Use uClibc C library

-static                 Compile and include all static libraries


Here are the choices for the above options:

Known ARM ABIs (for use with the -mabi= option):
  aapcs aapcs-linux apcs-gnu atpcs iwmmxt

Known ARM architectures (for use with the -march= option):
  armv2 armv2a armv3 armv3m armv4 armv4t armv5 armv5e armv5t armv5te armv6
  armv6-m armv6j armv6k armv6s-m armv6t2 armv6z armv6zk armv7 armv7-a armv7-m
  armv7-r armv7e-m ep9312 iwmmxt iwmmxt2 native

Known ARM CPUs (for use with the -mcpu= and -mtune= options):
  arm1020e arm1020t arm1022e arm1026ej-s arm10e arm10tdmi arm1136j-s
  arm1136jf-s arm1156t2-s arm1156t2f-s arm1176jz-s arm1176jzf-s arm2 arm250
  arm3 arm6 arm60 arm600 arm610 arm620 arm7 arm70 arm700 arm700i arm710
  arm7100 arm710c arm710t arm720 arm720t arm740t arm7500 arm7500fe arm7d
  arm7di arm7dm arm7dmi arm7m arm7tdmi arm7tdmi-s arm8 arm810 arm9 arm920
  arm920t arm922t arm926ej-s arm940t arm946e-s arm966e-s arm968e-s arm9e
  arm9tdmi cortex-a15 cortex-a5 cortex-a7 cortex-a8 cortex-a9 cortex-m0
  cortex-m1 cortex-m3 cortex-m4 cortex-r4 cortex-r4f cortex-r5 ep9312 fa526
  fa606te fa626 fa626te fa726te fmp626 generic-armv7-a iwmmxt iwmmxt2 mpcore
  mpcorenovfp native strongarm strongarm110 strongarm1100 strongarm1110 xscale

Known ARM FPUs (for use with the -mfpu= option):
  fpa fpe2 fpe3 fpv4-sp-d16 maverick neon neon-fp16 neon-vfpv4 vfp vfp3 vfpv3
  vfpv3-d16 vfpv3-d16-fp16 vfpv3-fp16 vfpv3xd vfpv3xd-fp16 vfpv4 vfpv4-d16


ARMed with our previous knowledge from part (B) we can try the following:

$ arm-none-linux-gnueabi-gcc.exe -march=armv7-a -mcpu=cortex-a9 -marm -mlittle-endian -mglibc -static hellow.c -o hellows
$ arm-none-linux-gnueabi-gcc.exe -march=armv7-a -mcpu=cortex-a9 -marm -mlittle-endian -mglibc hellow.c -o hellowd

Great! It seem to work. But as you can see, a statically compiled binary is about 100x bigger than a dynamically compiled one of size ~10K. But sometimes we need a static binary as it can help overcome crippled, buggy or platform specific system libraries.

But let's check if we got what we expected:

$ file hellows
hellows: ELF 32-bit LSB executable, ARM, version 1 (SYSV), statically linked, for GNU/Linux 2.6.16, 
not stripped

$ file hellowd
hellowd: ELF 32-bit LSB executable, ARM, version 1 (SYSV), dynamically linked (uses shared libs), 
for GNU/Linux 2.6.16, not stripped

$ arm-none-linux-gnueabi-objdump.exe -x hellows |less
...


Looks good, let's try to run it. ( /dtv/usb/sda1 )


ftp <tv_ip> 
ftp> put hellows /tmp/bin/hellows
ftp> put hellowd /tmp/bin/hellowd
ftp> quit

nc <tv_ip> 23 
shell> chmod 777 /tmp/bin/hellow*
shell> hellows
Hello world
shell> hellowd
Hello world

Excellent! We are now ready to try a more advanced example where we will make use of some platform specific system libraries to make a kernel module.


(X) Installing the Samsung Firmware Sources

Download the sources relevant to your TV set from the Samsung Open Source repository.
In our case (UE40ES5700) it would be UExxES6xxx.zip. For other ES models, it would be UNxxES8xxx.zip.


But these two are exactly the same, except the following:

1. E8 and E6 have slightly different VDLinux kernels
2. There is an additional OR1200.ZIP for the E8

The only files which are different are listed HERE.


After download, do test the downloaded zip archive with:

 $ unzip -t UExxES6xxx.zip

If you are curious to see detailed info of what's inside the ZIP archive before unzipping, do this:

$ unzip -Z UExxES6xxx.zip
...

Extract the ZIP file to a directory where you would like to keep your sources.

$ cd /zarm/src/
$ unzip UExxES6xxx.zip -d UExxES6xxx


This will unzip the following:

alsa-lib-1.0.23.tgz                            Advanced Linux Sound Architecture (audio and MIDI)
ATK.tgz                                        Accessibility Toolkit (screen User Interface)
binutils-2010q1.tgz                            A collection of binary tools (ld, as, nm, objdump etc.)
BROADCOM-bthid.tgz                             Broadcom Bluetooth HID drivers (keyboards, mice, game controllers)
BROADCOM-btusb.tgz                             Broadcom Bluetooth USB drivers (keyboards, mice, game controllers)
busybox-1.18.1.tgz                             Busybox combines many common UNIX utilities into a single executable
Cairo.tgz                                      A 2D graphics library (X Window, quartz, win32, PDF, PS, SVG file output)
FFMPEG.tar.gz                                  A cross-platform solution to record, convert and stream audio and video
glibc-2.11-2010q1.tgz                          The GNU C Library
Glibmm.tgz                                     A C++ interface for the popular cross-platform library Glib
gnutls-2.6.4.tar.gz                            GNU Transport Layer Security Library (SSL, TLS and DTLS protocols)
iptables-1.4.10.tgz                            Linux kernel firewall
libgcrypt-1.4.5.tar.gz                         A general purpose cryptographic library 
libgpg-error-1.7.tar.gz                        A library that defines common error values for all GnuPG components
LIBGPHOTO2.tar                                 The core library designed to allow access to digital camera by external programs
LibMMS_0.6.2.tgz                               A library for parsing mms:// and mmsh:// type network streams
libsoup.20120109.tgz                           An HTTP client/server library for GNOME
libtasn1-2.5.tar.gz                            The ASN.1 library used by GnuTLS
LIBUSB.tar                                     A C library that gives applications easy access to USB devices
Pango.tgz                                      A library for layout and rendering of multi-language text
RALINK_RTNET5572STA_V_2_5_0_1.tgz              Ralink RTnet RT5572 (Wifi USB dongle drivers)
RALINK_RTUTIL5572STA_V_2_5_0_1.tgz             Ralink RTnet RT5572 (Wifi USB dongle utilities)
readme.zip                                     HOW_TO_BUILD_X9X10.txt
SDL.tar.gz                                     Simple DirectMedia Layer (a multimedia library written in C)
uvc.tar.gz                                     USB Video Class (streaming webcams, digital cameras etc)
v4l2.tar.gz                                    Video4Linux-2 (a video capture API for Linux)
VDLinux_2.6.35.11.tgz                          Kernel sources (VDLinux, Tuxera NTFS, RFS, LinuStoreIII, FSR)
webkit-gtk.20120109.tgz                        WebKit is an open source web browser engine (Safari, Chrome)
WIRELESSTOOLS_29.tgz                           Wireless Tools (iwconfig, iwlist, etc)
xfsprogs-3.1.5.tgz                             A set of command-line tools to manage XFS filesystems


Which of these do you really need? Now that is the million dollar question. The simple and stupid answer is, that it depends on what you want to do.


a) If you need to compile some simple C-code using standard clibs and linux 
   system calls, you probably don't need any. (E.g. helloworld.c)

b) If you need to compile your own Kernel module (hellok.ko) you probably need:

   VDLinux_2.6.35.11.tgz

c) If you want to compile your own Kernel image (uImage) you probably only need:

   VDLinux_2.6.35.11.tgz

d) If you want to compile your own library object (somelib.so) you probably only need:

   VDLinux_2.6.35.11.tgz
   ++++

e) If you need to compile your own device driver you probably need:

   <the device driver sources>
   VDLinux_2.6.35.11.tgz
 ? glibc-2.11-2010q1.tgz
 ? Glibmm.tgz
 ? LibMMS_0.6.2.tgz

f) If you want to compile your own TV DSP (exeDSP, micom etc) you're screwed 
   (by Samsung) since there are no publicly available sources for that.


The better answer is, that it depends on how your kernel image has been setup and how you intend setup your compilation environment. We really don't want to have to setup and compile all sources from scratch, just to make a simple kernel module. The way to do that is by telling your cross-compiler where to find the kernel header files that it has to use the same configuration as that used to compile your kernel.

So for further details, we look at HOW_TO_BUILD_X9X10.txt inside the readme.zip. This file explains, in a very screwy way, how to build each of the items included on the UExxES6xxx.zip file. In fact you should not rely blindly on this info.

For example:

...
[ Building linux kernel ]

* Source code name : VDLinux_2.6.35.11.tgz 
* Unpack the kernel tarball and cd into it.
* Run "cd VDLinux_2.6.35.11/linux-2.6.35.11/".
* Run "cp -ar arch/arm/configs/X10P_defconfig_release .config".
* Run "make oldconfig".
* Run "make uImage".
 
[ Building busybox ]

* Source code name : busybox-1.18.1.tgz
* Unpack the busybox tarball and cd into it.
* Run "make clean". 
* Run "cp -ar configs/busybox_config .config".
* Run "make ARCH=arm CROSS_COMPILE=arm-v7a8v2r2-linux-gnueabi- oldconfig".
* Run "make ARCH=arm CROSS_COMPILE=arm-v7a8v2r2-linux-gnueabi- CONFIG_PREFIX=../temp_rootfs install".
* Run "cd ../temp_rootfs/bin".
...


Clearly, for general purpose use we need at least the VDLinux sources installed.
So we extract this in the same directory with:

$ (tar -zxvf VDLinux_2.6.35.11.tgz >vdlinux_tar.log) 2>&1


Here we have redirected the output to a log file for reference, while any errors will be shown on screen. This will create VDLinux_2.6.35.11 with the following sub-directories:

linux-2.6.35.11
TUXERA_NTFS
RFS_3.0.0_b043-LinuStoreIII_1.2.0_b039-FSR_1.2.1p1_b139_RTM


WIP!!

(Z) Place Holder Template

Bah!