Slashdot Mirror


New Release of MINIX 3 For x86 and ARM Is NetBSD Compatible

An anonymous reader writes MINIX 3 is a small POSIX-compliant operating system aimed at high reliability (embedded) applications. A major new version of MINIX 3 (3.3.0) is now available for download at www.minix3.org. In addition to the x86, the ARM Cortex A8 is now supported, with ports to the BeagleBoard and BeagleBones available. Finally, the entire userland has been redone in 3.3.0 to make it NetBSD compatible, with thousands of NetBSD packages available out of the box. MINIX 3 is based on a tiny (13 KLoC) microkernel with the operating system running as a set of protected user-mode processes. Each device driver is also a separate process. If a driver fails, it is automatically and transparently restarted without rebooting and without applications even noticing, making the system self-healing. The full announcement, with links to the release notes and notes on installation, can be found at the Minix Google Groups page.

22 of 93 comments (clear)

  1. A microkernel-based OS that 'just works' by Anonymous Coward · · Score: 2, Interesting

    with today's HW. Haha, wouldn't that be funny if ten years from now Linux and Minix switched places?

    Nah...

    1. Re:A microkernel-based OS that 'just works' by Megol · · Score: 5, Insightful

      Magic bullet? There never are any magic bullet for complex systems.
      A microkernel is the realization of best practices for security systems and - dare I say it - follows the original Unix philosophy.

      Do one thing (IPC) and do it well (ensure security guarantees are kept). Keeping the critical code small makes it easier to verify code in both the practical and mathematical sense.

  2. Re:High reliability? by DarkOx · · Score: 4, Insightful

    Its not novel but its simple and clean. Minix is really an education tool more than a production ready OS.

    --
    Repeal the 17th Amendment TODAY! Also Please Read http://www.gnu.org/philosophy/right-to-read.html
  3. Re:Drivers as processes? by Chandon+Seldon · · Score: 2

    Sure. So we've upgraded from the system crashing to one write failing.

    --
    -- The act of censorship is always worse than whatever is being censored. Always.
  4. Self-healing drivers by peppepz · · Score: 2

    Don't present userspace drivers as a panacea for all kinds of driver troubles: when a driver fails, it can make the hardware it drives hang your machine solid from the hardware's side, or make said hardware DMA all over your RAM with complete disregard any CPU-imposed protection; there's no safe recovery from such a situation, and in this case applications had better be stopped even if they appear to be still running.

    1. Re: Self-healing drivers by squizzar · · Score: 2

      Spoken like someone who has never jammed up a PCIe bus before.... driver mistakes can make systems go down hard. Even if the IOMMU is protecting the memory the underlying hardware might be flooding the bus with junk, or in some other unrecoverable or unmanageable state that requires the hardware to be reset. If the host has a way of driving the reset line to the device then you might get out of your bind but that's a long way from stateless - it would let you restart the hardware device without interfering with the system though. That said I don't think there's that much stuff out there that's robust enough to deal with crazy situations like that

  5. Re:High reliability? by bluefoxlucid · · Score: 5, Interesting

    The novel approach is that Tanenbaum invented the fucking thing. The specific current advantage is low-latency IPC--on ARM, Minix IPC doesn't even have a measurable cost (the context switch time required is under 20 microseconds), while on x86 IPC is more than 10 times faster than L4.

    Monoliths, e.g. Linux, don't have IPC latency because they don't context switch when making calls between major kernel functional units. Of course, if your network driver crashes, your whole system gets fucked up and dies; whereas Minix tries to take a state snapshot, reconstruct something workable, load it into a fresh run of the network driver, and continue without a hickup. This works extremely well with the disk and FS drivers. Ideally, we want this without paying for it.

  6. Re:Nothing to see here. ANOTHER Linux CLONE! by halivar · · Score: 3, Insightful

    Uhhh... I think you switched the cart and the horse, there, fella.

    http://en.wikipedia.org/wiki/L...

  7. Re:Drivers as processes? by bluefoxlucid · · Score: 5, Informative

    The file system write or read request doesn't return anything, the driver is detected as dead (heartbeat?), it's killed, resurrected, journals are replayed, and the request is resubmitted to the FS driver.

    It'll work. The program might notice a small pause, as if the disk was busy or the kernel yielded schedule to an interrupt handler.

  8. Re:High reliability? by MobyDisk · · Score: 3, Insightful

    Minix tries to take a state snapshot, reconstruct something workable,

    That's frieking fascinating. I just posted about how I didn't think restarting a driver could really be transparent because state would be lost. Then I read that it actually transfers the state. Do you have any good links with an overview of that? My immediate thought is "well, if the state is transferred, won't the restarted service crash too?" but I'm guessing someone has already thought of that...

  9. Re:Drivers as processes? by bluefoxlucid · · Score: 5, Interesting

    You can reconstruct state. A read request from hard disk will work the same way, repeatedly; a write request to a file system will write to a journal or the same blocks in a file or inode, while a write to a hard drive sector is isometric. Keeping the request buffer, resubmitting the request, and so on lets you reconstruct state. Even a network driver theoretically could read state from the network: it could request DMA from the NIC to a buffered memory area with a control structure of known layout, and the resurrection server could provide the control structure and buffered memory areas back to the driver if it needs to restart.

    The remainder of the driver state can be discarded. Bringing in new network frames, new writes to file systems, or the like shouldn't depend on the driver's internal state. Repeated crashing--for example, reloading the network driver as above and having the control structure point to a buffer of unmapped memory--could signal the OS to simply drop state and start fresh. Recovery is possible in many cases: TCP/IP, as a separate driver, would simply experience a dropped frame (lost packet), handling a state-reset network driver the same way as any other faulty media; a failed hard drive write would signal the FS driver to resubmit its write; and a failed file system operation could go so far as to reload the driver and run a journal replay or file system check (non-journaled file systems could use an in-memory journal to facilitate file system driver recovery).

    Consider state as a collection of significant and insignificant states. My Web browser right now has a lot of stuff in memory, a lot of things rendered on the screen, a state of how far down I've scrolled, and state describing where in memory all these things are--and where this text I'm typing is stored. If we unload the browser and then re-launch, the only state I need restored to post this message is a copy of this message, dumped anywhere in RAM, with a specific pointer somewhere referencing that buffer as the context of this particular textbox on this Web site. The browser's state may be completely different, yet only that piece of information is important; I can recover the rest by coming to this page and hitting "Reply To This".

    From that view, it's not hard to recover discrete processes in an OS. File system separate from disk driver means the FS can handle a disk driver crash and reload; user prorgrams won't notice a file system driver crash if the system just waits for the FS driver to reload and replay a journal or such to return state to sanity. The task entry for the user program tracks all the file handles. All of these things are separate, can communicate between mediators, or can mediate their own communications.

  10. Does Minix have much real-time capability? by SkOink · · Score: 5, Insightful

    As an embedded-systems guy, I'd _love_ to have a Unix-like where I could schedule events that were guaranteed-by-design to fire within some deadline of when they were scheduled. Then I could host my once-per-kHz hardware service routines on the same processor that was also running my device's web-server.

    Minix's microkernel architecture seems like an ideal fit for that kind of use case. If there are any Minix devs reading this thread, how easy would it be for me to make a system like that using Minix?

    --
    ---- I'll take you in a Hunt deathmatch any day.
    1. Re:Does Minix have much real-time capability? by SkOink · · Score: 4, Informative

      VxWorks?

      VxWorks is a great product. It's also waaaayyy outside of the price range of a hobbyist developer. Getting up and running with the VxWorks suite of tools can easily cost 20k (USD), and the recurring license fees are pretty significant as well. I would also bet that auditing the VxWorks source code (or trying to get custom patches in) would cost significantly more.

      --
      ---- I'll take you in a Hunt deathmatch any day.
    2. Re:Does Minix have much real-time capability? by tlhIngan · · Score: 3, Informative

      As an embedded-systems guy, I'd _love_ to have a Unix-like where I could schedule events that were guaranteed-by-design to fire within some deadline of when they were scheduled. Then I could host my once-per-kHz hardware service routines on the same processor that was also running my device's web-server.

      Minix's microkernel architecture seems like an ideal fit for that kind of use case. If there are any Minix devs reading this thread, how easy would it be for me to make a system like that using Minix?

      Your requirements mean you want a Real Time operating system - one that guarantees execution of a interrupt or other thing within a fixed deadline.

      If your deadline is a do-or-die thing, you have a hard-real-time requirement (i.e., it's a failure if you're late, period). if your deadline is more of a "well, please try not to, but under exceptional cases you can be a bit late" then it's firm real-time, and if it's "well, try not to be late, but it's OK if you are" then it's a soft real-time requirement.

      (Note: general purpose OSes often do run tasks that do have hard or soft realtime requirements. E.g., responding to a keyboard is generally a soft-to-firm realtime requirement - the user types something and generally expects a prompt response or the system will seem "slow". A hard realtime requirement would be playing back audio where failure to prepare a new block of audio results in a pop/skip/burp of the audio. Or back in the old days, burning a CD. If you didn't keep the buffers full, you'd be out a disc).

      Of course, a RTOS guarantees the deadline regardless of load.

      And there are a few that are POSIX compliant - QNX for one. There's also RTLinux which runs Linux as a general task within a realtime framework. I'm not sure if RedHat still maintains it, but eCos was an RTOS as well.

      And yes, RTOSes are capable of that - handling a 1kHz process plus a webserver at general processing - the RTOS knows it needs to service that task at 1kHz and will pre-empt the webserver as required.

  11. Re:High reliability? by bluefoxlucid · · Score: 3, Informative

    No idea. I've seen the performance tests where they repeatedly send kill signals to the disk driver to crash it over and over, and measure its impact on performance--large when you have this in a tight loop, yet the system trudges along, and stops being so god damn slow when you stop killing the disk service 1000 times per second.

    I can conjecture a lot about how it is and isn't possible--obviously you can't just restart a snapshot from a few ns ago, or tell it to try again, or rerun the service and dump the same exact data back over it; but you can resubmit requests and messages in any number of ways. If you're careful to use a request-acknowledge-free workflow (send a request, wait for an acknowledgement that it's completed, then free the memory for the request when it's acknowledged or when the requested information is returned), you can always replay a request if the server dies. You can even use a mediator to resubmit uncompleted requests or stored state (received frames, journaled file system actions, etc.) to a service if it gets restarted, hiding that process from other services.

    Minix documentation and demonstration show that they restart the service and it completes all requests--state is snapshotted and restored. How that state is snapshotted--internal to service, mediated by a message passer, or resubmitted by client services--I don't actually know. I just know it does it and it's technically possible in any number of ways.

  12. Re:High reliability? by bluefoxlucid · · Score: 3, Informative

    Last time I looked at this, L4 was some 1-2mS context switch on x86, back in the 1GHz chip era; Minix was 100uS; and it was some 20uS on ARM. ARM is a good architecture--even L4 was ridiculously fast on ARM. Mach was slow as balls all the time.

  13. Re:Linux clone by bluefoxlucid · · Score: 4, Informative

    From what I've seen, Minix is fast. It's built for speed, avoiding many costs of IPC the same way Linux does.

    In Linux, the address space is split. IA-32 4G/4G causes a full TLB and cache flush at syscall entry and return, creating massive slowness. IA-32 normal 3G/1G operation puts 1G at the top for kernel mappings and 3G at the bottom, while x86-64 puts 128TB at the top and 128TB at the bottom. In both cases for split address space, there's no TLB or cache flush when syscalling into the kernel; and returning to user space requires only selective cache and TLB invalidation, removing kernel-private data and leaving userspace data in tact. This greatly improves cache utilization and reduces expensive pagefaults by completely avoiding the kernel/user context switch, replacing it with a simple mode switch.

    In Minix, the many kernel contexts make all the same mappings, but lock access to the specific service. It's the same as Linux's split mapping, but with parts of the kernel unable to access other parts; IPC involves a few TLB and cache invalidations in each direction. This strategy lets you run an entire round trip call in under 100nS. It's about as long each way as a CALL and RET, so it's about the overhead of adding a function call along the code path.

  14. Re:Linux clone by bluefoxlucid · · Score: 3, Insightful

    But it will be complex in small, discrete, independently-verifiable pieces, like a cookie with raisins, M&Ms, and a peanut butter cup arranged on top rather than a chocolate-peanut-butter cookie with raisin puree mixed in.

  15. Re:Linux clone by bluefoxlucid · · Score: 4, Informative

    It has a 2% to 4% penalty for IPC, specifically. This is like when Theo de Raadt chose to argue with me that position-independent executables were "very expensive" and had "high performance overhead," and I pulled out oprofile and found that 0.2% of the execution time occurred in the main executable--which was 6% slower (when including -fomit-frame-pointer no longer providing a 5% boost), giving a total overhead of 0.012% total system slowdown--a few seconds lost per day.

    The difference is I was doing that back then, and not referencing shit I did 10 years ago.

    Minix's overhead is small. Minix uses fixed-length buffers, zero-copy strategies, mode switching, and the like to avoid doing any real work for IPC. It's like adding a function call to your code paths--like if you called get_fs_handle() and it called __real_get_fs_handle() without inlining it.

  16. Let's be different by spaceyhackerlady · · Score: 2

    I've followed Minix development with interest. The internal architecture is different from most OSs out there. Not different for the sake of being different, but different to show different solutions to problems. The way we do things in Linux et al is powerful, but it's not the only way.

    I haven't come up with a compelling reason to use it in my work (yet... :-), but I install each new release on a virtual machine and play with it.

    ...laura

  17. Re:Linux clone by bluefoxlucid · · Score: 2

    Not necessarily.

    There is a single, absolutely-optimal way to implement a computer program for a specific task in a specific language on a specific compiler targeting a specific CPU platform for a specific CPU model. In practice, we worry more about code readability, code maintainability, and the general-purpose usefulness of the operating system.

    Given what I said--that IPC carries about as much overhead as a function call when calling out to another part of the kernel--we don't even have to consider whether that overhead is so negligible as to be ludicrous to account for or whether it's incredibly large. The only practical impact is the same as using OpenBSD versus NetBSD versus FreeBSD versus DragonFly BSD: different approaches are taken in various kernels to solve the same problem, and they all jump through different numbers of lines of code, different interactions (i.e. DIV takes more cycles than SHR), different call traces (more or fewer function calls passing more or fewer arguments), and so on.

    In other words: the overhead is on the level that calling it "slower" is an abuse of terms, the same as claiming that the execl() call shouldn't be a wrapper for execve() because it makes the system slower. The practical impact isn't just small; it's smaller than the practical impact of every other factor in the execution of the code in question, and thus has no real implications for performance as an architectural consideration.

  18. Re:High reliability? by Pseudonym · · Score: 2

    Monoliths, e.g. Linux, don't have IPC latency [...]

    In the case of non-memory-mapped I/O (e.g. anything that goes through a file descriptor), the major cost isn't context switching, it's copying data. Microkernels have to transfer all this data between address spaces. Macrokernels, on the other hand, have to transfer it between user space and kernel space. It's basically the same operation with basically the same cost, but it falls under a different heading.

    --
    sub f{($f)=@_;print"$f(q{$f});";}f(q{sub f{($f)=@_;print"$f(q{$f});";}f});