Start of topic | Skip to actions
Porting Linux to a new ARM platformThis document provides a summary of the steps when porting Linux to a new ARM platform or a new processor. In this page we assume that the reader has a knowledge of C and assembly programming and is familiar with ARM and operating systems concepts such as interrupt handling, system calls and memory management. Some useful information can be found in the kernel documentation section on how to configure the kernel itself. It is probably best to familiarize with Linux on x86 before if you are not familiar with embedded platforms. In addition to Linux kernel source documentation, some notes maintained by community members are available on booting and setting up Linux for ARM platforms, you can consult the following kernel document and Vincent Sander's documentation for additional information.Porting steps
Development environmentDevelopment for embedded platforms is usually done using cross-development tools. In the case of Linux, the host platform is often a Linux host computer connected to the target board using Ethernet, serial and/or ICE/JTAG. The GNU compiler is required to build the Linux kernel. There is more information on downloading and installing GNU tools is available on LinuxDevTools. Other compilers compliant with the new ABI for the ARM Architecture can also be used to compile user-space applications and some libraries.Install and build the Linux kernelDownload the latest stable release of the Linux kernel sources from kernel.org and install the source in your local directory. Working from the latest kernel source base is preferred as older versions will not be supported by the community. Later kernel versions usually contain recent bug fixes and enhancements. Older kernels such as 2.4 kernels are no more actively supported.Adding board specific codeSupport code for a new board consist in processor support, board specific code including where devices are mapped etc. and device drivers. Source code for device drivers is based in the drivers/ directory and net/ directories. Board specific code should be placed into the arch/arm/ directory. The following sections will use ARM Versatile PB926EJ-S as an example and assume that the processor support code already exist. The board intialisation and definition files are located in the arch/arm/mach-versatile directory. ARM Versatile board comes in two different form factors, a compact version (Application Baseboard) and a expandable version (Platform Baseboard). This directory contains the following files:
Connecting it to the main build systemCreate a Kconfig file for the board in arch/arm/mach-versatile/ to link this board to the overall build system so that it can be selected when running make *config. Refer to Documentation/kbuild/kconfig-language.txt for a description of the syntax. A Makefile entry need to exist to enable the systen to recurse into the platform sub-directories. Use Makefiles from existing boards as starting points and modify as appropriate. Platform IDFinally, add your machine group and type ID. A unique identifier can be obtained by registering your machine at http://www.arm.linux.org.uk/developer/machines/. You could initially assign a local ID in arch/arm/tools/mach-types while developing your BSP locally and then register it to get an official ID. You must be careful when changing kernel version as new machine are regularly added and make sure this doesn't conflict with the ID you have chosen. This ID is used very early in the boot process to determine the platform type and pull in the correct initialisation functions. It is used by the boot loader and stored in banked registers (i.e. r1) before the bootloader hands over to the kernel. Device driversNew device driver should be added in the appropriate directories, net/ for network drivers or drivers/ for others. Makefiles and Kconfig files also need to be edited (or created) so they are linked to the rest of the system. The following book provide a good guide on how to develop new device drivers with Linux. If the board contains controllers or devices for which Linux already has support for, we only need to include these in Kconfig files and pass the correct parameters to these drivers when initialisation is done.Configure and build a kernel imageEnsure that the cross-toolchain program names are correct and accessible from your execution path (i.e. your PATH environment variable). To configure the kernel you can use some of the following command:
Kernel bootEarly signs of a working Linux kernel come from the output of printk(), which is routed directly to the first console. Having configured a serial console, we should be able to see some kernel messages on the serial port if it has been setup correctly. Note that often the bootmonitor from the board or the boot loader initialises the serial device, however the kernel should not necessarily rely on this. The setup of the serial console happens much later during the kernel initialisation process. Chances are your new kernel probably dies even before that which is where early printk are useful. printk() allows you to print text as early as the first line of C code. The early initialisation steps are listed in init/main.c:start_kernel(). From this you can see that the console_init() call is done later on after we already had calls to printk(). Early printk() is very useful, however the serial driver should be working to enable further debug. For Versatile platforms, the serial driver is in drivers/serial/amba-pl011.c.Debug with kgdbKGDB enables developers to debug the kernel while running and set breakpoints or do single stepping at source code level. If available, you can use two serial ports on the target, one used for KGDB communication and the other to print messages. You should use a crossover-cable (or null-modem) to connect it to your development host. Doing everything using one serial port is also possible. You should select the Remote GDB kernel debugging which is listed under Kernel hacking when you configure the kernel and then do a 'make clean' and recompile the kernel to make sure that debugging symbols are compiled into the generated Linux image. Run the new kernel image. At this stage the kernel will be waiting for a gdb client connection. If there is a cross-over serial cable connected between the serial port on the target and the host, you can then set the appropriate baud rate and start the gdb on your host:
Interrupt handlingWhen porting the kernel to a new board it often hangs in the calibration step. This is normal if the interrupt code is not yet implemented in which case jiffies are never updated. Before adding support code for interrupt handling you need to identify interrupt controllers, all interrupt sources and how they are routed. The following steps are involved to handle interrupts:
System time and timerLinux relies on a system timer to advance the tick count, jiffies. Without this, Linux won't run and will stop in calibrate_delay() during the startup process as jiffies will never be incremented. Access to a real-time clock (RTC) device is also required to obtain the calendar date and time when the kernel boots up. ARM Versatile board includes primecell SP804 which provide facilities for periodic timers. One of the timers is used to generate system ticks. This is done at the end of arch/arm/mach-versatile/core.c with the definition and initialisation of the versatile_timer structure.MMU - Overview and settingsTBD. -- PhilippeRobin - 26 Oct 2006Non-MMU - Overview and settingsTBD. -- RobertWarner - 22 Jan 2008 | |||||