A Rump Kernel Hypervisor for the Linux Kernel


April 23, 2013 posted by Antti Kantee

Ever since I realized that the anykernel was the best way to construct a modern general purpose operating system kernel, I have been performing experiments by running unmodified NetBSD kernel drivers in rump kernels in various environments (nb. here driver does not mean a hardware device driver, but any driver like a file system driver or TCP driver). These experiments have included userspaces of various platforms, binary kernel modules on Linux and others, and compiling kernel drivers to javascript and running them natively in a web browser. I have also claimed that the anykernel allows harnessing drivers from a general purpose OS onto more specialized embedded computing devices which are becoming the new norm. This is an attractive possibility because while writing drivers is easy, making them handle all the abnormal conditions of the real world is a time-consuming process. Since the above-mentioned experiments were done on POSIX platforms (yes, even the javascript one), the experiments did not fully support the claim. The most interesting, decidedly non-POSIX platform I could think of for experimentation was the Linux kernel. Even though it had been several years since I last worked in the Linux kernel, my hypothesis was that it would be easy and fast to get unmodified NetBSD kernel drivers running in the Linux kernel as rump kernels.

A rump kernel runs on top of the rump kernel hypervisor. The hypervisor provides high level interfaces to host features, such as memory allocation and thread creation. In this case, the Linux kernel is the host. In principle, there are three steps in getting a rump kernel to run in a given environment. In reality, I prefer a more iterative approach, but the development can be divided into three steps all the same.

  1. implement generic rump kernel hypercalls, such as memory allocation, thread creation and synchronization
  2. figure out how to compile and run the rump kernel plus hypervisor in the target environment
  3. implement I/O related hypercalls for whatever I/O you plan to do

Getting basic functionality up and running was a relatively straightforward process. The only issue that required some thinking was an application binary interface (ABI) mismatch. I was testing on x86 where Linux kernel ABI uses -mregparm=3, which means that function arguments are passed in registers where possible. NetBSD always passes arguments on the stack. When two ABIs collide, the code may run, but since function arguments passed between the two ABIs result in garbage, eventually an error will be hit perhaps in the form of accessing invalid memory. The C code was easy enough to "fix" by applying the appropriate compiler flags. In addition to C code, a rump kernel uses a handful of assembly routines from NetBSD, mostly pertaining to optimizations (e.g. ffs()), but also to access the atomic memory operations of the platform. After assembly routines had been handled, it was possible to load a Linux kernel module which bootstraps a rump kernel in the Linux kernel and does some file system operations on the fictional kernfs file system. A screenshot of the resulting dmesg output is shown below.

fs demo screenshot

It is one thing to execute a computation and an entirely different thing to perform I/O. To test I/O capabilities, I ran a rump kernel providing a TCP/IP driver inside the Linux kernel. For a networking stack to be able to do anything sensible, the interface layer needs to be able to shuffle packets. The quickest way to implement the hypercalls for packet shuffling was to use the same method as a userspace virtual TCP/IP stack might use: read/write packets using the tap device. Some might say that doing this from inside the kernel is cheating, but given that the alternative was to copypaste the tuntap driver and edit it slightly, I call my approach constructive laziness.

The demo itself opens a TCP socket to port 80 on vger.kernel.org (IP address 0x43b484d1 if you want to be really precise), does a HTTP get for "/" and displays the last 500 bytes of the result. TCP/IP is handled by the rump kernel, not by the Linux kernel. Think of it as the Linux kernel having two alternative TCP/IP stacks. Again, a screenshot of the resulting dmesg is shown below. Note that unlike in the first screenshot, there is no printout for the root file system because the configuration used here does not include any file system support. Yes, you can ping 10.0.2.17.

net demo screenshot

As hypothesized, a rump kernel hypervisor for the Linux kernel was easy and straightforward to implement. Furthermore, it could be done without making any changes to the existing hypercall interface thereby reinforcing the belief that unmodified NetBSD kernel drivers can run on top of most any embedded firmwares just by implementing a light hypervisor layer.

There were no challenges in the experiment, only annoyances. As Linux does not support rump kernels, I had to revert back to the archaic full OS approach to kernel development. The drawbacks of the full OS approach include for example suffering multi-second reboot cycles during iterative development. The other tangential issue that I spent a disproportionately large amount of time with was thinking about how releasing this code would affect existing NetBSD code due to GPL involvement. My conclusion was that this does not matter since all code used by the current demo is open source anyway, and if someone wants to use my code in a product, it is their problem, not mine.

For people interested in examining the implementation, I put the source code for the hypervisor along with the test code in a git repo here. The repository also contains the demos linked from this article. The NetBSD kernel drivers I used are available from ftp.netbsd.org or by getting buildrump.sh and running ./buildrump.sh checkout.

[2 comments]

 

pointers to rpi docs 2013Q1


March 23, 2013 posted by Matthew Sporleder

We get a lot of comments asking for tips on using the raspberry pi so I thought I would point out some docs:
evbarm/rpi wiki docs
An example of the rpi.img can be found here:
http://nyftp.netbsd.org/pub/NetBSD-daily/HEAD/201303221130Z/evbarm/binary/gzimg/ notice the HEAD (NetBSD -current), datestamp, arch path for future reference

There are also some concerns about building a kernel/img on your own.
building NetBSD
build.sh is one of the best features of NetBSD. You can cross compile from almost any other unix-like system with very little difficulty.

[1 comment]

 

NetBSD binary kernel modules usable on Linux in rump kernels


December 13, 2012 posted by Antti Kantee

Some years ago I wrote about the possibility to load and use standard NetBSD kernel modules in rump kernels on i386 and amd64. With the recent developments in buildrump.sh and the improved ability to host rump kernels on non-NetBSD platforms, I decided to try loading a binary NetBSD kernel module into a rump kernel compiled for and running on Linux. The hypothesis was that the NetBSD kernel modules should just work since both the NetBSD kernel and Linux processes use the ELF calling convention, and all platform details are abstracted by the rump kernel hypercall layer. Sure enough, after two small fixes to the hypervisor I could mount and access a FFS file system on Linux by using ffs.kmod as the driver.

[Read More] [2 comments]

 

gnats, mail-index outage


December 06, 2012 posted by S.P.Zeidler

The machine normally running www.NetBSD.org and also gnats and mail-index.NetBSD.org had a hardware problem. It is now working again on a new chassis. [0 comments]

 

Kernel Drivers Compiled to Javascript and Run in Browser


November 07, 2012 posted by Antti Kantee

The unique anykernel capability of NetBSD allows the creation of rump kernels, which are partially paravirtualized kernels running on top of a high-level hypervisor. This technology e.g. enables running the same file system driver in the monolithic kernel or as a microkernel style server in userspace. POSIX-compatible systems have been more or less supported as rump kernel hypervisors for the past 5 years. A long-time goal has been to extend hypervisor support further, for example to embedded systems. This would bring the solid driverbase of NetBSD available to such systems with only the cost of implementing the hypervisor.

To see how far things can go, last week I started toying with the idea of using a javascript engine as a rump kernel hypervisor. I was planning to compile the NetBSD kernel sources into javascript and manually implement the hypervisor. After some searching for a C->javascript compiler, I found emscripten, which translates C into javascript via LLVM bitcode. Not only is the compiler itself extremely mature, but there is also extensive support for the POSIX API. This meant that I could not only compile the kernel drivers to javascript with emscripten, I could also compile the existing POSIX hypervisor and have it work.

The approach of compiling kernel drivers into javascript allows them to be directly accessed from existing javascript code. Yes, I did add a sys/arch/javascript into the kernel source tree. This contrasts the approach taken by another similar experiment, where an x86 Linux is run inside a x86 machine emulator running in a javascript engine.

I have thrown together a small proof-of-concept demo of how to build a web service with the capability to access file system images using kernel file system drivers compiled to javascript. I compiled a rump kernel with support for the FFS, tmpfs and kernfs file systems. This rump kernel backend is tied to a lightweight web page which passes requests from forms to the rump kernel and displays results. When the javascript is run, it downloads an FFS image (rump.data), bootstraps a rump kernel, and mounts the FFS image r/o at /ffs. The status can be further manipulated with interactive commands.

The demo is available here. I've tested it to work with Firefox and tested it to not work with Internet Explorer. YMMV with other browsers. Note, the javascript and the FFS image together are close to 5.5MB in size, so the page may load for a few moments over a slow link -- javascript is not exactly compact and whitespace removal was the only size reduction technique I used. If you're interested in comparing the generated javascript with the C sources, you can also look at the unoptimized version (14MB).

[16 comments]

 

Introducing sysbuild and sysupgrade


August 07, 2012 posted by Julio Merino

If you are like me and do not like repeating manual tasks over and over again, you probably have written custom scripts to rebuild NetBSD from source and to upgrade your NetBSD installation to a new build. I have had such scripts for years, but they have always been very rudimentary, inflexible and unreliable. What's more: every NetBSD machine I have today has its own custom versions of these scripts, often with little incompatible tweaks to accomodate every installation.

I was now facing the time to rebuild my NetBSD development box (because its VM disk is running out of space), and the thought of having to reconfigure my environment to perform periodic NetBSD builds, and to have to continue using my deficient custom upgrade script gave me the energy to sit down and write decent versions of these two tools. The results of such efforts are sysbuild and sysupgrade, and their goal is to trivialize rebuilds and upgrades.

sysbuild, currently available in pkgsrc/sysutils/sysbuild, automates the process of fetching the NetBSD sources from a CVS repository and performing a build for one or more platforms. The process is defined by a configuration file that controls the parameters of the build, and building a new snapshot from scratch is as easy as issuing one parameter-less command. A companion sysbuild-user package configures an unprivileged system user to perform nightly builds of NetBSD from cron, which is very convenient for developers tracking NetBSD-current. My other post "Introducing sysbuild for NetBSD" and the sysbuild(1) manual page provide more details.

sysupgrade, currently available in pkgsrc/sysutils/sysupgrade, automates the process of bringing a NetBSD system up to date by using a collection of distribution sets (which can come from either sysbuild, your manual builds or a public FTP site). This tool does not have any upgrade knowledge of its own: it is "just" a script for the manual procedure of fetching the distribution sets, upgrading the kernel, unpacking the sets and upgrading /etc with the standard etcupdate and postinstall. My other post "Introducing sysupgrade for NetBSD" and the sysupgrade(8) manual page provide more details.

The tools are released under a typical permissive 3-clause BSD license. I have opted to place them in pkgsrc instead of the base system to give the tools some mileage and to make them immediately available to older releases and operating systems. However, my end goal for these tools (specially sysupgrade) is to end up being part of the NetBSD base system: I find it unfortunate that the base system does not provide a mechanism to upgrade itself to a newer release.

Enjoy the tools and please share your feedback!

... just keep in mind that these are fresh new code so obscure bugs may be lingering around. Hint: Run the included test suites to get some confidence in the implementation before running the tools.

[1 comment]

 

Start your week with meeting NetBSD


May 28, 2012 posted by Mike M. Volokhov

After weekend, on Monday, I usually warming myself up. It's always good to read an interesting article or meet eminent people to set a pitch for the week. This week such a reading was from Billy Toulas of the unixmen.com, popular Unix/Linux online magazine who just interviewed Martin Husemann.

Martin is one of those people with whom the NetBSD Project is strongly associated. He's former member of the NetBSD Board, and today is acting as sparc64 Portmaster and as part of NetBSD Security and Release Engineering teams. But don't be confused with all those loud names — Martin is very friendly man who fantastically can explain complex things.

The reading is interesting and long, and contains a number of amusing little know facts, so take a big popcorn pack, or start build.sh over NetBSD 6.0 BETA2 (just as I did) and enjoy the interview. [0 comments]

 

New NetBSD flyers available


March 18, 2012 posted by Benny Siegert

For informing our peers about NetBSD, for distributing at a conference or meet-up, or simply as a concise introduction – new NetBSD flyers are now available at http://www.NetBSD.org/gallery/advocacy/. They are made to be printed on A4 paper and folded twice. English and German versions are provided.

At the moment, there are three flyers: "What is NetBSD?" gives an overview about the project and the OS, while "Tips and Tricks for NetBSD newcomers" and "NetBSD for Newcomers – Switching from GNU/Linux" are more aimed at people who already know similar operating systems, particularly GNU/Linux, and want to know more about the differences between these systems and NetBSD.

We are very grateful to Julian Fagir, who provided these flyers to the project.

[4 comments]

 

Running NetBSD on the LG-N2R1D NAS-family


December 15, 2011 posted by Reinoud Zandijk

Article about installing NetBSD on a small nas device LG NAS-N2R1D. This requires some soldering and other black magic but otherwise pretty good example of NetBSD portability.

[Read More] [0 comments]

 

Fossil and Git mirrors of pkgsrc and src


August 03, 2011 posted by Jörg Sonnenberger

The NetBSD CVS repository has seen a lot of work over the recent months to clean up various historic artefacts. Together with the improvements in cvs2fossil and the Fossil->Git conversion, it is now possible to provide a precise, up-to-date conversion.

The Git repositories can be found on github, checkout pkgsrc and src.

The Fossil repositories can be found at src (mirror) and pkgsrc (mirror). The raw database as faster alternative to cloning can be found on ftp.NetBSD.org.

This repositories are synchronised with a normal latency of 2h. The only differences between a checkout from CVS and Fossil/Git are supposed to be related to historic checkouts of files pulled from a vendor branch. The implemented behaviour is consistent with the changes in the file. RCS IDs are all expanded using the same rules CVS follows.

[3 comments]

 

USB Keyboard Support for DDB


July 31, 2011 posted by Marc Balmer

More and more modern computers don't come with a "real" keyboard interface anymore, and that makes our lives hard when we have to enter the kernel debugger DDB. Well, not anymore if you run -current. jmcneill@ committed code which lets you use DDB with USB keyboards. See

http://mail-index.netbsd.org/source-changes/2011/07/30/msg025233.html

for the full commit message.

[1 comment]

 

NetBSD's Google Summer of Code Projects 2011


April 25, 2011 posted by S.P.Zeidler

The following projects have been chosen for Google Summer of Code™ this year (sorted by student's last name):
  • Implementing the algorithms described in RFC 6056 within the NetBSD
  • Student: Vlad Balan
  • Mentor: Christos Zoulas
  • Socket option to timestamp UDP packets in NetBSD kernel
  • Student: Dmitry Cherkassov
  • Mentor: Marc Balmer
  • pkgsrc cross-building: connecting the dots
  • Student: Efstathios Kamperis
  • Mentor: Aleksej Saushev
  • Add kqueue support to GIO
  • Student: Dmitry Matveev
  • Mentor: Julio Merino
  • Userspace file system and device driver code sharing
  • Student: Vyacheslav Matyushin
  • Mentor: Alistair Crooks
  • IPv6 support for NPF firewall
  • Student: Zoltan Arnold Nagy
  • Mentor: Martin Husemann, Mindaugas Rasiukevicius
  • Add support for FreeBSD package format, RPM and Debian packages(if time allows) to pkgsrc
  • Student: Anton Panev
  • Mentor: Jeremy C. Reed
  • Apropos replacement based on mandoc and SQLite's FTS
  • Student: Abhinav Upadhyay
  • Mentor: Jörg Sonnenberger
  • In-kernel implementation of posix_spawn
  • Student: Charles Zhang
  • Mentor: Martin Husemann
[0 comments]