Sunday, February 25, 2007

Good news ! I was able to boot a home compiled kernel for Palm Tungsten E2 today. :-) This time, I downloaded an older kernel revision from hackndev svn (revision 382, I think, from April 2006). It's a modified 2.6.16 and it's probably the revision nerdfeliz used to compile his kernel. The adjustments were simple, and after some trial and error, I was able to setup an USB serial port. Here are the steps to build the TE2 kernel:

download hackndev kernel revision 382

in the main Makefile, change the CROSS_COMPILE to reflect the prefix name of your cross toolchain (mine was "arm-linux-")

in arch/arm/mach-pxa/palmte2/palmte2_buttons.c, remove the __exit macro from palmte2_buttons_remove

open gtkterm or minicom and open /dev/ttyACM0 in your desktop (or ACMx if you have other ACM devices)

All right, then ! Now, we have a working ARM linux system and a really expensive dumb terminal linked to it !!! Not quite. :-( I was unable to log in the remote system using gtkterm or minicom, either with "root" user or "default" (buildroot default user), even after playing with securetty and passwd/shadow configurations. Also, there's another sad bug: there's some kind of problem with the SD card driver, it keeps popping error messages. More to come...

Tuesday, February 20, 2007

In a previous post I have showed how to make new style system calls in linux x86. I've also remarked that assuming that the __kernel_vsyscall address was always at a fixed address was wrong. The proper way to get the function address would be declare it as "extern", and link it with with linux-gate.so.1. However, I don't know how to do that, because linux gate is virtual and ld can't find it. I'll post here another way, that gets the information passed to the running software by the ELF loader. It retrieves an auxiliary ELF structure, that is present in the stack, after the usual argc, argv and envp pointers.

First, let's modify our previous hello.asm to call a new function "get_kernel_vsyscall", and set the address returned as the system call address:

So, we changed "linux_gate" into a variable and filled it with the address returned by "get_kernel_vsyscall", basically. This function loops in the stack, beginning with argc, until it finds the correct (key, value) pair in the ELF header:; vsyscall.asmbits 32global get_kernel_vsyscall%define ELF_VSYSCALL_ID 32 ; defined in elf.h as AT_SYSINFO%define ELF_EOF_ID 0 ; defined in elf.h as AT_NULL

section .textget_kernel_vsyscall:; Returns the kernel vsyscall address from the; ELF aux vector. The vsyscall address is the; subroutine used for the new style system call.; in:; eax: the address, in the stack, of "argc"; out:; eax: the kernel vsyscall address, or zero; on error

Weird, eh ? We needed to look for the AT_SYSINFO field (ELF_VSYSCALL_ID in the code) in some extra vector provided by the ELF loader. Other executable formats would give those parameters some other way. We have two options, now: use a hardcoded vsyscall address or retrieve it from the ELF vector. Compile and link with "nasm -f elf hello.asm; nasm -f elf vsyscall.asm; ld -o hello hello.o vsyscall.o".

I've downloaded hackndev modified linux kernel. It's a heavily modified kernel, with support for a lot of ARM PDAs. After reading TE2 mailing lists and some fixups I was able to compile a Tungsten E2 specific kernel. I couldn't boot it, however, the screen just faded after booting and nothing else. I tried two different kernel revisions and two different "config" files, with no success. The kernel image that is correctly booting in my Palm is from April 2006. I'll continue my research to a proper kernel in hackndev svn around this date.

Sunday, February 18, 2007

We all know that the x86 architecture is bizarre. An interesting event that has happened in the last 10 years was the change of the "system call" instruction. We all remember from DOS time that we issued "int 0x21" to make a DOS system call, and "int 0x10" to make a ROM BIOS system call. Some of us has even played with the linux system call, "int 0x80". However, five years ago, when using a Pentium IV, someone has found out that the "int" instruction could be half as fast in a Pentium IV than in a Pentium III. Why was that ?

Intel introduced a new system call instruction in Pentium Pro/Pentium II, called "sysenter" that was supposed to be a "Fast System Call" facility. This meant that Pentium processors had two system call instructions: one that was the fast system call and the other, the slow system call (currently, there are three system calls: "int", "sysenter" and "syscall" !!!). Linux has since migrated to new style system calls. Instead of changing the "int" logic to the "sysenter" logic, another approach was taken. A new virtual shared library was created, called "linux gate". This library is virtual because it's like a standard .so library, but only exists in memory (do a "ldd /bin/ls" and see if your system is using "linux-gate.so.1"). Applications (like libc or other system call front-ends) may then call a simple function exported from this library, __kernel_vsyscall, and this function will "systenter", "int" or issue whatever instruction is necessary for completing the system call. So here we have quick dirty "hello world" written in NASM assembly for linux (should work on linux 2.6 for x86). The code assumes that __kernel_vsyscall is always mapped at 0xffffe400 in memory (which is wrong ;-)).

Sunday, February 11, 2007

I was unable to compile glibc with the target architecture set to xscale-linux-elf. I think I should have used arm-linux at this moment, which is the same that buildroot uses. Back to buildroot, I've removed the software that was giving compile errors (jffs2/mtd utils) and was able to create a basic root filesystem. I was unable to use the system, however, because I don't have an installed keyboard and there was no virtual keyboard installed. I was unable to boot a newly compiled ARM stock kernel, with USB gadget support for telneting into it. Now I'll rebuild buildroot with Tiny X and Qtopia while I download hackndev's modified kernel and try to enable USB support.

Saturday, February 10, 2007

After being unable to automate a Xscale toolchain cross-build for my Palm TE2 with buildroot, I'll use the MIPS Cross Linux From Scratch to derive a native toolchain for TE2. The binutils cross-build worked with CLFS_TARGET=xscale-linux-elf.