Kernel

From openPMA
Jump to: navigation, search

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

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...

Google ads
Personal tools