[HN Gopher] Xous Operating System
       ___________________________________________________________________
        
       Xous Operating System
        
       Author : eustoria
       Score  : 161 points
       Date   : 2026-01-14 17:29 UTC (4 days ago)
        
 (HTM) web link (xous.dev)
 (TXT) w3m dump (xous.dev)
        
       | Rochus wrote:
       | Interesting, didn't hear from this system so far. Seems to be
       | funded by the EU. Apparently it is written in pure Rust since
       | 2020, and Andrew "bunnie" Huang seems to be involved.
       | 
       | Is there a PDF version of the book (https://betrusted.io/xous-
       | book/)?
        
         | romac wrote:
         | There is a single-page version of the book that you can save as
         | a PDF: https://betrusted.io/xous-book/print.html
        
           | Rochus wrote:
           | Great, thanks.
           | 
           | I assume the "kernel" makes heavy use of "unsafe", because
           | all the infrastructure assumed by Rust is not available. Or
           | how was this solved?
        
             | maxbond wrote:
             | It's not really about infrastructure but yes kernels and
             | firmwares have to do a lot of stuff the compiler can't
             | verify as safe, eg writing to a magic memory address you
             | obtained from the datasheet that enables some feature of
             | the chip. And that will need to happen in unsafe code
             | blocks. I wouldn't call that a problem but it is a reality.
        
               | Rochus wrote:
               | Are you one of the authors? Concerning the
               | "infrastructure": Rust assumes a runtime, the standard
               | library assumes a stack exists, a heap exists, and that
               | main() is called by an OS; in a kernel, none of this is
               | true. And the borrow checker cannot reason about things
               | like e.g. DMA controllers mutating memory the CPU
               | believes it owns, Memory-mapped I/O where a "read" has
               | side effects (violating functional purity), context
               | switches that require saving register state to arbitrary
               | memory locations, or interrupt handlers that violate the
               | call stack model. That's what I mean by "infrastructure".
               | It's essentially the same issue with every programming
               | language to some degree, but for Rust it is relevant to
               | understand that the "safety guarantees" don't apply to
               | all parts of an operating system, even if written in
               | Rust.
        
               | maxbond wrote:
               | I have no affiliation, I'm just a commenter.
               | 
               | The standard library requires a heap and such, but you
               | can enable the no_std attribute to work in environments
               | where they don't exist. https://docs.rust-
               | embedded.org/book/intro/no-std.html
               | 
               | Rust's safety model only applies to code you write in
               | your program, and there's a lot that's unsafe (cannot be
               | verified by the compiler) about writing a kernel or a
               | firmware, agreed. You could have similar problems when
               | doing FFI as well.
        
               | inferiorhuman wrote:
               | Rust assumes a runtime, the standard library assumes a
               | stack exists, a heap       exists, and that main() is
               | called by an OS;
               | 
               | Wrong.
               | 
               | Source: I'm writing Rust without a runtime without a heap
               | and without a main function. You can too.
        
               | xobs wrote:
               | The Rust runtime will, at a minimum, set up the stack
               | pointer, zero out the .bss, and fill in the .data
               | section. You're right in that a heap is optional, but
               | Rust will get very cranky if you don't set up the .data
               | or .bss sections.
        
               | comex wrote:
               | As will C.
        
               | oguz-ismail2 wrote:
               | No idea what either of you are talking about. It's the
               | operating system that sets those things up not the
               | language runtime.
        
               | monocasa wrote:
               | Not for kernels.
        
               | wmf wrote:
               | _standard library assumes a stack exists, a heap exists,
               | and that main() is called_
               | 
               | A small assembly stub can set up the stack and heap and
               | call main(); from then on you can run Rust code. The
               | other topics you mention are definitely legitimate
               | concerns that require discipline from the programmer
               | because Rust won't automatically handle them but the
               | result will still be safer than C.
        
               | bunnie wrote:
               | I am a maintainer. I think what you're referring to is
               | the problem where `std` is actually a veneer on C - so
               | for example, when Rust allocates memory on an x86-class
               | desktop, it actually invokes a C library (jemalloc, or
               | whatever the OS is using) and that networking is all
               | built on top of libc. Thus a bunch of nice things like
               | threads, time, filesystem, allocators are all actually
               | the same old C libraries that everything else uses
               | underneath a patina of Rust.
               | 
               | In Xous, considerable effort went in to build the entire
               | `std` in Rust as well, so no C compilers are required to
               | build the OS, including `std`. You can see some of the
               | bindings here in the Rust fork that we maintain:
               | https://github.com/betrusted-
               | io/rust/tree/1.92.0-xous/librar...
               | 
               | Thus to boot the OS, a few lines of assembly are required
               | to set up the stack pointer and some default exception
               | handler state, and from there we jump into Rust and stay
               | in Rust. Even the bootloaders are written in Rust using
               | the small assembly shim then jump to Rust trick.
               | 
               | Xous is Tier-3 Rust OS, so we are listed as a stable Rust
               | target. We build and host the binaries for our `std`
               | library, which native rustc knows how to link against.
        
               | Rochus wrote:
               | Thanks, interesting. My concern was less about which
               | language implements std, but rather about the semantic
               | mismatch between Rust's ownership model and hardware
               | behavior (e.g. DMA aliasing, MMIO side effects). So I was
               | curious what work-around you found; do you e.g. use
               | wrapper types with VolatileCell, or just raw pointers?
        
               | bunnie wrote:
               | Hmm, I think I see what you're asking. I'm not sure if
               | this exactly answers your question, but at least for
               | aliasing, because we have virtual memory all pages have
               | to be white-listed to be valid.
               | 
               | Thus "natural" aliases (say due to a decoder that doesn't
               | decode all the address bits) can't be mapped because the
               | OS would not accept the aliases as valid pages. This is
               | handled through a mechanism that goes through the SVD
               | description of the SoC (SVD is basically an XML file that
               | lists every register and memory region) and derives the
               | list of valid pages. The OS loader then marks those as
               | the set of mappable pages; any attempt to map a page
               | outside that list will lead to a page fault. One nice
               | thing about the SoC RTL being open source is that this
               | entire process of extracting these pages is scripted and
               | extracted from the SoC's source code, so while there can
               | be code bugs, at least human error is eliminated from
               | that process.
               | 
               | DMA devices on their own right can have "god mode" access
               | to memory, because they operate on physical memory
               | addresses and lack page translation tables. To that end
               | the preferred DMA mechanism _in hardware_ has an  "allow
               | list" of windows that can be enabled as DMA targets; on
               | reset the list is nil and nothing can be DMA'd, the OS
               | has to correctly configure that. So this is not a Rust-
               | level thing, this is just a driver-level hack. Not all
               | the DMA-capable peripherals have this safety mechanism
               | though, some of the IP blocks are just a big gun with no
               | safety and you're free to point it at your toes.
               | 
               | However, if you set up a DMA and then you read from it
               | later on - you're in unsafe territory. Rust can't reason
               | about that. So for structures that are intended as DMA
               | targets, they are coded in a peculiar way such that they
               | are marked as unsafe and you're using the read_volatile()
               | method on the raw pointer type to force the compiler to
               | not try to optimize out the read for any reason.
               | Furthermore, fence instructions are put around these
               | reads, and a cache flush is required to ensure the
               | correct data is pulled in.
               | 
               | This complexity is baked into a wrapper struct we create
               | specifically to handle dangerous interactions like this.
        
               | Rochus wrote:
               | Thanks, that's exactly what I was asking about. So if I
               | understand correctly: for the hardware interface layer
               | (DMA, MMIO), you're essentially writing disciplined
               | C-style code in unsafe blocks with volatile reads and
               | manual memory barriers, then wrapping it to contain the
               | unsafety. That's pragmatic.
        
               | bunnie wrote:
               | That's correct.
        
             | junon wrote:
             | You can't write a kernel without `unsafe` appearing
             | somewhere.
        
               | quotemstr wrote:
               | Yeah. That's why my preferred approach isn't to use Rust
               | for the core TCB. It'd be mostly unsafe anyway, so what's
               | the point? You can write in an all-unsafe language if you
               | want. you can still prove it correct out of band, and
               | seL4 has done that work for you.
               | 
               | Sure, you could just use unsafe Rust and prove it correct
               | with Prusti or something, but why duplicate work?
        
               | tadfisher wrote:
               | I guess then you aren't writing a kernel anymore, you're
               | writing a driver suite for seL4.
        
               | quotemstr wrote:
               | Yep. And that's a good place to be. Keep in mind that the
               | "driver suite" in an seL4 system includes a bunch of
               | things that others would put in the kernel: memory
               | management and swap, networking, filesystems, linking and
               | loading, and so on are all userspace. So, if you want,
               | you still get to differentiate based on interesting low-
               | level things.
               | 
               | Calling seL4 system guts a "driver suite" is like calling
               | rustc "just a preprocessor for LLVM IR". True, but only
               | in the most uselessly pedantic sense.
        
               | bunnie wrote:
               | It is true that hardware, by definition, is a big ball of
               | globally mutable state with no guarantees about
               | concurrency, data types, or anything else. However, one
               | could take the view that it's the role of the OS to
               | restrict & refine that raw power into a set of APIs that
               | are safe, through a set of disciplines, such as reasoning
               | through why an unsafe block might actually be sound.
               | 
               | unsafe means that the compiler can't provide any
               | guarantees about what happens inside the unsafe block.
               | However, it is possible to manually ensure those
               | guarantees.
               | 
               | Thus as a matter of discipline every time an unsafe block
               | is used there's a comment next to it recanting the mantra
               | of safety: This `unsafe` is sound because ... all data
               | types are representable, the region is aligned &
               | initialized with valid data, the lifetime is static, we
               | structurally guarantee only one owner at a time (no
               | concurrency issues)...often times in writing that
               | comment, I'll be like, "oh, right. I didn't _actually_
               | think about concurrency, we 're going to need an Atomic
               | somewhere around this to guarantee that" - and that saves
               | me a really hard-to-find concurrency bug down the road.
               | 
               | So while this is a very manual process, I have found the
               | process of documenting safety to be pretty helpful in
               | improving code quality.
               | 
               | Once you've established safety, then you do get some nice
               | things in your life, like Mutexes, Refcells, Arcs, and
               | the whole collections library to build an OS on top of,
               | which saves us a lot of bugs. It is kind of nice to have
               | a situation where if the code compiles, it often just
               | works.
        
               | junon wrote:
               | Because not ALL of it is unsafe. The point of using Rust
               | in the kernel is to write abstractions over the unsafe
               | bits and then utilize safe Rust for all the logic you
               | build on top.
        
               | imtringued wrote:
               | >It'd be mostly unsafe anyway, so what's the point?
               | 
               | The vast majority of the code that will be tagged
               | "unsafe", will be done so because you're doing the
               | equivalent of FFI, but implemented in hardware. If there
               | was a way to automatically generate the binding from a
               | register map, the only purpose of the unsafe keyword
               | would be to warn you that the effect of the ffi call you
               | are doing is unknown. In other words, the unsafe marker
               | isn't some kind of admission of defeat. It marks the
               | potentially unsafe sections of the code where additional
               | care might be required.
               | 
               | This means you're throwing out the baby with the
               | bathwater.
        
             | jandrewrogers wrote:
             | Use of "unsafe" is unavoidable. Various pieces of hardware
             | are directly writing into the address space. Concepts of
             | "ownership" and "mutability" go beyond code semantics.
        
             | ajb wrote:
             | From the talk linked above, they went to considerable
             | effort to design a system with a cheap processor which
             | nevertheless contains an mmu, and so most other embedded
             | kernels, which assume the lack of one, are not applicable.
             | So the point of writing in rust is that they can ensure
             | that some of the guarantees of rust are enforced by the
             | hardware. (It's been a while since I watched that talk, so
             | I don't recall exactly which ones). And this is a
             | microkernel, not a monolithic kernel, so they will be using
             | hardware guarantees even between kernel components.
        
               | quotemstr wrote:
               | To be fair, 1) Zephyr _can_ take advantage of an MMU if
               | you have one, and 2) Linux itself scales down
               | surprisingly far. Keep in mind that its lineage extends
               | far back in time and that it retains much of its ability
               | to run on low-spec hardware.
        
         | utopiah wrote:
         | It's not directly funded by the EU, it's funded by NLNet which
         | is only in part funded by the EU. The goal is to collect money
         | from large sources (e.g. EU) from relatively complex
         | subsidiaries that are too big for small projects then dispatch
         | and evaluate.
         | 
         | Source : I have an NLNet funded project, so like Xous
         | https://github.com/betrusted-io/xous-core?tab=readme-ov-file...
         | I have such banners at the bottom of my repository.
        
         | bunnie wrote:
         | Thanks to a PR from a community member (millette) there's now a
         | PDF: https://betrusted.io/xous-book/pdf/xous-book.pdf
        
       | throwaway89201 wrote:
       | Here's their 39c3 talk about Xous:
       | https://media.ccc.de/v/39c3-xous-a-pure-rust-rethink-of-the-...
        
         | jauntywundrkind wrote:
         | The talk is great. Good into to Xous, to using the MMU sort of
         | to do a rust borrow-checked owned memory system.
         | 
         | Also Bunnie talks about making the Baochip: a 1+4 small-tiny
         | risc-v design. That hitchhikes on another company's core! "Can
         | I also put fuses on so we can use this as a risc-v design?"
         | "Sure"! So awesome!!
        
         | IshKebab wrote:
         | This was a really great talk. Full of interesting things. E.g.
         | his BIO system for replacing Raspberry Pi's proprietary PIO. It
         | uses RV32E (16 registers) and then uses x16-31 as custom
         | registers to directly control the pins so you can do GPIO
         | without the usual delays from MMIO.
        
       | mmooss wrote:
       | What problem is this solving? Are there no OSes for medium
       | embedded systems? Are they too expensive?
        
         | Drunk_Engineer wrote:
         | Trust and transparency: https://betrusted.io
        
         | miduil wrote:
         | Key aspects from the talk iirc (I was in the audience :)):
         | 
         | * Real time embedded CPUs are usually without an MMU -> kernels
         | such as FreeRTOS lack secure memory due to the lack of MMUs in
         | those CPUs
         | 
         | * A kernel targeting embedded CPUs with MMUs that supports
         | secure memory management
         | 
         | * Secure memory communication a there called server/client
         | method to communicate leveraging Rust borrow checker build time
         | for later having "user-land processes" to communicate via
         | pages.
         | 
         | These things combined allow a very small kernel, with user-
         | space implementation of usually kernel-level functionality,
         | such as the system clock timer (presented in the talk).
         | 
         | All of this is meant to provide a complete trustworthy
         | processing chain, from CPU dies that can be inspected through
         | infrared microscopy through the CPU epoxy package/cover to the
         | entire build/software tool chain.
         | 
         | The Xous OS project both takes care of the Kernel, but also the
         | CPU/RISC-V runtime with an MMU, something that is usually quite
         | difficult to obtain - but due to synergy effects with another
         | chip consumer/organization they managed getting their custom
         | processor manufactured.
        
         | topspin wrote:
         | There is QNX. seL4 is another.
         | 
         | The former is proprietary. The latter kernel is GPL2, similar
         | to Linux.
        
           | panick21_ wrote:
           | QNX is not open source.
           | 
           | And seL4 is a kernel, not an OS. And it pretty hard to work
           | with specially if you want any kind of dynamic system.
        
             | wickrom wrote:
             | What did you mean by a dynamic system ?
        
               | pjmlp wrote:
               | One where processes, drivers and libraries come and go
               | during the whole OS uptime.
        
             | LargoLasskhyfv wrote:
             | There is Genode, which can run atop of seL4(amongst
             | others).
             | 
             | https://genode.org/
             | 
             | https://genodians.org/
             | 
             | https://en.wikipedia.org/wiki/Genode
        
         | utopiah wrote:
         | The problem is : do you trust your hardware? If not can you
         | build, or buy, hardware that you can verify? So they built
         | https://www.crowdsupply.com/sutajio-kosagi/precursor with an
         | FPGA instead of a CPU from Intel or SpacemiT and are going up
         | and down the chain to insure that EVERYTHING can be inspected.
        
         | IshKebab wrote:
         | It's about providing the security benefits we get from MMUs
         | (e.g. process isolation) to microcontrollers. There are no OSes
         | for that space because basically no microcontrollers have MMUs.
         | They had to make one for this OS.
         | 
         | I highly recommend watching the talk, it's very good!
        
       | otterley wrote:
       | (2022)
        
         | gjvc wrote:
         | not helpful
        
         | fsiefken wrote:
         | xous is under active development: https://github.com/betrusted-
         | io
         | 
         | recent talk by bunnie, sean "xobs" cross
         | 
         | https://events.ccc.de/congress/2025/hub/en/event/detail/xous...
         | 
         | https://app.media.ccc.de/v/39c3-xous-a-pure-rust-rethink-of-...
         | 
         | https://www.youtube.com/watch?v=DaWkfSmIgRs
        
           | otterley wrote:
           | I don't disagree. However, this is a "news" site, and so, we
           | should be posting stories about recent events related to the
           | project, as opposed to a homepage that hasn't been updated in
           | years.
           | 
           | It's the difference between posting a story about a recent
           | Tesla lawsuit vs. linking to Tesla's homepage.
        
       | quotemstr wrote:
       | Oh, cool. An operating system.
       | 
       | > Every Xous Server contains a central loop that receives a
       | Message, matches the Message Opcode, and runs the corresponding
       | rust code
       | 
       | Rust? Only Rust?
       | 
       | An OS has no business dictating implementation language. Inside
       | my isolated microservice, I should be able to run anything I damn
       | well please.
       | 
       | Rust's own safety guarantees are a red herring for security at
       | this level, BTW, because you can't trust them over an IPC or
       | system call boundary. The other process can just lie to you about
       | being safe.
       | 
       | I'm a fan of microkernels and microservice models in general, but
       | not if they sacrifice one of their core advantages: arms-length
       | decoupling of implementation strategies through having isolated
       | services communicate only through stable, versioned interfaces.
       | 
       | > A thread connects to a Server using a 128-bit ID. This ID may
       | be textual if the server uses a well-known name that is exactly
       | 16-bytes wide such as _b "ticktimer-server" or _b"xous-name-
       | server", or it may be a random number generated by a TRNG.
       | 
       | What? This mechanism seems ripe for squatting attacks. How do I
       | know I'm talking to the service I want to contact instead of
       | somebody squatting the name? Using the name namespace for
       | randomly generated IDs (binary!) or an ASCII name stuffed into
       | the same bytes.
       | 
       | Better to give every object on the system its own unique
       | unforgeable, unguessable ID and treat mapping from human-legible
       | names to these strong IDs as its own service, one that can have
       | namespace and authentication policies tailored to a given
       | environment.
       | 
       | > since sending pages of memory is extremely cheap.
       | 
       | Depending on architecture, doing virtual address tricks ranges
       | from expensive to exorbitant. Real-world systems doing bulk
       | transfers over shared memory either rotate among pre-mapped
       | buffers (Wayland, Surface/BufferQueue) or just have the kernel do
       | one efficient scatter/gather memcpy into address space controlled
       | by the recipient (Binder).
       | 
       | I'm not excited by this "lend" IPC primitive Xous has. Seems like
       | more trouble than it's worth. You can add a queue of pre-mapped
       | buffers on top as a separate service if you need it.
       | 
       | > Processes can allocate interrupts by calling the ClaimInterrupt
       | call.
       | 
       | Good! It's about time more people write drivers as regular
       | programs that treat IRQs like any other input event and less as
       | magical things that for some ghastly reason must run with
       | ultimate privileges just to do a DMA once in a while.
       | 
       | That said, just as a matter of elegance, I'd treat an interrupt
       | literally like an regular input source and make it a device node
       | on the FS, not some special kind of resource managed with its own
       | system call.
       | 
       | In Linux terms, I should be able to open /dev/irq/5 and expect it
       | to work like an eventfd. Isn't that elegant?
       | 
       | > ...memory will not be backed by a real page, and will only be
       | allocated by the kernel once you access the page
       | 
       | Ugh. Contractual overcommit. Linux does overcommit too. It's an
       | unfixable mistake. I'm disappointed to see a greenfield OS adopt
       | the same strategy. Doubly so for an embedded system that might
       | want precise control over commit charge.
       | 
       | See, in more mature virtual memory setups, we distinguish between
       | reserving address space (which you do with mmap and such) and
       | reserving allocated capacity (which we call "commit"). If you
       | turn overcommit off on Linux (or use Windows at all) you get an
       | elegant model where you can mmap(..., PROT_NONE) and not have
       | your process "billed" for the memory in your allocated region --
       | but once you protect(..., PROT_WRITE), you can "charged" for that
       | memory because after the mprotect returns, you're contractually
       | permitted to write to that memory with the expectation you don't
       | segfault or get some kind of "Opps. Just kidding. Don't have the
       | memory after all!" signal.
       | 
       | > IncreaseHeap(usize, MemoryFlags) will increase a program's heap
       | by the given amount
       | 
       | What?? No! sbrk() is a terrible interface. Why get locked into
       | having one region of address space called "the heap"? Modern
       | systems (OpenBSD does especially well here among POSIX systems)
       | don't have a "heap" like a damn PDP-11. Instead, malloc allocates
       | out of memory pools that it internally manages using general
       | purpose mmap. The set of anonymous memory regions so managed is
       | what constitutes the heap. No magic. Kernel doesn't even need to
       | know what a heap is. It speaks only the sweet, soothing language
       | of mmap.
       | 
       | > There are different memory regions in virtual
       | 
       | Wait. There are two dozen hard coded virtual addresses that form
       | an ABI? There goes ASLR. What is this, MS-DOS? Should I load an
       | XMS driver? Maybe shadow video RAM?
       | 
       | > The kernel supports enabling the gdb-stub feature which will
       | provide a gdb-compatible server on the 3rd serial port
       | 
       | Good. Maybe they have build IDs and a symbol server too?
       | 
       | > The loader uses a miniature version of the ELF file format.
       | 
       | Good, but...
       | 
       | > A problem with the ELF format is that it contains a lot of
       | overhead
       | 
       | Bad call. I'm not a big fan of ELF (e.g. relative to PE) but it's
       | not that bad and any conceivable savings in things like dynamic
       | section segment descriptions isn't going to be worth a lifetime
       | of compatibility headaches.
       | 
       | Just use standard ELF. It was designed for computers shittier
       | than the ones in disposable vapes today.
       | 
       | > ELF supports multiple flags. For example, it is possible to
       | mark a section as Executable, Read-Only, or Read-Write.
       | 
       | Yes, but...
       | 
       | > Unfortunately these flags don't work well in practice, and
       | issues can arise from various permissions problems.
       | 
       | Eh, they work fine. (Plus, the section flags aren't relevant.
       | Dead metadata. You don't need a section table at all,
       | technically. An ELF loader cares about the _segment_ table, and
       | segments often span more than one section.)
       | 
       | > The Xous build system uses the xtask concept
       | 
       | You want Yocto. You'll lost a huge chunk of your audience once
       | they learn your OS doesn't build with Yocto. Is it fair? No.
       | Yocto sucks. But it's what the embedded world uses, and if you're
       | already asking them to make a leap of faith using your new OS,
       | you don't ask them to wear a blindfold and learn a new build
       | system at the same time.
       | 
       | ("Isn't Yocto for Linux?" You can use Yocto to build whatever OS
       | you want if you don't use Poky, the default Linux distribution
       | the Yocto build system produces. Mechanism vs. policy
       | separation.)
       | 
       | > Push notifications are used when we want to be alerted of a
       | truly unpredictable, asynchronous event that can happen at any
       | time.
       | 
       | IMHO, the more useful distinction is between two-way and one-way
       | messages. For the latter, you don't expect a response, but
       | otherwise every single part of the protocol stack is the same. I
       | wouldn't have made a separate "push notification" facility.
       | 
       | > The Plausibly Deniable DataBase (PDDB) is Xous' filesystem
       | ...features "plausible deniability", which aims to make it
       | difficult to prove "beyond a reasonable doubt" that additional
       | secrets exist on the disk
       | 
       | I'm super happy to see a feature like this integrated into an OS.
       | 
       | > The core of a Mutex is a single AtomicUsize. This value is 0
       | when the Mutex is unlocked, and nonzero when it is locked.
       | 
       | No priority inheritance? Shame. I'm a huge fan of robust PI in
       | small systems as a way to bound critical operation latencies
       | dynamically.
        
         | saagarjha wrote:
         | > An OS has no business dictating implementation language.
         | 
         | As opposed to all those OSes that only publish headers in one
         | language right that require everyone to go through heroic
         | effort to interoperate with it?
         | 
         | > This mechanism seems ripe for squatting attacks. How do I
         | know I'm talking to the service I want to contact instead of
         | somebody squatting the name?
         | 
         | Nobody is going to stop you from typosquatting yourself, no
        
           | quotemstr wrote:
           | > As opposed to all those OSes that only publish headers in
           | one language right that require everyone to go through heroic
           | effort to interoperate with it?
           | 
           | Everyone can speak C ABI. It's just a matter of making memory
           | and registers spell out the right things.
           | 
           | Only Rust can speak to a Rust API that needs monomorphization
           | before it can be used. I'd have the same objection to an OS
           | project based on a C++ API, BTW. (Android gets this wrong for
           | some of their HALs, sadly.)
           | 
           | > Nobody is going to stop you from typosquatting yourself, no
           | 
           | True, but if it's about the same amount of work either way,
           | you might as well design the system such that it could
           | conceivably run services at different trust levels.
           | 
           | And if you don't have different trust levels? Why not just
           | stick everything in one address space, like Midori?
           | 
           | I can see a case for something simpler and more streamlined
           | than your typical Unix system, but I imagine that thing being
           | something more this Zephyr or FreeRTOS and not require an
           | MMU. This project does require an MMU and virtual memory.
           | 
           | I appreciate the effort that's gone into Xous, but I'm not
           | sure who it's for except Rust fans who really like greenfield
           | projects. It's just as alien as seL4 but without the
           | mathematical correctness assurances.
           | 
           | I think it'd be cool to make something like this a middleware
           | layer atop seL4 that helps make building systems with it
           | practical.
        
         | fellowmartian wrote:
         | Yocto? Nobody is expecting Yocto for deeply embedded systems
         | likely to be built on this OS. It's closer to FreeRTOS, Zephyr,
         | Embassy, but with this additional hardware-level safety
         | guarantees.
        
           | quotemstr wrote:
           | My Yocto point might be colored by my experience of having
           | seen multiple teams stick with Yocto beyond (IMHO) the point
           | of pain and reason due to familiarity and industry inertia.
        
         | xobs wrote:
         | > Rust? Only Rust?
         | 
         | Yes, this OS is written in Rust. However, since it has a well-
         | defined ABI, and all services are defined to use `#[repr(C)]`,
         | and the interface is simple primitive enums, it's designed with
         | C-like language support in mind. The hardest part in C is
         | getting an equivalent to `#[repr(C, align(4096))]` which, last
         | time I checked, only let you do alignments up to 64 or so
         | without resorting to linker tricks.
         | 
         | > This mechanism seems ripe for squatting attacks
         | 
         | There are only a few services with well-known names, and they
         | start up before things like the scheduler are running. Most
         | things go through the nameserver service which supports things
         | like attestation, finite-client limits, and signature checking.
         | 
         | > Just use standard ELF.
         | 
         | Sure, there's a loader available that lets you run standard ELF
         | files: https://github.com/betrusted-io/xous-
         | core/tree/main/apps/app...
         | 
         | The bootloader uses the MiniELF format because we can make
         | assertations about things like the order of sections and about
         | merging multiple segments, while also stripping non-loadable
         | sections. It would be possible to just bundle all the ELF
         | images for all programs together, but if you're generating the
         | loader image you might as well shrink the image a bit.
         | 
         | > What?? No! sbrk() is a terrible interface.
         | 
         | Then you can call `MapMemory(NULL, NULL, [size], RWX)`:
         | https://docs.rs/xous/latest/xous/syscall/fn.map_memory.html
        
       | Animats wrote:
       | That's a neat little system.
       | 
       | Two surprising design decisions:
       | 
       | - One-way messages. You send, then, in a separate operation, you
       | wait for a reply. This happens at each end. That means two extra
       | trips through the scheduler and more time jitter. QNX has a
       | blocking "MsgSend" which sends and waits for a reply. The
       | scheduler transfers control to the receiving thread in the common
       | case where the receiver is waiting, which behaves like a
       | coroutine with bounded latency. It's a subtle point, but one of
       | the reasons QNX is so well behaved about jitter.
       | 
       | - Interprocess communication by memory remapping instead of
       | copying. This is high overhead for small messages, and at some
       | fairly large size, becomes a win. Remapping pages means a lot of
       | MMU and cache churn. Cost varies with the CPU and memory
       | architecture. Mach worked that way, and the overhead was high.
       | Not sure how expensive it is with modern MMUs. Do you have to
       | stop other threads that might have access to the page about to be
       | unmapped?
        
         | xobs wrote:
         | > One-way messages
         | 
         | Messages are either one-way (Send or Scalar), or are two-way
         | (BlockingScalar, Lend, or MutableLend). For two-way messages,
         | the calling process inherits the quantum of the sending
         | process, so the only penalty is the cost of two context
         | switches.
         | 
         | > Interprocess communication by memory remapping instead of
         | copying
         | 
         | This is true for Send, Lend, and MutableLend, but for Scalar or
         | BlockingScalar you get 5xusize values instead, which is used
         | for things like `msleep` or `uptime`.
         | 
         | You would have to stop access to other threads that might have
         | access to the page about to be unmapped, but Rust guarantees
         | that if you have a mutable reference, you're the only one with
         | access to the page.
        
       | LowLevelBasket wrote:
       | I have mixed feelings about rust but the more I look into the
       | xous, docs the more interesting this becomes
        
         | tucnak wrote:
         | Once in a while projects like pgrx, or xous come along that
         | really beat the pack as far as Rust projects are concerned.
         | Actually delivering novel capabilities
        
       | forgotpwd16 wrote:
       | Unexpectedly wasn't asked: How it compares to Redox, another
       | message passing microkernel system written in Rust? Also, what
       | _for embedded devices_ means? What specific features has that
       | other microkernel systems don 't, or just means is limited in
       | scope*?
       | 
       | *Contrast to Redox that is meant to be general purpose but also
       | offers an embedded-oriented minimal version.
        
         | bunnie wrote:
         | Can't comment on Redox as I'm not familiar with it (maybe xobs
         | is), but "for embedded devices" means design choices are made
         | to accommodate smaller memory footprints - hundred k's of RAM,
         | ROM; not the gigabytes expected in desktop-class OSes. So, this
         | is in the same class as e.g. zephyr, threadx, chibi-os, Tock,
         | etc. and has no explicit aspirations to be able to run e.g.
         | server workloads. An example of such a trade-off is sticking
         | with a 32-bit pointer size from the get-go. No desktop or
         | server-class OS could make that trade-off, but the memory
         | savings from smaller pointer and object sizes is meaningful on
         | a memory-constrained device.
        
         | pornel wrote:
         | Redox is for CPUs that cost >$100.
         | 
         | Xous is for CPUs that cost <$1.
        
       | hulitu wrote:
       | > Xous Operating System
       | 
       | So it is a kernel and can run on "hardware". On which "hardware",
       | is left as an exercise for the user.
        
         | jojomodding wrote:
         | RISC-V with an MMU. They're building a chip for it to run on,
         | see https://baochip.com/
        
       | goodpoint wrote:
       | For a grass-root project GPL would be a better choice.
        
       | JBiserkov wrote:
       | I fell in love with the metal Dvorak-keyboard Precursor ever
       | since I saw bunnie post about it in 2019
       | https://xcancel.com/bunniestudios/status/1210540127430336517...
       | 
       | High resolution image:
       | https://pbs.twimg.com/media/EMyz0mUXkAIyVMf.jpg?name=orig
        
       ___________________________________________________________________
       (page generated 2026-01-18 23:01 UTC)