HOWTO Change the Linux Kernel Start Address

From Texas Instruments Wiki
Jump to: navigation, search

Purpose

The purpose of this article is to instruct users on how to change the start address for the Linux kernel. This is useful if you wish to leave a section of memory at the beginning of DDR for use by the DSP and allocate the rest of the DDR memory to the Linux kernel. For example if you have a system with 256MB of DDR and a codec server which requires 16MB of DDR you could partition the system like:

  • Linux Kernel: 0 - 232MB
  • CMEM memory: 232 - 240MB
  • DSP: 240 - 256MB

In this system if you change the amount of memory in the system you will need to rebuild the DSP image to be positioned at a new spot in DDR. This can be a complicated process.

However, if you instead use a memory map like:

  • DSP: 0 - 16MB
  • Linux Kernel: 16 - 248MB
  • CMEM memory: 248 - 256MB

Then when increasing the amount of DDR in the system you would only need to recompile the kernel.

Having the DSP image at the beginning of DDR also allows you to easily change the DSP image without having to modify anything else in the system as long as the new DSP image will fit within 16MB.

Kernel Modifications

This section will discuss the modifications required in the kernel to relocate the start address of the kernel to leave DDR space at the beginning of DDR for the DSP.

NOTE:  It is important to note that as of now the Linux kernel requires the start address to be a multiple of 16MB.
       This means that the addresses should be incremented by 0x1000000.

Using Kernel Config

On later versions of the LSP 2.6.18 kernel there are configuration options in the kernel that allow you to change the kernel start address. To check if your kernel supports config time setting of the start address do:

  1. make xconfig (or menuconfig)
  2. Go to System Type->TI DaVinci Implementations
  3. Look for the following options:
    1. SDRAM offset for the Kernel
    2. ZRELADDR location for the Kernel
    3. PARAMS_PHYS location for the Kernel
    4. INITRD_PHYS location

You should see something like the picture below:

Kernel start address xconfig.jpg

While still in xconfig you can change the SDRAM, ZRELADDR, PARAMS_PHYS, and INITRD_PHYS locations for you memory map. For example to allocate 16MB of memory at the beginning of DDR for the DSP image you can double click on each item and change the value. Press ENTER to save each value. i.e.

  • SDRAM = 0x1000000
  • ZRELADDR = 0x81008000
  • PARAMS_PHYS = 0x81000100
  • INITRD_PHYS = 0x81800000

Save the configuration and compile the kernel. The kernel will now start at 16MB of DDR.

Kernels without Config Option

Some versions of the 2.6.18 kernel may not have support for changing the kernel start address from the configuration menu. For these kernels you will need to modify the kernel files themselves to do this (you can use this example patch as a reference). This section will cover what changes are required in the kernel. In this example the modifications are for the DM6446 device.

NOTE: These instructions are for the 2.6.18 kernel.  They have not been validated against any other kernel
      versions but the changes should be similar.

The files to be modified are:

  1. arch/arm/mach-davinci/board-evm.c
  2. arch/arm/mach-davinci/Makefile.boot
  3. include/asm-arm/arch-davinci/memory.h

For boards other than DM6446 please modify the corresponding board files.

Modifying board-evm.c

In the board-evm.c file you need to change the value of BOOT_PARAMS in the MACHINE_START section. For example: Original code:

BOOT_PARAMS(0x80000100)

New code:

BOOT_PARAMS(0x81000100).

Modifying Makefile.boot

In the Makefile.boot file you need to change the values for zreladdr-y, params_phys-y, and initrd_phys-y. For example: Original code:

zreladdr-y  := 0x80008000
params_phys-y  := 0x80000100
initrd_phys-y  := 0x80800000

New code:

zreladdr-y  := 0x81008000
params_phys-y  := 0x81000100
initrd_phys-y  := 0x81800000

Modifying memory.h

In the memory.h file you need to change the value of DAVINCI_DDR_BASE. For example: Original code:

#define DAVINCI_DDR_BASE    0x80000000

New code:

#define DAVINCI_DDR_BASE    0x81000000

U-Boot Modifications

This section will discuss the modifications required in u-boot to change the start address of the Linux kernel to leave DDR space at the beginning of DDR for the DSP. By default u-boot loads itself into DDR at 16MB. If the kernel start address is modified to be at 16MB then u-boot will overwrite itself when loading the Linux kernel and be unable to start kernel execution.

U-Boot using UBOOT_START

In some versions of u-boot (i.e. DM357) the board/davinci/config.mk file contains two variables that must be set to change the start address of u-boot and the Linux kernel load address. These variables are UBOOT_START and SDRAM_OFFSET. To determine if you are using this version of u-boot you can do:

grep -r UBOOT_START *

from the root of the u-boot source tree. If you see this variable used for your board then follow these instruction. If not follow the instructions in the next section.

  • Change the TEXT_BASE value to the location where u-boot should be located in DDR. For example:

Original code:

TEXT_BASE = 0x81080000

New code:

TEXT_BASE = 0x82080000
  • Change the SDRAM_OFFSET to the offset in DDR where you want the kernel loaded. For example:

Original code:

SDRAM_OFFSET = 0x0

New code:

SDRAM_OFFSET = 0x1000000

Other U-Boot versions

In other versions of u-boot which do yet define BOOT_START and SDRAM_OFFSET you must modify the following files (you can use this example patch as a reference):

  1. board/davinci/config.mk
  2. include/configs/davinci.h
NOTE:  The above listed files are for the DM6446.  For other boards please change the files to point to the
       proper config.mk and davinci header files for that board.

Modifying config.mk

The config.mk file needs to be modified to change the address where the u-boot code is loaded. For example: Original code:

TEXT_BASE = 0x81080000

New code:

TEXT_BASE = 0x82080000

Modifying davinci.h

The davinci.h file needs to be modified to change the address where the Linux boot parameters are stored. Optionally you can change the amount of memory that u-boot uses. Check the example patch for information on changing the amount of DDR used by u-boot. Original code:

#define LINUX_BOOT_PARAM_ADDR  0x80000100

New code:

#define LINUX_BOOT_PARAM_ADDR  0x81000100

Updating CMEM Memory Region

If you change the amount of memory in your system you will often need to update the CMEM memory region as well. To show how this works we will consider the changes required to CMEM when moving from 256MB of DDR to 128MB.

Original Memory Map:

  • DSP: 0 - 16MB
  • Linux Kernel: 16 - 248MB
  • CMEM memory: 248 - 256MB

New Memory Map:

  • DSP: 0 - 16MB
  • Linux Kernel: 16 - 120MB
  • CMEM memory: 120 - 128MB

In the original case CMEM would be set to have it's phys_start and phys_end parameters specify the memory region between 248-256MB. An example modules.sh file then might be: -

# insert cmemk, tell it to occupy physical 248MB-256MB.
insmod cmemk.ko phys_start=0x8F800000 phys_end=0x90000000 pools=1x4145728,5x829440,1x61440,1x10240

This corresponds to the settings:

phys_start = 0x8F800000
phys_end   = 0x90000000

To change the CMEM memory region you need to change the phys_start and phys_end parameters. Remember that the start of DDR memory is based at 0x80000000. In this case the new modules.sh would be:

# insert cmemk, tell it to occupy physical 248MB-256MB.
insmod cmemk.ko phys_start=0x87800000 phys_end=0x88000000 pools=1x4145728,5x829440,1x61440,1x10240

i.e. the phys_start, phys_end changes but not the individual pools or sizes.

These values were calculated using the following formula:

phys_start = <DDR Base> + (<CMEM start MB> * 1024 * 1024)
phys_end   = <phys_start> + (<CMEM size> * 1024 * 1024)
i.e.
phys_start = 0x80000000 + (120 * 1024 * 1024) <---- convert to hex
phys_end   = 0x87800000 + (8 * 1024 * 1024) <---- convert to hex

You can change these values in the loadmodules.sh script that is part of the DVSDK demos so that you do not need to enter them after each boot.

Additional Information

For more information on changing the system memory map see the links below: