Monday, May 25, 2009

Time loop in VMware guest

If the guest VM should always boot with the same date/time on the RTC, two actions must be done:

1. Edit the .vmx file of the guest VM, and add a line like this:

rtc.starttime = "1238765436"

where the number is a 1970-based epoch, in seconds.

2. Boot the guest VM, and run VMtools. Disable the host-to-guest time synchronization, and reboot the guest VM.

Then, the guest VM will always boot with the same date and time in the calendar.

Wednesday, May 20, 2009

Setup a Samba server


Edit /etc/samba/smb.conf and add set the basic settings in the 'global' section. The only important item is the "security=user" option.

The important thing is to enable the samba users with:

# smbpasswd -a

which adds (-a) a new user to the samba user database, and sets a new password to it.
Not doing this causes a 'permission denied' error in the client when attempting to mount it.

The syntax to mount a samba share is:

# mount -t cifs -o user=,pass= //server/resource

In the /etc/samba/smbusers file, it is possible to map sambe user names to UNIX user names, but it is not required to do so. By default, samba does a one-to-one mapping.

If we want to announce the samba shares on the network, it is necessary to start the 'nmb' service. Use the normal chkconfig interface to start smb and nmb on startup:

# chkconfig --add nmb
# chkconfig --level 3 nmb on
# chkconfig --level 4 nmb on
# chkconfig --level 5 nmb on




Tuesday, May 12, 2009

Set up VMware server on a x86_64 system

Setting up a 1.0.8 VMware server on a 64-bit PC creates some problems because VMware is distributed in binary form only (rpm packages) for 32-bit i386 architectures .

In my case, the target distribution is a Fedora 10 x86_64, so the first step was installing the 32-bit base libraries, that is, glibc, X11, etc. This can be easily done with the 'yum' installer:

# yum install glibc.i686 libgcc.i386 lidstdc++.i386 zlib.i386
# yum install libX11.i386 libXtst.i386 libXrender.i386 libXt.i386

Also, some Perl modules are required for the VMware installer to work properly:

# yum install perl-ExtUtils-Embed

which is not 32-bit specific, of course.

Now, we are in a position where the VMware-server package may be installed:

# rpm -ivh VMware-server-1.0.8.i386.rpm

If we hadn't installed the i386 libraries, the vmware-server rpm could be installed anyway but problems would appear when running the vmware-config.pl script, which runs the vmware-ping utility, which is a 32-bit one.

Now, some patches to the vmware distribution must be installed. In my case, the vmware-any-any-117d could not be installed, as it returned an error when compiling the kernel modules (something about an already defined symbol). The update that worked fine was 'vmware-update-2.6.27-5.5-2.tar.gz' but this depends on the particular kernel version that runs in my target system.

Installing this update is quite straightforward, however, this tarball contains a compiled 'update' executable which is intended for 32-bit installations. I decided to delete it and recompile manually before running the update:

# tar xfz vmware-update-2.6.27-5.5-2.tar gz
# cd vmware-update-2.6.27-5.5-2
# rm update
# gcc update.c -o update
# ./runme-pl

The 'runme.pl' script automatically launches the 'vmware-config.pl' script. I accepted all the proposed default answers, except for the NAT networking, which I answered 'no', the host-only networking -also 'no'- and the TCP port to listen to, which is by default 904, but I changed it to 902 to match the default port the clients connect to (why this discrepancy in the defaukt values?).

If I had accepted the 904 port in the server side, then the client wouldn't connect to the server and would return a 'connection refused' error. Fortunately, the client connectiomn dialog accepts an optional port number after the server IP, i.e. myserver:904.

After this, the client still returned an error when attempting to connect to the client: 'login incorrect (username/password)'. After some investigations, I found out that the problem was in the PAM libraries. Again, only the 64-bit pam libraries were installed, but vmware expects the 32-bit libraries, so the user authentication failed. Unfortunately, the pam i386 and x86_64 libraries cannot coexist simultaneously, because there are some common files provided by both packages (i.e. the man pages). So, the workaround is to download the pam package and its dependencies, and do a force install:

# yumdownloader --resolve pam.i386
# rpm -ivh --force *.rpm

Also, we must configure the proper path to the pam libraries.
Edit /etc/pam.d/vmware-authd :

#%PAM-1.0
auth sufficient /lib/security/pam_unix2.so shadow nullok
auth required /lib/security/pam_unix_auth.so shadow nullok
account sufficient /lib/security/pam_unix2.so
account required /lib/security/pam_unix_acct.so

After all this, vmware server runs correctly and clients may connect.

To install the vmware client (a.ka. vmware-server-console), all I had to do is install the client rpm:

# rpm -ivh VMware-server-console-1.0.8-126538.i386.rpm
# vmware-config-server-console.pl

and that's all.

Tuesday, December 16, 2008

Using code sourcery to build a toolchain

Though it looks quite primising, it was very tough trying to build a cross toolchain using code-sourcery.

They provide prebuilt binary toolchains, but I none with the gcj compiler, so I had to use their build scripts to build my own toolchain.

The script they provide wasn't designed to run on any machine. In fact, it does not run on a machine different to the author's one. There are many hardwired directories and custom build is very tough. Though I tried to understand it, at the end some unexplainable errors appeared.

In conclusion, code sourcery for custom toolchains is not an option nowadays.

Testing the MIKA JVM

Downloading mika requires subversion as there seem to be no tarballs available for download.
Subversion requires port 3690, plus other tools.

Mika's repository is :
http://www.k-embedded-java.com/mika/trac/wiki/DownloadMikaNew

The dependencies are: jikes and jam.

Jikes is a java compiler from IBM. It is available as an rpm for FC4. No problems installing it.

Jam is a set of Ant scripts for building java applications. Just run configure, make, and make install. However, my FC4 has some broken links: /etc/alternatives/java_sdk_exports.
I had to edit the link to point to the installed JDK: /usr/lib/jvm/java-1.4.2-gcj

To build mika, I had to edit the Configuration/cpu/arm file, where the toolchain executables are defined. It wrongly assumes that the compiler was arm-linux-gcc, ignoring the CC variable.

To run the build process, type:
ant -DPLATFORM=default -DJAM.PLATFORM=arm-linux

Results are similar to the Skelmir's VM but with a different balance: setVisible is 3 times faster, but the screen creation is 3 times slower. The net performance is more or less the same.


Mika looks quite lightweight in terms of the flash footprint required.

Using crosstool-ng

The objective is to build a valid toolchain for ARM that supports gcj with the GTK peer classes.
The latest gcc is required (version 4.3) which has the latest GNU classpath version, and still evolving.

I tried several options to build a toolchain: crosstool, code-sourcery, etc, but crosstool-ng is the only one that was able to build a 4.3 toolchain without problems. The original crosstool was able to build a toolchain up to gcc 4.1.1/glibc 2.3.2. Newer versions of gcc or glibc did not compile.

Building and installing crosstool is very straightforward. Create a temporary directory, untar the tarball (crosstool-1.3.0) and run:

mkdir /usr/crosstool-ng (as root)
chown /usr/crosstool-ng

./configure --prefix=/usr/crosstool-ng
make
make install

and then add /usr/crosstool-ng/bin to the PATH variable.

The toolchain to be built is configured by running:
ct-ng menuconfig

There are some important hints:

1. The build tuple must be:
CT_BUILD=i686-pc-linux-gnu
which does not mean that the links i686-pc-linux-gcc -> gcc must be created. Crosstool-ng already creates its own wrapper scripts for this.

2. EABI
Defines how code is generated according to some specific conventions. gcc 4.3 is able to generate EABI-compliant code. All the user-space code must be compiled with the same EABI version, and the kernel must be compiled with EABI support if the user-space code is also EABI.
A toolchain may be created with EABI support, but this does not necessarily mean that the code generated is EABI. Some gcc flags control this. The glibc library was compiled using EABI, therefore the kernel must be compiled with EABI support, otherwise the 'init' program would not be loaded by the kernel.

3. Kernel headers
If we are using a new kernel (i.e. 2.6.1 or greater) then the best option is to use the sanitized kernel headers provided by the kernel's makefile. Crosstool-ng automatically invokes this makefile to generate the sanitized header set. By the way, using the latest 4.3 gcc, requires a late glibc (2.6 or 2.7), which in turn, requires a 2.6 kernel.

4. glibc ports
If the option "use glibc ports" is not enabled, the glibc compilation may return an error like "target arm is not supported". As of glibc 2.5, the architecture-dependent stubs of glibc are distributed as separate tarballs.

5. Dependencies
gcc 4.3 requires mrfp library version 2.3.2 or greater, which requires automake > 1.10 and autoconf > 2.60. There are no rpms for these versions for FC4, so I had to download the sources and install them manually

6. Enabling gcj/java support
Must enable the java language.
Also, the specific java/gtk support must be enabled in the gcc build flags:

CT_CC_EXTRA_CONFIG=

--enable-java-awt=gtk --enable-gtk-cairo --disable-gtktest
--x-libraries=/lib --x-includes=/include/X11

note that the GTK peer classes provided by GNU classpath require some X libraries, though the GTK compiled uses the Directfb frontend, not the X-lib frontend. It seems that it still uses some X libraries for rendering functionality or something like that. Hopefully, these libraries are not required in the target system. In particular, it requires the libXtst, libart, libXrender and libXrandr libraries.

It is important to set the pkg-config variables, so that the configure scripts of gcc and its subprojects are able to find the GTK libraries:

export PKG_CONFIG_PATH=/usr/lib/pkgconfig
export PKG_CONFIG_LIBDIR=/usr/lib/pkgconfig

the pkgconfig files (.pc) must be placed in these directories. Note that the 'prefix' keys in these files must be set to the location of the installed GTK files /usr.

there are GTK include files in different locations, such as: usr/lib/glib-2.0/include.

7. Restarting crosstool-ng
Crosstool has a nice feature that allows the process to be restarted at some specific stage, thus speeding up the trial and error build process. However, this functionality must be enabled in the menuconfig, and this functionality has some limitations:
1. changing some configuration items (i.e. gcc build flags) take no effect if the process is restarted. The entirre build process must be started from the beginning.
2. Do not break crosstool-ng while downloading the tarballs. If so, clean the tarballs directory as some files may be corrupted.

8. X libraries
Some GTK peer classes cannot be compiled because they require a GTK library compiled with xlib support. For instance, the cairo-xlib.h and gdk/gdkx.h include files are required.

After all these steps were solved, a toolchain with gcj/gtk support was built without errors.

Thursday, November 6, 2008

SIGIO terminates program

I have compiled the IPC/nt library (inter-process communications) for the i686 architecture, on a CentOS 5.2 release. Compilation was ok, but at runtime, the programs that link with this library die unexpectedly when receiving data from the IPC layer. The message shown is "I/O possible".

Of course, this did not happen on the original embedded systems this library was originally developed for, so I assume something has changed. There are two possibilities:

1. getpid() no longer returns the pid of the calling thread, but the pid of the entire process.
2. the default action of the SIGIO signal has changed, causing the program to terminate rather than ignoring the signal.

The mechanism that IPC/nt uses to work with asynchronous sockets is the following: a thread listening to SIGIO signals is created. Any asynchronous socket opened sets the owner of the SIGIO signals to the thread's pid (hence the getpid issue here). When data arrives (I/O is possible), a signal is sent to the thread which wakes up the other threads listening on the sockets using a mutex/condition variable.

Then I came across this note that explains what is happening (though it does not explain exactly what has changed):
If a nonzero value is given to F_SETSIG in a multi-threaded process running with 
a threading library that supports thread groups (e.g., NPTL), then a positive value
given to F_SETOWN has a different meaning: instead of being a process ID identifying
a whole process, it is a thread ID identifying a specific thread within a process.
Consequently, it may be necessary to pass F_SETOWN the result of gettid instead
of getpid(2) to get sensible results when F_SETSIG is used. (In current Linux threading
implementations, a main thread’s thread ID is the same as its process ID. This means that
a single-threaded program can equally use gettid(2) or getpid(2) in this scenario.)

So, I replaced the call to getpid() by a call to gettid(), which I have proven it is
also backwards compatible. It works fine.