1.2 Linux Board Porting Series - Module 2 - Linux Board Port Overview

[MUSIC PLAYING] Hello, and welcome to Module 2 of the Linux Board Porting Online Series. Module 2 is an overview of the board porting process. The majority of developers who use TI processors are designing a custom hardware platform, one that meets the specific I/O, power, and form factor requirements of their end product.
If these developers want to use Linux with their product, they will need the relevant drivers to support this custom hardware. Fortunately, TI provides a software development kit, or SDK, for each Sitara ARM product family. And this SDK supports various development boards. These boards provide a known good starting point, so that, in most cases, drivers don't need to be written from scratch but either modified or, in some cases, simply reconfigured to support any hardware differences.
The first step in porting the SDK to custom hardware is to choose the development board which most closely fits the design to which you are porting. This should be done during the definition of the custom hardware. And whenever possible, the hardware components of the custom platform should be chosen to match one of these boards.
It's important to understand that there is a significant effort in the porting of drivers. And this effort is directly proportional to the amount of difference between the reference hardware and the end product. It's TI's recommendation that you only deviate from reference hardware when absolutely necessary for the product's differentiation.
Let's look at an example. We'll use the AM335x Starter Kit to represent a custom platform. Of course, TI has already ported Linux to this platform. But if that weren't the case, and this was instead your custom design, what would be required to realize full Linux support?
Well, the first step would be to select a similar board as a starting point. In this case, the BeagleBone white is an excellent choice, because of its similarity to the AM335x Starter Kit. This is not a coincidence. TI has followed our own advice and chosen to reuse hardware between these two development platforms in order to minimize the driver development effort.
The next step is to identify hardware differences between the reference board and the custom design. There are two key additions that the AM335x Starter Kit adds to the BeagleBone white. The first is a touch screen LCD, and the second is an audio output port. As per our previous criterion, these changes represent product differentiation, which is to say the addition of multimedia functionality on top of the base BeagleBone platform. Thus, drivers will need to be developed for these two new interfaces.
Keep in mind that, as part of the base platform support package, a full set of drivers is developed by TI for the peripherals of the SOC device-- in this case the AM3358. So even in this example, there would be a generic LCD controller driver available as a starting point. This differentiation between processor support and board support is important and will be discussed in more detail in the next slide. Also, keep in mind that, in reality, these audio and LCD drivers are available today from TI as a starting point since the AM335x Starter Kit is fully supported in the SDK. We're only using this case study as an example of what would otherwise be necessary in order to complete the relevant hardware support.
Here, we see a comparison between our starting point, the BeagleBone white, and our target board, the AM335x Starter Kit. The differences are shown in red, which are the audio and the LCD support at the bottom of the board catagory. Because both boards use the same device, they share both the core architecture, which is the Cortex-A8, and the peripherals that are specific to the AM3358 system-on-chip device.
This will be the case for any porting effort based on TI ARM devices, since all Sitara device families have a software development kit that supports at least one development platform. So even in the worst case where all external components on the board are changed, a significant portion of the SDK Linux Support Package is still relevant and does not need to be modified. Also, as shown on the next slide, the source code for the Linux kernel is organized by these three layers of architecture, system-on-chip, and board.
In the context of the Linux kernel source code, these layers of architecture, SOC, and board are given the names platform, machine, and board, respectively. These layers are organized into separate directories, which is helpful during the porting process as it separates source code that is unlikely to need modification from that which is more likely to need to be modified. These three layers sit atop the Linux kernel shared common code, which is the portion of the Linux source code that is unchanged, regardless of the hardware that Linux is running on-- be it an x86 desktop or in AM335x embedded device.
Directly above the Linux shared common code, we have the platform code. For the AM335x device, this is the code which is specific to the Cortex-A8 core. While it was necessary for TI to modify this layer in order to provide support for the Cortex-A8, our customers should never need to modify this layer.
The next layer is the machine layer. This is the device-specific layer and contains the majority of the device drivers corresponding to the various peripherals of the SOC. Ideally, these drivers will be independent from the board-specific hardware that attaches to the device, requiring only a modification to the configuration of the driver to interface to various external components. In some cases, this is true. But it should be noted that for certain drivers, this may not be feasible, requiring modification of the driver source code when porting from one board to another.
And then the final layer at the top is the board layer. This is where the majority of the board porting effort is contained. Ideally, all of the board-specific information is contained in the board file, generally is configuration parameters for the drivers that reside at the machine layer.
Now that we've reviewed the basic structure of the Linux kernel source code, the first step in our hypothetical board port would be to load the code which doesn't need modification onto the new target in order to verify correct operation. Usually, this would be done in steps-- for instance, bringing up just the power and clocking subsystems along with a simple peripheral, such as GPIO or the serial port, in order to verify the bring-up. Later, the more complex peripherals could be sequentially added, such as USB and ethernet, until every peripheral is verified.
It's particularly useful in a custom design to replicate the exact hardware of either a UART, ethernet port, or a USB port, as these are the three most useful ports for debugging. And having a known good support during the initial bring-up of the board is extremely valuable. Also, there is usually little or no differentiation to be reached by modifying the external components which form these interfaces.
Next, of course, we'll need to address the hardware changes. Some of the more common changes when porting across hardware are shown here. Pin multiplexing and device clocking are two fundamental configuration requirements that must be addressed in any board port, even at the stage of the initial bring-up of common components as shown on the previous slide.
Next, we see the audio and LCD hardware as shown in the red boxes in the lower right. This change to board level hardware may or may not require modification of the driver source code as provided at the machine layer, but at the very least will require a reconfiguration of the Linux kernel to include the relevant drivers. Finally, the change of external components will require configuration data and peripheral initialization functions to be added to the board file, which are used to initialize the new hardware.
Taking a closer look at the board file, which, again, is the key component of the board port, we see that it's predominately comprised of configuration structures and initialization routines. As an example, there's a data structure in the light green section at the top of the file which defines the pin multiplexing, as well as an initialization function in the following yellow section that uses this data structure as an input to set the appropriate registers.
Similar pairs of configuration structure and initialization functions exist for various peripherals and external board components. The board file is located in the machine directory. There may be multiple board files in the machine directory corresponding to various hardware platforms that all share a common device.
The other components of the machine directory are as shown on this slide. Predominantly, it contains various drivers, although other device-specific code such, as PLL and power management routines are located here as well. The Linux kernel source code has a separate machine directory for each of the machines that it can be built for.
In summary, there are four major concepts to implementing a board port. First, the Linux kernel must be configured with the appropriate drivers for any hardware that has been modified or added into the system. This may or may not include modification of the base driver code itself.
Second, the board file needs to be modified to support any configurational changes. Within the board file, the pin multiplexing is set. Other combinations of configuration structures and initialization routines are used to set up the various peripherals and corresponding drivers that are used to interact with the added or modified external hardware.
What is the first step in the porting process? The first step to a board port is to choose the preexisting board that you will start from. TI's development boards with software development kit support are an excellent starting point for any board port. Ideally, the custom hardware to which are porting has been chosen to match this preexisting board.
Both U-Boot and the Linux kernel are organized into three layers. The lowest layer is the architecture, also known as the platform, which is the core device, such as the ARM Cortex-A8 core. The next layer is the SOC, or machine layer, and contains the code which is particular to a given device or SOC, System-On-Chip, beyond its core architecture predominantly comprised of the various drivers used to control the device's peripherals.
The final layer is the board layer, which generally contains initialization data that is specific to the various board components that are external to the Linux device. Understanding these three layers can save a lot of time and effort during the board porting, as in many cases, only the board layer will require modification.
This concludes Module 2 of the Linux Board Porting Online Series. Please proceed to Module 3, which is an overview of the Linux boot process.
[MUSIC PLAYING]

Module 4 - Linux/U-boot Source Code Structure: Overview of the layered organization of the source code files for both Linux and U-boot, focusing on those files which are most pertinent to a typical board porting effort.

Module 5 - Installing Code Composer Studio: This first lab exercise of the series is a recording of the presenter installing Code Composer Studio. In particular, installation of the proper JTAG drivers and a valid CCS license are required to debug U-boot. This is the first of three lab exercises centered around debugging U-boot using JTAG.

Module 6 - Building U-boot in CCS: This lab exercise shows the user how to set up a makefile-based project in Code Composer Studio in order to rebuild u-boot from source code.

Module 7 - Debugging U-boot with JTAG in CCS: This module is a recording of the presenter using Code Composer Studio and an xds560 emulator to debug U-boot on the Beaglebone Black platform.

Module 8 - Installing SDK and Building Kernel with Debug Symbols: This module is a recording of the presenter installing the Sitara Software Development Kit (SDK) and rebuilding the Linux Kernel with Debugging Symbols. It is the first of three modules demonstrating the debugging of the Linux Kernel in Code Composer Studio using JTAG.

Module 9 - Booting Linux from MMC/SD Card and TFTP: This module is a recording of the presenter using the SDK utility to build a bootable MMC/SD card for the AM335x starter kit and modifying the card to load the Linux Kernel from a TFTP server.

Module 10 - Debugging Linux Kernel with JTAG in CCS: This module is a recording of the presenter configuring JTAG debugging of the Linux Kernel using Code Composer Studio. It is the final in a ten-part series.