Contrast to the hard time I give Rust when it is spammed ontop of layers of C, I am quite interested in 100% pure Rust operating systems. Interestingly the name of your R4R is quite unfortunate because it has nothing to do with Rust as a language!After exploring alternatives like Zig and Rust, I concluded that C remains the most practical, predictable, and hardware-transparent language for low-level system development on 32-bit Intel machines.
This is very interesting. I always assumed that Qemu provided more flexible x86 emulation than VirtualBox but perhaps not. Are there plans to support Qemu in future or does Qemu need to be changed?
- Designed to run on real hardware (i386/i486) as well as emulators like Bochs, or VirtualBox.
- Note: QEMU is currently unsuitable for testing this build due to a known issue with legacy i486 protected-mode task switching.See QEMU Bug 2024806 – “Protected mode LJMP via TSS/LDT fails with pc=nil.”
This is also interesting. So what is your ultimate goal for this? I.e what features of R4R do you plan to provide to demonstrate this?R4R attempts to bring all four rings into play in a coordinated and observable way.
Your link isn't one.According to the question I asked here:
Updated!Your link isn't one.
The original desire and inspiration was to write this in Rust, so the inspiration for R4R originally came from there. My capabilities are not that great now, so I decided to go with C and I'm still not happy with LLVM support for x86_32 because it makes a lot of gaps in the code... I started the project with a burning desire to get Rust people interested if they find this interesting.Contrast to the hard time I give Rust when it is spammed ontop of layers of C, I am quite interested in 100% pure Rust operating systems. Interestingly the name of your R4R is quite unfortunate because it has nothing to do with Rust as a language!
The ultimate goal of R4R is to demonstrate, in a tangible and observable way, how all four Intel x86 protection rings (0–3) can coexist and interact within a single operating system — each with its own stack, TSS, LDT, and clearly defined domain.This is also interesting. So what is your ultimate goal for this? I.e what features of R4R do you plan to provide to demonstrate this?
// Signed types
typedef int8_t i8; // 8-bit signed integer
typedef int16_t i16; // 16-bit signed integer
typedef int32_t i32; // 32-bit signed integer
typedef int64_t i64; // 64-bit signed integer
// Unsigned types
typedef uint8_t u8; // 8-bit unsigned integer
typedef uint16_t u16; // 16-bit unsigned integer
typedef uint32_t u32; // 32-bit unsigned integer
typedef uint64_t u64; // 64-bit unsigned integer
// Pointer-sized unsigned integer (32-bit architecture assumed)
typedef u32 uptr;
You caught that well, it's a completely unnecessary nop here, I missed that when I was testing something in the BOCHS debugger...Nice.
Few years I started my own. But then RL (kids,..) took precedence..
Out of curiosity: why did you put an extra nop in the handler?
When I started my project I hated att syntax. Ended up rewritting everything with att.. I still tend to disassemble with intel one (objdump/gdb/ida..) but less so.
I completely understand your frustration... I just like it this way because this is a completely hardware-dependent system and I want shorter but more precise type descriptions because I liked it when I was programming embedded hardware... I answered you honestly. I haven't used the cppchek analyzer before.Okay, I've read all the documentation, at the end I see your OS on the COMPAQ CONTURA it's way cool. I'm working on a project like yours and I have to thank GPT for helping me too.
Your code is clean and clear; there are still some magic numbers. Don't you use static code analysis (clang-tidy or cppchek) ? I'm disturbed by your typedef for regular types, why you do that ?
C:// Signed types typedef int8_t i8; // 8-bit signed integer typedef int16_t i16; // 16-bit signed integer typedef int32_t i32; // 32-bit signed integer typedef int64_t i64; // 64-bit signed integer // Unsigned types typedef uint8_t u8; // 8-bit unsigned integer typedef uint16_t u16; // 16-bit unsigned integer typedef uint32_t u32; // 32-bit unsigned integer typedef uint64_t u64; // 64-bit unsigned integer // Pointer-sized unsigned integer (32-bit architecture assumed) typedef u32 uptr;