Kernel-with-device-tree

From ArmadeusWiki
Revision as of 01:35, 9 July 2012 by Jorasse (Talk | contribs) (Running: remove useless command)

Jump to: navigation, search

Background

The idea behind device tree is quite simple. When the kernel starts, it needs to initialize the drivers for the devices on the board. But often on embedded systems, devices can't be discover at running time. In this case, the Linux kernel has a c file that initialize the devices for the board. So the kernel must be modified/compiled for each board.

Another way is to provide a small file that describe the board to the Linux kernel. When the kernel start, it reads this file (called dtb for Device Tree Binary) to know the devices on the board, and initialize usefull drivers.

Some information on device tree may be found here:

Compilation

To use device tree on arm, both bootloader (U-Boot) and kernel should be compiled with the support of device tree.

U-Boot

Note Note: The APF27/U-boot 2012.04.01 patch 3.6, APF28/U-Boot 2012.04.01 patch 1.5 and APF51/U-Boot 2012.04.01 patch 1.5 are already configured to support device tree.


To enable device tree on u-boot, it's quite simple:

  • add "#define CONFIG_OF_LIBFDT" in the u-boot configuration file (include/configs/<board>.h).

On armadeus SDK, this file is in this directory: buildroot/target/device/armadeus/<board>/<board>-u-boot-<version>.h

For example, for u-boot 2012.04 on apf27, it's: buildroot/target/device/armadeus/apf27/apf27-u-boot-2012.04.h

Nothing else needs to be done, because the u-boot image is build by the armadeus SDK with the command "make".

NOTE: on u-boot 2012.04, the command bootm with device tree is broken. If you want to use it,

you need to fix it with the following patch: http://git.denx.de/?p=u-boot.git;a=commit;h=1723997610ace497252d6f9a44ec76c06951ae43

NOTE2: it's fixed on u-boot 2012.04.01 that's the current (since June 2012) release used on all the APF boards.

Linux

The kernel > 3.4 have already the support of some arm SoC.

  • imxl (apf9328) : no
  • imx27 (apf27) : yes
  • imx51 (apf51) : yes
  • imx28 (apf28) : yes

The configuration file should have (should be done by default):

  • CONFIG_MACH_IMX27_DT (on APF27)
  • CONFIG_MACH_IMX51_DT (on APF51)
  • CONFIG_MACH_MXS_DT (on APF28)
  • CONFIG_SERIAL_IMX
  • CONFIG_SERIAL_IMX_CONSOLE

Nothing else needs to be done, because the kernel image is build by the armadeus SDK with the "make" command.

dtb

A dtb (Device Tree Binary) file is created from a dts (Device Tree Source) file.

The kernel has already the support of device tree for imx27 (APF27), imx28 (APF28) and imx51 (APF51).

But both board (apf28 and apf51) hasn't a dts file. So a file <board>.dts must be added to in the directory arch/arm/boot/dts of the linux kernel.

The armadeus SDK don't have support for dtb image generation. So you have to do it yourself.

  • go to the directory buildroot/output/build/linux-<version>
  • add the file <soc>-<board>.dts the directory arch/arm/boot/dts/
  • build the dtb with the command:
$ make ARCH=arm <soc>-<board>.dtb

The file <soc>-<board>.dtb should appear in arch/arm/boot/

$ cp buildroot/output/build/linux-3.5-rc5/arch/arm/boot/imx28-apf28.dtb /tftpboot/

Running

Start the U-Boot previously compiled, and then :

  • load the kernel in memory
  • load the dtb in memory
  • run the command bootm with 3 arguments: <kernel addr> - <dtb addr>

The second argument is "-", it means that there isn't an initrd to load.

For example, on APF27, it should be something like this:

BIOS> setenv consoledev ttymxc0
BIOS> setenv baudrate 115200
BIOS> setenv dtbaddr 0xa0800000
BIOS> tftp $loadaddr apf27-linux.bin
BIOS> tftp $dtbaddr imx27-apf27.dtb
BIOS> setenv consoledev ttymxc0
BIOS> setenv console console=$consoledev,115200
BIOS> setenv bootargs ${console} earlyprintk
BIOS> run addnfsargs addipargs
BIOS> bootm $loadaddr - $dtbaddr

On the APF27, 28 and 51 with the latest U-Boot version things are even simpler:

  • Device Tree can be loaded from the Flash memory
  • The variable fdt_addr_r defines the RAM address to load the DTB structure and will be used to notify the kernel of the DT location in RAM
  • APF27: Set the fdt_addr_r to A1000000 - APF28: set the fdt_addr_r to 41000000
  • Some scripts are availaible to update the dtb partition: download_dtb (download the dtb in RAM from your local network) - flash_dtb (tranfert a dtb from RAM to flash) - update_dtb (download and flash a dtb)
  • the boot scripts ubifsboot, nfsboot and mmcboot support booting a kernel with a DT

Here is the example on the APF27:

BIOS> setenv consoledev ttymxc0
BIOS> setenv fdt_addr_r a1000000 (with the apf27 - 41000000 with an apf28 - 91000000 with an apf51 )
BIOS> run update_kernel
BIOS> run update_dtb
BIOS> boot  (on the APF27 that now supports the NAND in DTS - use run nfsboot on the other boards)

Here is the example on the APF28:

BIOS> setenv fdt_addr_r 41000000
BIOS> run update_kernel
BIOS> run update_dtb
BIOS> saveenv
BIOS> boot