Booting LKL inside Haiku
Porting LKL to the Haiku kernel API
To boot LKL inside Haiku, first I have port LKL to a new pseudo-architecture. For this project I have two choices:
- write a user space file system driver (similar to googlefs) and port LKL to the Haiku system call API (or a higher level library)
- write a kernel space file system driver and port LKL to Haiku's kernel API.
Porting detailsPorting LKL is much simpler than porting the whole Linux kernel to a new architecture. Much of the low-level details are already taken care of by the portable LKL layer. One only needs to provide a set of runtime environment dependent primitives that cannot be (efficiently) emulated in a portable manner:
- memory management routines
- synchronization primitives
- thread management
- time and timer generators
- a (screen/log) printing routine
Because LKL does not require memory protection mechanisms (there will be no processes running in the LKL operating system – all calls are considered from kernel space), support for memory management becomes trivial: LKL just needs a physical memory pool that the Linux kernel can use for its memory allocation needs. The poll of memory will be managed by the kernel using a mix of buddy, SLUB/SLAB/SLOB/SLQB/SL*B algorithms just like on a normal system. This pool will only be used for buffers and structures dynamically allocated by the kernel. The kernel code and
statically allocated data will not be part of this poll as they are managed by Haiku's kernel add-on loader (see
The file system driver does not need to interact with interrupts or anything like that, so it does not have any special requirements. This greatly simplifies my work: as memory does not need to be locked (
lock_memory) or unlocked in RAM at various times, the memory support can be reduced to
free (we all know that
malloc or any kind of access (read/write/execute) to a unlocked memory address can block, don't we?).
LKL needs threading support because the Linux kernel uses threads for internal house-keeping, like processing I/O requests or running softirqs, tasklets or workqueues and journaling tasks.
Starting/stopping threads from Haiku's kernel is similar to other more familiar APIs (e.g. POSIX):
spawn_kernel_thread takes a function
f and a generic pointer
arg as arguments and creates a new thread that will execute
Two things should be noted here:
- threads are initially suspended, you need to call
resume_threadto actually run the thread's code. This differs from the traditional POSIX API and I spent some time investigating why my threads were never running :P.
- threads (as other Haiku kernel resources – e.g. semaphores) can be given a name. This helps a lot in KDL trips
However there's a catch: releasing a semaphore automatically invokes Haiku's scheduler, and this shouldn't be done in a number of contexts like when interrupts are disabled. Unfortunately the legacy BeOS docs license forbids improvements and such a warning cannot be written in release_sem's documentation. It's important to replace
release_sem(s) calls with
release_sem_etc(s, 1, B_DO_NOT_RESCHEDULE) if this can be called in such a context.
Time and timers
LKL needs to know the current time (not the time since starting the computer, but the absolute time – as in a wall clock) for a variety of tasks, but for this driver we need it to set a valid time stamp on files. For this LKL uses
real_time_clock_usecs which returns the time since start of the Unix epoch (January 1st 1970) in microseconds.
Any operating system needs a functioning timer interrupt to function properly. Linux support two categories of programmable interrupt timer (PIC) chips: timers that fire periodically or timers that can efficiently be programmed to fire at various moments and stop firing in certain intervals. We simulate the second kind of PICs in Haiku, thus generating a smaller amount of LKL-interrupts (not real hardware interrupts), for a lower overhead:
KERN: [lkl-console] Switched to NOHz mode on CPU #0Now that the LKL boots and shuts down correctly, we have to build the file system driver that uses it :)