Introducing ELK: A Bare Metal Environment for ELLCC

ELLCC (pronounced “elk”) is a C/C++ programming environment based on the clang/LLVM compiler. The goal of ELLCC is to provide a complete tool chain and run-time environment for developing C/C++ programs for embedded systems. ELLCC supports several Linux targets today, specifically ARM, Mips, PowerPC, and x86 systems. ELK (which might mean “embedded little kernel” or “embedded Linux kernel”) is a work-in-progress that allows the ELLCC tool chain to target bare metal environments where an OS is not available or needed.

What will differentiate ELK from other bare metal environments is that the goal is to provide a fairly complete Linux-like environment without the need for actually running Linux. ELK is in the design and development stage right now, but the basic functionality has been implemented based on work done using ELLCC for bare metal development and making the ELLCC tool chain easily configurable.

The thing that makes ELK fairly unique is that it uses the C and C++ libraries compiled for Linux. It does this by handling Linux system calls using the normal system call mechanism for each target. ELK has extensible system call handling capability so that new system call emulators can be added as needed. ELK is being developed by setting up the infrastructure for program start up in the bare metal environment and handling system calls and context switching in a small assembly language file. A fairly functional example for ARM can be seen here. System call support can be added easily. Here is a simple exit() system call example:

/* Handle the exit system call.
 */     
#include <bits/syscall.h>       // For syscall numbers.
#include <stdio.h>
#include <kernel.h>

// Make the simple console a loadable feature.
FEATURE(exit, exit)

static int sys_exit(int status)
{
    printf("The program has exited.\n");
    for( ;; )
      continue;
}       
        
CONSTRUCTOR()   
{       
    // Set up a simple exit system call.
    __set_syscall(SYS_exit, sys_exit);
}       

Here’s an example of a simple ARM program running on QEMU in system (bare metal) mode:

[~] dev% cat hello.cpp
#include <iostream>

int main()
{
  std::cout << "hello world" << std::endl;
}
[~] dev% ~/ellcc/bin/ecc++ -target arm-elk-engeabi hello.cpp -g
[~] dev% ~/ellcc/bin/qemu-system-arm -M vexpress-a9 -m 128M -nographic -kernel a.out
audio: Could not init `oss' audio driver
unhandled system call (256) args: 1, 268472376, 1610613215, 1610613023, 1207961673, 1241513736
unhandled system call (45) args: 0, 0, 0, 1241512408, 590752, 0
unhandled system call (45) args: 4096, 4111, 1241512408, 1241512336, 592800, 1254352
unhandled system call (192) args: 0, 8192, 3, 34, -1, 0
unhandled system call (45) args: 4096, 4111, 34, 1241512336, 592800, -1
unhandled system call (192) args: 0, 8192, 3, 34, -1, 0
hello world
unhandled system call (248) args: 0, 1207962904, 1309668, 0, 1207991180, 1241513736
The program has exited.

Notice that there are several unhandled system calls (I did say that ELK is a work-in-progress) but enough has been implemented that “hello world” comes out.
The C version is a little quieter:

[~] dev% ~/ellcc/bin/qemu-system-arm -M vexpress-a9 -m 128M -nographic -kernel a.out
audio: Could not init `oss' audio driver
unhandled system call (256) args: 1, 268472376, 1610613215, 1610613023, 1207961673, 1241513736
hello world
unhandled system call (248) args: 0, 0, 1207983756, 0, 1207985256, 1241513736
The program has exited.

The current state of ELK is that only the ARM version is at all functional. It supports multiple threads, memory allocation using malloc, semaphores, and timers. ELK started out as a couple of prototypes to test the feasibility of using Linux libraries on bare metal and to enhance the ability to configure the tool chain for multiple environments. I like the way that the development is going so far and hope to have a complete ARM implementation soon and support for the other targets soon after that. You can browse the complete source code for ELK.

Leave a Reply

Your email address will not be published.