#OBOS (not vibecoded)
1 messages ยท Page 30 of 1
mmm
i could give waitable objects a new field
called interrupted
and check if that was enabled
but again idk that may be stupid too
where is the waitable_header structure defined
i dont have clangd working
and i dont want to bear -- make the project
or whatever build system u use
hold on i have a search feature
found it
omar do u think adding a new field called interrupted is a good idea
i want to check this againist you
whenever u come back let me know
im not gonna touch anything until i know what i am thinking of is a good idea or no, i really do NOT wanna nyauxify obos
code is very well written btw
ill give you this
@thick jolt did you get muted
L
a note: not all waitable objects have use_signaled=true
which causes the signaled field to be ignored
(I really need to document my code)
yea
im adding it
?
oh right
okay but its still complaining
even after i changed it to 0
weird?
why would you have a field with 0 bit width
OHHHH
you can't store anything in 0 bits
you can store nothing in 0 bits
for good reason
well yeah but that's not very useful lol
:p
why so
they're just bad
for stuff like fixed-bit structures
what i could do is just make interruptable true or whatever
signal the object
and then we can check
you're gonna abstract this behind a separate function right?
and not make the user set that field then call signal threads
abort_wait will do this
ah okay
whats the naming scheme for your functions
don't forget to name it in obos' naming convention
you could that as CoreH_AbortWaitingThreads
return type of void correct
obos_status
okay
implement in wait.c pls
wrong
set interrupted to true
then just return CoreH_SignalWaitingThreads(obj, true, false);
otherwise you're repeating code
how is this
look again
whoops sorry
np
in CoreH_SignalWaitingThreads
no
the waitonobject function
I can do wait on objects since that is more complicated
hold on
wrong
what do i do here
just do
if (obj->interrupted) return OBOS_STATUS_ABORTED after the block function is called
how do i test it ๐ญ
on another
where
thread try to acquire it
basically:
mutex mut;
// thread one
acquire(mut)
interrupt_wait(WAITABLE_OBJECT(mut));
// thread two
// calls into wait on object
assert (acquire(mut) != ABORTED);```
in which function
kentry?
sure
okay
do i need to create threads or
oh
sorry
it's np
which place is correct
bottom of the file
oaky
wait if you're gonna make a pull request
how don't you have a fork
afaik that's the only way to pr if you don't have write access
to a repo
just fork it
like bottom bottom of the file
then you can git remote set-url origin link/to/fork
yes
but above the inline asm
around line 860
no, 950
it's really unorganized
here???
.
okay
okay
but unfortunately, my threading api is bumcheeks

// not psuedocode
thread* thr = CoreH_ThreadAllocate(nullptr);
thread_ctx thr_ctx = {};
void* stack = Mm_VirtualMemoryAlloc(&Mm_KernelCtx, nullptr, 0x10000, 0, VMA_FLAGS_KERNEL_STACK, nullptr, nullptr);
CoreS_SetupThreadContext(&thr_ctx, (uintptr_t)thread_entry_here, (uintptr_t)&any_user_data_here, true, stack, 0x10000);
CoreH_ThreadInitialize(thr, THREAD_PRIORITY_NORMAL, Core_DefaultThreadAffinity, &thr_ctx);
CoreH_ThreadReady(thr);
take this snippet
nah you only need one
okay
as you already have another thread: the kernel main thread
Core+Helper
Core+arch Specific
whats the api for creating a mutex
mutex mut = MUTEX_INITIALIZE();```
okay
okay
okay and then call waitforobjects or smthin?
yes
after you acquire the mutex in thread one
which is the kmain thread (where the entry code executes)
then you also must acquire the mutex in thread two
but u said i only needed one thread
maybe it's better to acquire the mutex in thread two first, and abort the wait there
I only said you needed to create one thread
ye
okay brb i might be gone for an hour or 2
sure
how do i get the kentrys mutex
through the user data
you see that one parameter here
yes
i dont have auto complete working so
whats the field im looking for?
okay
no
oh
pass &mut there
wtf rust
huh???????
nvm
know c?
yes
what is the function called
&any_user_data_here is a placeholder
yesa
okay
&mut
and in both threads after having acquired the mutex, add ur interrupt wait function
and one of those waits should fail
like this
with aborted
if you did all correctly
you see where I add thread_entry_here
that's also a placeholder
the one im running in right now?
i havent created 2 threads hiold on
ohhh
nvm i dont understand
im sorry.
wait
do i put test_program into it
probs no
sorry
you are making another thread, yes
for hte other part of the test
?
MAKE THAT THE NETRY POINT
oops caps
lock
mkae the entry point the lock???
Possible spam detected for user: oberrow. Please contact a moderator to be unmuted.
.!unmute @flint idol
@flint idol is not muted.
next time ban
wait really????
oberrow or nyaux not get timed out every day challenge 
your serious?
he's talking to me
oh thank god
I'm not evil
who
void static?
also give it mutex* mut as a parameter
why is the void upper case
static void
thanks
40 stars on obos
because of ur userdata this works
indeed
there
sorry
np
its &mut
my abort_wait
yes
yes
okay
also do the same thing in the other thread you start
acquire+abort_wait
then Core_ExitCurrentThread
also you need to make sure the wait gets aborted properly
by checking the status of acquire
if (obos_is_error(status)) printf("fail");
nop
kk
btw
in mutex acquire you will need to make some changes
when it calls Core_WaitOnObject it never checks the status
okay
acquire it then abort
the idea here is to create two threads racing for the mutex, and the one that doesn't get it first will simply hang acquiring it
okay
yes
yea i understand
and then the one that does get the mutex aborts the other mutex waiting
okay
not quite there yet
obos_status status = Core_MutexAcquire(mut);
and also: WAITABLE_OBJECT(*mut)
okay done
so it should look like:
obos_status status = Core_MutexAcquire(mut);
CoreH_AbortWaitingThreads(WAITABLE_OBJECT(*mut));```
and the same thing on the first thread, but you don't dereference any pointers
okay
to mut
then you compile obos
and in theory, status in one of the threads will be aborted
which you can printf
in arch_kernelmainbootstrap
yup
now you will most likely run into a small bug with mutexes
because acquire doesn't forward the status of WaitOnObject
anyway gtg eat
so lets make someone changes to that
you should be able to figure this out easily
if (status_of_wait_object != success) return status_of_wait_object; // then do the other shit
Gl and godspeed
Why is everything green
idk
okay
making changes to acquire
is this correct @flint idol
wait
no nvm
i have no idea
@flint idol
OOHOHOHOH WAIT
okay
@flint idol
i did this
is this correct yes or no
in acquiring
i think hes gone
hello?
also having these build errors
@flint idol ??????
Gcc version?
13.3.0
Hmm
Try clang
Reconfigure with -DOBOS_USE_CLANG=ON
You need to delete the cmake cache
Tho
rm CMakeCache.txt
rm build/CMakeCache.txt
Can you ls build
x86_64
Oh ok
Now delete it
i did
Do this
And obos will be built with clang
#include <locks/wait.h> at the top of the file maybe?
idk
I do that tho
ur toolchain is cursed
now its just this
you define this in wait.h, right?
i didnt put it in wait.h
well no wonder then
bruh
execute_process(COMMAND x86_64-elf-gcc -print-file-name=no-red-zone/libgcc.a OUTPUT_VARIABLE LIBGCC)
if (LIBGCC STREQUAL "no-red-zone/libgcc.a")
# Use normal libgcc
execute_process(COMMAND x86_64-elf-gcc -print-file-name=libgcc.a OUTPUT_VARIABLE LIBGCC)
endif()```
this is how I get it..
can you run x86_64-elf-gcc -print-file-name=no-red-zone/libgcc.a
and show me the output
hmm
can you go to line 52 of src/build/x86_64/toolchain.cmake and add message("hai")
and reconfigure cmake
after deleting cache
WTH, obos Thor reference
okay
???
Thats managarms kernel btw
ik
This is still funny
@real pecan obos curse
Do this @thick jolt
id did that
there was no hi
Did you reconfigure cmake and delete the cache
yes
Rather, delete the cache then reconfigure the cache
Lol
The beginning
i did
The message should be printed at configure time
OHHH
If it isn't then I have an idea of what the bug is
If it is then I also have an idea of what the bug is
hold on
im like playing cs 2 with streaks and laura, after this match ill do so
its 2-2
Bruh ok
wdym bruh ok ๐ญ
What's your premier rating
Ohh
Btw did you give up on nyaux or smth
Why'd you wanna contrib to obos
Nyaux obos merge when
Lol was joking
news to me
lmao
what happened to rust
L
to which im not giving up
W
nyaux you need rust handholding
add a ++ and then i might agree
Is the right answer
๐ฃ๏ธ GET OUT
C is painful
Skill issue
skill issue
yea exactly what you're having
rust gave you some sort of harness 
I'm thinking about writing stuff in Ada for pmOS
Trust me it was the opposite
-๐ฆญ
Best language
Ada is a W
I know SQL, it should be similar
I wouldn't say that if ironclad weren't written in it
i'd rather use V
Didnt go well for mint
I also had Go runtime almost working...
JVM when
wasm
After I get a disk driver
When uJVM
Lmao
And a shell
uUSB first
Pmos running Minecraft playing on a server running on managarm

Running in QEMU on Linux
Just write the drivers for obos then everyone needs to write shims for the obos driver interface
@flint idol finish pci headers for infy
cp obos/src/oboskrnl/driver_interface/pci.h uAPI/include
Done
fake
Oberrow back then: scared to touch acpi
Oberrow now: first hobby os with S3 suspend
im back
@flint idol
Bruh
Real
i did it exactly
I will be with you in a bit
kk
back
line 50 of the same file, insert this:
message(${LIGCC})
then delete cache and reconfigure
btw, if 9+47 is airplane, and your boat has a flat tire as you fly through the desert, what should you have in your back pocket?
๐ญ
what
wth
i have no fucking idea
well I know the workaround
replace that if line with:
if (LIBGCC STREQUAL "no-red-zone/libgcc.a" OR LIBGCC STREQUAL "")
line 51
@thick jolt
good
if that doesn't work, try replacing the if at line 50 with:
if ("${LIBGCC}" STREQUAL "no-red-zone/libgcc.a" OR "${LIBGCC}" STREQUAL "")
@thick jolt
oaky
while this does lead me to raise the question of why your gcc doesn't have the no-red-zone libgcc, we can ignore that for now
still
can u just compile my changes @flint idol and test them please
okay
then you can pop that in here and I will apply it and test it for you
in the repo root
can you ls in the repo root
don't do that yet
git format-patch HEAD
still nothing
git format-patch HEAD~1
okay i have the patches
send
compiling
kk
good news mr. nyaux man
after fixing a bug in my code
your stuff worked
partially
yeah
I will amend your commit for it to be your github account
then commit my code making the fixes
to the test
although there is a slight problem, sometimes the status for both threads is SUCCESS
oh no

I will debug that
okay
bruh
if (obj->interrupted)
return OBOS_STATUS_ABORTED;
CoreH_ThreadBlock(curr, true);```
you're supposed to do that after the block
I think I'll actually remove the test actually
I don't usually push code with a test in it
and I will be making a proper commit message
oki
let me know when u commit
i probs wont contribute much as i have my own kernel to work
on
but
not pressuring you
just if you're ever bored
and if it's ultra stupid I'll add you to the credits
okay
if you're ever bored again and feel like contributing to obos, here are some current TODOs that I have for you:
- fix the m68k port
- fix the gdb stub
- rewrite the disk swap interface
- make the driver loader mostly platform-independant
okay thanks
if my code works first-try that means it's actually not working
I am currently fixing a bug related to standby/dirty lists and shared pages.
Previously, it would blindly assume that it could put any page on standby/dirty, which included shared pages.
This behaviour is incorrect, as if a page is shared, it's possible, and very likely, that the other shared page(s), are still using it while it's supposed to be treated as standby memory, or memory that will become standby (i.e., dirty pages).
The solution was to add another reference counter to struct page (physical page ofc)
// A reference count of virtual pages that have this page paged in.
// Must always be <= refcount.
_Atomic(size_t) pagedCount;```
this vmm work inspires me to unfuck my pagecache
it's not buggy, just shitty
this branch is getting out of hand
maybe you should merge it lol
I want to get my syscalls finished first
and fix any regressions in the m68k port
in a separate discord server, I predicted that I would have ~70 syscalls by the end of this
and I can never forget TTYs
which I need to implement
basically everything here
plus this vmm work
after getting myself to stop procrastinating
I am now going to finish the new api to the vmm
streaming obos in voice one
for those who care for some reason
those who care ๐
this shit is so boring
cant believe my code for obos worked first try ish
still streaming?
okay
huh?
WHERES UR MANGA PLUS OS
Manga I haven't drawn any panels for yet lol, still working on the script. OS, er, I forgot about XD, I think I was trying to figure out how to read a Ext2 file path
Lemme find my OS' thread
OK Idk how to link to a thread but it's called AquaOS
thank you
uh oh
obos in debug mode broke
it's clang doing dumb shit with kasan
it looks like it's poisoning the stack
if (OBOS_USE_CLANG)
add_compile_options($<$<COMPILE_LANGUAGE:C,CXX>:-Wno-error=unknown-pragmas>
$<$<COMPILE_LANGUAGE:C,CXX>:-Wno-unknown-pragmas>
$<$<COMPILE_LANGUAGE:C,CXX>:-Wno-error=unknown-attributes>
$<$<COMPILE_LANGUAGE:C,CXX>:-Wno-error=c23-extensions>)
if (OBOS_ENABLE_KASAN)
set (OBOS_ENABLE_KASAN OFF)
message (WARNING "OBOS does not support Clang's ASAN implementation. If you really care about this, make a PR, as I don't.")
endif()
endif()```
fixed it
have you tried setting the asan call threshold to 0?
I have no idea what that means
-mllvm -asan-instrumentation-with-call-threshold=0 should get rid of clang making inline shadow map checks if that's what its doing
this is only to the compiler right?
yes
aka this
I love this stack trace
poor man's stack trace
#define OffsetOfReg(reg) ((uintptr_t)&(((ioapic_registers*)nullptr)->reg))
could clang be treating this as UB
and cause UBSan to yell at me?
I'm just gonna spam OBOS_NO_UBSAN until it boots
actually I'll just properly fix the bugs
local man reinvents offsetof
why the hell did my 2nd monitor just die on me 
can u just bt
Just use offsetof??
for the love of allah
It has a built-in even
I did
t'was broken
it's back
๐ญ
Works in python
and in C
but UBSan doesn't like it
and also it happens to be a bug
it boots now
https://github.com/OBOS-dev/obos/pull/27
Decided to finally make a draft PR for the userspace-work branch
since it's getting pretty close to getting merged
time to continue vfs syscalls
I hope to get these done within a couple hours
should be simple enough, right?
We should be in bash by the end of the month
- oberrow, august 2024
maybe I'm mistaken, but I think we're not in bash
Well u did a lot of other things
Ye
is it bad that read is able to read even if the target buffer is mapped as RO 
void* kbuf = Mm_MapViewOfUserMemory(CoreS_GetCPULocalPtr()->currentContext, (void*)buf, nullptr, nBytes, 0, &status);
if (obos_is_error(status))
return status;
Mm_MapViewOfUserMemory ignores any protection flags the user set
so when the kernel gets it's view of user memory, it can do whatever the hell it wants
of course the change in prot flags isn't reflected in user-mode
like you could do something like Vfs_FdRead(file, "heheheh I am evil", 5, NULL);
and the first five bytes of the string literal would be over written with whatever was in the file

maybe I should fix that
I'll add a parameter called "respectUserProtection"
which does the following:
- when checking if the user pages exist, if anyone of the user pages has different protection flags than the ones the kernel desires in it's mapping, it
return OBOS_STATUS_PAGE_FAULT
if (respectUserProtection)
{
if (kprot & OBOS_PROTECTION_EXECUTABLE)
{
OBOS_Error("Kernel is doing shady things, refusing to map user pages as executable inside the kernel address space. If all is in your favour, this is a bug, otherwise it's malware.");
return false;
}
// If the kernel wants an RW mapping, but the user range is RO, then fail.
if (!!(kprot & OBOS_PROTECTION_READ_ONLY) < rng->prot.ro)
return false;
}```
it's fair to refuse mapping kernel pages as executable if they're being shared from user mode
for safety
why are you sharing kernel pages
why
kpti
otherwise I'd need to do very large amounts of memcpy
and allocation
for reading files
and writing files
so I thought to myself, why don't I just have a function to map user pages into the kernel context temporarily, so I can just pass the pages mapped in kernel mode to the vfs' read/write functions
so that's what I did
well then you control the protection
idk why you add a check
you need to read into something, just set the write bit
you need to write, only set the read bit
which is exactly what I did
what I added was a way to make sure the user can't do something like this:
Vfs_FdRead(file, "heheheh I am evil", 5, NULL);
and it returning success and doing the read into the RO string literal
with that, I should have my vfs syscalls implemented
implementing syscalls is really just a bunch of code copy+pasting when they just call into kernel functions with the exact same API
I promised a redesign of my I/O interface
but I think it's better to do that after merging this branch
#1141057599584878645 message
Next thing on the list is partition probing syscalls
void OBOS_PartProbeAllDrives(bool check_checksum);
obos_status OBOS_PartProbeDrive(struct dirent* ent, bool check_checksum);```
that will correspond almost directly to a call to either of these functions
in fact, the first function can be directly made a syscall
without glue code
ok finished those syscalls

๐ก
driver interface syscalls now
driver_id *Drv_LoadDriver(const void* file, size_t szFile, obos_status* status);
obos_status Drv_StartDriver(driver_id* driver, thread** mainThread);
obos_status Drv_UnloadDriver(driver_id* driver);```
obos_status Drv_PnpLoadDriversAt(dirent* directory, bool wait);```
these are the functions I will expose
and I will add another syscall:
handle Sys_FindDriverByName(const char* name /* assumed to be 64-bytes at max */);```
also:
// Returns the next driver in the list
// The handle 'curr' is not automatically closed.
handle Sys_EnumerateLoadedDrivers(handle curr);
as well as:
obos_status Sys_QueryDriverName(handle drv, const char* namebuf, size_t sznamebuf /* need not be over 64 */);```
I though you were supposed to just let the kernel page fault on itself and handle that there
well two things:
- I can't do that, I do KPTI (user pages and kernel pages are separated through completely different CR3s, as opposed to just a bit in the PTE)
- even if I could do that, I wouldn't, as I want to be able to give the user a status telling it it page faulted, which could prove difficult if I just let it page fault
You add a shim function?
wdym?
Like save the registers, make pf handler switch to some function which returns error
I also kinda have that problem, but my issues are because of nonpreemptive kernel
Otherwise mapping and unmapping have a huge performance hit
I'd rather map than allocate then do a slow ass memcpy_k_to_usr
at least for large sized IO
Also kpti assumes userspace pages are still mapped
does it?
(at least that's how I've been understanding it)
that's a misunderstanding
you only have the bare minimum of the kernel mapped in a user context
Yes
i.e., only enough to make a switch to the actual kernel context+ring3
And then another mapping with full user context + full kernel
well I haven't been doing that (oops)
And then you can copy efficiently
I'm not sure, but I think switching page tables is still a barrier against side channels (?)
(I'm not an expert and don't have a lot of interest in security vulnerabilities, besides the basics)
what I do is have it switch to the kernel's CR3 in the IRQ handler when coming from ring3
and then do all user memory access through a special function
memcpy_k_to_usr+memcpy_usr_to_k
Yeah, that's reasonable
But you have a flag which protects you from reading user memory from ring 0
So in your functions, you can just disable that temporarely and read user memory as needed (?)
Without inducing costs of page faults
for (size_t i = 0; i < count; )
{
MmS_QueryPageInfo(ctx->pt, (uintptr_t)usr_src + i, nullptr, &usrphys);
if (!usrphys)
{
// Mm_VirtualMemoryUnlock(ctx, futex, sizeof(*futex));
return OBOS_STATUS_PAGE_FAULT;
}
size_t currCount = bytes_left > OBOS_PAGE_SIZE ? OBOS_PAGE_SIZE-((usrphys+usroffset)%OBOS_PAGE_SIZE) : (size_t)bytes_left;
memcpy((void*)((uintptr_t)k_dest + i), MmS_MapVirtFromPhys(usrphys+usroffset), currCount);
usroffset = 0;
i += currCount;
bytes_left -= currCount;
}```
it does this
for usr_to_k
and vice versa for k_to_usr
TODO: Could it be possible to include these functions in the user CR3, then drop to the user CR3 to do the k_to_usr memcpy or usr_to_k memcpy?
How many cycles do pagefaults take on modern CPUs?
#x86
For small stuff, you can have some sort of scratch area
Which is mapped to both
So you first copy there from kernel to userspace-facing mapping
And then to userspace userspace
hmm
it's only been two hours ๐ญ
TTYs are tomorrow 
then I can merge the branch
theoretically
wait
I'VE BEEN SAVED
signal-related syscalls
void OBOSS_SigReturn(interrupt_frame* frame);
obos_status OBOS_Kill(struct thread* as, struct thread* thr, int sigval);
obos_status OBOS_SigAction(int signum, const sigaction* act, sigaction* oldact);
obos_status OBOS_SigSuspend(sigset_t mask);
obos_status OBOS_SigPending(sigset_t* mask);
enum {
SIG_BLOCK,
SIG_SETMASK,
SIG_UNBLOCK,
};
obos_status OBOS_SigProcMask(int how, const sigset_t* mask, sigset_t* oldset);
obos_status OBOS_SigAltStack(const uintptr_t* sp, uintptr_t* oldsp);```
those are the signal-related APIs I will expose
to user mode
Current roadmap:
Signal syscallsDirectory syscalls- exec syscall
- TTYs
- merge userspace-work
- OBOS x86_64 gcc target
- mlibc
- bash
then you're gonna realize everything's broken because you didnt test anything
indeed

that was the plan
done
theoretically since these are just practically memcpys then just calling into the appropriate signal function
they should work
now dirent syscalls would be simple, if I could find the part of the POSIX spec for them
there it is
u will hit bash soon
Yes
roadmap here
where as nyaux will be left in the dust struggling to fix bug after bug
hopefully by the new year

Nyaux bash twice before pmOS
nahhh wont happen
ill probs hit another bug
after this one
then after that one
I need to implement working set
yea we def gonna encounter a LOT of bugs
Then AHCI driver
-# you start working on obos 
Before that I'll probably get caught in writing some other random drivers
Then decide to "improve" VMM again
anyways no more distractions back to debugging nyaux
say, what if I didn't want to implement alphasort
posix mandates it
but idk if my kernel needs it as a syscall
or if mlibc does it for me
This should probably be done in libc
hmm
mlibc doesn't
even have sysdeps for any of those dirent functions
only sys_read_entries
which ones are you thinking of?
the read entries one does all that mlibc needs the kernel (or posix server) to do
stuff like opendir, readdir, closedir, etc.
not to worry, mlibc will do all those
well what is sys_read_entries supposed to do?
I know it reads the dirents
but what exactly is the format of the struct it's reading into
struct dirent
hold on, I think I found it:
typedef struct dirent {
uint32_t inode; // Inode number
uint32_t type;
char name[NAME_MAX]; // Filename
} dirent_t;```
so this
i think mlibc has its own definition and expects in that form
ah ok
thanks
I'm sure it'd be perfectly fine if I always set inode to zero
right
what could possibly go wrong
I'm going to need to make stat syscalls
why did no one tell me I could something like man stat.3type
to find the struct stat format
int sys_read_entries(int handle, void *buffer, size_t max_size,
size_t *bytes_read);```
is buffer allowed to be NULL here?
and if it is, do I just set *bytes_read = however many bytes it would read
see which stubs call into this and read the posix spec
it's not posix, iirc

