Hacker News new | past | comments | ask | show | jobs | submit login

Let's assume you want write most of the operating system in the high level language and as little as possible in assembler.

For most languages, writing hardware trap handler becomes quite a bit of an issue. In trap handler you cannot rely on an extensive runtime system. Anything that does garbage collection is probably out. Anything that does dynamic memory allocation is out as well.

Beyond that, how easy is it to create pointers, create datastructures that match a specific memory layout, etc. Low level device drivers need to talk to hardware in very specific ways. If it is hard to talk to the hardware, most people are probably not going to bother using that language for an operating system.

In theory you could mix and match languages in a kernel. For example, a filesystem could be written in a language that has an extensive runtime system.




I'd say that Rust (and, to a smaller extent, Zig, and, AFAICT, Ada) allow to write code that is guaranteed to not allocate, and define the exact memory layout of certain structures, all while offering much tighter protections than C.

Of course, there are things that cannot be expressed in safe code in either language. But marking fragments of code as unsafe, where C-like unconstrained access is allowed, helps a lot to minimize such areas and make them explicit.

There is definitely room for a more expressive and safe languages in the kernel-level space. We can look at Google Fuchsia or maybe at Redox OS, both are very real operating systems trying to use safer languages, with some success.


I think stability plays a big role in C continuing to remain dominant. Rust and Zig arent there yet, and wrt Rust in particular the ownership model doesn't play nearly as nicely in non-deterministic environments (taking far more code to deal with hardware such as an external display or printer that might, for example, get randomly unplugged at any point in time works against the grain of a static memory ownership analysis).


I'd say it's a good example why more static checks like lifetimes are useful.

With them, you can at least tell apart data structures that are fleeting and can disappear when a cable is ejected, and those which should stay put. This likely might help avoid another double-free or another freed pointer dereference.



Ada still has plenty of UB; it's just that the cases where it arises are usually more explicit.


If we don't adopt X because it doesn't solve 100% of the problems, then we will never improve.


If anything in the kernel is written in a language that has an extensive runtime system... Well, extensive runtime systems are pretty reliably resource hungry. And when they might suddenly need which sorts of resources tends to be unpredictable.

Vs. the kernel must keep working reliably when resources are running low.


But, today linux simply kills any process to free memory. What could prevent a gc (which also serves allocations, not only collects them back) to just do that on an emergency cycle? Destroy a record in a process array and reclaim its pages (of course without doing any allocations on the way, or by using an emergency pool). Or even just reclaim its pages and wait for it to crash on a page fault if you feel lazy.

which sorts

Dynamic languages only do memory-related ops unpredictably, or is it more than that?




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: