Username/Email:  Password: 
TwitterFacebookFlickrRSS

Running Embedded Linux on SuperH

Bhavana explains how to use RedBoot firmware to get Linux running on Hitachi's SuperH development boards.

With the proliferation of embedded architectures, companies are spending more money than ever to develop products utilizing embedded technologies. There is no doubt that there are numerous embedded architectures to choose from, like ARM, PowerPC, MIPS and SuperH. However, if price, performance, power and code density are required, then Hitachi SuperH is a good choice.

This article demonstrates running embedded Linux on the Hitachi SuperH target using Red Hat Linux and RedBoot as the boot loader. We discuss initial setup, related kernel details and copying the Linux kernel to Flash memory. We illustrate the appropriate use of JFFS2 and NFS filesystems and address some board-specific kernel issues with examples.

SuperH Solution Engine Boards

For the purpose of demonstrating the ease of using the SuperH base, we will use the Solution Engine family of development boards. Solution Engine boards make implementing SuperH-based designs easy and provide complete platforms ready for application development. The platforms provide spacious SDRAM and Flash memory to enable development of large and complex programs as well as rapid evaluation of the available peripherals. Though most of the discussion here is common to all SuperH targets, we will use the SH77x9 class of Solution Engines to illustrate the kernel and firmware.

Boot-Loader Environment

When working with embedded devices, a downloading and debugging environment to which the development machine can interface is a must. We use and recommend RedBoot for this purpose. RedBoot is a standardized embedded debug and bootstrap solution that provides firmware for running on embedded targets. It supports downloading and debugging of Flash and network booting of the Linux kernel, and downloading and updating of Flash images remotely via serial or Ethernet connections. There are ways to load Linux directly using the Hitachi boot loader (onboard monitor). However, using RedBoot as the firmware and boot loader is a lot friendlier.

Host Requirements and Target Setup

The development host must have an Ethernet port and an available serial port to connect to the target. A terminal emulator, such as minicom, can be used to communicate serially with the embedded board. You can use the hyperterminal or TELIX shareware program if you so desire. RedBoot can download a file via serial or Ethernet connections, though the latter is preferred for speedy downloads. A TFTP server must be set up on the network to which the SuperH target is connected, as RedBoot requires TFTP service for file downloading. This will ensure speedy kernel image and filesystem downloads.

Now, connect the host serially to the SuperH target via the board serial SCI connector. Plug the development machine and SuperH target Ethernet connections to a hub using a standard Ethernet cable. If the TFTP server is installed on the development machine, you can get away with connecting the target and host via a crossover Ethernet cable and creating a private LAN. This usually is preferred because the embedded system is isolated from the rest of the network. Use minicom to connect to the serial port with settings at 38400, 8N1. Turn both hardware flow control and software flow control off.

Assume for now that RedBoot is already running in Flash. We will discuss the process of reflashing the firmware later. The network configuration for the board is done in RedBoot. There are two ways of accomplishing this, either by using BOOTP or by configuring a static IP address. The BOOTP method would require the presence of a DHCP server in the same network. Below is an example of the SuperH board configured with a static IP address, where Default server IP address is the TFTP server IP address:

RedBoot> fconfig -l
Run script at boot: false
Use BOOTP for network configuration: false
Local IP address: 192.100.17.192
Default server IP address: 192.100.17.14
GDB connection port: 9000
Network debug at boot time: false

Instructions to configure the RedBoot environment are given at http://sources.redhat.com/ecos/docs-latest/redboot/configuring-the-redboot-environment.html.

Cross-Compilation Setup

The Red Hat Linux kernel supports a variety of boards, including the SuperH Solution Engine. Download the latest source RPM from the Red Hat FTP site (ftp://ftp.redhat.com/pub/redhat/linux/rawhide/SRPMS/SRPMS/). Install the kernel RPM and execute the spec file to install the kernel tarball. For a quick start define architecture and toolchain target triplet in the Makefile to cross-build for SuperH:

ARCH := sh
CROSS_COMPILE = sh-linux-gnu-

Configure the kernel using make xconfig with the system type Solution Engine and processor type SH7709 and build a compressed zImage binary:

make dep; make clean; make zImage.

Now, a few words regarding the various Solution Engine boards is in order. There are several incarnations of Solution Engine 7709 targets, and we have found architectural differences. The embedded device programming is such that chip differences would require software modification. Onboard memory differences like SDRAM vs. EDORAM would warrant changes to the firmware. We encountered some problems due to hardware differences between 7709R and the rest of the Solution Engines. The board was so different that kernel and driver changes were required for it to boot. I would like to mention two of those issues to illustrate the nature of the problems and depth of possible code changes.

The Solution Engine setup could not turn off all interrupts effectively at startup. This was because of interrupt layout differences. So the interrupt corresponding to the Ethernet controller remained enabled. When Linux initialized its interrupts, the interrupt pertaining to the Ethernet controller arrived. Since it was too early in the boot process and the Ethernet controller was not yet initialized, the interrupt could not be serviced, and as a result the target hung.

The solution was to disable the interrupt and reset the Ethernet controller with the reset_enet() function. There is no doubt that there are more elegant ways of solving this, but there is no denying its nastiness:

static void reset_enet(void)
{
  *(volatile unsigned short *) PA_83902_RST = 0;
  __delay (500);
  *(volatile unsigned short *) PA_83902_RST = ~0;
  __delay (500);
}

Next, the target dropped DHCP requests due to a misconfiguration of the buffer values. The problem was in the processing between the RAM buffer and Ethernet controller. The Ethernet controller driver required a different start page in the transfer buffer and stop page in the receive buffer, different from what was defined. Also, the related IRQ was different on this board and had to be configured specifically for the 7709R target.

______________________