Linux kernel source tree
C C++ Assembly Makefile Perl Objective-C
Pull request Compare This branch is 575 commits ahead, 13299 commits behind torvalds:master.
Latest commit c874d36 Jan 19, 2017 @tavip tavip committed on GitHub Merge pull request #300 from lkl/issue-294
lkl tools: cpfromfs: fix root directory copy
Failed to load latest commit information.
Documentation Merge tag 'v4.9' into merge-linux-4.9 Dec 24, 2016
arch lkl: filter null bytes from syscall_defs.h Jan 8, 2017
block Don't feed anything but regular iovec's to blk_rq_map_user_iov Dec 7, 2016
certs certs: Add a secondary system keyring that can be added to dynamically Apr 11, 2016
crypto Merge tag 'v4.9' into merge-linux-4.9 Dec 24, 2016
drivers Merge branch 'linus' of git://… Dec 10, 2016
firmware WHENCE: use for LinuxTV URLs Dec 4, 2015
fs Merge tag 'v4.9' into merge-linux-4.9 Dec 24, 2016
include Merge tag 'v4.9' into merge-linux-4.9 Dec 24, 2016
init Merge tag 'v4.9' into merge-linux-4.9 Dec 24, 2016
ipc ipc: account for kmem usage on mqueue and msg Oct 28, 2016
kernel Merge tag 'v4.9' into merge-linux-4.9 Dec 24, 2016
lib Merge tag 'v4.9' into merge-linux-4.9 Dec 24, 2016
mm shmem: fix shm fallocate() list corruption Dec 6, 2016
net can: raw: raw_setsockopt: limit number of can_filter that can be set Dec 7, 2016
samples bpf/samples: Fix PT_REGS_IP on s390x and use it Nov 28, 2016
scripts Merge tag 'v4.9' into merge-linux-4.9 Dec 24, 2016
security apparmor: fix change_hat not finding hat after policy replacement Nov 21, 2016
sound dbri: move dereference after check for NULL Dec 6, 2016
tools lkl tools: cpfromfs: fix root directory copy Jan 18, 2017
usr usr/Kconfig: make initrd compression algorithm selection not expert Dec 13, 2014
virt KVM: use after free in kvm_ioctl_create_device() Dec 1, 2016
.cocciconfig scripts: add Linux .cocciconfig for coccinelle Jul 22, 2016
.get_maintainer.ignore Add hch to .get_maintainer.ignore Aug 21, 2015
.gitattributes .gitattributes: set git diff driver for C source code files Oct 8, 2016
.gitignore Merge branch 'misc' of git://… Aug 2, 2016
.mailmap Merge branch 'upstream' of git://… Oct 15, 2016
COPYING [PATCH] update FSF address in COPYING Sep 10, 2005
CREDITS Fix up a couple of field names in the CREDITS file Dec 2, 2016
Kbuild scripts/gdb: provide linux constants May 24, 2016
Kconfig kbuild: migrate all arch to the kconfig mainmenu upgrade Sep 20, 2010
MAINTAINERS Merge tag 'v4.9' into merge-linux-4.9 Dec 24, 2016
Makefile Merge tag 'v4.9' into merge-linux-4.9 Dec 24, 2016
README README: Delete obsolete i386 info + update arch/i386/ paths Aug 14, 2016 Redirect to Documentation/lkl.txt Nov 17, 2015
REPORTING-BUGS Docs: fix missing word in REPORTING-BUGS Feb 15, 2016
circle.yml lkl tools: add script for coding style checks for CircleCI builds Sep 10, 2016


LKL (Linux Kernel Library) is aiming to allow reusing the Linux kernel code as extensively as possible with minimal effort and reduced maintenance overhead.

Examples of how LKL can be used are: creating userspace applications (running on Linux and other operating systems) that can read or write Linux filesystems or can use the Linux networking stack, creating kernel drivers for other operating systems that can read Linux filesystems, bootloaders support for reading/writing Linux filesystems, etc.

With LKL, the kernel code is compiled into an object file that can be directly linked by applications. The API offered by LKL is based on the Linux system call interface.

LKL is implemented as an architecture port in arch/lkl. It uses host operations defined by the application or a host library (tools/lkl/lib).

Supported hosts

The supported hosts for now are POSIX and Windows userspace applications.

Building LKL, the host library and LKL based tools

$ make -C tools/lkl

will build LKL as a object file, it will install it in tools/lkl/lib together with the headers files in tools/lkl/include then will build the host library, tests and a few of application examples:

  • tests/boot - a simple applications that uses LKL and exercises the basic LKL APIs

  • fs2tar - a tool that converts a filesystem image to a tar archive

  • cptofs/cpfromfs - a tool that copies files to/from a filesystem image

  • lklfuse - a tool that can mount a filesystem image in userspace, without root priviledges, using FUSE

Building LKL on FreeBSD

$ pkg install binutils gcc49 gnubc

#If you don't have a gcc binary:
$ ln -sf /usr/local/bin/gcc49 /usr/local/bin/gcc

#Prefer ports binutils and GNU bc(1):
$ export PATH=/sbin:/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/usr/lib64/ccache

$ gmake -C tools/lkl

Building LKL on Ubuntu

$ sudo apt-get install libfuse-dev libarchive-dev xfsprogs

# Optional, if you would like to be able to run tests
$ sudo apt-get install btrfs-tools

$ make -C tools/lkl

# To check that everything works:
$ cd tools/lkl
$ make test

Building LKL for Windows

In order to build LKL for Win32 the mingw cross compiler needs to be installed on the host (e.g. on Ubuntu the following packages are required: binutils-mingw-w64-i686, gcc-mingw-w64-base, gcc-mingw-w64-i686 mingw-w64-common, mingw-w64-i686-dev).

Due to a bug in mingw regarding weak symbols the following patches needs to be applied to mingw-binutils:

and i686-w64-mingw32-gas, i686-w64-mingw32-ld and i686-w64-mingw32-objcopy need to be recompiled.

With that pre-requisites fullfilled you can now build LKL for Win32 with the following command:

$ make CROSS_COMPILE=i686-w64-mingw32- -C tools/lkl

Building LKL on Windows

To build on Windows, certain GNU tools need to be installed. These tools can come from several different projects, such as cygwin, unxutils, gnu-win32 or busybox-w32. Below is one minimal/modular set-up based on msys2.

Common build dependencies:

  • MSYS2 (provides GNU bash and many other utilities)
  • Extra utilities from MSYS2/pacman: bc, base-devel

General considerations:

  • No spaces in pathnames (source, prefix, destination,...)!
  • Make sure that all utilities are in the PATH.
  • Win64 (and MinGW 64-bit crt) is LLP64, which causes conflicts in size of "long" in the Linux source. Linux (and lkl) can (currently) not be built on LLP64.
  • Cygwin (and msys2) are LP64, like linux.

For MSYS2 (and Cygwin):

Msys2 will install a gcc tool chain as part of the base-devel bundle. Binutils (2.26) is already patched for NT weak externals. Using the msys2 shell, cd to the lkl sources and run:

$ make -C tools/lkl

For MinGW:

Install mingw-w64-i686-toolchain via pacman, mingw-w64-i686-binutils (2.26) is already patched for NT weak externals. Start a MinGW Win32 shell (64-bit will not work, see above) and run:

$ make -C tools/lkl

LKL hijack library

LKL hijack library ( is used to replace system calls used by an application on the fly so that the application can use LKL instead of the kernel of host operating system. LD_PRELOAD is used to dynamically override system calls with this library when you execute a program.

You can usually use this library via a wrapper script.

$ cd tools/lkl
$ ./bin/ ip address show

There are environmental variables to configure the behavior of LKL. The followings are the list of those variable for your environment.


    The interface type in host operating system to connect to LKL. The following example specifies a tap interface.

    $ LKL_HIJACK_NET_IFTYPE=tap LKL_HIJACK_NET_IFPARAMS=tap0 ip address show

    Additional configuration parameters for the interface specified by LKL_HIJACK_NET_IFTYPE. The parameters depend on the interface type (LKL_HIJACK_NET_IFTYPE).

    $ LKL_HIJACK_NET_IFTYPE=tap LKL_HIJACK_NET_IFPARAMS=tap0 ip address show

    the IP address of the interface specified by LKL_HIJACK_NET_TAP.

    $ LKL_HIJACK_NET_IP= ip address show

Additionally, DHCP is experimentally available with the following syntax.


    the network mask length of the interface specified by LKL_HIJACK_NET_TAP.


    the MAC address of the interface specified by LKL_HIJACK_NET_TAP.

    $ LKL_HIJACK_NET_MAC="aa:bb:cc:dd:ee:ff" ip address show

    the gateway IP address of LKL network stack.

     $ LKL_HIJACK_NET_GATEWAY= ip address show

    the MTU size of the interface specified by LKL_HIJACK_NET_TAP.

     $ LKL_HIJACK_NET_MTU=1280 ip address show

    Add a list of permanent neighbor entries in the form of "ip|mac;ip|mac;...". ipv6 are supported

     $ LKL_HIJACK_NET_NEIGHBOR="|12:34:56:78:9a:bc;2001:db8:0:f101::3|12:34:56:78:9a:be" ip neighbor show

    Setting it causes some debug information (both from the kernel and the LKL library) to be enabled. It is also used as a bit mask to turn on specific debugging facilities. E.g., setting it to 0x100 ("export LKL_HIJACK_DEBUG=0x100") will cause the LKL kernel to pause after the hijack'ed app exits. This allows one to debug or collect info from the LKL kernel before it quits.

     $ LKL_HIJACK_DEBUG=1 ip address show

    Pin LKL kernel threads on to a single host cpu. LKL_HIJACK_SINGLE_CPU=1 pins only LKL kernel threads while LKL_HIJACK_SINGLE_CPU=2 also pins polling threads.

     $ LKL_HIJACK_SINGLE_CPU=1 ip address show

    Work as a bit mask to enable selective device offload features. E.g., to enable "mergeable RX buffer" (LKL_VIRTIO_NET_F_MRG_RXBUF) + "guest csum" (LKL_VIRTIO_NET_F_GUEST_CSUM) device features, simply set it to 0x8002.

    See virtio_net.h for a list of offload features and their bit masks.

     $ LKL_HIJACK_OFFLOAD=0x8002 ./netserver -D -f


Q: How is LKL different from UML?

A: UML prodivides a full OS environment (e.g. user/kernel separation, user processes) and also has requirements (a filesystem, processes, etc.) that makes it hard to use it for standalone applications. UML also relies heavily on Linux hosts. On the other hand LKL is designed to be linked directly with the application and hence does not have user/kernel separation which makes it easier to use it in standalone applications.

Q: How is LKL different from LibOS?

A: LibOS re-implements high-level kernel APIs for timers, softirqs, scheduling, sysctl, SLAB/SLUB, etc. LKL behaves like any arch port, implementing the arch level operations requested by the Linux kernel. LKL also offers a host interface so that support for multiple hosts can be implemented.