Live data from Hacker News

Hobby x86 kernel written with Zig

github.com

141–150 of 229 posts

Re: Hobby x86 kernel written with Zig

#141
post #38

Earlier quoted context omitted.

In general you'll find that zig is easier to read than Rust (see the first version of this project in Rust [0]) because it's a simpler language. For kernel programming this is even more so the case: * zig has native support for arbitrary sized integers. In Rust I used to do bitshifts, Now I just have a packed struct of u3/u5/u7 whatever (see `src/pci/pci.zig`). Of course Rust has a bitflags crate but I didn't find it…

On the other hand safe Rust code will be memory safe..

Same for many other languages... as far as memory safety goes because there are performance tradeoffs in a kernel.

Re: Hobby x86 kernel written with Zig

#142
post #113

Earlier quoted context omitted.

It's not interesting to talk about a system that might or might not exist in the future. (There is a word for that—"vaporware".) The point is that Zig doesn't even try to prevent UAF now, so you can't say that it's safer than languages that do prevent the problem. > As an example, instead of soundly eliminating bugs of kind A, reducing bugs of kinds A, B and C -- for a similar cost -- may well be safer. Hasn't this e…

> The point is that Zig doesn't even try to prevent UAF now I wouldn't say Zig exists at all right now, but just as it strives to one day be production-ready, it strives to prevent use-after-free. Safety is a stated goal for the language. > Hasn't this essentially been what C++ has been trying for memory safety for decades, without success? No. I'm talking about a mechanism that can detect various errors at runtime,…

> Rust, BTW, doesn't entirely guarantee memory-safety, either

> We always make some compromises on soundness; the question is where the sweet-spots are.

Excellent point. There are complex tradeoffs and the "rust is safe" slogan is just a slogan.

Re: Hobby x86 kernel written with Zig

#143
post #38

Earlier quoted context omitted.

On the other hand safe Rust code will be memory safe..

not if you have to keep using unsafe blocks.

Unsafe blocks don't mean it's unsafe: just that the language's safety scheme can't prove anything about that particular block. You prove each safe externally with Rust's safety handling everything else (i.e. majority of the code).

You can also go further like I did here:

https://news.ycombinator.com/item?id=21840431

You're still worrying about a smaller portion of your code.

Re: Hobby x86 kernel written with Zig

#144
post #58

Earlier quoted context omitted.

yes, that's the point i'm making. saying "if you write your kernel in rust, it will be memory safe" is a little goofy, because writing kernels in rust requires you to drop into unsafe blocks way too often.

The ammount of unsafe blocks is pretty small compared to the rest of the code. Which means those parts can be reviewed more extensively. If anything your argument is pretty goofy.

What I find is that, while Rust unquestionably improves the security of software, the argument that you can minimize unsafe code and thoroughly inspect it doesn't tell the full story, because in my experience people end up writing general-purpose unsafe blocks, and while they are controlled by the "safe" outside, the sequence of actions the "safe" code tells them "unsafe" code to execute can lead to subtle bugs.

Re: Hobby x86 kernel written with Zig

#145
post #91
post #64

Earlier quoted context omitted.

C is portable assembly, I’d recommend learning it together with the assembly for the platform you’re learning on, so you can actually understand the stack, heap, calling conventions, etc.

C is portable assembly until it isn't: - no access to carry/overflow flag in registers making it a chore to write bigint libraries - no way to guarantee emitting add with carry or sub with borrow even though those are simple instructions and some architecture (6502) don't even provide a normal add/sub - need to drop down to assembly to implement resumable function/fibers to avoid the syscall costs of ucontext/setjmp/…

Precisely my point - learning both together as they compliment each other instead of C abstracting the underlying computer away.

Re: Hobby x86 kernel written with Zig

#146
post #122

Earlier quoted context omitted.

> No. I'm talking about a mechanism that can detect various errors at runtime, and is turned on or off for various pieces of code and/or for all code at various stages of development What you are describing exists: ASan. We have a pretty good answer to the question "is ASan sufficient to prevent memory safety problems in practice": "no, not really". > Rust, BTW, doesn't entirely guarantee memory-safety, either, when…

> We have a pretty good answer to the question "is ASan sufficient to prevent memory safety problems in practice" That is not the question we're interested in answering, and elimination of all memory errors is no one's ultimate goal, certainly not at any cost. By definition, unsound techniques will let some errors through. The question is which approach leads to an overall safer program for a given effort, and soundn…

P.S.

> Notice that the working approaches have something important in common: a strong system that, given certain assumptions, guarantees the lack of memory safety problems.

That's a very good point and I'm not arguing against it. It's just that even if it's true -- and I'm more than willing to concede that it is -- it still doesn't answer the question, which is: what is the best approach to achieving a required level of correctness?

The "soundness" approach says, let's guarantee, with some caveats, certain technical correctness properties that we can guarantee at some reasonable cost. The problem is that that cost is still not zero, and my hypothesis is that it's not negligible. My personal perspective is that Rust might be sacrificing too much for that, but that's not even what has disappointed me with Rust the most. I think -- and I could be wrong -- that Rust sacrifices more than it has to just to achieve that soundness, by also paying for "zero-cost abstractions," which, for my taste, is repeating C++'s biggest mistake, namely sacrificing complexity for the appearance of high-level abstraction that may look convincing when you read the finished code (perhaps more convincing in Rust than in C++), but falls apart when you try to change it. Once you try to change the code you're faced with the reality that low-level languages have low abstraction; i.e. they expose their technical details, whether it's through code -- as in C and Zig -- or through the type system, as in Rust. Zig says, since the abstraction in low-level languages is low anyway (i.e. we cannot really hide technical details) there is little reason to pay in complexity for so-called zero-cost abstractions.

Language simplicity goes a long way, even as far as sound formal verification is concerned. For example, there are existing sound static analysis tools that can guarantee no UB for C -- but not the complete C++, AFAIK -- with relatively little effort. It's not yet clear to me whether Zig, with its comptime, is simple enough for that, though.

It is my great interest in software correctness, together with my personal aesthetic preferences, that has made me dislike language complexity so much and made me a believer in "when in doubt -- leave it out."

Re: Hobby x86 kernel written with Zig

#147
post #91
post #64

Earlier quoted context omitted.

C is portable assembly, I’d recommend learning it together with the assembly for the platform you’re learning on, so you can actually understand the stack, heap, calling conventions, etc.

C is portable assembly until it isn't: - no access to carry/overflow flag in registers making it a chore to write bigint libraries - no way to guarantee emitting add with carry or sub with borrow even though those are simple instructions and some architecture (6502) don't even provide a normal add/sub - need to drop down to assembly to implement resumable function/fibers to avoid the syscall costs of ucontext/setjmp/…

need to drop down to assembly to implement resumable function/fibers to avoid the syscall costs of ucontext/setjmp/longjmp

Which syscalls would be involved in setjmp/longjmp?

Re: Hobby x86 kernel written with Zig

#148
post #91

Earlier quoted context omitted.

C is portable assembly until it isn't: - no access to carry/overflow flag in registers making it a chore to write bigint libraries - no way to guarantee emitting add with carry or sub with borrow even though those are simple instructions and some architecture (6502) don't even provide a normal add/sub - need to drop down to assembly to implement resumable function/fibers to avoid the syscall costs of ucontext/setjmp/…

need to drop down to assembly to implement resumable function/fibers to avoid the syscall costs of ucontext/setjmp/longjmp Which syscalls would be involved in setjmp/longjmp?

See http://www.1024cores.net/home/lock-free-algorithms/tricks/fi... on ucontext

And for longjmp, Apple source for example https://opensource.apple.com/source/Libc/Libc-262/i386/sys/s.... It does seem like glibc impl doesn't involve syscalls: https://groups.google.com/forum/#!topic/comp.unix.programmer...

Re: Hobby x86 kernel written with Zig

#149
post #6

Earlier quoted context omitted.

> I used to do this in Rust but I switched to zig for maintainability and readability over Rust. Can you expand on this ? I'm asking out of curiosity because I want to learn a "system" programming language (for whatever definition there is to this term). So far I briefly tried Rust and Nim and found the former more difficult to read. I know nothing about Zig, how would you place it between these two ?

In general you'll find that zig is easier to read than Rust (see the first version of this project in Rust [0]) because it's a simpler language. For kernel programming this is even more so the case: * zig has native support for arbitrary sized integers. In Rust I used to do bitshifts, Now I just have a packed struct of u3/u5/u7 whatever (see `src/pci/pci.zig`). Of course Rust has a bitflags crate but I didn't find it…

I looked over zig when it was first announced and really liked the idea, it was just too fresh for me to work with.

But I've always had a mental note to go back once it got a bit more stable because I really do like the ideas behind it.

It sounds to me like it's definitely getting there and that's awesome.

Re: Hobby x86 kernel written with Zig

#150
post #51

Earlier quoted context omitted.

As an ancestor in this thread pointed out: it's hard/impossible to go without unsafe in a kernel. Proof (and they have a policy to only use unsafe when not otherwise possible): https://github.com/redox-os/kernel/search?q=unsafe&unscoped_...

yes, that's the point i'm making. saying "if you write your kernel in rust, it will be memory safe" is a little goofy, because writing kernels in rust requires you to drop into unsafe blocks way too often.

The value is in knowing where the unsafe operations are.

It could be argued that's not a huge value gain since you're so far down the stack, but that's the value of the unsafe keyword.

Post reply on HN