|
IntroductionPorting Linux to a new board is a relatively simple task, but it does require a reasonable knowledge of how the kernel is put together. This document aims to provide a tuturial style approach to adding a new board. It assumes you know how to build the kernel from scratch. This procedure is not set in stone, it will change as the kernel evolves. In this tutorial, we will be creating a kernel for a new board, code named Saruman, produced by CompanyX which has an ST40STB1 on it, plus some PCI slots. We recommend that you put your board support into a separate directory structure to separate it from the rest of the kernel tree, and hopefully make it easier to integrate your changes with future revisions of the kernel. Apply the following patch Saruman diff. This patch will set up a template for a new board. You can change the name of the board and company by running a script over the patch before you apply it if you wish. This patch was generated aginst kernel version 2.4.17, as released in our 1.0 release. The rest of the tutorial will explain what the patch does so you can modify it for your own requirments. Changing the config filesThe first step is to change the kernel configuration for the new board. The main configuration file is in arch/sh/config.in An entry is created under the SuperH system type in the Processor type and features menu thus:
What this essentially does is create a preprocessor symbol called CONFIG_SH_STB1_SARUMAN that can be used to conditionally compile the kernel if this option is selected. The order in the menu is irrelevant. The patch also creates a file called .hhl_target_board, which is used by the makefile as the name of the board. Test this out by doing:
Hopefully, you should now see a menu option allowing you to select a Saruman board. The cpu type is not set automatically, you must change it to an STB1. Where memory is located is handled by the Memory on LMI option, if you memory isn't on the LMI you will need to deselect this and put in the appropriate value. Board SetupThis is done in setup_saruman.c, in the function setup_saruman(). Add any board initialisation routines here. The patch also creates a Makefile in the CompanyX directory, which you will need to change if you add more files to the build. The SuperH port of kernel supports the concept of a machine vector, which is an attempt to abstract out the board specific parts of the kernel, to allow a generic kernel to be built which will boot on many different boards. At the time of writing, this has only been partially successful, in that there are still some things that must be conditionally compiled in. Hopefully, this will improve over time. The machine vector for the Saruman board is contained in mach_saruman.c. If you look at this structure, you will see that it contains abstactions for I/O functions etc, which we will cover in more detail now. The I/O systemIt is necessary for the kernel to know how to communicate with any peripherals that may be on the board, such as any PCI devices or any on board devices like super-io chips or non PCI ethernet controllers for example. There are two main classes of devices to deal with, those where you intend to write your own device driver, and those where you are trying to utilise an existing linux driver. In the first case, you can effecively ignore the existing Linux I/O subsystem, and just write directly to the device using the ctrl_out(),ctrl_in() macros which simple take an address. For the second class of device, it is neccesary to set up the I/O subsytem so that, for example, calls to inb() at a particular address are redirected to the real hardware. It is important to realise that the addresses used by inb(),outb() are in a completely different address space, they are not memory addresses, and can be changed to point at whatever piece of hardware needs to be controlled in this fashion. The most important hardware block that needs this done is the PCI interface. We will first set up the io system to just handle PCI devices, and will then show how to change this to allow specific on board devices to use existing drivers. The critical function in this is the isa_port2addr function. The purpose of this function is to translate from a pc style io address to a real memory address. In the case of PCI only, this is very simple as I/O addresses are translated to point at the PCI I/O region located at 0xb6000000. This is configured to generate I/O addresses starting at zero on the actual bus. The patch creates a header file called io_saruman.h which is included from io.h. The actual implementation of the saruman_isa_port2addr() is in mach_saruman.c If you wish to add support for particular hardware then you must hook the saruman_isa_port2addr() function located in mach_saruman.c to return the appropriate address for wherever you want to map the device. Note that the addresses you choose to map the device at must be less than PCIBIOS_MIN_IO which is where the PCI system will start handing out I/O addresses. PCIBIOS_MIN_IO is currently set to 0x2000. In the case of the Saruman board, we have assumed that there are no on board peripherals that must be redirected, hence the function only translates I/O addresses that fall within the PCI I/O address range. InterruptsFor PCI, it is neccessary to tell the kernel on which interrupt vector it can expect to get interrupts from a particular slot. In the case of our mythical Saruman board, we will assume that it has all the interrupt lines for the pci slots attached to the common INTA input on the st40. This is the easiest case to deal with. This is not yet abstracted out in machine vector, so the patch modifies pci_st40.c, in the function map_harp_irq() thus:
If the interrupts are fed through some external interrupt controller, you will need to write some support routines to provide functionality such as enabling and disabling interrupts etc. Look in stboards/irq.c for an example of this. This interrupt controller is used on many ST boards, and allows each slot in the system to have it's own unique interrupt, rather than multiplexing them onto one pin. If the interrupts are not multiplexed, you will need to modify the same function to map between the slot numbers on the board and the appropriate interrupt line. This is effectively controlled by which devsel line goes to which slot. If you are not sure about the mapping the easiest way to figure it out is to simply put a printk in the routine and then put a card that needs an IRQ in the first slot, see what slot number the kernel is using for that board, and then repeat for all the other slots. The machine vector in mach_saruman.c is set to tell the kernel that we do not have an external interrupt controller.
MTD Flash file systemIf you want to use the MTD flash file system, you will also need to add appropriate code into drivers/mtd/maps/companyxboards.c, describing how much flash ROM you have in your system, and any VPP programming you have to do to enable flash writes. Heartbeat LEDIf you have a spare LED on the board, we would strongly recommend that you implement the Heartbeat function. This allows you to see if the processor is still functioning, and is very useful when debugging. Have a look in led.c for a stub where you can insert approprate code.
|
|||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||