#Zinnia
1 messages · Page 3 of 1
dead os
real
i might be stupid
[ 23.019718] [ 1] thread: Forked thread 1, new ID 2, IP at 0x000000004101319F
[ 23.020710] [ 1] process: Forked process "/bin/ash", new pid 2
[ 23.021368] [ 1] syscall: User program is calling "waitpid" (42)
[ 23.022052] [ 1] syscall: User program is calling "sigsuspend" (43)
[ 23.022793] [ 1] sigsuspend: Waiting...
[ 23.023470] [ 2] vm: Page fault:
[ 23.023896] [ 2] vm: Attempted to access 0xFFFFFFFFFFFFFFFF (ip: 0xFFFFFFFFFFFFFFFF)!
[ 23.024790] [ 2] vm: - Page was not present
[ 23.025278] [ 2] vm: - Fault was caused by a read access
[ 23.025899] [ 2] vm: - Fault was caused by the user
[ 23.026458] [ 2] vm: - Fault was caused by an instruction fetch
[ 23.027136] [ 2] process: Killing PID 2
why would it jump to 0xFFFFFFFFFFFFFFFF
maybe this is an mlibc thing?
wouldn't it print a message then?
♫ 99 little bugs in the code ♫
♫ 99 little bugs ♫
♫ take one down, patch it around ♫
♫ 137 little bugs in the code ♫
i WILL be losing it
when i get back i'm going to finish the port to xbstrap
no more cursed rust builder
we are so back
i've finally fixed the toolchain issues (partially skill issues on my end)
i'm currently moving everything over to xbstrap
i might need some help with image building support (loopback etc)
but otherwise it's lookin good
okay fuck it i'm already using linux abi headers might as well use the linux option
yoooo okay everything finally builds
i also have image building set up now
so the xbstrap changes cango into main branch as soon as the xbstrap PRs are merged
udrm!!
oh yea
loading module at 0x0000000000000000
yea that's correct
those are built in modules
so base address is 0
more optimizations :DDD
💔 clang-format
lmao
btw where can one make this
search for locket gif generator
my sanity has deteriorated even further
building rust with meson is another level of autism i didn't think was possible
why do you even build rust with meson lmfao
cargo crates are ultrakanker to integrate with C/C++ projects
also you need a bunch of extra flags that a makefile would do otherwise
even redox can't use cargo lol
depends on whether if you're doing a little rust with your c or a little c with your rust
and c++ is worse than c for this
a little C with your rust is wayy easier than a little rust with your C
adding rust to an existing codebase is quite hard
ok cool i just wanted to put this out here to clear any confusions
if you want you can take over flanterm-rs
i want to maintain it later but i can't rn
and it's build script is borked as hell
it thinks it needs to rebuild every single build which is not good for reproducability
it would be a good learning experience with bindgen and stuff
oof
that's a me skill issue tho
and since there is no user other than me
I didn't fix it
you could make it good enough to upload to crates.io
if u want
Didnt even know __FILE__ and such existed
Ewwww, C++
What does that do anyway
it's like macros but cooler
autism
are you rewriting menix in rust?
iirc it's a microkernel now™️
minix
holy
minix 2
yes
wasn't menix already in rust?
macros ftw?
why do you need an internal module?
can't you just re-export everything and not export stuff you don't want re-exported?
that's the point
i reexport it so i don't have to duplicate the code lol
just don't make them pub and make them pub(...)
pub(crate), pub(super) etc.
i don't actually remember if it was super or something else
let me try
yea it was super
i might have overthought it
yea there's some advantage of what you overengineered but
I doubt you actually need that
i probably dont
and non-pub can be accessed by child modules iirc
well, i want to make sure that the structs explicitly reexported are available under that name
i haven't written rust in a few months tho
basically, i want a trait or header-ish thing for architectures
for common behavior
in C i did this through a header and static_asserts
but in rust this makes little sense
rust does have static asserts
not that part
so you can e.g. make sure PAGE_SIZE isn't bogus if that's what you need
i mean, having a declaration of common behavior
like this
it's a bit cursed here because while this works, i need to always import both the impl and the trait
i'd like not to
i doubt you actually need this, if init() and stuff weren't implemented it wouldn't compile
when something used init() it would be an error
true
it is yes
are you gonna have arch singletons lmao
no lol
they're static fns after all
i guess i wanted to make sure the functions are there and have common documentation? not sure what my motivation was
this is from my old old rust attempt from 2023
what I do is just make them normal functions (not associated functions)
hmmm for documentation
because it shows up nicely in rustdoc
you could import a common markdown file with #[doc = whatever]
real?
yea doc comments are syntax sugar for doc attributes
interesting
idk if you can like
create an doc/arch.md or whatever then import only a piece of it
if that's possible that's what you want
otherwise you would need to have separate files for each
e.g. doc/arch/early_init.md
oh shit that's a thing?
literally what i need
this definitely is
and if it's not a thing you can make a thing
proc macros ftw
just make a proc macro similar to include!() but parses markdown headers and allows you to include a section
then you can #[doc = include_section!("path/to/arch.md", "early_init")]
or you could make an attribute macro
okay maybe a little overkill
#[doc_section(arch, early_init)]
or similar
yea maybe
but this is a good crate idea tbh
maybe a full blown preprocessor
you know how some documentation stuff let you do SECTION:whatever ENDSECTION:whatever in comments for hiding or showing parts of the code block
we could preprocess similarly
???? what was i thinking here
this is literally what CommonPageMap was for
why was this a different struct
okay all that stuff is gone now
@uncut jackal would you know how i best do TLS?
in C i had a fixed size array
thread local storage or transport layer security?
the former
this might not be the smartest way
i have a box which i leak and convert to a pointer during init
tbh idk lol
redox isn't the best place to check how stuff is done
not because it's bad, but in my experience it isn't really easy to navigate
hmm
i mean
i could also do a per cpu allocation
as in, instead of using the id as an index, i'll just store a pointer to the struct
so i can reference it
yea i'll do that
info() is insanely UB btw
this, except without mut
but then i can't modify it :(
you have to raise the IRQL to mess with per-cpu data correctly anyway
so you can make "raise irql" give you an "irql raised token" valid only for the lifetime of the scope which has a raised irql
and then you can define a "percpucell" which is !Send and also can be turned from &T into &mut T if you have that special token
huh
and why do i need that
you need it for correctness anyway?
like you cant mess with per-cpu state unless preemption is off
i can tho?
define can
or do you mean i shouldnt
you cant do it in a way that preserves correctness
you cant touch per-cpu state with preemption on
if you do, rustc reserves the right to make your code rm -rf /
all this needs to store is callback functions, active thread and stack pointers
because its a data race
this is a thing in C too i dont know why you are so surprised lol
i've never used irqls :P
it just worked
dunno what they are
the only thing that actually wrote to the per cpu block was the scheduler
okay but you read from it outside of the scheduler?
yes
well that is invalid
and a data race
because you could be preempted in the middle of the read
huh
and then the scheduler messes with the state
??? crazy surprising osdev knowledge: data races are a thing! and you need to turn off preemption before reading stuff that preemption writes!
oh that's what you mean
yes
u have an example?
uh
struct PreemptionOffToken<'a> { _p: PhantomData<&'a ()> }
struct CPUCell<T> { data: UnsafeCell<T> }
fn without_preemption<F, R>(f: F) -> R where for<'a> F: FnOnce(PreemptionOffToken<'a>) -> R {
assert!(preemption_is_on());
disable_preemption();
let v = f(PreemptionOffToken { _p: PhantomData });
enable_preemption();
v
}
impl<T> CPUCell<T> {
fn get<'a>(&'a self, tok: &'a PreemptionOffToken<'a>) -> &'a T { /* SAFETY: somoene on discord told me this is fine */ unsafe { &*self.data.get() } }
fn get_mut<'a>(&'a self, tok: &'a mut PreemptionOffToken<'a>) -> &'a mut T { unsafe { /* SAFETY: see above */ &*self.data.get() } }
}
something like this
ah with phantomdata
okay i think (?) i'm ready to start booting again
after trying to reconstruct my early kernel from years ago
we are so back
getting further
i think im starting to understand what this does? where is without_preemption supposed to come in?
is it similar to what the spin crate Mutex does?
where you do a lock() and as long as it doesn't get dropped you don't get preempted
the spin crate mutex doesnt do that tho?
ah sorry i put two sentences into one
I meant you do a lock and get a context
not the preemption part
without_preemption is how you'd turn off preemption if you want to access CPUCells
so for example I'd do
without_preemption(|x| x.get().runtime += 1);
did i get that right?
you'd do without_preemption(|token| cpu_cell.get_mut(token).runtime += 1); according to the code
or x for short
that's actually a really cool thing to do
i did the same thing and now i can verify the ipl in PerCpu::get
but i might write this shi in c++
i dont like rust
my code is 95% ub rn lol
lol
In some cases per cpu counter manipulation could be done without ipl modification
It depends on the counter and whether the arch has appropriate atomic op
yea in that specific example
i use the cpu struct to store the currently running thread, so i assume I'd have to disable preemption for the entire time i do anything with the thread
that is UB
if you give out a &mut at least
that is only okay if you give out &T
yeah, it's inspired by ghostcell
how is it ub to give out a &mut T
isnt it ub to give out a &mut T twice
consider ```rs
raiseipl();
let a = PerCpu::get();
let b = PerCpu::get();
*a = 123; // welcome to rust UB land!
actually the UB might only be if you write to BOTH at least once
yeah this is the problem with rust
the rules make it really hard to write ub-free code in a lot of cases
without putting expensive locks around everything
if you can atomically load "current cpu's thread pointer" then you needn't disable preemption
oh btw i have seen a new interesting way of implementing something like RCU
but not really
on amd64 e.g. a %gs-relative mov with offsetof(struct cpu, thread); on aarch64, an x18 relative load; on risc-v, a tp relative load
struct GlobalState {
value: AtomicPtr<T>,
lock: Mutex,
}
struct State {
last_known: Ref<T>,
}
fn load(s: &mut State, p: &GlobalState) {
if p.value.load_relaxed() != s.last_known.ptr() {
p.lock.lock();
s.last_known = Ref::from_ptr(p.value.load_relaxed());
p.lock.unlock();
}
s.last_known.clone()
}
roughly
yeah which is the reason why i realized i should give up and use c++ instead
lets me write cool stuff like that but with less implicit ub
would something like this work too?
//Pseudo
struct Cpu { ... }
trait Preemptible<T> where T: Drop { ... }
impl Drop for Cpu { ... }
static FOO: Preemptible<Cpu>;
fn do_stuff() {
let cpu = FOO.get();
cpu.thread = next_thread;
}
so now i give you one shot to guess why im rewriting shkwve in C++

T: Drop is a meaningless bound
do you want to express "has nontrivial drop glue"?
i guess
wtf is Preemptible
hm
would Preemptible::get make sure u can access it without being preempted or what
i'd prefer the way mutex acquiring is done
in which case just have a without_preemption
as in, the preemption is disabled until the thing is dropped
yeah that works too i think?
because otherwise i'd be writing functions that consist of only lambdas
also thats not a huge problem
i dont like it 
struct PreemptionOffToken { _p: () }
impl Drop for PreemptionOffToken {
fn drop(&mut self) { enable_preemption(); }
}
impl PreemptionOffToken {
pub fn get() -> PreemptionOffToken { assert!(preemption_is_on()); disable_preemption(); PreemptionOffToken { _p: () } }
}
cpucell remains as before
note that that assert is required for UB-free operation
thank you
you could also just put the current thread pointer in fs/gs (x86), x18/tpidr_el1 (arm), tp (riscv)
on risc-v, isn't that what sscratch is for?
saving stuff after exceptions
because you need at least one spare GPR
the x86 solution is TSS
the arm solution is letting you switch stacks
the riscv solution is to give you a special csr
speaking of, is R/W on a CSR slower than a normal register access?
same question with MSRs
yesn't
on x86 some MSRs are serializing some aren't
similar story on RISC-V probably
i think all MSRs are serializing?
i'm 99% sure that TSC deadline isn't
thats an msr?
yeah?
wtf
isnt it?
i thought its mmio
you write some value to the APIC LVT register
but i am pretty sure you poke an MSR to reconfigure it
ah yeah but you dont reconfigure that often
you do poke an MSR to reconfigure it
reconfigure = change the deadline
and i'm pretty sure that MSR does not serialize
relevant material from the intel spec if you're interested
im feeling this so much right now
it's a huge pain
oh shit
i also have to port the standard library for userspace, don't i
i hate everything
maybe i need to overthink my system architecture
hm
what about a microkernel with one big userspace component
you can if you really want to
or you can write your own wrappers
but if you want to use all the cool crates and already built tools then yeah, you need std
good thing is that if you plan to be posix/have posix server then your life is significantly easier
yes that's the idea
exactly
kinda defeats the point
i think this is a sign to just stick to C
i already have that ported and with userspace
indecisiveness is a curse
i don't want to pour in infinite amounts of time and effort
i just want to get it working :P
good mindset
it's just a hobby project after all
good thing i didn't commit anything yet
i will switch from cmake to meson though
working with other projects made me like it more
yea meson is based af
i love it
meanwhile cmake makes you modify internal variables
i also managed to make some projects unable to build with Unix Makefiles
lmao
lol
but on the other hand
meson only accepts their author's ideas of how a build system should work
everything lol
cmake lets you mess with internal variables at least
in meson, there is the author's opinions, and there are your opinions which are definitely exactly the same as the author's
like for example
you dont need functions
right?
the meson authors think you dont so you will not have them
you can get away without functions just fine
is it annoying? yes
but is it a dealbreaker? absolutely no
the point is, the same pattern extends to all of meson
the authors decided you don't need to do something
so you don't
nah
my scuffed ass go-based build system is great
its now in its second generation!
cmake is the thing you want for cursed setups
literally
you use -T linker.ld
i use -T obj/link1-nhkru934bvi7va5rgg2g1dusjju52rfe3kme0quv53lha.lds
we are not the same
i mean before in cmake i had a whole ass option/dependency tracking function
best linker script ever!
dont mind all of the spaces that's a side effect of go's templating engine

are you laughing at my use of a template engine to make my linker script????
why would u do that even
so i can generate the linker script programatically?
because a bunch of it depends on config options lol
cursed
nah
yuh
for example the load base
but whatever floats ur boat
is a config option
no thats cringe
i mean it is
config option is better
.
i do
you do what
server side linker script rendering
thats a thing in linker scripts?
mold doesnt have linker scripts tho
it does
just very rudimentary support
ah i see
it doesn't support most features
based
wtf
yeah no
ill stick to gotemplate
it works
why is that a dealbreaker lol
fair
the authors decided I can't control environment variables that meson passes to tests
the authors decided I replace a shared library's runpath, I can only append
I don't want it to pass LD_LIBRARY_PATH
if i set it myself, it prepends it's own entries
if I use environment() and unset() it, meson errors and says it can't be unset
they literally made it impossible to unset i don't get it
ig they don't want dynamic linker tests
i think its just programs that meson executes for u
if it exists with non-zero it means the test failed
and it prints stderr when it fails
i think that's it at least
you don't need to generate your linker script to be able to set this from a config option:
// config.S
.globl __load_base
.set __load_base, CONFIG_LOAD_BASE```
```ld
. = __load_base;
yeah, a symbol defined with .set doesn't belong to a section either so you don't have to worry about relocation etc
or ofc you can just run your compiler's preprocessor on the linker script
ok that is cursed lmao
yeah, or i can run it through go text/template
why did it time out entering acpi mode
also i guess u dont call uacpi_namespace_initialize?
u should
when
after load
and also finalize_gpe_initialization
btw is it expected that it times out?
not really
is you impl for io in/out correct
it doesn't in qemu
probably not lol
we could take a look at the fadt dump but yeah
lol
tbh it's non-obvious
yeah
like it's possible to approach this and think that the author of uACPI got lazy and decided to write io instead of mmio
there should be a comment
is this for uDRM development?
it's more or less a prerequisite
i'll be able to focus on udrm until at least the start of march

nice
POV: you're getting fucking destroyed
I actually pulled through and got somewhat far with the microkernel rewrite
tomorrow is ELF loading time
then i should already be in user space
Nice
@grave peak is there already a rust kernel with uacpi support?
i am not aware of any, but maybe i missed something cool :^)
@idle flower's WIP kernel i think
Soon TM
how far is it
because menix might be the first one to run uacpi-rs then 
i'm in user space now and my servers can communicate
idk if i want to put uacpi in user mode
Still writing code for the kernel
With my current progress it might take a few months
Likely
I don't see why you wouldn't
i may need firmware configuration before user mode
like madt, hpet, etc
still
i need the tables before user mode
sure, i can delegate power management and so on to user space, but there are some parts that i need in the kernel
I will have one in kernel and one in userspace, the kernel one will only supply tables for Numa stuff, ioapic, hpet and the userspace one will actually run aml and be part of bus/device enumeration
are you going to implement the bare bones mode as a feature?
UACPI_BAREBONES_MODE in kernel, and the full thing in userspace
Yes as a feature flag
it's not even a thing in master yet 
merge when
this week
based
but your kernel is rust as well right
yes
so for you it's soon ™️
i mean i can probably PR some changes in if @idle flower doesn't have the time

I am still a bit stuck on type.h, once that's cleared the most stuff should be easy
Except handlers
what exactly?
Object stuff like create, assign
ah
And if I should make certain conversions infallible either with ub or panic
For enums
pls no ub
That's what I thought
It would then panic if uacpi supplies invalid enum values
Like ones that aren't defined
I can push my wip to dev1.0 in a few hours
thx
i sitll wouldnt do that tho
importing 30k lines of code for something that can be done in 500
it compiles out all other code
so its really 500 lines
if u have it in userspace anyway u can reuse the same submodule
importing 30k lines of uacpi instead of doing table enum in 500 lines urself
but as infy said
incremental compilation + lto + its all ifndef’d away
well the crate is already there, so might as well use it lol
actually incremental compilation wont do shit its a different set of flags
but lto + barebones mode still
i dont think it needs lto, literally every .c file is completely ifndef'ed
and most of table.c as well
well barring e.g. vsnprintf
yep that makes perfect sense
i know i wouldnt handroll table parsing because im lazy 
its like 50 lines of c++ with templates
not that bad
but table type definitions bleh
i hate writing struct definitions from specs
yeah at the very least u could #include <acpi.h>
same
Undefinded reference 
?
AmlUndefindedReference
where?
cool
@idle flower wyd in vc
in case you have questions
lol
im now at version 3 on how to write pageing code
i can show you version 1, it was the reason why i needed bigger monitors
afk for the next ~15mins
Menix
im back
in a positive way?
i can give you my pageing code if you need more confusion
lol
i have done paging in C already
i just need to translate it to a generic interface
there was this one templated c++ version by fadanoid which looks cool
but im too lazy to look fo0r it
from:fadanoid gist.github.com
just earch that ig
okay i'm puzzled
i think my linker script is correct
it's the same one from the C version
but printing them in order yields this trash
nvm i'm a brainlet
i know exactly what mistake you made and i dont blame you lmao
enlighten us lol
he was using the linker symbols as values?
i thought it was obvious enough with them being of type VirtAddr lol
"called `"
yeah for those symbols you need to get their address, they aren't addresses already
i think he figured it out when he said “i’m a brainlet”
lmao
but i dont blame him, it may feel intuitive this way :^)
xd
i had this already figured out but happily ignored it for some reason
yes i did exactly this and then it hit me
v=03 is a breakpoint
huh
yeah i can see now
what could it be triggered by
let me try the debug build
brother what
...
😭 howwwww
also, why does this shit not call my IDT handler?
AAAAAAAAAAAAAAAAAAA
wait no
okay yea
i can ask it to do a software interrupt and it handles it
but it doesn't handle the exceptions
is this a TSS meme?
i don't think i'm doing anything really different than my old C version
it's really weird
cr2 says fffffff8002c600
maybe you're trying to write to that region
it shows it's mapped as read only
it's part of rodata
whats the instruction at that rip
hold on i did a rebuild, let me update the rip
uh
it jumped to the stack it seems 🫠
okay let me just save some stuff
this is the mapping that limine establishes
oh there are actually some differences
i gotta cross reference with the c version
what's the A in info tlb
i think accessed
the humble 0xCC opcode
where do you see that
int 3
my mind
but uh
oh i thought you meant that that thread ran the 0xcc opcode
what the shit is happening
i mean that'd be the source of the breakpoint exception
instruction fetch from present page
but tlb says it can :(
maybe i fucked up the previous levels
i probably did
actually, how do you have to map the previous levels
like, what flags do they get
usually just present + write
i do present + write + (user)
oh yeah also works
this is what you get for rewriting 

can you show the code mayhaps?
which part do you wanna see?
the page table stuff
whats the addr2line of that fault rip
this
hmm off by 4k? comparing the limine mappings to your mappings you start mapping stuff at VA 0x...1000 and limine starts at 0x...0000
ah lol
broooooo
mfwww
yea i think that's the problem
fml
my mapping calc is just broken
ah that's also why it can't call the isr
calc is slang for calculator for those just joining the stream
oh offset does not count in the phdr segment
since it's after + SIZEOF_HEADERS
Is menix being rewritten in rust now
yes

i'm having a mental breakdown rn trying to figure out what the correct logic for the calc is
offset = 0xffffffff80000000 then it's correct?
me when i said that it's due to the headers
progress
riveting
okay so it first faults exactly after writing to cr3
ah yes obviously
that's the second fault address
qemu faults so hard that it resets everything to limine tables???
this is probably an actual qemu bug
that's funny tho
that's probably uefi's doing?
idk
ah yea you're right
limine has a 0 idt
i am going to push this now, but i have 0 clue why it's page faulting
the address it tries to access is regular code and is mapped according to qemu
NOOOOOOOOOOO OMFG
my generic code does if !Exec { flags |= NX }
okay we are back
it works again
that sounds ok tho
it does until it maps all higher levels as NX 
okay we're in user mode again
so about the same state minus all the drivers and uacpi
i should start working on the posix server
About that...

not printing addresses as 0x, upper hex, and padded with zeroes to 8 chars is punishable by law
those are literally physical 💀
yes? that's what i said
lol
especially since it's padded
^
i prefer lower hex because i can see where the letters are :3
so you don't see where the letters are in upper hex?
so you're half blind?
/s
Is there a more elegant way of storing percpu storage than this shit
what is this
yes please give me Mutex<Vec<Box<>>> of something
they have played us for absolute fools
why do you need a mutex on percpu data?
static mutable data
@pine rock this is what i'm doing atm
ough
let me check what i do
well i also enable OXFXSR and OSXMMEXCPT
i check my feature mask against cpuid 0xd ecx 0 and 0xd ecx 1 as well, although idk if you're doing that somewhere else
heres my entire implementation near enough
actually just take the link instead lol https://github.com/apache-hb/BezOS/blob/master/sources/kernel/src/xsave.cpp
linux does some extra stuff with ecx > 2 leafs in cpuid but i think that can be skipped unless you want to use compacted xsave
oh yeah the xsave bit in cpuid isnt set before you set osxsave in cr4
so your cpuid query is stale afaict
actually scratch that
yea i dont care about that tbh
i just get the total size and use that
yeah i'd guess that you're just not setting all the cr4 flags then
your cpuid macro is fucked i guess
incredible
coming back to this
how does everyone else do per cpu storage
i have a PT_NOLOAD section that i put percpu stuff into at link time then use that to fill a per cpu structure and put it into %gs
so you have a fixed amout of cpus?
no i allocate one per cpu area per cpu core lazily during smp startup
probably yes
you can use tls if you want but then you're stuck with fsbase because thats the abi
oh no i don't want to use elf tls
i just don't know how to store it properly in code
as in, i probably want a way to access the data globally, right?
while at the same time being accessible by individual cores
inline asm to do gs relative loads is the normal way
i dont have global access and havent found that to be an issue yet
just have a vec of pointers to percpu storage if you really need it
but how would i do e.g. thread migration
abusing queues probably
i could make a submission queue that idle cpus can check and if it's viable to migrate then it will do it that way
Zst struct with deref impl that uses gs as a ptr
Then instantiate that struct as const and deref it when needing to access it
Can send you my code after work

imo most of it doesnt need to be globally accessible, an exception being a way to run a particular function on another cpu (with an argument or two).
true, i don't actually think i have a use for globally accessible data
i hate my brain
every time i'm "rewriting" this shit i just want to go back to C 😭
just one more rewrite bro
@brisk totem opinion
i do have to rewrite my arch stuff to be more generic
like vmm
Then it's a good thing you use rust now
same thing with rust
why can't rust be more like C in terms of stability 😭
one of the goals is to make something that's small in binary size
and modular
but rust kinda forces me to have neither
fucking hell
Rust without std has large binaries?
Do you do release build?
yes
What symbols?
What's their purpose?
But a kernel should be executable not dylib
Just don't have kernel modules
Microkernel ftw

i mean, my only real goal is to have openrc + weston running
then i can die happy
openrc already half works
but that's mostly because my vfs impl is trash
rewrite menix in c++ 
because it lets you write a much nicer print function, and also gives you namespaces
hm
i was trying to do rust
lol
is it currently C?
C is just too good
yes
ah
C23
even better
personally i prefer clang23 :^)

(i.e. c23 + [[clang::overloadable]])
loll
that's just c+
overloadable is just too good
hm
i never really thought about using c++
i would ignore the entirety of the STL anyways
yeah
nice thing is that you can choose what you want to use from c++
yeah
and write c code with some c++ features
Doesn't rust have namespaces via mod
yes that was vs C not vs rust
my goals with menix are
- modular
- compact (both source/binary)
- easily portable
- async IO
C async is somewhat scuffed
it is
but its doable