ChorusOS 5.0 Board Support Package Developer's Guide

Chapter 3 Writing a New Board Support Package

This chapter describes the source file tree that you need to create for your new BSP. It also shows some examples of the content of the files in this tree, using the template files that are provided in the BSP source add-on package.

Creating a New BSP Source Tree

In order to create a new BSP component for your board you will need to create a new directory tree that contains all the required files. A good starting point for this is to duplicate an existing BSP source tree for a reference board that most closely resembles your board.


Note -

An optional BSP source package can be installed which contains example BSP and driver source files for both reference targets and other boards. There is also a template/ directory that contains the files that can be copied and used as a starting point for implementing a new BSP or device driver (contained in bsp/ and drv/ directories respectively.


Figure 3-1 New BSP Source Tree

Graphic

All reference BSP source trees for reference target boards are contained in the source_dir/nucleus/bsp/family/board directory, as shown in the above diagram.

You can either create your new my_board/ directory within the ChorusOS installed source tree under the appropriate family directory, or elsewhere on your file system. The path to your new BSP component is set up in your build_dir (see configure(1CC)) when you build your ChorusOS system image.

Your new BSP source tree will contain the following (see Figure 3-1):

You may also need to add any drivers that are specific to your board. For more information on this see "Driver Source File Structure").

Building a ChorusOS System Image with a New BSP/DRV Component

A kernonly system image is a minimal system image that contains no POSIX file system or networking layers. It is recommended that when creating a system image for a new board you initially create a kernonly system image, to limit the testing and debugging to the essential microkernel components only. Once this minimal configuration works, you can enable the support of other devices used by the POSIX OS layer and configure and build a standard ChorusOS system image that includes this layer.

To create a new ChorusOS kernonly system image you need to create a build directory and use the configure(1CC) command to prepare the build directory for ChorusOS, as shown below.

% cd build_dir
% configure -b $TOOLS $KERNEL -s $DRV $BSP
% make
% make kernonly

The two components DRV and BSP indicate the paths of your new BSP and you will notice that they are source components (indicated by the -s option). For more detailed information on building a system image with a new BSP component and booting the ChorusOS system image on a new target board see the ChorusOS 5.0 Source Delivery Guide and Part II of the ChorusOS 5.0 Installation Guide.


Note -

It is important to note that when adding new drivers to an existing BSP, the BSP should be considered as a new one. This is because the addition of new drivers to an existing BSP modifies some source files, in particular the initial device tree and the target.xml. (On some platforms the target.xml file may be split into multiple files: drivers.xml, drvlist.xml and target.xml. In this situation the drivers.xml and drvlist.xml files are included in the target.xml file. )


An Example of Some Typical BSP Source Files

This section gives you some more detailed information on the files that you must have in a BSP source tree using template files as examples. The templates/ directory can be found by installing the BSP source package.

The Top Level BSP Directory

For this example, the new BSP directory will be called my_board. This top level directory must contain at least the following four files:

This section contains a short description of these files, showing the template files.


Example 3-1 New BSP: Makefile.bin

COMPONENT += BSP

BSP.all::

BSP_XML = target.xml target_action.xml

xml:: DEVTOOLS.all
   @sh $(DEVTOOLS_DIR)/cpxml $(BUILD_DIR)/conf/mkimage $(BSP) $(BSP_XML)

XML8 += mkimage/mkimage.xml

The COMPONENT macro defines a list of components that will be processed in the build phase. The BSP source component is added to this list. Note that only the name "BSP" is required.

The xml makefile target is used to copy the target.xml and target_action.xml files to the $(BUILD_DIR)/conf/mkimage directory. The mkimage/mkimage.xml file is added to the XML macro. This XML file will be used at the end of the build to generate the image.


Example 3-2 New BSP: Makefile.src

BSP_SRC = $(BSP)/src

all:: BSP.all 

BSP.all:: $(BSP_DIR)/DONE

$(BSP_DIR)/DONE: $(BSP_DIR)/Makefile 
        sh $(DEVTOOLS_DIR)/resync BSP -f $(BSP) -s $(BSP_DIR)
        cd $(BSP_DIR); $(MAKE)
        touch $(BSP_DIR)/DONE

$(BSP_DIR)/Makefile: $(BSP_SRC)/Imakefile
        sh $(DEVTOOLS_DIR)/ChorusOSMkMf $(BUILD_DIR) -s \
           $(BSP_SRC) -b $(BSP_DIR) -d $(BSP_DIR)
        cd $(BSP_DIR); $(MAKE) Makefiles

This makefile defines the BSP.all target used to compile and link the BSP source files.

The ChorusOSMkMf tool is used to create Makefiles from Imakefiles (see ChorusOSMkMf(1CC)for more details).

The BSP_DIR variable is defined as $(BUILD_DIR)/build-BSP. This directory will be used as the build directory and the binary delivery directory.

The example target.xml file shown in section "The target.xml File Structure", specifies the target specific elements needed to produce a system image. This file contains the Embedded Component Markup Language (ECML) which is used to describe the configuration of the BSP as well as other target specific configuration in ChorusOS. For more information on ECML see "ECML Syntax" in ChorusOS 5.0 Source Delivery Guide.

This file must be adapted for your particular board.

The pathname ${BSP_DIR}/bin/my_board is used to reference a number of BSP binaries. The my_board name can be replaced by an explicit reference to your board. In this case, remember to change this path in the Project.tmpl file, detailed in Example 3-4.


Example 3-3 New BSP: target_action.xml

<!DOCTYPE folder PUBLIC "-//Sun Microsystems//DTD \
ChorusOS//EN" "ChorusOS.dtd">

<folder name='MYBOARD specific actions' visible='no'>
  <description>MYBOARD system image action</description>

  <action name='Archive renaming'>
    <application>shellCommand</application>
    <definition name='shellCommand_cp'>
      <type name='ShellCommand' />
      <value field='command'>
        <vstring>cp</vstring>
      </value>
      <value field='argument'>
        <value index='size'>
          <vstring>${IMAGE_DIR}/bank/sys_bank</vstring>
        </value>
        <value index='size'>
          <vstring>${RESULT}</vstring>
        </value>
      </value>
    </definition>
  </action>

</folder>

The target_action.xml file, detailed above, copies the sys_bank file into a file defined by the RESULT variable. This variable is defined as ${BUILD_DIR}/${SYSTEM}, where ${SYSTEM} is the name of the image to be produced. Note that multiple banks can be combined, and specific binary format headers can be included, to produce a more complex system image.

The src Directory

This src directory must contain the following two files:

It also contains the following directories:

The Project.tmpl file is used to produce a makefile to build your new BSP component (see ChorusOSMkMf(1CC)).


Example 3-4 New BSP: Project.tmpl

#include "Package.rules"

SRC_DIR         = SourceDir
BUILD_DIR       = BuildDir
DIST_DIR        = DistDir

VPATH           = $(SRC_DIR)$(REL_DIR)

WARN            = $(WARN_ON)

MYBSP_DIST_BIN  = $(DIST_DIR)/bin/mybsp

DRV_DIST_BIN    = $(DRV_DIR)/bin/drv

INCLUDES        = -I$(NUCLEUS_DIR)/include/chorus \
                  -I$(NUCLEUS_DIR)/include/stdc   \
                  -I$(DRV_DIR)/include/chorus \
                  -I$(DIST_DIR)/include/chorus \
                  -I$(SRC_DIR)$(REL_DIR)

BSP_LIBS        = $(NUCLEUS_DIR)/lib/boot_tools/boot_tools.s.a \
                  $(NUCLEUS_DIR)/lib/util/util.s.a \
                  $(NUCLEUS_DIR)/lib/bki/bki.s.a \
                  $(NUCLEUS_DIR)/lib/cpu/cpu.s.a \
                  $(NUCLEUS_DIR)/lib/stdc/stdc.s.a \
                  $(NUCLEUS_DIR)/lib/boot_tools/sys/sys.s.a 

The MYBSP_DIST_BIN variable defines the directory which programs will be exported to. The name mybsp can be changed to the real board name. The DIST_DIR variable is defined by the path given with the -d option of ChorusOSMkMf. This path is the same as BSP_DIR: $BUILD_DIR/build-BSP. The DRV_DIST_BIN variable will be used to reference objects exported by the DRV component.


Example 3-5 New BSP: src-level Imakefile

#define IHaveSubdirs

SUBDIRS = boot dbg reboot

This Imakefile lists all of the sub-directories for each BSP class and should not be edited.

The boot Directory

This is the directory where the source files for the boot program reside:

This section contains a short description of the boot files, showing examples from the template directory.


Example 3-6 New BSP: Imakefile

C__SRCS = boot.c

AS_SRCS =

OBJS = $(C__SRCS:.c=.o) $(AS_SRCS:.s=.o)
BspProgTarget(boot, start, $(OBJS), $(BSP_LIBS))

DistProgram(boot, $(MYBSP_DIST_BIN)$(REL_DIR))

Depend($(C__SRCS) $(AS_SRCS))

The BspProgTarget macro is used to produce the boot relocatable binary file. The final link will be done by the mkimage tool. The first argument is the name of the binary. The second argument is the entry point, the third is the list of objects and the fourth is the list of libraries used in the link process.

The DistProgram macro copies the file given by the first argument to the directory specified by the second argument. Therefore, in the example above, the boot binary file will be copied in to the $BSP_DIR/bin/my_board/boot directory.


Example 3-7 New BSP: boot.c

void
start()
{
    /* Code for your BSP boot */
}

This file needs to be adapted to your board.

The dbg Directory

The dbg directory contains the platform-dependant code for the debug agent, and some driver code that is necessary for debugging your BSP (that is the console and watchdog drivers). There are four files located at this top level:


Example 3-8 New BSP: dbg Imakefile

C__SRCS = dbgBsp.c ns16550Bsp.c

AS_SRCS =

OBJS = $(C__SRCS:.c=.o) $(AS_SRCS:.s=.o)

DRIVERS = \
        $(DRV_DIST_BIN)/dbg/ns16550.o

BspProgTarget(dbgBsp, dbgBsp_init, $(OBJS), $(DRIVERS) $(BSP_LIBS))

DistProgram(dbgBsp, $(MYBSP_DIST_BIN)$(REL_DIR))

Depend($(C__SRCS) $(AS_SRCS))

Note that dbgBsp relocatable binary file is linked with the ns16550.o object, which is located in the DRV component.


Example 3-9 New BSP: dbgBsp.c

#include <bki/bki.h>
#include <bki/dbgBsp.h>

#include <drv/dbg/dbgUart.h>
#include <drv/dbg/dbgWdt.h>

DbgBsp dbgBsp = {
    dbgBsp_initDrivers,
    dbgUart_ioctl,
    dbgUart_mayGet,
    dbgUart_getChar,
    dbgUart_mayPut,
    dbgUart_putChar,
    dbgBsp_ioRemap,
    dbgBsp_boardReset,
    dbgWdt_setStoppedFlag
};

unsigned int hostStopped = 0;

    void
dbgBsp_init (BootConf* conf)
{
        /* debug BSP specific initialization code */

    conf->dbgBsp = dbgBsp;
}

    static void
dbgBsp_initDrivers (int port, struct DbgBsp_sgtty* stty)
{
        /* code for UART and WDT intialization */
}

    static void
dbg_boardReset (int mode)
{
        /* code for your board reset */
}

    static void
dbgBsp_ioRemap (int flags, void* base)
{
    if (flags & DKI_IOREMAP_WDT) {
        /* WDT device remap */
    }
    if (flags & DKI_IOREMAP_UART) {
        /* UART device remap */
    }
}

    static void
dbgWdt_setStoppedFlag (unsigned char v)
{
    hostStopped += (v ? 1 : (hostStopped ? -1 : 0));
}

Note that dbgBsp.c needs to be adapted for your board.


Example 3-10 New BSP: ns16550Bsp.c

#include <drv/dbg/ns16550Bsp.h>

    void
ns16550_init(int port)
{
    /* Code for your board */
}

    void
ns16550_outb(unsigned int reg, unsigned char val)
{
    /* Code for your board */
}

    unsigned char
ns16550_inb(unsigned int reg)
{
    unsigned char c;
    /* Code for your board */
    return c;
}

    unsigned short
ns16550_divisor(unsigned int baud)
{
    unsigned short divisor;
    /* Code for your board */
    return divisor;
}

    void
ns16550_ioremap(void* newbase)
{
    /* Code for your board */
}

Note that the example above is for an ns16550 UART. The file will be need to be adapted for your board.

The reboot Directory

The reboot directory contains the platform dependant code for the reboot part of the board support package. This directory is optional, and in fact it is possible to include the reboot related code in the boot directory. If you implement reboot in a separate reboot directory the following two files are located at the top level: