Hello again,

This is also to ask a review for a rumprun patch to run
Linux kernel as a rump kernel (instead of NetBSD).  This
patch also is related with the following PR.

https://github.com/rumpkernel/rumprun/pull/93

The patch also adds two submodules: patched musl libc and
patched LKL to be able to run on rump hypercall with a
proper build toolchain.

The patch is still young and may need more update but I
would like to hear your opinion on the direction to support
an alternate rump kernel.

--

From b214dcdc38967ba0a99598e571ef9be69976f301 Mon Sep 17 00:00:00 2001
From: Hajime Tazaki <thehaj...@gmail.com>
Date: Sun, 26 Mar 2017 10:24:30 +0900
Subject: [PATCH] linux: add linux rump kernel build

build-rr.sh adds new -r option to switch what rump kernel is used:
NetBSD is the default one and add Linux one for the alternative in this
patch.

Although there are several limitations (listed below) in this stage,
this would be a first step toward supporting alternate rump kernel
across different ones.

Limitations:
- no xen execution support (build should be fine)
- no i486 build support
- TLS is not properly implemented: tests are failed and uses
  TEST_LESS env for the minimum test
- CXX is always false: CXX=false should be added to build linux rump
  kernel
- no libz support
- no cookfs (/rootfs) support
- rumprun-packages needs more work: current test on travis is only build
  test and the executions might have various issues.
---
 .gitmodules                            |   8 +-
 .travis.yml                            |  32 ++++--
 app-tools/rumprun                      |  12 ++-
 app-tools/rumprun-bake.conf            |  14 +++
 build-rr.sh                            |  73 +++++++------
 buildrump.sh                           |   2 +-
 include/rumprun-base/config.h          |   4 +
 include/rumprun-base/rumprun.h         |  16 +++
 lib/librumprun_base/Makefile           |  16 ++-
 lib/librumprun_base/config.c           |  56 ++++++++++
 lib/librumprun_base/linux_initfini.c   |  29 +++++
 lib/librumprun_base/rumprun-private.h  |   1 +
 lib/librumprun_base/rumprun.c          |  38 ++++++-
 lib/librumprun_base/syscall_misc.c     |  17 ++-
 lib/librumprun_tester/rumprun_tester.c |  13 +++
 lib/librumprun_tester/tester.h         |  17 +++
 linux                                  |   1 +
 musl                                   |   1 +
 platform/Makefile.inc                  |  13 +++
 platform/makepseudolinkstubs-linux.sh  | 103 ++++++++++++++++++
 platform/xen/Makefile                  |   6 ++
 rumpkernel/linux.sh                    |  60 +++++++++++
 rumpkernel/netbsd.sh                   |  26 +++++
 tests/basic/misc_test.c                |   3 +-
 tests/buildtests.sh                    |   6 ++
 tests/cmake/test.c                     |   2 +-
 tests/configure/test.c                 |   2 +-
 tests/hello/hello.c                    |   2 +-
 tests/nolibc/Makefile                  |  16 ++-
 tests/nolibc/main.c                    |  11 +-
 tests/nolibc/nolibc.h                  |   7 +-
 tests/nolibc/stub.c                    | 191 +++++++++++++++++++++++++++++++++
 tests/runtests.sh                      |   9 +-
 33 files changed, 735 insertions(+), 72 deletions(-)
 create mode 100644 lib/librumprun_base/linux_initfini.c
 create mode 160000 linux
 create mode 160000 musl
 create mode 100755 platform/makepseudolinkstubs-linux.sh
 create mode 100644 rumpkernel/linux.sh
 create mode 100644 rumpkernel/netbsd.sh
 create mode 100644 tests/nolibc/stub.c

diff --git a/.gitmodules b/.gitmodules
index aa198d45ab16..743d9f903fe9 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -1,6 +1,12 @@
 [submodule "buildrump.sh"]
        path = buildrump.sh
-       url = https://github.com/rumpkernel/buildrump.sh
+       url = https://github.com/libos-nuse/buildrump.sh
 [submodule "src-netbsd"]
        path = src-netbsd
        url = https://github.com/rumpkernel/src-netbsd
+[submodule "linux"]
+       path = linux
+       url = https://github.com/libos-nuse/lkl-linux.git
+[submodule "musl"]
+       path = musl
+       url = https://github.com/libos-nuse/musl.git
diff --git a/.travis.yml b/.travis.yml
index 421c914360de..fd337834e901 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -11,17 +11,33 @@ before_script:
   - sudo apt-get install --only-upgrade binutils gcc -y
 
 env:
-  - PLATFORM=hw MACHINE=x86_64 TESTS=qemu EXTRAFLAGS=
-  - PLATFORM=hw MACHINE=i486 ELF=elf TESTS=qemu EXTRAFLAGS='-- -F 
ACLFLAGS=-m32 -F ACLFLAGS=-march=i686'
-  - PLATFORM=xen MACHINE=x86_64 TESTS=none EXTRAFLAGS=
-  - PLATFORM=xen MACHINE=i486 ELF=elf TESTS=none EXTRAFLAGS='-- -F 
ACLFLAGS=-m32'
-  - PLATFORM=hw MACHINE=x86_64 TESTS=qemu EXTRAFLAGS= CXX='false'
-  - PLATFORM=hw MACHINE=x86_64 TESTS=none KERNONLY=-k EXTRAFLAGS= 
-  - PLATFORM=xen MACHINE=x86_64 TESTS=none KERNONLY=-k EXTRAFLAGS=
+  - PLATFORM=hw MACHINE=x86_64 TESTS=qemu RUMPKERNEL="-r netbsd" EXTRAFLAGS=
+  - PLATFORM=hw MACHINE=i486 ELF=elf TESTS=qemu RUMPKERNEL="-r netbsd" 
EXTRAFLAGS='-- -F ACLFLAGS=-m32 -F ACLFLAGS=-march=i686'
+  - PLATFORM=xen MACHINE=x86_64 TESTS=none RUMPKERNEL="-r netbsd" EXTRAFLAGS=
+  - PLATFORM=xen MACHINE=i486 ELF=elf TESTS=none RUMPKERNEL="-r netbsd" 
EXTRAFLAGS='-- -F ACLFLAGS=-m32'
+  - PLATFORM=hw MACHINE=x86_64 TESTS=qemu RUMPKERNEL="-r netbsd" EXTRAFLAGS= 
CXX='false'
+  - PLATFORM=hw MACHINE=x86_64 TESTS=none RUMPKERNEL="-r netbsd" KERNONLY=-k 
EXTRAFLAGS=
+  - PLATFORM=xen MACHINE=x86_64 TESTS=none RUMPKERNEL="-r netbsd" KERNONLY=-k 
EXTRAFLAGS=
+  - PLATFORM=hw MACHINE=x86_64 TESTS=qemu RUMPKERNEL="-r linux" EXTRAFLAGS= 
TEST_LESS=1
+  - PLATFORM=hw MACHINE=i486 ELF=elf TESTS=qemu RUMPKERNEL="-r linux" 
EXTRAFLAGS='-- -F ACLFLAGS=-m32 -F ACLFLAGS=-march=i686' TEST_LESS=1
+  - PLATFORM=xen MACHINE=x86_64 TESTS=none RUMPKERNEL="-r linux" EXTRAFLAGS=
+  - PLATFORM=xen MACHINE=i486 ELF=elf TESTS=none RUMPKERNEL="-r linux" 
EXTRAFLAGS='-- -F ACLFLAGS=-m32'
+  - PLATFORM=hw MACHINE=x86_64 TESTS=qemu RUMPKERNEL="-r linux" EXTRAFLAGS= 
CXX='false' TEST_LESS=1
+  - PLATFORM=hw MACHINE=x86_64 TESTS=none RUMPKERNEL="-r linux" KERNONLY=-k 
EXTRAFLAGS=
+  - PLATFORM=xen MACHINE=x86_64 TESTS=none RUMPKERNEL="-r linux" KERNONLY=-k 
EXTRAFLAGS=
+
+matrix:
+   allow_failures:
+      # no CXX
+      - env: PLATFORM=hw MACHINE=x86_64 TESTS=qemu RUMPKERNEL="-r linux" 
EXTRAFLAGS= TEST_LESS=1
+      - env: PLATFORM=xen MACHINE=x86_64 TESTS=none RUMPKERNEL="-r linux" 
EXTRAFLAGS=
+      # no i486 build yet
+      - env: PLATFORM=hw MACHINE=i486 ELF=elf TESTS=qemu RUMPKERNEL="-r linux" 
EXTRAFLAGS='-- -F ACLFLAGS=-m32 -F ACLFLAGS=-march=i686' TEST_LESS=1
+      - env: PLATFORM=xen MACHINE=i486 ELF=elf TESTS=none RUMPKERNEL="-r 
linux" EXTRAFLAGS='-- -F ACLFLAGS=-m32'
 
 script:
   - git submodule update --init
-  - ./build-rr.sh -o myobj -j16 -qq ${KERNONLY} ${PLATFORM} ${EXTRAFLAGS}
+  - ./build-rr.sh -o myobj -j16 -qq ${RUMPKERNEL} ${KERNONLY} ${PLATFORM} 
${EXTRAFLAGS}
   - . ./myobj/config
   - ./tests/buildtests.sh ${KERNONLY}
   - ./tests/runtests.sh ${TESTS}
diff --git a/app-tools/rumprun b/app-tools/rumprun
index a5e1d5ac331e..26b2f8645211 100644
--- a/app-tools/rumprun
+++ b/app-tools/rumprun
@@ -691,7 +691,7 @@ run_qemu ()
        if [ -n "$opt_interactive" ]; then
                ${qemucmd} -append "${json_coma}"
        else
-               qemucmd="${qemucmd} -display none"
+               qemucmd="${qemucmd} -display none -vga none"
                ${qemucmd} -append "${json_coma}" 1>/dev/null 2>&1 &
                echo qemu:$!
        fi
@@ -703,7 +703,13 @@ bake_iso ()
        [ -z "${DUMPCMD}" ] || die -D not supported by iso.  Use -T.
 
        type xorriso >/dev/null || die bake_iso needs xorriso
-       type grub-mkrescue >/dev/null || die bake_iso needs grub-mkrescue
+       if type grub-mkrescue 2>/dev/null >/dev/null; then
+               MKRESCUE=grub-mkrescue
+       elif type grub2-mkrescue 2>/dev/null >/dev/null; then
+               MKRESCUE=grub2-mkrescue
+       else
+               die bake_iso needs grub-mkrescue or grub2-mkrescue
+       fi
 
        store_blkspec=json_store_iso_blkspec
        store_netspec=json_store_netspec
@@ -777,7 +783,7 @@ bake_iso ()
            $(basename $1) >> "${ISODIR}/boot/grub/grub.cfg"
        cp ${bootimage} "${ISODIR}/boot"
        cp "${TMPDIR}/json.cfg" "${ISODIR}"
-       grub-mkrescue -o ${opt_name} "${ISODIR}"
+       ${MKRESCUE} -o ${opt_name} "${ISODIR}"
 }
 
 make_ec2 ()
diff --git a/app-tools/rumprun-bake.conf b/app-tools/rumprun-bake.conf
index b54e16e7cef7..4e62a0bb59f2 100644
--- a/app-tools/rumprun-bake.conf
+++ b/app-tools/rumprun-bake.conf
@@ -149,3 +149,17 @@ conf hw_generic
                        _pciether               \
                        _usb
 fnoc
+
+conf hw_lkl
+       create          "LKL generic (a.k.a all) targets"
+       add             -llkl
+       add             -lrumprun_base
+       add             -lrumpdev_linux_pci
+fnoc
+
+conf xen_pv_lkl
+       create          "Xen with paravirtualized I/O drivers with LKL"
+       add             -llkl
+       add             -lrumprun_base
+       add             -lrumpdev_linux_pci
+fnoc
diff --git a/build-rr.sh b/build-rr.sh
index 2bb318b77125..73e2831a6087 100755
--- a/build-rr.sh
+++ b/build-rr.sh
@@ -49,6 +49,7 @@ helpme ()
        printf "\t-o: use non-default object directory\n"
        printf "\t-k: build kernel only, without libc or tools\n"
        printf "\t-s: specify alternative src-netbsd location\n\n"
+       printf "\t-r: type of rump kernel [netbsd|linux]. default netbsd\n\n\n"
        printf "\tbuildrump.sh opts are passed to buildrump.sh\n"
        printf "\n"
        printf "The toolchain is picked up from the environment.  See the\n"
@@ -96,6 +97,8 @@ parseargs ()
        KERNONLY=false
        RROBJ=
        RUMPSRC=src-netbsd
+       LKLSRC=linux
+       RUMPKERNEL=netbsd
        STDJ=-j4
        EXTSRC=
 
@@ -103,7 +106,7 @@ parseargs ()
        DOinstall=false
 
        orignargs=$#
-       while getopts '?d:hj:ko:qs:' opt; do
+       while getopts '?d:hj:kr:o:qs:' opt; do
                case "$opt" in
                'j')
                        [ -z "$(echo ${OPTARG} | tr -d '[0-9]')" ] \
@@ -116,6 +119,14 @@ parseargs ()
                'k')
                        KERNONLY=true
                        ;;
+               'r')
+                       RUMPKERNEL="${OPTARG}"
+                       if [ ${RUMPKERNEL} != "netbsd" -a ${RUMPKERNEL} != 
"linux" ]; then
+                               echo '>> ERROR:'
+                               echo '>> -r option (RUMPKERNEL) must be netbsd 
or linux'
+                               exit 1
+                       fi
+                       ;;
                'o')
                        RROBJ="${OPTARG}"
                        ;;
@@ -180,6 +191,8 @@ parseargs ()
                DOinstall=true
        fi
 
+       . rumpkernel/${RUMPKERNEL}.sh
+
        case ${RUMPSRC} in
        /*)
                ;;
@@ -190,6 +203,7 @@ parseargs ()
 
        export RUMPSRC
        export BUILD_QUIET
+       export RUMPKERNEL
 
        ARGSSHIFT=$((${orignargs} - $#))
 }
@@ -297,6 +311,9 @@ setvars ()
        abspath RRDEST
        abspath RROBJ
        abspath RUMPSRC
+       abspath LKLSRC
+       export RROBJ
+       export LKLSRC
 }
 
 checktools ()
@@ -357,7 +374,7 @@ buildrump ()
            -s ${RUMPSRC} -T ${RUMPTOOLS} -o ${BROBJ} -d ${STAGING}     \
            -V MKPIC=no -V RUMP_CURLWP=__thread                         \
            -V RUMP_KERNEL_IS_LIBC=1 -V BUILDRUMP_SYSROOT=yes           \
-           ${extracflags} "$@" tools
+           ${extracflags} -l ${RUMPKERNEL} "$@" tools
 
        echo '>>'
        echo '>> Now that we have the appropriate tools, performing'
@@ -367,7 +384,7 @@ buildrump ()
        RUMPMAKE=$(pwd)/${RUMPTOOLS}/rumpmake
 
        TOOLTUPLE=$(${RUMPMAKE} -f bsd.own.mk \
-           -V '${MACHINE_GNU_PLATFORM:S/--netbsd/-rumprun-netbsd/}')
+           -V '${MACHINE_GNU_PLATFORM:S/--netbsd/-rumprun-${RUMPKERNEL}/}')
 
        [ $(${RUMPMAKE} -f bsd.own.mk -V '${_BUILDRUMP_CXX}') != 'yes' ] \
            || HAVECXX=true
@@ -406,7 +423,7 @@ EOF
        # build rump kernel
        ${BUILDRUMP}/buildrump.sh ${BUILD_QUIET} ${STDJ} -k             \
            -s ${RUMPSRC} -T ${RUMPTOOLS} -o ${BROBJ} -d ${STAGING}     \
-           "$@" build kernelheaders install
+           -l ${RUMPKERNEL} "$@" build kernelheaders install
 
        echo '>>'
        echo '>> Rump kernel components built.  Proceeding to build'
@@ -421,33 +438,6 @@ buildapptools ()
        ${MAKE} -C app-tools BUILDRR=true install
 }
 
-builduserspace ()
-{
-
-       usermtree ${STAGING}
-
-       LIBS="$(stdlibs ${RUMPSRC})"
-       ! ${HAVECXX} || LIBS="${LIBS} $(stdlibsxx ${RUMPSRC})"
-
-       userincludes ${RUMPSRC} ${LIBS} $(pwd)/lib/librumprun_tester
-       for lib in ${LIBS}; do
-               makeuserlib ${lib}
-       done
-}
-
-buildpci ()
-{
-
-       if eval ${PLATFORM_PCI_P}; then
-               (
-                       cd ${PLATFORMDIR}/pci
-                       ${RUMPMAKE} ${STDJ} obj
-                       ${RUMPMAKE} ${STDJ} dependall
-                       ${RUMPMAKE} ${STDJ} install
-               )
-       fi
-}
-
 wraponetool ()
 {
 
@@ -476,6 +466,7 @@ makeconfig ()
        echo "TOOLTUPLE=${quote}${TOOLTUPLE}${quote}" >> ${1}
        echo "KERNONLY=${quote}${KERNONLY}${quote}" >> ${1}
        echo "PLATFORM=${quote}${PLATFORM}${quote}" >> ${1}
+       echo "RUMPKERNEL=${quote}${RUMPKERNEL}${quote}" >> ${1}
 
        echo "RRDEST=${quote}${RRDEST}${quote}" >> ${1}
        echo "RROBJ=${quote}${RROBJ}${quote}" >> ${1}
@@ -517,7 +508,7 @@ dobuild ()
 
        # do final build of the platform bits
        ( cd ${PLATFORMDIR} \
-           && ${MAKE} BUILDRR=true \
+           && ${MAKE} BUILDRR=true RUMPKERNEL=${RUMPKERNEL} \
            && ${MAKE} BUILDRR=true install || exit 1)
        [ $? -eq 0 ] || die platform make failed!
 }
@@ -543,11 +534,19 @@ doinstall ()
                # first, move things to where we want them to be
                cd ${STAGING}
                rm -rf lib/pkgconfig
-               find lib -maxdepth 1 -name librump\*.a \
-                   -exec mv -f '{}' 
rumprun-${MACHINE_GNU_ARCH}/lib/rumprun-${PLATFORM}/ \;
-               find lib -maxdepth 1 -name \*.a \
-                   -exec mv -f '{}' rumprun-${MACHINE_GNU_ARCH}/lib/ \;
-
+               if [ ${RUMPKERNEL} = "netbsd" ] ; then
+                       find lib -maxdepth 1 -name librump\*.a \
+                           -exec mv -f '{}' 
rumprun-${MACHINE_GNU_ARCH}/lib/rumprun-${PLATFORM}/ \;
+                       find lib -maxdepth 1 -name \*.a \
+                           -exec mv -f '{}' rumprun-${MACHINE_GNU_ARCH}/lib/ \;
+               elif [ ${RUMPKERNEL} = "linux" ] ; then
+                       find lib -maxdepth 1 -name \*.a \
+                           -exec cp -f '{}' 
rumprun-${MACHINE_GNU_ARCH}/lib/rumprun-${PLATFORM}/ \;
+                       find lib -maxdepth 1 -name \*.a \
+                           -exec mv -f '{}' rumprun-${MACHINE_GNU_ARCH}/lib/ \;
+                       # FIXME: need to create empty librump.a for linux
+                       ar rc 
rumprun-${MACHINE_GNU_ARCH}/lib/rumprun-${PLATFORM}/librump.a
+               fi
                # make sure special cases are visible everywhere
                for x in c pthread ; do
                        rm -f 
rumprun-${MACHINE_GNU_ARCH}/lib/rumprun-${PLATFORM}/lib${x}.a
diff --git a/buildrump.sh b/buildrump.sh
index 9c9b022cb211..294a478dacf6 160000
--- a/buildrump.sh
+++ b/buildrump.sh
@@ -1 +1 @@
-Subproject commit 9c9b022cb2115734935e50600c867a3bc230b32c
+Subproject commit 294a478dacf68ed1fbfdfd551e890b78e71a99c8
diff --git a/include/rumprun-base/config.h b/include/rumprun-base/config.h
index c1c16ed8cbbd..f56407d4c8c2 100644
--- a/include/rumprun-base/config.h
+++ b/include/rumprun-base/config.h
@@ -48,4 +48,8 @@ struct rumprun_exec {
 TAILQ_HEAD(rumprun_execs, rumprun_exec);
 extern struct rumprun_execs rumprun_execs;
 
+#ifndef __arraycount
+#define __arraycount(_ar_) (sizeof(_ar_)/sizeof(_ar_[0]))
+#endif
+
 #endif /* _BMKCOMMON_RUMPRUN_CONFIG_H_ */
diff --git a/include/rumprun-base/rumprun.h b/include/rumprun-base/rumprun.h
index fb5b59ce79f8..e08f3725d1f8 100644
--- a/include/rumprun-base/rumprun.h
+++ b/include/rumprun-base/rumprun.h
@@ -42,4 +42,20 @@ void rumprun_daemon(void);
 
 extern int rumprun_cold;
 
+#ifndef _STRING
+#define        _STRING(x)      x
+#endif
+
+#ifndef __strong_alias
+#define        __strong_alias(alias,sym)                               \
+       __asm(".global " _STRING(#alias) "\n"                   \
+             _STRING(#alias) " = " _STRING(#sym));
+#endif
+
+#ifndef __weak_alias
+#define        __weak_alias(alias,sym)                         \
+       __asm(".weak " _STRING(#alias) "\n"             \
+             _STRING(#alias) " = " _STRING(#sym));
+#endif
+
 #endif /* _RUMPRUN_BASE_RUMPRUN_H_ */
diff --git a/lib/librumprun_base/Makefile b/lib/librumprun_base/Makefile
index 1426205dd5f0..3269db920341 100644
--- a/lib/librumprun_base/Makefile
+++ b/lib/librumprun_base/Makefile
@@ -2,10 +2,14 @@ LIB=          rumprun_base
 
 SRCS=          main.c rumprun.c
 SRCS+=         parseargs.c config.c
-SRCS+=         malloc.c netbsd_initfini.c signals.c
-SRCS+=         syscall_mman.c syscall_misc.c
-SRCS+=         __errno.c _lwp.c libc_stubs.c
-SRCS+=         daemon.c
+SRCS+=         malloc.c
+SRCS+=         __errno.c libc_stubs.c
+SRCS+=         daemon.c syscall_misc.c
+
+.if ${RUMPKERNEL} == "netbsd"
+SRCS+=         netbsd_initfini.c signals.c
+SRCS+=         _lwp.c
+SRCS+=         syscall_mman.c
 SRCS+=         sysproxy.c
 
 # doesn't really belong here, but at the moment we don't have
@@ -14,6 +18,10 @@ SRCS+=               platefs.c
 
 INCS=          platefs.h
 INCSDIR=       /usr/include/rumprun
+.else
+SRCS+=         linux_initfini.c
+CFLAGS+=       -DCONFIG_LKL -DMUSL_LIBC
+.endif
 
 WARNS=         5
 
diff --git a/lib/librumprun_base/config.c b/lib/librumprun_base/config.c
index 009986193276..39fd611094c6 100644
--- a/lib/librumprun_base/config.c
+++ b/lib/librumprun_base/config.c
@@ -30,14 +30,26 @@
  */
 
 #include <sys/param.h>
+
+#ifdef __linux__
+#include <sys/types.h>
+#include <stdbool.h>
+#endif
+
+#ifdef __NetBSD__
 #include <sys/disklabel.h>
+#endif
 #include <sys/ioctl.h>
 #include <sys/stat.h>
 
+#ifdef __NetBSD__
 #include <ufs/ufs/ufsmount.h>
 #include <isofs/cd9660/cd9660_mount.h>
 
 #include <dev/vndvar.h>
+#elif __linux__
+#include <sys/mount.h>
+#endif
 
 #include <assert.h>
 #include <err.h>
@@ -418,6 +430,7 @@ handle_net(jsmntok_t *t, int left, char *data)
        return 2*objsize + 1;
 }
 
+#ifdef __NetBSD__
 static void
 makevnddev(int israw, int unit, int part, char *storage, size_t storagesize)
 {
@@ -533,6 +546,49 @@ mount_kernfs(const char *dev, const char *mp)
        return false;
 }
 
+#elif __linux__
+
+static char *
+configvnd(const char *path)
+{
+       errx(1, "vnd is not supported with LKL \"%s\"", path);
+       return NULL;
+}
+
+static char *
+configetfs(const char *path, int hard)
+{
+       errx(1, "etfs is not supported with LKL \"%s\"", path);
+       return NULL;
+}
+
+static bool
+mount_blk(const char *dev, const char *mp)
+{
+       /* XXX: hardcored major/minor value for virtio-blk */
+       unsigned long major = 254, minor = 0, enc_dev;
+
+       enc_dev = (minor & 0xff) | (major << 8) | ((minor & ~0xff) << 12);
+
+       if (mknod(dev, 0666 | S_IFBLK, enc_dev) == -1)
+               err(1, "mknod %s", dev);
+
+       if (mount(dev, mp, "ext4", 0, NULL) == 0)
+               return true;
+       if (mount(dev, mp, "iso9660", MS_RDONLY, NULL) == 0)
+               return true;
+
+       return false;
+}
+
+static bool
+mount_kernfs(const char *dev, const char *mp)
+{
+       errx(1, "kernfs is not supported with LKL \"%s\"", dev);
+       return false;
+}
+#endif
+
 struct {
        const char *mt_fstype;
        bool (*mt_mount)(const char *, const char *);
diff --git a/lib/librumprun_base/linux_initfini.c 
b/lib/librumprun_base/linux_initfini.c
new file mode 100644
index 000000000000..ad560ce9a29d
--- /dev/null
+++ b/lib/librumprun_base/linux_initfini.c
@@ -0,0 +1,29 @@
+#include <stdio.h>
+
+void _init(void);
+void __init_libc(char **envp, char *pn);
+
+typedef void (*initfini_fn)(void);
+extern const initfini_fn __init_array_start;
+extern const initfini_fn __init_array_end;
+
+static void libc_start_init_priv(void)
+{
+       _init();
+       const initfini_fn *a = &__init_array_start;
+       for (; a < &__init_array_end; a++)
+               (*a)();
+}
+
+
+void _linux_userlevel_init(void);
+void _linux_userlevel_init(void)
+{
+       static char dummy_argv[16] = "rumprun-lkl";
+       static char *initial_env[] = {
+               NULL,
+       };
+
+       __init_libc(initial_env, dummy_argv);
+       libc_start_init_priv();
+}
diff --git a/lib/librumprun_base/rumprun-private.h 
b/lib/librumprun_base/rumprun-private.h
index c58b6f029af4..bbf5afd78f52 100644
--- a/lib/librumprun_base/rumprun-private.h
+++ b/lib/librumprun_base/rumprun-private.h
@@ -28,6 +28,7 @@
 
 void _netbsd_userlevel_init(void);
 void _netbsd_userlevel_fini(void);
+void _linux_userlevel_init(void);
 
 void rumprun_lwp_init(void);
 
diff --git a/lib/librumprun_base/rumprun.c b/lib/librumprun_base/rumprun.c
index 5d76ce9a74c6..424726e888e8 100644
--- a/lib/librumprun_base/rumprun.c
+++ b/lib/librumprun_base/rumprun.c
@@ -23,12 +23,16 @@
  * SUCH DAMAGE.
  */
 
+#ifdef __NetBSD__
 #include <sys/cdefs.h>
+#endif
 
 #include <sys/types.h>
 #include <sys/mount.h>
 #include <sys/queue.h>
+#ifdef __NetBSD__
 #include <sys/sysctl.h>
+#endif
 
 #include <assert.h>
 #include <err.h>
@@ -43,7 +47,14 @@
 #include <rump/rump.h>
 #include <rump/rump_syscalls.h>
 
+#ifdef __NetBSD__
 #include <fs/tmpfs/tmpfs_args.h>
+#endif
+
+#ifdef __linux__
+#define CONFIG_AUTO_LKL_POSIX_HOST
+#include <lkl_host.h>
+#endif
 
 #include <bmk-core/platform.h>
 
@@ -79,22 +90,31 @@ int rumprun_cold = 1;
 void
 rumprun_boot(char *cmdline)
 {
+#ifdef __NetBSD__
        struct tmpfs_args ta = {
                .ta_version = TMPFS_ARGS_VERSION,
                .ta_size_max = 1*1024*1024,
                .ta_root_mode = 01777,
        };
-       int tmpfserrno;
+       int x;
+#endif
+       int tmpfserrno = -1;
        char *sysproxy;
-       int rv, x;
+       int rv;
 
        rump_boot_setsigmodel(RUMP_SIGMODEL_IGNORE);
        rump_init();
 
        /* mount /tmp before we let any userspace bits run */
+#ifdef __NetBSD__
        rump_sys_mount(MOUNT_TMPFS, "/tmp", 0, &ta, sizeof(ta));
+#elif __linux__
+       rump_sys_mount("tmpfs", "/tmp", 0, NULL, 0);
+#endif
+
        tmpfserrno = errno;
 
+#ifdef __NetBSD__
        /*
         * XXX: _netbsd_userlevel_init() should technically be called
         * in mainbouncer() per process.  However, there's currently no way
@@ -107,6 +127,9 @@ rumprun_boot(char *cmdline)
         */
        rumprun_lwp_init();
        _netbsd_userlevel_init();
+#elif __linux__
+       _linux_userlevel_init();
+#endif
 
        /* print tmpfs result only after we bootstrapped userspace */
        if (tmpfserrno == 0) {
@@ -121,9 +144,10 @@ rumprun_boot(char *cmdline)
         * (note: we don't check for errors since net.inet.ip.dad_count
         * is not present if the networking stack isn't present)
         */
+#ifdef __NetBSD__
        x = 0;
        sysctlbyname("net.inet.ip.dad_count", NULL, NULL, &x, sizeof(x));
-
+#endif
        rumprun_config(cmdline);
 
        sysproxy = getenv("RUMPRUN_SYSPROXY");
@@ -208,6 +232,7 @@ mainbouncer(void *arg)
        exit(rv);
 }
 
+#ifdef __NetBSD__
 static void
 setupproc(struct rumprunner *rr)
 {
@@ -256,6 +281,7 @@ setupproc(struct rumprunner *rr)
 
        pipein = newpipein;
 }
+#endif
 
 void *
 rumprun(int flags, int (*mainfun)(int, char *[]), int argc, char *argv[])
@@ -270,7 +296,11 @@ rumprun(int flags, int (*mainfun)(int, char *[]), int 
argc, char *argv[])
        rr->rr_argv = argv;
        rr->rr_flags = flags; /* XXX */
 
+#ifdef __NetBSD__
        setupproc(rr);
+#elif __linux__
+       lkl_parse_env();
+#endif
 
        if (pthread_create(&rr->rr_mainthread, NULL, mainbouncer, rr) != 0) {
                fprintf(stderr, "rumprun: running %s failed\n", argv[0]);
@@ -365,7 +395,9 @@ void __attribute__((noreturn))
 rumprun_reboot(void)
 {
 
+#ifdef __NetBSD__
        _netbsd_userlevel_fini();
+#endif
        rump_sys_reboot(0, 0);
 
        bmk_platform_halt("reboot returned");
diff --git a/lib/librumprun_base/syscall_misc.c 
b/lib/librumprun_base/syscall_misc.c
index cc00f2d0292e..1430267cf360 100644
--- a/lib/librumprun_base/syscall_misc.c
+++ b/lib/librumprun_base/syscall_misc.c
@@ -23,13 +23,23 @@
  * SUCH DAMAGE.
  */
 
+#ifdef __NetBSD__
 #include <sys/cdefs.h>
 #include <sys/resource.h>
 #include <sys/time.h>
+#elif __linux__
+#include <bmk-rumpuser/core_types.h>
+#include <bmk-core/types.h>
+#include <sys/reboot.h>
+#undef __predict_false
+#define __predict_false(x) (x)
+#endif
 
 #include <errno.h>
 #include <fcntl.h>
+#ifdef __NetBSD__
 #include <lwp.h>
+#endif
 #include <pthread.h>
 #include <signal.h>
 #include <stdio.h>
@@ -46,7 +56,11 @@ _exit(int eval)
 
        if (__predict_false(rumprun_cold)) {
                printf("\n=== bootstrap failed\n");
+#ifdef __NetBSD__
                reboot(0, NULL);
+#elif __linux__
+               reboot(0);
+#endif
                /*NOTREACHED*/
        }
 
@@ -58,7 +72,7 @@ _exit(int eval)
 
        pthread_exit((void *)(uintptr_t)eval);
 }
-
+#ifdef __NetBSD__
 /* XXX: manual proto.  plug into libc internals some other day */
 int     ____sigtimedwait50(const sigset_t * __restrict,
     siginfo_t * __restrict, struct timespec * __restrict);
@@ -105,3 +119,4 @@ __getrusage50(int who, struct rusage *usage)
        /* XXX: wrong in many ways */
        return ENOTSUP;
 }
+#endif /* __NetBSD__ */
diff --git a/lib/librumprun_tester/rumprun_tester.c 
b/lib/librumprun_tester/rumprun_tester.c
index 364ffdd2fdd8..881b7429f03e 100644
--- a/lib/librumprun_tester/rumprun_tester.c
+++ b/lib/librumprun_tester/rumprun_tester.c
@@ -42,6 +42,10 @@
 #include <string.h>
 #include <unistd.h>
 
+#ifdef __linux__
+#include <sys/stat.h>
+#endif
+
 #include <rumprun/tester.h>
 
 #define INITIAL "??   0\n"
@@ -76,6 +80,15 @@ main(int argc, char *argv[])
        if (argc < 2 || strcmp(argv[1], "__test") != 0)
                return rumprun_test(argc, argv);
 
+#ifdef __linux__
+       /* XXX: need mknod qemu/virtio only */
+       unsigned long major = 254, minor = 0, enc_dev;
+       enc_dev = (minor & 0xff) | (major << 8) | ((minor & ~0xff) << 12);
+
+       if (mknod("/dev/ld0d", 0666 | S_IFBLK, enc_dev) == -1)
+               err(1, "rumprun_test: mknod");
+#endif
+
        /*
         * XXX: need a better way to determine disk device!
         */
diff --git a/lib/librumprun_tester/tester.h b/lib/librumprun_tester/tester.h
index b099b01b0715..858c697d6bac 100644
--- a/lib/librumprun_tester/tester.h
+++ b/lib/librumprun_tester/tester.h
@@ -26,7 +26,24 @@
 #ifndef _BMK_BASE_RUMPRUN_TEST_H_
 #define _BMK_BASE_RUMPRUN_TEST_H_
 
+#ifdef __NetBSD__
 #include <sys/cdefs.h>
+#else
+#ifndef __BEGIN_DECLS
+#define __BEGIN_DECLS
+#endif
+#ifndef __END_DECLS
+#define __END_DECLS
+#endif
+
+#ifndef roundup2
+#define        roundup2(x,m)   ((((x) - 1) | ((m) - 1)) + 1)
+#endif
+
+#ifndef __arraycount
+#define __arraycount(_ar_) (sizeof(_ar_)/sizeof(_ar_[0]))
+#endif
+#endif
 
 __BEGIN_DECLS
 int rumprun_test(int, char **);
diff --git a/linux b/linux
new file mode 160000
index 000000000000..214a97d8c327
--- /dev/null
+++ b/linux
@@ -0,0 +1 @@
+Subproject commit 214a97d8c327091275c39fa821c9558aeda07a6d
diff --git a/musl b/musl
new file mode 160000
index 000000000000..097debfdddd4
--- /dev/null
+++ b/musl
@@ -0,0 +1 @@
+Subproject commit 097debfdddd4dc29d828c9ed561171e644afe4ee
diff --git a/platform/Makefile.inc b/platform/Makefile.inc
index a82c33559691..741e38df91de 100644
--- a/platform/Makefile.inc
+++ b/platform/Makefile.inc
@@ -5,21 +5,25 @@ endif
 CPPFLAGS+=     -Iinclude -I../../include -I${RROBJ}/include -nostdinc
 CFLAGS+=       ${BUILDRUMP_TOOL_CFLAGS}
 
+ifeq (${RUMPKERNEL},netbsd)
 TARGETS=       rumpkernlibs
 # compiler_rt is strictly speaking necessary only in KERNONLY=true,
 # but building it always makes testing kernonly easier
 TARGETS+=      compiler_rt
 INSTALLTGTS+=  librumpkern_bmktc_install
 INSTALLTGTS+=  librumpkern_mman_install
+endif
 
 ifneq (${KERNONLY},true)
 TARGETS+=      userlibs
 INSTALLTGTS+=  librumprun_base_install librumprun_tester_install2
+ifeq (${RUMPKERNEL},netbsd)
 INSTALLTGTS+=  librumprunfs_base_install_custom
 ifeq (${CONFIG_CXX},yes)
 INSTALLTGTS+=  libunwind_install2
 endif
 endif
+endif
 
 ifeq (${BUILDRR},true)
 CPPFLAGS+=      -I${RROBJ}/dest.stage/include
@@ -84,13 +88,22 @@ endif
 PSEUDOSTUBS:= ${RROBJ}/pseudolinkstubs
 
 ${PSEUDOSTUBS}.c: ${RROBJLIB}/librumprun_base/librumprun_base.a
+ifeq (${RUMPKERNEL},netbsd)
        sh ../makepseudolinkstubs.sh ${NM} ${RUMPSRC} $< $@
+endif
+ifeq (${RUMPKERNEL},linux)
+       sh ../makepseudolinkstubs-linux.sh $@
+endif
 
 ${RROBJ}/bmk.ldscript: ${LDSCRIPT}
        ln -sf $< $@
 
 commonlibs: platformlibs userlibs
+ifeq (${RUMPKERNEL},netbsd)
 userlibs: ${PSEUDOSTUBS}.o ${RROBJLIB}/librumprun_base/librumprun_base.a 
${RROBJLIB}/librumprun_tester/librumprun_tester.a ${LIBUNWIND} 
${RROBJLIB}/librumprunfs_base/librumprunfs_base.a
+else
+userlibs: ${PSEUDOSTUBS}.o ${RROBJLIB}/librumprun_base/librumprun_base.a 
${RROBJLIB}/librumprun_tester/librumprun_tester.a
+endif
 platformlibs: ${RROBJLIB}/libbmk_core/libbmk_core.a 
${RROBJLIB}/libbmk_rumpuser/libbmk_rumpuser.a ${RROBJ}/bmk.ldscript
 rumpkernlibs: ${RROBJLIB}/librumpkern_bmktc/librumpkern_bmktc.a 
${RROBJLIB}/librumpkern_mman/librumpkern_mman.a
 compiler_rt: ${RROBJLIB}/libcompiler_rt/libcompiler_rt.a
diff --git a/platform/makepseudolinkstubs-linux.sh 
b/platform/makepseudolinkstubs-linux.sh
new file mode 100755
index 000000000000..a0e30f0f8909
--- /dev/null
+++ b/platform/makepseudolinkstubs-linux.sh
@@ -0,0 +1,103 @@
+#!/bin/sh
+
+TMP=$1
+
+cat << EOF > ${TMP}
+int *__errno(void) __attribute__((weak));
+int *__errno(void)
+{
+       return 0;
+}
+
+
+int rumpuser_thread_create(void *(*f)(void *), void *arg, const char *thrname,
+       int joinable, int pri, int cpuidx, void **tptr) __attribute__((weak));
+int rumpuser_thread_create(void *(*f)(void *), void *arg, const char *thrname,
+       int joinable, int pri, int cpuidx, void **tptr)
+{
+       return 0;
+}
+
+void rumpuser_thread_set_cookie(void *thread, void *cookie) 
__attribute__((weak));
+void rumpuser_thread_set_cookie(void *thread, void *cookie)
+{
+}
+
+void *rumpuser_thread_get_cookie(void) __attribute__((weak));
+void *rumpuser_thread_get_cookie(void)
+{
+       return 0;
+}
+
+void *realloc(void *p, int n) __attribute__((weak));
+void *realloc(void *p, int n)
+{
+       return 0;
+}
+
+void *calloc(int m, int n) __attribute__((weak));
+void *calloc(int m, int n)
+{
+       return 0;
+}
+
+void free(void *cp) __attribute__((weak));
+void free(void *cp)
+{
+}
+
+long lkl_syscall(long no, long *params) __attribute__((weak));
+long lkl_syscall(long no, long *params)
+{
+       return 0;
+}
+
+void _start(void);
+void _start(void)
+{
+}
+
+void _exit(int);
+void _exit(int t)
+{
+}
+
+struct bmk_thread;
+struct bmk_thread *
+bmk_sched_create_withtls(const char *name, void *cookie, int joinable,
+       void (*f)(void *), void *data,
+       void *stack_base, unsigned long stack_size, void *tlsarea)
+       __attribute__((weak));
+struct bmk_thread *
+bmk_sched_create_withtls(const char *name, void *cookie, int joinable,
+       void (*f)(void *), void *data,
+       void *stack_base, unsigned long stack_size, void *tlsarea)
+{
+       return 0;
+}
+
+void   *bmk_sched_tls_alloc(void) __attribute__((weak));
+void *
+bmk_sched_tls_alloc(void)
+{
+       return 0;
+}
+
+void   *bmk_sched_gettcb(void) __attribute__((weak));
+void *
+bmk_sched_gettcb(void)
+{
+       return 0;
+}
+
+void   bmk_sched_join(struct bmk_thread *) __attribute__((weak));
+void bmk_sched_join(struct bmk_thread *t)
+{
+}
+
+void   bmk_sched_exit_withtls(void)  __attribute__((weak));;
+void   bmk_sched_exit_withtls(void)
+{
+}
+
+EOF
diff --git a/platform/xen/Makefile b/platform/xen/Makefile
index 4f074f784ff0..65d5ef67c665 100644
--- a/platform/xen/Makefile
+++ b/platform/xen/Makefile
@@ -14,7 +14,9 @@ OBJ_DIR ?= $(CURDIR)/obj
 
 LDSCRIPT:= $(abspath $(OBJ_DIR)/xen/minios.lds)
 
+ifeq (${RUMPKERNEL},netbsd)
 INSTALLTGTS=   librumpxen_xendev_install librumpnet_xenif_install
+endif
 
 include ../Makefile.inc
 
@@ -49,7 +51,11 @@ links:
 $(eval $(call BUILDLIB_target,librumpxen_xendev,.))
 $(eval $(call BUILDLIB_target,librumpnet_xenif,.))
 
+ifeq (${RUMPKERNEL},netbsd)
 xenlibs: ${RROBJLIB}/librumpxen_xendev/librumpxen_xendev.a 
${RROBJLIB}/librumpnet_xenif/librumpnet_xenif.a
+else
+xenlibs:
+endif
 
 $(MAINOBJ): $(RUMP_OBJS) platformlibs xenlibs
        $(CC) -Wl,-r $(CFLAGS) $(LDFLAGS) $(RUMP_OBJS) -nostdlib -o $@ \
diff --git a/rumpkernel/linux.sh b/rumpkernel/linux.sh
new file mode 100644
index 000000000000..6d921e5324bb
--- /dev/null
+++ b/rumpkernel/linux.sh
@@ -0,0 +1,60 @@
+export RUMP_PREFIX=${RUMPSRC}/sys/rump
+RUMP_INCLUDE=${RUMPSRC}/sys/rump/include
+abspath RUMP_INCLUDE
+export RUMP_INCLUDE
+export LKL_EXT_OPT="rumprun=yes"
+
+builduserspace ()
+{
+# build musl libc for Linux
+(
+       set -x
+       set -e
+       echo "=== building musl ==="
+       abspath STAGING
+       cd musl
+       LKL_HEADER="${RROBJ}/dest.stage"
+       CIRCLE_TEST_REPORTS="${CIRCLE_TEST_REPORTS-./}"
+       ./configure --with-lkl=${LKL_HEADER} --disable-shared --enable-debug \
+                   --disable-optimize --prefix=${STAGING}/ CFLAGS="-DRUMPRUN"
+       # XXX: bug of musl Makefile ?
+       make obj/src/internal/version.h
+       make install
+)
+}
+
+
+buildpci ()
+{
+       echo '>>'
+       echo '>> Build PCI stuff'
+       echo '>>'
+
+       # XXX:, FIXME: LKL still needs librumpuser from src-netbsd
+       mkdir -p ${STAGING}/../include/
+       ln -s -f ${RUMPSRC}/sys/rump/include/rump/ ${STAGING}/../include/
+       cp -rpf ${RUMPSRC}/sys/rump/include/rump/ ${STAGING}/include/
+
+       # XXX:
+       mkdir -p ${RROBJ}/rumptools/dest/usr/include/sys/
+       cp include/bmk-core/queue.h ${RROBJ}/rumptools/dest/usr/include/sys/
+
+       CFLAGS="-I ./include -I ${PLATFORMDIR}/include/ -I 
${PLATFORMDIR}/xen/include/ -I ${RUMPTOOLS}/../include/ 
-I${LKLSRC}/arch/lkl/drivers"
+       abspath BROBJ
+       abspath STAGING
+
+       HYPERCALLS=
+       if [ ${PLATFORM} = "hw" ] ; then
+               ${CC:-cc} ${CFLAGS} ${PLATFORMDIR}/pci/rumppci.c -c -o 
${BROBJ}/rumppci.o
+               ${CC:-cc} ${CFLAGS} ${PLATFORMDIR}/pci/rumpdma.c -c -o 
${BROBJ}/rumpdma.o
+               HYPERCALLS="${BROBJ}/rumppci.o ${BROBJ}/rumpdma.o"
+       else
+               ${CC:-cc} ${CFLAGS} ${PLATFORMDIR}/pci/rumphyper_pci.c -c -o 
${BROBJ}/rumphyper_pci.o
+               ${CC:-cc} ${CFLAGS} ${PLATFORMDIR}/pci/rumphyper_dma.c -c -o 
${BROBJ}/rumphyper_dma.o
+               HYPERCALLS="${BROBJ}/rumphyper_pci.o ${BROBJ}/rumphyper_dma.o"
+       fi
+       make RUMP_BMK_PCI_HYPERCALLS="${HYPERCALLS}" -C 
${LKLSRC}/arch/lkl/drivers/
+       make RUMP_BMK_PCI_HYPERCALLS="${HYPERCALLS}" -C 
${LKLSRC}/arch/lkl/drivers/ \
+            DESTDIR=${RROBJ}/rumptools/dest/usr install
+
+}
diff --git a/rumpkernel/netbsd.sh b/rumpkernel/netbsd.sh
new file mode 100644
index 000000000000..21ca6823197d
--- /dev/null
+++ b/rumpkernel/netbsd.sh
@@ -0,0 +1,26 @@
+builduserspace ()
+{
+
+       usermtree ${STAGING}
+
+       LIBS="$(stdlibs ${RUMPSRC})"
+       ! ${HAVECXX} || LIBS="${LIBS} $(stdlibsxx ${RUMPSRC})"
+
+       userincludes ${RUMPSRC} ${LIBS} $(pwd)/lib/librumprun_tester
+       for lib in ${LIBS}; do
+               makeuserlib ${lib}
+       done
+}
+
+buildpci ()
+{
+
+       if eval ${PLATFORM_PCI_P}; then
+               (
+                       cd ${PLATFORMDIR}/pci
+                       ${RUMPMAKE} ${STDJ} obj
+                       ${RUMPMAKE} ${STDJ} dependall
+                       ${RUMPMAKE} ${STDJ} install
+               )
+       fi
+}
diff --git a/tests/basic/misc_test.c b/tests/basic/misc_test.c
index e5f7c969a5ee..1df5ef8a9869 100644
--- a/tests/basic/misc_test.c
+++ b/tests/basic/misc_test.c
@@ -64,7 +64,8 @@ dommap(size_t len, int munmapperpage)
 {
        void *v;
 
-       v = mmap(NULL, len, PROT_READ|PROT_WRITE, MAP_ANON, -1, 0);
+       v = mmap(NULL, len, PROT_READ|PROT_WRITE, MAP_ANON | MAP_PRIVATE,
+                -1, 0);
        if (v == MAP_FAILED)
                return errno;
        memset(v, 'a', len);
diff --git a/tests/buildtests.sh b/tests/buildtests.sh
index cab3b9416cda..01151629a239 100755
--- a/tests/buildtests.sh
+++ b/tests/buildtests.sh
@@ -42,9 +42,15 @@ test_apptools()
        case ${PLATFORM} in
        hw)
                RUMPBAKE_PLATFORM='hw_generic'
+               if [ ${RUMPKERNEL} = "linux" ] ; then
+                       RUMPBAKE_PLATFORM='hw_lkl'
+               fi
                ;;
        xen)
                RUMPBAKE_PLATFORM='xen_pv'
+               if [ ${RUMPKERNEL} = "linux" ] ; then
+                       RUMPBAKE_PLATFORM='xen_pv_lkl'
+               fi
                ;;
        *)
                echo ">> unknown platform \"$PLATFORM\""
diff --git a/tests/cmake/test.c b/tests/cmake/test.c
index 2e0fa9ca9bc5..d280c4a95591 100644
--- a/tests/cmake/test.c
+++ b/tests/cmake/test.c
@@ -10,7 +10,7 @@
  * So we assume a Linux host.
  */
 
-#ifdef HAVE_SYS_EPOLL_H
+#if defined (HAVE_SYS_EPOLL_H) && (__NetBSD__)
 #error Should not have epoll.  In case NetBSD now has epoll, please update 
test.
 #endif
 #ifndef HAVE_SELECT
diff --git a/tests/configure/test.c b/tests/configure/test.c
index 2e0fa9ca9bc5..d280c4a95591 100644
--- a/tests/configure/test.c
+++ b/tests/configure/test.c
@@ -10,7 +10,7 @@
  * So we assume a Linux host.
  */
 
-#ifdef HAVE_SYS_EPOLL_H
+#if defined (HAVE_SYS_EPOLL_H) && (__NetBSD__)
 #error Should not have epoll.  In case NetBSD now has epoll, please update 
test.
 #endif
 #ifndef HAVE_SELECT
diff --git a/tests/hello/hello.c b/tests/hello/hello.c
index 03e36e0ed589..552f8396a022 100644
--- a/tests/hello/hello.c
+++ b/tests/hello/hello.c
@@ -5,7 +5,7 @@
 
 #include <rumprun/tester.h>
 
-#if defined(__linux__) || !defined(__NetBSD__)
+#if !defined(__linux__) && !defined(__NetBSD__)
 # error compiler wrapper fail
 #endif
 
diff --git a/tests/nolibc/Makefile b/tests/nolibc/Makefile
index f69d2fb08fec..886b0214bc61 100644
--- a/tests/nolibc/Makefile
+++ b/tests/nolibc/Makefile
@@ -3,10 +3,10 @@ include ${BUILDRUMP_TOOLFLAGS}
 
 CFLAGS+=       ${BUILDRUMP_TOOL_CFLAGS}
 
-LDFLAGS:= -L$(abspath 
../../rumprun/rumprun-${MACHINE_GNU_ARCH}/lib/rumprun-${PLATFORM})
+LDFLAGS:= -L${RRDEST}/rumprun-${MACHINE_GNU_ARCH}/lib/rumprun-${PLATFORM}
 LDFLAGS+= -L${RROBJ}/lib/libcompiler_rt
 
-CPPFLAGS+= -I../../include -I../../rumprun/rumprun-${MACHINE_GNU_ARCH}/include
+CPPFLAGS+= -I../../include -I${RRDEST}/rumprun-${MACHINE_GNU_ARCH}/include
 CPPFLAGS+= -I../../platform/${PLATFORM}/include
 
 LDSCRIPT= ${RROBJ}/bmk.ldscript
@@ -15,14 +15,22 @@ LDFLAGS+= ${LDFLAGS.${MACHINE_GNU_ARCH}.${PLATFORM}}
 
 OBJS= main.o ${RROBJ}/rumprun.o
 
+ifeq (${RUMPKERNEL},netbsd)
+LIB_RUMP= -lrumpvfs -lrump
+LIB_EXTRA=-lcompiler_rt
+else ifeq (${RUMPKERNEL},linux)
+CFLAGS+= -DLINUX_RUMP -Wno-error=strict-prototypes
+LIB_RUMP=-llkl
+endif
+
 .PHONY: clean
 
 main.elf: ${OBJS}
        ${CC} ${CFLAGS} ${LDFLAGS} -T${LDSCRIPT}                        \
        ${OBJS}                                                         \
        -nostdlib                                                       \
-       -Wl,--whole-archive -lrumpvfs -lrump -Wl,--no-whole-archive     \
-       -lcompiler_rt                                                   \
+       -Wl,--whole-archive ${LIB_RUMP} -Wl,--no-whole-archive          \
+       ${LIB_EXTRA}                                                    \
        -o $@
 
 clean:
diff --git a/tests/nolibc/main.c b/tests/nolibc/main.c
index b13769294d5f..1ec069a845e0 100644
--- a/tests/nolibc/main.c
+++ b/tests/nolibc/main.c
@@ -6,7 +6,16 @@
 #include "nolibc.h"
 
 #include <rump/rump.h>
+#ifdef LINUX_RUMP
+#include <lkl.h>
+int rump___sysimpl_reboot(int, char *);
+#define rump_sys_reboot rump___sysimpl_reboot
+#define rump_sys_write lkl_sys_write
+#define rump_sys_open lkl_sys_open
+#include "stub.c"
+#else
 #include <rump/rump_syscalls.h>
+#endif
 
 static ssize_t
 writestr(int fd, const char *str)
@@ -25,7 +34,7 @@ bmk_mainthread(void *cmdline)
        writestr(1, "Hello, stdout!\n");
 
        bmk_printf("open(/notexisting): ");
-       fd = rump_sys_open("/notexisting", 0);
+       fd = rump_sys_open("/notexisting", 0, 0);
        if (fd == -1) {
                int errno = *bmk_sched_geterrno();
                if (errno == RUMP_ENOENT) {
diff --git a/tests/nolibc/nolibc.h b/tests/nolibc/nolibc.h
index b0c668c9d5f9..bf2e39a8026f 100644
--- a/tests/nolibc/nolibc.h
+++ b/tests/nolibc/nolibc.h
@@ -16,14 +16,17 @@ typedef long                ssize_t;
 typedef unsigned long  size_t;
 typedef long           register_t;
 
+typedef long long      loff_t;
 typedef int64_t                off_t;
 typedef uint64_t       dev_t;
 typedef uint32_t       mode_t;
-typedef int            gid_t;
-typedef int            uid_t;
+typedef unsigned       gid_t;
+typedef unsigned       uid_t;
 
 typedef unsigned int   u_int;
 typedef unsigned long  u_long;
+typedef unsigned char  __uint8_t;
+typedef unsigned short __uint16_t;
 
 struct timespec;
 struct itimerspec;
diff --git a/tests/nolibc/stub.c b/tests/nolibc/stub.c
new file mode 100644
index 000000000000..c0c9239c75ce
--- /dev/null
+++ b/tests/nolibc/stub.c
@@ -0,0 +1,191 @@
+/*
+ * XXX:
+ *
+ * Stub function definitions which LKL _accidentally_ uses
+ * and should not be used
+ */
+
+#include <stdarg.h>
+
+/* setjmp */
+       __asm__(
+".global __setjmp\n"
+".global _setjmp\n"
+".global setjmp\n"
+".type __setjmp,@function\n"
+".type _setjmp,@function\n"
+".type setjmp,@function\n"
+"__setjmp:\n"
+"_setjmp:\n"
+"setjmp:\n"
+       "mov %rbx,(%rdi);"         /* rdi is jmp_buf, move registers onto it */
+       "mov %rbp,8(%rdi)\n"
+       "mov %r12,16(%rdi)\n"
+       "mov %r13,24(%rdi)\n"
+       "mov %r14,32(%rdi)\n"
+       "mov %r15,40(%rdi)\n"
+       "lea 8(%rsp),%rdx\n"        /* this is our rsp WITHOUT current ret addr 
*/
+       "mov %rdx,48(%rdi)\n"
+       "mov (%rsp),%rdx\n"         /* save return addr ptr for new rip */
+       "mov %rdx,56(%rdi)\n"
+       "xor %rax,%rax\n"           /* always return 0 */
+       "ret\n"
+                       );
+
+/* longjmp */
+__asm__(
+".global _longjmp\n"
+".global longjmp\n"
+".type _longjmp,@function\n"
+".type longjmp,@function\n"
+"_longjmp:\n"
+"longjmp:\n"
+       "mov %rsi,%rax\n"           /* val will be longjmp return */
+       "test %rax,%rax\n"
+       "jnz 1f\n"
+       "inc %rax\n"                /* if val==0, val=1 per longjmp semantics */
+"1:\n"
+       "mov (%rdi),%rbx\n"         /* rdi is the jmp_buf, restore regs from it 
*/
+       "mov 8(%rdi),%rbp\n"
+       "mov 16(%rdi),%r12\n"
+       "mov 24(%rdi),%r13\n"
+       "mov 32(%rdi),%r14\n"
+       "mov 40(%rdi),%r15\n"
+       "mov 48(%rdi),%rdx\n"       /* this ends up being the stack pointer */
+       "mov %rdx,%rsp\n"
+       "mov 56(%rdi),%rdx\n"       /* this is the instruction pointer */
+       "jmp *%rdx\n"               /* goto saved address without altering rsp 
*/
+                       );
+
+int rumpns_vsscanf(const char *buf, const char *fmt, va_list args);
+int __isoc99_sscanf(const char *buf, const char *fmt, ...);
+int __isoc99_sscanf(const char *buf, const char *fmt, ...)
+{
+       va_list args;
+       int i;
+
+       va_start(args, fmt);
+       i = rumpns_vsscanf(buf, fmt, args);
+       va_end(args);
+
+       return i;
+}
+
+int rumpns_snprintf(char *buf, size_t size, const char *fmt, ...);
+int snprintf(char *buf, size_t size, const char *fmt, ...);
+int snprintf(char *buf, size_t size, const char *fmt, ...)
+{
+       return rumpns_snprintf(buf, size, fmt);
+}
+
+int rumpns_vsnprintf(char *buf, size_t size, const char *fmt, 
__builtin_va_list args);
+int vsnprintf(char *buf, size_t size, const char *fmt, __builtin_va_list args);
+int vsnprintf(char *buf, size_t size, const char *fmt, __builtin_va_list args)
+{
+       return rumpns_vsnprintf(buf, size, fmt, args);
+}
+
+void *rumpns_memcpy(void *dest, const void *src, size_t count);
+void *memcpy(void *dest, const void *src, size_t count);
+void *memcpy(void *dest, const void *src, size_t count)
+{
+       return rumpns_memcpy(dest, src, count);
+}
+
+int rumpns_memcmp(const void *cs, const void *ct, size_t count);
+int memcmp(const void *cs, const void *ct, size_t count);
+int memcmp(const void *cs, const void *ct, size_t count)
+{
+       return rumpns_memcmp(cs, ct, count);
+}
+
+void *rumpns_memset(void *s, int c, size_t count);
+void *memset(void *s, int c, size_t count);
+void *memset(void *s, int c, size_t count)
+{
+       return rumpns_memset(s, c, count);
+}
+
+char *rumpns_strncat(char *dest, const char *src, size_t count);
+char *strncat(char *dest, const char *src, size_t count);
+char *strncat(char *dest, const char *src, size_t count)
+{
+       return rumpns_strncat(dest, src, count);
+}
+
+size_t rumpns_strlen(const char *s);
+size_t strlen(const char *s);
+size_t strlen(const char *s)
+{
+       return rumpns_strlen(s);
+}
+
+char *rumpns_strcpy(char *dest, const char *src);
+char *strcpy(char *dest, const char *src);
+char *strcpy(char *dest, const char *src)
+{
+       return rumpns_strcpy(dest, src);
+}
+
+char *rumpns_strncpy(char *dest, const char *src, size_t count);
+char *strncpy(char *dest, const char *src, size_t count);
+char *strncpy(char *dest, const char *src, size_t count)
+{
+       return rumpns_strncpy(dest, src, count);
+}
+
+int rumpns_strncmp(const char *cs, const char *ct, size_t count);
+int strncmp(const char *cs, const char *ct, size_t count);
+int strncmp(const char *cs, const char *ct, size_t count)
+{
+       return rumpns_strncmp(cs, ct, count);
+}
+
+char *rumpns_strchr(const char *s, int c);
+char *strchr(const char *s, int c);
+char *strchr(const char *s, int c)
+{
+       return rumpns_strchr(s, c);
+}
+
+
+size_t rumpns_strspn(const char *s, const char *accept);
+size_t strspn(const char *s, const char *accept);
+size_t strspn(const char *s, const char *accept)
+{
+       return rumpns_strspn(s, accept);
+}
+
+size_t rumpns_strcspn(const char *s, const char *reject);
+size_t strcspn(const char *s, const char *reject);
+size_t strcspn(const char *s, const char *reject)
+{
+       return rumpns_strcspn(s, reject);
+}
+
+char *strtok(char *restrict s, const char *restrict sep);
+char *strtok(char *restrict s, const char *restrict sep)
+{
+       static char *p;
+       if (!s && !(s = p)) return NULL;
+       s += strspn(s, sep);
+       if (!*s) return p = 0;
+       p = s + strcspn(s, sep);
+       if (*p) *p++ = 0;
+       else p = 0;
+       return s;
+}
+
+char *getenv(const char *name);
+char *getenv(const char *name)
+{
+       /* not supported */
+       return NULL;
+}
+
+unsigned long rumpns_simple_strtoul(const char *, char **, unsigned int);
+unsigned long strtoul(const char *restrict s, char **restrict p, int base);
+unsigned long strtoul(const char *restrict s, char **restrict p, int base)
+{
+       return rumpns_simple_strtoul(s, p, base);
+}
diff --git a/tests/runtests.sh b/tests/runtests.sh
index 5791eb3e2704..bf678ff40e03 100755
--- a/tests/runtests.sh
+++ b/tests/runtests.sh
@@ -33,8 +33,11 @@ cd $(dirname $0) || die 'could not enter test dir'
 export RUMPRUN_WARNING_STFU=please
 
 # TODO: use a more scalable way of specifying tests
-TESTS='hello/hello.bin basic/ctor_test.bin basic/pthread_test.bin
-       basic/tls_test.bin basic/misc_test.bin'
+TESTS='hello/hello.bin basic/ctor_test.bin basic/pthread_test.bin'
+if [ -z "${TEST_LESS}" ] ; then
+TESTS=${TESTS}' basic/tls_test.bin basic/misc_test.bin'
+fi
+
 [ -x hello/hellopp.bin ] && TESTS="${TESTS} hello/hellopp.bin"
 
 STARTMAGIC='=== FOE RUMPRUN 12345 TES-TER 54321 ==='
@@ -74,7 +77,7 @@ runguest ()
        # img2=$3
 
        [ -n "${img1}" ] || die runtest without a disk image
-       cookie=$(${RUMPRUN} ${OPT_SUDO} ${STACK} -b ${img1} ${testprog} __test)
+       cookie=$(${RUMPRUN} ${OPT_SUDO} ${STACK} -M 1024 -b ${img1} ${testprog} 
__test)
        if [ $? -ne 0 -o -z "${cookie}" ]; then
                TEST_RESULT=ERROR
                TEST_ECODE=-2
-- 
2.9.3




Reply via email to