Kernel
From openPMA
Contents |
[edit] There are some places you can look for the sources:
The Archos site has some together with the Toolchain you'll need:
http://www.archos.com/products/ip_centric/pma_400/_pop_sdk.html Note, this is the sources for a pre 1.14-2 kernel.
We recently got up to date sources from Archos:
http://www.openpma.org/pmawiki/documents/linux-jbm3.cvs.tar.gz We used those sources as a base for the openPMA kernel. Up to date kernel sources can be obtained from the subversion repository.
[edit] Kernel command line
The only way to get a booting kernel is to override the bootloader with the CONFIG_CMDLINE from the kernel config. (see openPMA:Experiments)
CONFIG_CMDLINE="console=null mem=42M root=/dev/null rootflags=physaddr=0x12A00000 init=/linuxrc"
Certain parameters need to match the aimage-size that this kernel image is meant for.
[edit] How to build a bootable kernel
This has held us for a while. After all it was just two slashes... Here's the whole story:
- Grab the Archos sources like referenced in Kernel
- unpack to a convenient location
- apply the following patch:
diff -h not-working/arch/arm/mach-omap/av500.c working/arch/arm/mach-omap/av500.c 270c270 < BOOT_PARAMS(0x10000100) --- > // BOOT_PARAMS(0x10000100)
- either copy a working config or create one (config can be found in the subversion repository)
- make oldconfig
- make dep
- make zImage
- the ready to use zImage will be in ./arch/arm/boot
NB: This asumes that you have a toolchain installed and the $PATH is set correctly.
Full story on that Patch available here: Kernel
[edit] Bootloader
The bootloader copies the kernel and the cramfs inside the aimage to a predetermined address in memory and then executes the kernel-init. The kernel itself must be told what address this is (a strange implementation, it could find out itself by looking at the Program Counter). So that's what the config line for the kernel is for. The default config line is:
CONFIG_CMDLINE="console=null mem=42M root=/dev/null rootflags=physaddr=0x12A00000 init=/linuxrc"
This tells the kernel that it has 42 MB of RAM to handle and leave alone the other 22 MB of RAM the PMA offers. Those 22 MB are the *upmost* 22 MB of RAM and are the place where the bootloader loads the kernel and the cramfs to during boot (the black line at the bottom of the bootscreen is an indication for the copying). This is also the reason why the cramfs currently must not grow any larger than 22 MB.
The physaddr=0x12a00000 option tells the kernel that it resides precisely at this address. 0x2a00000 translates to decimal 44,040,192 or 42 x 1024 x 1024 = 42 MB. The extra "1" explains like this: the upper four bits of the physical address range decide which device the address is in. "2" is for flash (all physical addresses inside the bootloader begin with "0x2"), the "1" is for DRAM and there may be others e.g. for peripherals or the DSPs.
To sum this up: in order to give the kernel a different amount of RAM to handle, we have to change the mem-option (e.g. mem=46M for a cramfs which is not larger than 18 MB) and adjust the physaddr option to hex(64-18=46MB)=0x2e00000 adding the extra "1" at the beginning. Thus, the config line would look like this:
CONFIG_CMDLINE="console=null mem=46M root=/dev/null rootflags=physaddr=0x12E00000 init=/linuxrc"
The problem is, that the bootloader doesn't know that we plan to put the cramfs to a different place in mem. And it's the bootloader that copies the kernel and the cramfs to the mem and executes the kernel-init. So we have to tell the bootloader where to put the kernel and the cramfs. This is done via the header of the aimage.img. To be precise, offset 0xa4 of the aimage.img/aimage.hdr holds the physical address within two bytes (this is a strange alinement because the most significant halfword resides at a word boundary, it seems as if the lower 16 bits of the physaddr are truncated). A hexdump of the beginning of the header looks like this:
00000000 2E 2F 61 69 6D 61 67 65 2E 69 6D 67 00 00 00 00 ./aimage.img.... 00000010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00000020 00 00 00 00 00 00 00 00 41 52 43 48 4F 53 00 00 ........ARCHOS.. 00000030 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00000040 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00000050 54 75 65 20 4A 75 6C 20 32 36 20 31 36 3A 32 39 Tue Jul 26 16:29 00000060 3A 32 30 20 32 30 30 35 0A 00 00 00 00 00 4F 53 :20 2005......OS 00000070 20 66 6F 72 20 74 68 65 20 50 4D 41 34 30 30 00 for the PMA400. 00000080 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00000090 00 00 00 00 00 00 1C 03 00 00 00 80 C0 10 84 22 ..............." 000000A0 09 00 00 00 A0 12 84 92 55 01 89 AF F2 49 AB BC ........U....I..
You should notice the "A0 12" in the middle column of the last line. In our example, we now have to change that to:
000000A0 09 00 00 00 E0 12 84 92 55 01 89 AF F2 49 AB BC ........U....I..
This tells the bootloader to put the kernel and the cramfs 4 MBs farther behind in mem thus freeing 4 MB of RAM for applications!
[edit] build system
the kernel can be found here:
trunk/src/linux-pma
but in order to build it you'll need
- to read that: Howto_create_your_own_aimage
- be shure that the following option exist in your .config:
CONFIG_CMDLINE="console=null mem=48M root=/dev/null rootflags=physaddr=0x13000000 init=/linuxrc"
- use this script name it build_openpma.sh:
#!/bin/sh export OPENPMA_DIR=/opt/openpma export ARCH=arm export AR=arm-linux-ar export AS=arm-linux-as export CC=arm-linux-gcc export CPP=$OPENPMA_DIR/bin/cpp export LD=arm-linux-gcc export NM=arm-linux-nm export RANLIB=arm-linux-ranlib export STRIP=arm-linux-strip export PATH=$OPENPMA_DIR/bin:$PATH export CFLAGS="-march=armv4 -mtune=arm9tdmi -Os" make make dep make zImage
- copy the zimage to the trunk build location:
cp trunk/src/linux-pma/arch/arm/boot/zImage trunk/tools/trunk
- build the aimage.img
cd trunk/tools make trunk
- the image will be in tools/trunk
copy aimage.img and openpma.img to your pma...

