 Next up is Justin Cormack on Rump and Justin is a NetBSD developer who does a lot of work in Rump. Time-to-time he uses that scripting language too. So the next 45 minutes are yours, please, Justin. Hi. Oh, this is right. This is working. Right. So, yeah, I'm going to talk about running applications on the NetBSD Rump kernel. I'm also going to talk about the stuff we've been working on with Rump kernel and an introduction to it for people who are familiar with what it's for and some stuff that we're planning to do with Rump kernel as well. So the slides are possibly on that URL, eurobsdcon.miriabit.eu, although they didn't seem to be available from this room, but there are links to stuff on them. I don't know why. If someone can fix the why they're not working from here. The DNS seemed to be working. So it's a bit weird. Anyway, so there's links if you want to go there or if you're on the live stream, it might be helpful because the slides definitely seem to be working if you're not in this room. So the Rump kernels are kind of a slightly odd thing. It's something that's only available in NetBSD and it's one of the unique features of NetBSD. And it's basically NetBSD, but with a whole lot of stuff taken out. It's most of the kernel, but it can't execute binaries, it can't schedule threads, it doesn't understand anything about users or anything like that. Well it kind of does, but it doesn't understand memory management or anything like that. So it's a kind of, it's quite a lot of the NetBSD kernel, but with a whole lot of stuff that's not there, which sounds kind of useless. But really it's the drivers, and the drivers are kind of, they're the majority of the kernel. They're the quite often the most frustrating bit of the kernel, and they're the bit that takes a long time to write. They deal with actual hardware, which is buggy, and they also deal with the kind of nice bits of stuff that as a user you like to use with a kernel. So it deals with actual file systems rather than just raw blocks on disks, and sockets, and 2CP, and stuff like that are all in the drivers. And so that's the stuff that users really need in a kernel. I mean users like to be able to allocate some memory and things as well, but we're going to tell that in a second. So what we do with the Rumpkernel is basically we use something else to do those missing parts, some sort of host system which will do memory allocation, and just let you run these drivers on their own, either on top of another operating system or in a special purpose application we'll go into that in a second. So the easiest way to just think about it is just a way of running drivers, unmodified drivers from NetBSD, somewhere else that you might want to run them. And why might you want to do something weird, like running drivers not in an operating system? I mean they sit there on the operating system and they work. You kind of basically want to fill in the gaps and use a very simple kind of virtual machine-like capability to run these drivers on top of some other kind of environment. And so there's basically a hypercall there, which is very much like a virtual machine. It basically provides memory allocation, threads, mutexes, random numbers, and a clock pretty much, and a bit of I.O. And the original use case of this was running this in user space on NetBSD in particular. With the main point of it was actually for testing, and testing was kind of the way I got interested in the RUN kernel as well, because I like testing, and testing's good. And it was, I started going to the talks at FOSSTEM about NetBSD, and I got interested in testing on NetBSD, and that's what kind of brought me into this, being interested in this thing in the first place. And in particular you can test little parts of your kernel in isolation, so you can just test a single kernel driver without having to create a system, boot into it. Maybe the rest of the kernel isn't working because you've broken something else. Because you don't have to boot into it, it's much quicker. You can build a full RUN kernel from scratch in 10, 15 minutes, and less than that incrementally, run the tests. So you've really got this kind of environment where you can say you're working on a new driver, you can change it around, rebuild it, test it quickly, run some tests against it, and make sure it's still working, and do test-driven development for drivers, which has always been difficult. A lot of people have worked around it in their development processes for drivers by writing a prototype driver in user space or hooking it up to user space to poke the hardware and see what happens and so on. But that's difficult to do with things like if you want to change the TCP IP stack, you've really got to boot into the system, run some tests and so on. With virtual machines, that's easier than it used to be with actual hardware, but it's still actually much easier just to sit in user space, run it, run GDB on it, set breakpoints, see what's going wrong, get a core dump when it crashes, and just treat it like a normal program you're writing. It's a sort of sane and sensible way of working with stuff. The other original use case, apart from tests and development, was running stuff in user space like file systems in user space, the fuse type things, but if you want the old M-tools type tools that we used to use for file systems in user space where if your kernel doesn't have support for that, you can run a file system in user space. But again, those were often kind of clunky and used duplicated code. The important thing was run kernels. The code you're running is exactly the same code, so it's not modified at all. It just sits there, it runs, you just compile it and link it slightly differently into user space. Until very recently, 99% of the use case for Rump was the test suite in their PSD, which has used Rump for many years now. It basically is specifically written for Rump, so it says Rump in it, it says Rump says Makeda and so on, or there's been a hijacked library that used preload to try and work around that. And it's usable, it's used in the tests, it's been useful for a long time, but it's kind of slightly clunky and painful because you have to specifically write for a Rump kernel, which is a kind of weird thing to do. So I started working on Rump kernel seriously about a year and a half ago, and so I'm going to talk about some of the stuff that's happened really since that period, some of which I've done, some of which Antti, who's the main developer, has done, some of which other people have done. We started to grow a decent community around Rump kernel now, and I'll talk about some of the other things that people are doing. So the first thing I got involved in was someone suggested on the Lua mailing list, or the Lua JIT mailing list actually, which is a JIT compilation of Lua, that it might be nice to run Lua directly on Zen, like the Erlang on Zen project, and there's various other ones of these X on Zen projects, Mirage and things like that. And I thought that sounded quite an interesting idea, and I've been getting more and more interested in the Rump kernel stuff, and I thought, well, one way of doing this would be to use the Rump kernel to provide the system layers that Lua needs to run. I mean, Lua is a very straightforward POSIX portable program, but it obviously needs some stuff to actually run, it needs to open files, it needs some memory allocation, you need a basic system calls, not a lot, but it needs something. So it actually turned out to be relatively not too horrible to do the basic thing, because Zen in its tree includes a really stupidly simple operating system called Minios, which is just there, well, originally I think it was just there, as a part of their tests and as generally as part of the example of how you actually use the Zen hypercall layer. So it turned out that Minios actually had pretty much everything you needed to, well, pretty much everything you needed to actually build a hypercall layer for the Rump kernel built into it already, because the things that the hypercall layer for Rump kernel is actually, again, just the stuff you expect, clocks, random numbers and some memory allocation and so on. So actually getting the Rump kernel to run was relatively straightforward, but the thing that we wanted to do was actually run an application on it, which an unmodified copy of Lua. So the process we went through to do this was basically, well, we needed obviously we need libc to compile Lua, so we took NetBSD's libc and basically ripped out the actual system call layer that actually just calls the system calls and just replaced those with calls to the equivalent Rump kernel functions and compiled the rest of libc with the Zen cross compiler and then compiled a library version of Lua, which is relatively straightforward to do, linked it all together and actually got it to boot and got it to run the Rump kernel test suite and everything works fine. So that was really the first time we actually run a real full application on the Rump kernel. It was quite exciting and it boots up in almost zero time because it doesn't, especially if you don't mount a file system or anything like that, it's really quick. You can just run it with the Zen XL tool, bang, runs your code. So this was my first involvement on Rump kernel. It was all quite productive, relatively painless. The patches against libc that we had to do to do this were a bit messy, but not too bad. I'll talk about those a little bit more later. So I was quite excited by that and I started playing around with the Rump kernel a bit. The next thing I worked on in particular was portability. At the time, I started it, the Rump kernel obviously runs on NetBSD, it was always run on NetBSD. It also run on Linux and it ran on Dragonfly at that time, I think, and Solaris. So I went around and fixed the free BSD and open BSD ports, which was mostly fairly straightforward. And Android, which is a weird environment, but I thought it was quite fun because you can boot up a Rump kernel on your phone and show people. I just realised I haven't got it installed on this phone because I've got a new phone, but that's quite nice. And also, architectures, cross-builds from, particularly from, non-NetBSD platforms on these different things that were a bit of a pain, but it runs on all the, we run, it's extensively tested on, you know, RMEX-06 MIPS, PowerPC, Spark, and it'll probably run and everything. There are very few issues now that you just need to, if you're not using it on NetBSD and you're using a different set of compilers and so on, I think we've ironed out most of those kind of basic portability issues now. There's still work to do, but it's much better. So if you're porting it to another weird environment, a lot of the work's been done. I also got involved in setting up tests. So basically, we do continuous integration with the Rump kernel code. There's every commit on TravisCI, which runs on, it's an automated service that runs from GitHub or anywhere else on Linux. And then there's a build bot set up, which runs on pretty much every other one of the supported platforms, a large selection of the supported platforms. Originally just on the Rump kernel commits, but actually, of course, the Rump kernel is NetBSD and all the codes really in NetBSD. So I set up a builder to build from NetBSD current, which runs every, currently every hour and a half. You can see it looks like this, the links are on, if you click through the links are there. So these are all the different platforms it builds on. And actually, it does take less than an hour to run on all those on currently on two servers with about eight virtual machines, some physical machines, some cross builds. As I said, each build tends to only take maybe 10 minutes on a single machine, but as they all run in parallel, it slows down a little bit. Build bot's kind of annoying, but it does, it's easy to set it up. It is annoying to do things that I'd like to do on continuous integration, like, and I fade around with a bit and it's kind of possible to hack it, but it's painful. I want to put a single source, because at the moment, all these do their own checkouts. Put a single source, build that, save the build, so you can use them elsewhere, run the cross-compiled code on real hardware or emulated hardware, so you can see if it actually runs because only the non-cross builds run the actual tests mostly. A lot of it's just a build test, not a run time test. But it catches a lot of the possibility of regressions in NetBSD, so I pick those up really fast. As far as I'm aware, I'm the only person doing regular cross builds of NetBSD, so if you break something in our tool chain, I'll probably notice within a few hours that something's broken. I'm got a major alert, so it doesn't hassle me, but I do tend to notice fix those things, because that's kind of useful. It also uses LJ-Syscall, which is a code I wrote before to run the case. This is a program I wrote in Lua, which, or LuaJet, again, which basically understands the ABI's of NetBSD, Linux, OpenBSD, FreeBSD, different releases of, and runs system calls directly against those kernels. It runs about 130-odd tests, depending on which BSD you're running, because some of them are specific to a particular one. It takes about a minute, so it's very much the fastest way of running a smoke test on a new build. It doesn't require any compiling, because it's all interpreted, so it really is very, very quick to run tests. All those that aren't cross builds will run that, and so that gives some extra confidence that someone hasn't broken something. Again, that's testing at the moment. I'll talk a bit later about more testing that I want to do, but it's certainly, you know, we look at this and the Rump Kernel builds, the Rump Kernel script that you use to build Rump, which is for building stuff, not on NetBSD, if you're not using NetBSD, or if you want to use it as a snapshot on NetBSD, we take a build that we know works, take a snapshot, and that's available. So we're reasonably happy that the stuff that's available for users is working and tested, and so on. Obviously they're potentially bugs, but we're reasonably happy that the tests are there. So running applications is the thing that was quite exciting with the Zen port. And over Christmas last year, I started thinking about whether you could actually run applications on the Rump Kernel in a straightforward way. Applications that aren't written as Rump in it, and so on specifically for Rump, but normal NetBSD applications, I was wondering if you could run them in the user space ports of Rump Kernel, which is what people mostly use, because it's the easiest thing to use for testing, it's what you use for driver development, and so on. And I thought if we could run applications then, not necessary things like lure, but the actual basic things that will be really useful, because it had been bugging me for a while, was that you couldn't even run a basic thing to configure your Rump Kernel, because normally, say you want to test the RAID drivers, you need to build a RAID set, and there's a bunch of command line commands to build that, but you can't actually run those commands. So what you had to do was basically at the moment, if you wanted to write a test for the RAID system, or if you wanted to just experiment, modify it, you basically had to write something that custom for the Rump Kernel, that did the IRCuttle or whatever commands the subsystem you were working on needed, and that was kind of annoying if you wanted to do anything complicated. So I thought maybe there's some way in which we can get this stuff to compile in user space. Originally, the first thing I came up with were involved compiling the NetBSD code as a shared library and loading it into a wrapper program called Main in the shared library, and it worked. It was a bit horrible, but it kind of worked. It showed that this was actually possible. Then a month or two later, I decided it was too late, and it was too annoying. I managed to write another version, basically a script there, which is kind of basically the main issue is that you're trying to run a NetBSD libc in order to compile your NetBSD commands, but you're also running a libc on the host, and of course they have exactly the same symbols in them. But one set is supposed to be talking to the Rumpkernel. One set is actually talking to your real kernel, and obviously this is a big mess. If you just try and link your programs together, it's just not going to work. I came up with a scheme that does work, which basically does a whole bunch of symbol renaming, and I'll tell you exactly in a minute. But it works, and you can basically compile. There's a little script that compiles stuff out of the NetBSD tree, so you can compile pretty much all the core user space stuff. The way it works, basically, is that you can compile the script. You take the stuff you're building for NetBSD, you link it all without host libc at all, and then use object copy to rename a bunch of symbols, so that they point at the Rumpkernel symbols, fix up a few horrible things like main, because you're going to have another main where you're going to link in. Localize all the symbol names in the object that you've created, and then link it in with Rumpkernel and host libc. If you click on that link there, you can see the script. I do have a plan to do a third rewrite to make it even nicer and more straightforward, but at the moment there's a cross-compiler now, which will cross-compile to this and run the link scripts as a GCC wrapper, which works fine, works on NetBSD, and it works on Linux. You can hack it to work on FreeBSD, but FreeBSD's GCC is doing something a bit weird, and so it's a bit hacky, but it needs fixing. Basically, it's usable, and here's an example of how you use it. There's kind of two modes for using the Rumpkernel user space. This is example with the Rump server. Now, the Rump server is a thing that basically runs the Rumpkernel in one process, and you send a system calls from another process, which seems a slightly odd thing to want to do, but otherwise, you tend to run the Rumpkernel, and then when you terminate the real process, the Rumpkernel terminates, which means effectively, in sort of machine terms, you boot up your machine, it runs something, and it stops, which isn't that much use if you want to just modify the state of something. The remote process like this, you can just run the newly compiled IF config, and you can see your network interface. You can just create new network interfaces. You can ping stuff. Pretty much everything works. A set of test scripts that runs through and creates RAID devices and so on in the repository. This is the current list of supported commands that have reasonably been tested, and most of them are useful. Some things in a Rumpkernel context aren't particularly useful, but basically, creating file systems, creating network interfaces, syskirtle, mounting file systems, making directories, copying stuff in and out of the Rumpkernel bit of a system, permissions, and stuff like that, making device nodes, which obviously you need to do when you want to talk to devices, stuff for wireless, so wireless devices, you can deal with that, encrypted devices, encrypted files, and stuff like that. It's a decent set. It's really easy to add more stuff. It's just a bit. You just need to test it. It could do with more tests as well to make sure that, but most things work. There's a few weirdnesses because the things the Rumpkernel doesn't support. In particular, Rumpkernel doesn't really support signals, so occasionally things use signals. The net BSD implementation of ping six, but not ping, uses a timer with a signal, so you can only ping once, and then it just sits there waiting. Generally, you can just use this stuff as if you're using a normal computer. That's the thing. You can just sit there. There's a little shell wrapper that sets the paths and shows you which Rumpkernel you're talking to, and you can just sit there and do IF config and stuff like that. It can just sit there and run, and you can just script it all to set up your Rumpkernel, how you want for testing your driver, your writing, and so on. Basically, you've suddenly got this whole user space. You can suddenly start actually configuring drivers, testing them. There's this cross compiler that can probably run most user space code. There's some thread support, which is a bit experimental, but it does work as well. So if you've got code that uses threads, you can even run that. It hasn't been tested hugely heavily. There's a few things that use fork and so on, which may or may not be so good. The Rumpkernel remote does have an emulation for fork, so things do kind of work. In fact, most do work in user space, but they obviously won't run in a Rumpkernel somewhere else. So if the user space tools that call fork and exec and so on, actually there's enough emulation to make those work. There's basically a little emulation layer that emulates the things that you can emulate in user space. So a lot of MSM map and things like that all work. It's a decent way to run stuff. It does need cleaning up and upstreaming. The patches to libc are now very small, because I upstream most of them. There are new patches to the make files. There's no actual patches to libc at all. It's an unmodified libc. It just doesn't build in the syscall stubs, and that's really the main change. But it needs a bit of, and it's all, there's a flag around, it defs around everything. All the small things got fixed over time, I think. So I'll probably work on upstreaming it when I get back. It also needs fixing for non-x86 architectures, again, just adding the extra defines around the things in the make file. It's only just dealing with that system called layer. I think if we, it's very non-intrusive, again, as I said, it's just in the make file. I'd like to build some more of user space in the libraries. We might as well just build everything, really. But things like, it would be nice to build the ZFS tools so that it's easy for someone to start, when someone decides they want to start doing some more work on NPSD ZFS, I don't know. Then having those tools, the ZFS tools build would be useful. Because file systems are a perfect thing for running a user space, you just need a file to use as a block device and you can get going, or multiple files if you need multiple block devices. It's actually really straightforward. There's no need to ever boot a file system while you're developing it at all. So you should be able to just do those development and user space. I had a chat with one of the ZFS on Linux developers who said he might work on ZFS for NPSD if he could do it all in Linux. They didn't have to actually use NPSD. There's uses for these things. I'd like to run NPSD tests using this, which would be really nice, because it basically means you could run user space tests without actually booting the kernel at all, which would be nice. As you're developing stuff, rather than doing a full kernel build, install an Easter. An Easter is nice and easy and it's quite quick, but just being able to do make and execute your test script just there without actually even, as you're developing, makes it easier to do test-driven development and so on. And the build process for the user space stuff is a bit slow and long, and it should be. But it's one of these things. I mean, one of the things I spend most time doing since I've been working on Rumpkernel is looking at build processes and watching them scroll past and wondering why they're broken and trying to fix them. In a way, Rumpkernel is mostly about building. There's actually a lot of code in it, but there's a lot more build than make files than there is code. And I'd like to do continuous integration testing if the Rumpkernel code on current at the moment is because there's these libc make file patches, which are annoying, when those are upstream to be able to run it on current, which would be nice. More things we've been working on. I wrote a green threads implementation of the user space, the Rumpkernel hypercall there, which seems a funny thing to want to do. It runs on pthreads normally, which is kind of as you'd expect. This basically just uses get context, swap context, so it compiles on most things and runs the whole netBSD kernel basically as a uniprocessor kernel in a single process with no threads. One of the main aims of this was actually for running on embedded stuff where you want to compile Rumpkernel, but you don't actually have a whole pthreads library to run it on, so it won't compile. So you've got something really basic. But there's also got other uses. It would be really easy and quite fun to make an entirely deterministic implementation. Rumpkernel is kind of straightforward, and particularly with this implementation it's very straightforward. All the threads run to completion or when they block and then it switches to another thread. So the only stuff that makes it non-deterministic is the input that comes in through the Rumpkernel hypercall there, which is the random numbers in the clock and anything you've got on a file system or something like that. But doing things like exact replay of your netBSD test case, for example, should be possible just by feeding in the same timestamps and random numbers. And so you should be able to do things like reproduce bugs exactly even if they're non-deterministic and so on, or modify things and modify timings until you hit a non-deterministic bug and then be able to give it to someone, say, look, run this, this driver's got this lock up in this situation, things like that. So I think that would be quite a fun thing to do. It should be really easy now because all those scheduling stuff's all deterministic. It's just the input state that's not. But as that all comes through, this small Rump hypercall there, it's entirely easy to replay the same values on the same hypercalls. So that's a project for anyone who would like a nice project. Next thing that Antie added was PCI support. The first thing in Linux user space, because Linux conveniently has, being the next two ways of writing user space PCI drivers, they're both differently annoying. It's very typical of Linux. The one we've done so far is UIO, which is quite simple, works for a lot of devices, but it doesn't work with some other devices. So I think that's a good thing. It doesn't like MSI interrupts, I think. It'll just say no for some devices. But it runs, but it will, for example, run most wireless cards, for example. And certainly Antie did some wireless device development using the Rump kernel entirely in user space on Linux to write an FBSD driver. And you can sit there. You can basically reinitulate the device, if your driver goes wrong as you're developing it. You don't have to, you can just sit there. It's not being used by the host. You disable it from the host kernel to the host kernel, doesn't talk to it, and you've got full control over it. You can run your driver in user space. And so this is really useful if you want to work on developing a new PCI driver. And you want to make it much more difficult to lock up your machine and so on while you're doing it. And you can use GDB on it and things like that. The second Linux one, VFIO, I'll probably write a driver for that. You need an IOMMU to use that. And most of the machines I've got don't have IOMMUs. But I think I've got one that does now. So I'll try and fix that. It would be really nice to be able to run it under a BSD. My current thought that I've not spent much time doing a quick look at is that free BSD is probably the next easiest target with, because Beehive basically has user space, PCI driver framework now. And I reckon it should be possible to adapt that because that lets you put devices into your hypervisor, into your professional machines. And that's pretty much all you need. Basically, you want to remove them from the host kernel and be able to talk to them from user space. It's pretty much the same thing. So I reckon a free BSD port would be quite easy and then that would probably be applicable to net BSD much more straightforwardly. But that's definitely a real improvement for device driver development. Not having to actually develop your device driver on a while actually having to boot the kernel into it. And without having to do things like pass through to a virtual machine and so on, which you can do, but it's much easier to just iterate in user space. There's also, Antti decided that he, as well as booting on Zen, he wanted to build a boot on various other hypervisors in particular. So he did a project a few months ago basically to boot on a basically either bare metal or a virtualized x86 machine. This is, it's a very, it's a really small, it took him a week to write it. But in a way that's the thing about the run kernel. You've got all the drivers. So in a week with a hundred lines of code, you've got a kernel, you can boot up and it's got PCI support. It's got some vertio support. So if you're on a KVM, you can get the emulated network device and disk. And it'll run on actual hardware with a BIOS. It's x86 32 bit only at the minute and it uses the green thread type code so it doesn't have hardware threads or any single processor. But it's a proof of concept really. My plan with this is to do an arm port to the embed microcontroller platform to see if I can fit NetBSD run kernel onto a microcontroller that's too small to actually run NetBSD proper. So I need to, you know, see how small I can squeeze it in to try and boot it on a microcontroller because that would be a, again, a fun thing that where this kind of bare metal thing, which doesn't have a full operating system, it just has the absolute minimum you need to run kind of makes a lot of sense. And that's the nice thing about NetBSD, it's very portable to this kind of thing. So you can run it maybe on an even smaller toaster than previously. So yeah, I've got a little microcontroller with an ethernet, but I'm hoping to play around with and get that running on. The main thing is working out how little memory and storage you can get away with. So I bought one with a slight excess of memory and storage so I can start big and cut it down to a more standard size microcontroller and see how much space it actually takes up. See how much you can optimize the build and depending on what you want to run on it. But that's one of my experiments. Another thing that happened completely outside the NetBSD community is that you can run it as the genode decided that they needed some file system drivers. Now genode is I think the correct thing to call it is a operating system framework rather than operating system. They support the L4 microkernel and they have basically changed it to run the NetBSD file system drivers on their kernel as microkernel type user space processes with 3,000 light untrusted code that runs that. So that's quite exciting. We also got a Lego which is quite exciting. So fundamentally there are four different environments that we now support the kernel running on. So user space hosted the Zen Power Virtualized type environment, the bare metal one, or microkernels as servers. That's basically, and this is the sort of architecture of it which you probably can't see very well from the look of it. We have much better documentation, still needs improving but there's a wiki, there's a lot of stuff and there's a lot still to do in improving documentation and upstreaming. So people are really interested in high performance network stacks in user space. So come and get involved. This is where we are. I'm running an operating system conference in London on 25th November which you should come to and there's a run kernel hack day the day after, also in London following on from that. We'll also be at Foster, I think me and Auntie. There's a main list, FreeNode, run kernel, there's usually someone around. Come on, ask questions and get some help. Questions? All right. Hi Justin. Great talk, thank you. I remember, and I know you're not Auntie, but I remember Auntie writing at some point, I have a keen disinterest in hardware and he was explicitly not going to the route of romp controlling hardware. Do you know where that was and why that changed? I think someone, as far as I can work out, someone paid him to write a wireless driver. He hated it and he still hates the hardware, but he will write drivers if you ask him. So he decided he would write it all using romp in user space. Wireless was a really good test of all the user space infrastructure because you have to configure your wireless card, set up access points and all that. So it was actually a really useful thing and it's a good test of PCI and so on. Although he doesn't like, it was complaining about the size of the spec for wireless and so on. It was a useful thing to do, I think. Hope to see you in November. How much work is adding support for new IOMMU architecture, for example, on ARM? On ARM? Yes. I think starting with V7? Yes, there isn't any. I don't know. I think, I haven't really looked at that on ARM. I shouldn't have thought it was too much work. It's not, you know, mainly, I would have thought you could probably do it in a week, as a guess. I think you're in the air. It's not horrible. You mentioned Minix 3 in one of the slides. Yes. We've been thinking about maybe porting ROM to Minix 3. We have a generic POSIX interface, although no kernel threads. Any idea how much time it would take to port it to a generic POSIX system? If you want to run it just as a user space process, it's very little work. It should run already in user space. I imagine that you want to link it into the Minix 3 kernel rather than user space. In theory, it should just run. I had a quick look, but I think, I don't know, I don't know. I think it's a matter of just cross-building it. I tried building it natively, but build.sh isn't very happy building it natively on Minix 3 at the moment. I ran it. When did you try that? I don't know. A few weeks ago, very briefly. I should talk to you about it. I think it should, probably a cross-build might be easier, but it should just work. As long as you support, I mean, it runs on Android, and Android is the most useless POSIX user space there is. The Android port took me a day. In theory, in fact, it's the same. But no, the Android port took a day, and that was just dealing with the things it had missing or with broken headers or things like that. You mentioned signals were an issue in Rump Run, so was the thought to rewrite some of the code that uses signals to different ways of doing timers or add signal emulation into the library? There's a sort of signal emulation. There's a sort of signal emulation, but it's not... I don't like it. It's a bit... I'd rather rewrite the code and not use signals. The weird thing on NBSE, Ping4 doesn't use signals. Ping6 does. The code could be more similar between Ping4 and Ping6, frankly. There's no reason to use... I'm not a big fan of signals. There's no reason to use signals to do something like timers. We've got nice things. We've got cake here. There's no real reason to use signals. Yeah, sure. Yeah, there's no real reason. I mean, signals do work in user space, Rump, but not necessarily on other platforms. So I don't really... And they don't necessarily quite work exactly right. You've got a choice of ways to emulate that. It's not really worth spending more time on trying to emulate them, I don't think. I mean, it's because Rump doesn't understand processes, so signals are host signals, really. You can't really interrupt a Rump system call, but you can kind of fake it a bit. But it's not really worth it. Ping6 was the only thing that I came across where signals seem to be an issue. And for tests, you only need to ping once, normally, anyway. Any more? Well, do come and talk to me, and hang me about things if you want to ask more questions.