#Nyaux
1 messages Β· Page 36 of 1
yeah
mb
like if u set offset to zero, arent u saying that the 104 bytes of tss are actually iopb
yeah thats what I do
basically saying there is zero bytes in iopb
because the limit is 104
it probably doesnt but im intrigued
a valid tss wouldn't be a cause for a bug
i know
but adding it causes this
π€·ββοΈ
then something else is the problem
most likely
iobp base == 0 would be a bit of a security issue no? because u are prolly allowing some portio in userspace by accident
its fine
yeah that's what I thought too
I just didn't touch it at all before
lol
uint16_t sizeoftss = sizeof(struct TSS) - 1;?
lol
its the limit
so what lol
yea
whats the last commit that works
uhhhh that one
lmao aight
What does SDM say on the matter
sizeof(TSS) -1 doesn't crash my kernel
But I'm setting granularity bit
Yeah it's working
uint64_t constructedlow = ((uint64_t)base_low << 16) | ((uint64_t)base_mid << 32) | ((uint64_t)base_midhi << 56) | ((uint64_t)access_byte << 40) | sizeoftss;
Base mid
why << 32
Ok it's right nvm
because
Somehow everything looks right to me
lmao
Have you tried aligning struct TSS?
To 4
Not sure it will change anything
since it's after lapic_id
i told u its random each boot
Are you sure it's because of TSS?
How do I build this thing
do u have nix
error: 'cc-runtime' is not a Git repository
No
remember
I am pretty convinced this has absolutely nothing to do with the tss
yea same
huh interesting
OK @surreal path WTF
WHATS GOING ON
0xd
what in the fuck is this
That's what I told him to change

its unfinsihed
What in the actual fuck is this

is this the problem wux?
0: v=0d e=0048 i=0 cpl=0 IP=0028:ffffffff80087878 pc=ffffffff80087878 SP=0030:ffff800007b0efb8 env->regs[R_EAX]=0000000000000048
RAX=0000000000000048 RBX=0000000000000000 RCX=ffffffff800efc60 RDX=01000099802c0000
RSI=0000000000000000 RDI=ffffffff800efc00 RBP=ffff800007b0efe0 RSP=ffff800007b0efb8
R8 =0000000000000000 R9 =0000000000000000 R10=0000000000000000 R11=0000000000000000
R12=0000000000000000 R13=0000000000000000 R14=0000000000000000 R15=0000000000000000
RIP=ffffffff80087878 RFL=00000006 [-----P-] CPL=0 II=0 A20=1 SMM=0 HLT=0
ES =0030 0000000000000000 00000000 00009300 DPL=0 DS [-WA]
CS =0028 0000000000000000 00000000 00209b00 DPL=0 CS64 [-RA]
SS =0030 0000000000000000 00000000 00009300 DPL=0 DS [-WA]
DS =0030 0000000000000000 00000000 00009300 DPL=0 DS [-WA]
FS =0030 0000000000000000 00000000 00009300 DPL=0 DS [-WA]
GS =0030 ffff800001998018 00000000 00009300 DPL=0 DS [-WA]
LDT=0000 0000000000000000 00000000 00008200 DPL=0 LDT
TR =0000 0000000000000000 0000ffff 00008b00 DPL=0 TSS64-busy
GDT= ffffffff800efc10 00000057
IDT= 0000000000000000 00000000
CR0=80010011 CR2=0000000000000000 CR3=000000000005a000 CR4=00000020
DR0=0000000000000000 DR1=0000000000000000 DR2=0000000000000000 DR3=0000000000000000
DR6=00000000ffff0ff0 DR7=0000000000000400
CCS=00000001ffff0000 CCD=00000000ffff8000 CCO=SARQ
EFER=0000000000000d00
check_exception old: 0xd new 0xd
1: v=08 e=0000 i=0 cpl=0 IP=0028:ffffffff80087878 pc=ffffffff80087878 SP=0030:ffff800007b0efb8 env->regs[R_EAX]=0000000000000048
RAX=0000000000000048 RBX=0000000000000000 RCX=ffffffff800efc60 RDX=01000099802c0000
RSI=0000000000000000 RDI=ffffffff800efc00 RBP=ffff800007b0efe0 RSP=ffff800007b0efb8
R8 =0000000000000000 R9 =0000000000000000 R10=0000000000000000 R11=0000000000000000
R12=0000000000000000 R13=0000000000000000 R14=0000000000000000 R15=0000000000000000
RIP=ffffffff80087878 RFL=00000006 [-----P-] CPL=0 II=0 A20=1 SMM=0 HLT=0
ES =0030 0000000000000000 00000000 00009300 DPL=0 DS [-WA]
CS =0028 0000000000000000 00000000 00209b00 DPL=0 CS64 [-RA]
SS =0030 0000000000000000 00000000 00009300 DPL=0 DS [-WA]
DS =0030 0000000000000000 00000000 00009300 DPL=0 DS [-WA]
FS =0030 0000000000000000 00000000 00009300 DPL=0 DS [-WA]
GS =0030 ffff800001998018 00000000 00009300 DPL=0 DS [-WA]
LDT=0000 0000000000000000 00000000 00008200 DPL=0 LDT
TR =0000 0000000000000000 0000ffff 00008b00 DPL=0 TSS64-busy
GDT= ffffffff800efc10 00000057
IDT= 0000000000000000 00000000
CR0=80010011 CR2=0000000000000000 CR3=000000000005a000 CR4=00000020
DR0=0000000000000000 DR1=0000000000000000 DR2=0000000000000000 DR3=0000000000000000
DR6=00000000ffff0ff0 DR7=0000000000000400
CCS=00000001ffff0000 CCD=00000000ffff8000 CCO=SARQ
EFER=0000000000000d00
check_exception old: 0x8 new 0xd
Most stable part of nyaux
lmao
surprise surprise when I commented out the unfinished part it works
that and this
i still need to load the kernel registers into a kstack
and then load the userspace registers
It's crashing in ltrw still
oh
In here
what was it
Btw this
TR =0000 0000000000000000 0000ffff 00008b00 DPL=0 TSS64-busy
seems half-sus
It's crashing in late-init
When he's loading other cores
I guess
How do I change how many cores it has

It page faults
fun
a lot
more UB
In memcpy
it shouldnt be
OH REALLY?
yea
Lmfao
In create kentry
Stop blaming it on UB
well ubsan is screaming
You've no one but yourself to blame
Just come work on obos with me
i mean yeah i created the UB
Come unfuck the obos ec driver
im not giving up on my kernel
exact;y
on the BSP
When uUSB
do u even create the local data
uEC
I cant pinpoint where u do
its statically allocated
Already wip by other people
check sched.c
Whom
Nooby
yes the fuck it is
look
look WHERE
That looks like per cpu data to me
yes ik
Whatever happened to normal variable names...
i dont
have we????
sec
Nah
He returns &bsp if he's on the bsp
In get cpu local
oh jesus
He does
thats so cooked
Until you access gs relative data on the bsp in assembly
In arch_create_per_cpu_data()
doesnt get called for the bsp
It does
doesnt
yea ill fix it
but wheres the ub wux
u said u arrived
arch_late_init()
that doesnt get called for the bsp
check limine spec @flat nymph
It does in bootstrap()
What for
Nyaux challenge: Don't have people get confused as shit when they read it's code, level impossible
real
Tbf reading obos' code can give brain cancer
At one point I started adding "Abandon all hope, ye who enter here" to the beginning of some files
void *him = get_some_shit()
void *that = him + 0x78;
x86_arch_specific_random_functionwithsomeungodlylongname(that - 1);
lmao
Yes
lol
no I thought I did
apparently u do some cursed shit with the bsp local
not sure why it wouldnt work like every other cpu local but it is Nyaux so
fair
It casually pagefaults in if (cpu->run_queue == NULL && cpu->start_of_queue == NULL)
yes ubsan catches it
What if I actually set msr in BSP? 
asserts everywhere really help with that btw
yes
yes u agree with me
sure do
LMAO
Although that makes no sense
THAT SHOULD NOT HAPPEN
on the foruth day of christmas nyaux gave to me
5 billion bugs
and the sixth day of christmas nyaux gave to me
Give up
an extra memory bug under the tree
I don't get the pattern
what pattern
ill solve it
but first
we need to solve these bugs
@silver yarrow i see everyone is struggling with the cursedness of nyaux lol
yea i think there may be severe memory corruption
cause otherwise none of this would happen
it has to be memory corruption or something
obos only has minor memory corruption, come work on it instead
some bug in the slab or vmm

please stop trying to get me to give up on my kernel
it will never happen

It is joke
ik
Chill

how does this even happen
That knowledge is only with god
I just shilled for obos in lounge as well
Still waiting for suspend article on osdev wiki
Yeah only prayer can help you now
pretty much π
You know what else can help
what
lmao
@flat nymph can u maybe join vc
i wanna see the bugs for myself
if ur free ofc
Ok
okay
oberrow approved
Actually not oberrow approved, he will curse obos
you might be saying to yourself, "obos is already cursed though"
Or u can uncurse nyaux
it pales in comparison to nyaux
it's variable names:
- bruh
- hi
- shit
- dsfd
- stuff
no thanks
Lol
Mr beast should make a video about hiring every Microsoft engineer to work on nyaux
Can all ms engineers decurse nyaux
impossible task
The condition is they make do with existing code
No rewrites
Lol
Commit message: fix all memory corruption bugs in obos
Lol
master hasn't had code pushed to it since september
UB is the nyauxmaster equivalent of gremlins
its 1am
ive been at this for nearly 6hours
maybe ill js sleep
okay so instead of just sleeping
im gonna debug nyaux all night
maybe ill find something
yea bug my bad bug thats undefined behavior that was caused by me
at this point there has to be some memory corruption going o
n
i want to mcmcmc
end my life

don't
did you not before 

lmao
im still having page faults
but the behavior is consisent now
ubsan is telling me this
so thats weird
BUT HEY
BEHAVIOR IS CONSISENT NOWW!!!
WE GOT CLOSER!!!
infy is asleep lmao
I know
@flat nymph sleep in peace
ive made the behavior consisent
by putting a lock on kmalloc
Race condition
yep
Nice
The shittest thing to debug
literarly
to which im unsure is being caused by
well now we know nyaux code is not impossiblely cursed
just
yk
always put a lock on ur allocators guys!!!
if any function is gonna be access and written to by multiple cpus
put a lock
please
Lock free structures are fun
The Rules Of Nyaux:
- Zero Out Your Pages.
- Put locks on things that will be accessed and written to by multiple cpus.
- thy variable names shall make zero sense
- have the worst most cursed formatting possible
anyways
time to debug this
no
my brain is absolutely fried
from no sleep
no my problem solving is probs shit rn
ngl
time for redbull
lol
when I have a bug thats hard to resolve and it's late i just give up and spend the next day fixing it
that just means your per-cpu data wasnt set btw
it was tho
something funky is going on
but at least its consisent for once
ALL GOOD
WUX WE HAVE GOODNEWS
AND SOME ISH NEWS
GOOD NEWS WE FIXED THE WEIRD INCONSISENTCY
IT WAS THE FACT WE DIDNT HAVE A LOCK ON KMALLOC
BAD NEWS STILL HAVING ISSUES WITH PER CPU DATA BEING NULL
latest in gh?
yep
alright
oh motherfucker
99% sure I figured it out
yeap I got it @surreal path
yeah I knew it
remove that i suppose
I have had this kind of problem before
I'm trolling lol
no because my problem solving is shit ren
plus i wouldnt have thought of that
If it were my kernel I would have thought of it
Because I fixed a problem like that one day ago
to be clear the only data segment u need to load is ss
thanks
ds can be zero
yea we get it ur much more experienced
fs, gs u never touch
like me with women π
just ss
okay
Don't forget cs
zero in ds and es
idk why you would call it reload_CS
okay put zero in ds and cs
its the label for far jmp
He far jumps there
ah
The people at AMD decided it would be a good idea to remove far jumps
the retfq
lol
so this
im in the states for christmas rn so only 7pm for me
eh sure, u could load ds and es somewhere much earlier and forget about it but that works
does it matter?
no
No
okay not worrying abt it
does it matter to my ocd brain? yeap
but ur entire kernel makes my brain want to shutdown for a year to begin with
π
I was here to insult motivate
So yw
Now when nyaux on real he
*wh
**hw
Damn it I can't type on me phone
skill issue
i will run
but after i fix up the scheduler with yk
before that however im gonna nap
sleep*
goodnight
night
I'm sleeping too
π
If this was directed toward me, I am too tired to do stuff anymore
Brain is shutting down
Debugging EC drivers does that to a person
Especially when you do it from 7 am to 9 pm
Drives you nuts
tried impling this
not so great time
thats load ctx into kstack
which runs fine
do_savekstackandloadkstack: ; rdi has thread old and rsi has thread new
push rbp
push rax
push rbx
push rcx
push rdx
push rsi
push rdi
push r8
push r9
push r10
push r11
push r12
push r13
push r14
push r15
test rdi, rdi
jz .skipstore
mov [rdi + 0xB0], rsp ; store into kernel stack ptr the value of rsp
.skipstore
mov rsp, [rsi + 0xB0] ; load from kernel stack ptr into rsp
mov rdi, rsp
call change_rsp0
pop r15
pop r14
pop r13
pop r12
pop r11
pop r10
pop r9
pop r8
pop rdi
pop rsi
pop rdx
pop rcx
pop rbx
pop rax
pop rbp
ret
thats my do_savekstack_andloadkstack
dunno whats going on i know im supposed to be asleep ngl
its 4am
i cannot slerep
π
You only have to save the saved registers
And you throw this away
or maybe not
You have to push the return address into there
morning
no i dont
userspace stack already has its rip set to the threads entry
Add label right after call syscall whatever
In syscall instruction handler
Or some interrupt handler
explain further
why do i need to add a label
also thats not how u spell label

How do your interrupts handlers look
isr_stub_%1:
; Push a dummy error code if a 2nd parameter has been passed to the macro
%if %0 == 2
push %2 ; Push dummy error code
%endif
test byte [rsp + 16], 0x3; Are lower 2 bits(priv lvl) of CS selector 0?
jz .skipswapgs1 ; If they are 0 (kernel mode) then skip swap
swapgs ; Otherwise swapgs in user mode
.skipswapgs1:
push rbp
push rax
push rbx
push rcx
push rdx
push rsi
push rdi
push r8
push r9
push r10
push r11
push r12
push r13
push r14
push r15
; push gs ; Save previous state of segment registers
; push fs
push %1 ; Push the interrupt number
mov rdi, rsp ; put value of stack pointer into paramter 1 of c interrupt handler
mov rax, [idt_handlers + %1 * 8]
; Get the registered handler to call
cld ; Required by the 64-bit System V ABI
call rax
mov rsp, rax
add rsp, 8 ; skip int number
; Restore previous state of segment registers
; pop fs
; pop gs
pop r15
pop r14
pop r13
pop r12
pop r11
pop r10
pop r9
pop r8
pop rdi
pop rsi
pop rdx
pop rcx
pop rbx
pop rax
pop rbp
test byte [rsp + 16], 0x3; Are lower 2 bits(priv lvl) of CS selector 0?
jz .skipswapgs2 ; If they are 0 (kernel mode) then skip swap
swapgs ; Otherwise swapgs in user mode
.skipswapgs2:
add rsp, 8 ; Skip error code
iretq
%endmacro
like this]
and also i realized why it page faults
because theres still values that wern't popped off the kstack
this
No
yea
Because you don't push return address
the stack is therefore corrupted
i do
Where
iretq?
isr stubs
wut
What do those functions doo
you literally pop those
here
no cause i also push kstack
bru
#if defined(__x86_64__)
struct StackFrame arch_create_frame(bool usermode, uint64_t entry_func, uint64_t stack)
{
if (usermode)
{
struct StackFrame meow = {.rip = entry_func,
.rsp = stack,
.cs = 0x40 | (3), // USER CODE
.ss = 0x38 | (3), // USER DATA
.rbp = stack,
.rflags = 0x202};
return meow;
}
else
{
struct StackFrame meow = {.rip = entry_func,
.rsp = stack,
.cs = 0x28, // USER CODE
.ss = 0x30, // USER DATA
.rbp = stack,
.rflags = 0x202};
return meow;
}
}
#endif
Why
Where do you push retrurn address
That's not it
wdym
yea
yea
This
What do you have on stack?
- userspace rip, rsp, cs, ss, rflags
- userspace registers (rax - r15)
====== - a bunch of C shit which calls do_savekstackandloadkstack
====== - return address which called do_savekstackandloadkstack
- kernel registers which you save
(again, this only needs to save the saved registers, but that's besides the points)
calls in order
yes
What you push:
- userspace registers
- return address? no
- kernel registers
Where are you expecting this to return in ret?
into sched
Wtf is mov %rsp?
debug purposes
First ```x86asm
do_savekstackandloadkstack: ; rdi has thread old and rsi has thread new
; do_savekstackandloadkstack(Thread *old, Thread *new)
push rbx
push rbp
push r12
push r13
push r14
push r15
mov [rdi + 0xB0], rsp ; store into kernel stack ptr the value of rsp
mov rsp, [rsi + 0xB0] ; load from kernel stack ptr into rsp
pop r15
pop r14
pop r13
pop r12
pop rbp
pop rbx
ret
mhm
Second ```c
const size_t saved_stack_size = sizeof(long)*6;
void load_ctx_into_kstack(struct thread_t t, struct StackFrame userctx)
{
t->kernel_stack_ptr -= sizeof(struct StackFrame);
(struct StackFrame)t->kernel_stack_ptr = user_ctx;
t->kernel_stack_ptr -= sizeof(void);
(void)t->kernel_stack_ptr = return_from_kernel_in_new_thread;
t->kernel_stack_ptr -= saved_stack_size
}```
third ```x86asm
return_from_kernel_in_new_thread:
pop r15
pop r14
pop r13
pop r12
pop r11
pop r10
pop r9
pop r8
pop rdi
pop rsi
pop rdx
pop rcx
pop rbx
pop rax
pop rbp
test byte [rsp + 16], 0x3; Are lower 2 bits(priv lvl) of CS selector 0?
jz .skipswapgs2 ; If they are 0 (kernel mode) then skip swap
swapgs ; Otherwise swapgs in user mode
.skipswapgs2:
add rsp, 8 ; Skip error code
iretq
this is the defination of stackframe
Yes
i see what ur trying to do
Well, add it
return_from_kernel_in_new_thread is that function address?
This is a general idea of what you should have
Yes
Also, you have to swap the kernel stack
But you can do it from C
so ur not exactly saving the kernel stack garbage in load_ctx_into_kstack
What
as in\
krnctx
wdym, we are clearly swapping stacks here
I mean in TSS
yea ofc
i mean we are not doing anything about krnctx or whatever tf
Idk
what about the userspace registers
oh nvm
You load them here
so when we ret, we go into return_from_kernel_in_new_thread
that makes sense
hold on while i implement this stuff
what is saved stack size
and why are we
t->kernel_stack_ptr -= sizeof(void*);
Because you push a pointer
For 6 registers that you push
why just those 6 registers
why not more
yk what im not gonna question
Because of calling conventions
yea cause we need those still are scratch registers or wtv
@flat nymph what about syscalls
Change it to be the same as what you have in your structs
ik i did
Like of you push interrupt number and error code, pop those
What about them
You can return to C which could do some extra shit
no its okay
all good
dw
okay im running it
it died

when calling change_rsp0???
no nvm its not even consisent

this is my asm code
global return_from_kernel_in_new_thread
return_from_kernel_in_new_thread:
add rsp, 8 ; skip int num
pop r15
pop r14
pop r13
pop r12
pop r11
pop r10
pop r9
pop r8
pop rdi
pop rsi
pop rdx
pop rcx
pop rbx
pop rax
pop rbp
test byte [rsp + 16], 0x3; Are lower 2 bits(priv lvl) of CS selector 0?
jz .skipswapgs3 ; If they are 0 (kernel mode) then skip swap
swapgs ; Otherwise swapgs in user mode
.skipswapgs3:
add rsp, 8 ; Skip error code
iretq
do_savekstackandloadkstack: ; rdi has thread old and rsi has thread new
push rbx
push rbp
push r12
push r13
push r14
push r15 ; dont ask why these 6 registers only, mr miskakov never bothered explaining
test rdi, rdi
jz .skipstore
mov [rdi + 0xB0], rsp ; store into kernel stack ptr the value of rsp
.skipstore
mov rsp, [rsi + 0xB0] ; load from kernel stack ptr into rsp
mov rdi, rsp
call change_rsp0
pop r15
pop r14
pop r13
pop r12
pop rbp
pop rbx
ret
my schedd code
g
it wont let me post the code snipped
cringe
thats load ctx
that is schedd
i dont get why its dying ngl
im doing everything right?
π
uhh any idea @flat nymph ?
i got none
What's the point of skipstore?
if old thread is null
but thats besides the point
seems to be failing somewhere
Your kernel_stack_ptr should probably point to the top of the stack
Not to the stored location
Same in rsp0
Is 0xB0 the right offset?
where the stack pointer is rn?
yes i counted
No
where it isnt?
kstack + 262144
makes sense
ill have to make 2 pointers in my thread
one for the base
one for the current ptr for yk
Broken rsp?
Yes
yea
or you can put thread on stack
okay so for rsp0 it will have to be base ptr of stack
hold on
and for syscall
You can also probably do call change_rsp0 from C
its good
okay im testing now
IT FUCKING WORKS
IT FUCKINS WORKS @flat nymph

AND IT WORKS PERFECTLY??
YOOOO
Why wouldn't it
WELL THANK YOU MISHKAVO
NOW I HAVE A PROPER
YK
PROPER SCHEDULER IG
OLD NYAUX NEVER HAD THIS BTW
AND THAT RAN BASH
SO
π
also
even tho i got my voice back
i still havent talked
should i talk
it feels so weird to talk
i havent in like 4 days now
@kind root @finite summit π proper saving and loading context that the very first nyaux kernel (which ran bash btw never had)
ANYWAYS
vfs time chat?
the fun part now

oh wait
before that
interrupt controller like APIC
i need to get working
i also might need a hashmap
i will port a library
somehow
What does that mean
okay so
in all previous nyaux schedulers
there was no actual switching out of rsp0, or saving kernel registers and stuff. it was just *stackframe = thread->frame
now we actually have proper shit
as all schedulers have
with every new nyaux feature comes 50 bugs
lmao
(per each line of code written)
and 5 days of debugging
lmao fr
π
just for some nerd to tell him he did it wrong
and it should be done this way
and not that way
anyways
i will port a hashmap library after i play some roblox
because is christmas
you can copy+paste the one I copy+pasted
if you want
but why does the lapic need a hashmap??
ioapic or lapic?
oh
why not just have a linked list
how else am i getting my timer interrupts??
idfk
of madt ioapic redirection entries
also stupid and un needed
you register a GSI once in a blue moon
is funny 
anyways i go play roblox, ugh the smell of pizza CAN SOMEONE JS TAKE MY PIZZA LIKE SERIOUSLY
WHY DOES MY DAD WANT IT IN MY EROOM
IF IM NOT GONNA EAT IT TIL TMRW
π
bro i get hes trying to get me to eat more but
come on
btw you mean madt ioapic redirection entries, right?
good
you're nyauxmaster, you do the most cursed stuff sometimes
aim high
so omar will be forced to play portal 2 co-op with me
because obos will also be able to run it
I will be dead by then

i think half life 2's source code is leaked
so u can probs compile that and somehow port that
maybe one day
*an array, there are at max like 16 or whatever the number of isa irqs is
and when will portal 2's source code get leaked
so i can port it
π‘
smh
just use a glibc compatible libc
you need to get 1-1 binary compatibility
like hzlibc
its not binary compatible with glibc tho
with linux
fair 
you need to make nyaux linux
i am not using some obsecure libc tho
hzlibc 
*obscure

π‘
it even runs factorio (though you cant share saves between factorio ran on glibc)
lies
prove it
anyway you could port wine
probs
lol
proof?
There are a lot of functions still to be implemented
I have sent scs of it somewhere
make it easy to port
yeah likely no with the amount of sysdeps it requires
so if I port it to obos, I get factorio?
yea

does it run bash
yes
fake not real
about stuff like xorg I am not sure, I should do LFS with it again and get that far
u could probs get factrio on mlibc
ngl thop
someone get linux on mlibc
to test this
do lfs with mlibc 
yes you can and I have done that (though it needs a preloaded compat lib)
preloaded compat lib?
wdym
already exists
lol
chromium ran on mlibc linux first
yes!!!
well some mlibc stuff is incompatible with glibc (like the pthread struct sizes) so you have to override them with ones that are https://github.com/qwinci/mlibc-glibc-compat
peak roblox gameplay
maybe ill have that working with nyaux
these sysdeps look like they were taken straight from linux' syscalls
shit wrong reply
meant to reply to this
I mean some of them are for implementing linux specific libc fns
but then there is just posix stuff that mlibc also has sysdeps for
I will try porting glibc stuff eventually
through linux compat
imagine factorio on your OS 
I would get ~1 fps
then @elder shoal can waste his time doing factrio in nyaux instead of doing astral work

I wonder if the bottleneck is llvmpipe or managarm
you can def get more out of llvmpipe, on linux I got like double that (I don't exactly remember how much tho, might also have been slightly more than that)
is the perf still shitty if you turn off vsync
Nyax with factorio before gta 6
also, what do the profiles look like


