#OBOS (not vibecoded)
1 messages Β· Page 33 of 1
you can do it per-commit iirc
I've done it before
yea
curl -sL https://github.com/user-or-org/repo/archive/sha1-or-ref.tar.gz | tar xz
marker
well that's useful
what if hte reason your laptop is bricked is because you tested nyaux on it
*th
**the
lmao π
no not rlly
it was nobara actually
that killed my system
idk what it did but motherboard is fried!
anyway, it is now time to separate host and target recipes
is there really a point though 
No
there isn't
time for buildall
installall is like the exact same but with an extra step
because the compiler needs to be able to find compiled libraries in the sysroot, buildall will be aliased to installall
and I am renaming those commands to build-all and install-all
i am in ur walls
also guess who found their old ah laptop
i did!!!
And I was the reason your laptop broke
u dont mind me drilling into the walls right
π‘
wow
okay im drilling into the walls
anyways i found my old laptop
so osdev can continue
just compile times are gonna suck ass

i have the same cpu in my current machine lol
π
still probably better than my cpu
"Intel(R) Core(TM) i5-4590T (4) @ 3.00 GHz"
definitely better than what I used to have to deal with all the time on my laptop: "Intel Pentium Silver N5000 (4) @ 1.10 GHz" (boost of 2.70 GHz)
now that I implemented this
it's actually really smart
if I want to multithread this
which I do
so with that, I should have the build-all command implemented
it tries to make the most of multithreading
basically, in build_pkg_and_dependents, if it can, it will try to start a new thread to build a dependent of that package
and then at the end of that function, it joins the thread
which I actually don't know if I need to do that
or even should join the new thread
it's very lightly tested
the dependency graph literally looks like this:
hello depends bash
I use semaphores to synchronize thread creation
yeah maybe I should just pthread_detach the thread after creating it
and not join it after looping through the dependants
if (!(--data->missing_dep_count))
{
int val = 0;
sem_getvalue(&awake_threads, &val);
if (val)
{
if (sem_trywait(&awake_threads) != 0)
goto no_thread;
pthread_t thr_id = {};
// We can now start a thread.
int ec = pthread_create(&thr_id,
NULL,
build_thread, data);
if (ec)
{
perror("pthread_create");
fprintf(stderr, "Ignoring error.\n");
goto no_thread;
}
pthread_detach(thr_id);
continue;
}
no_thread:
res = build_pkg_and_dependants(data, curl_hnd);
if (!res)
break;
continue;
}```
why spawn threads?
parallelism
all you do is run through a graph and fork off to run other commands
I'd just use gnu parallel maybe
i don't understand what you want to parallelize here though
I am parallelizing the building of packages
and why does that need threads?
well for individual packages the parallelism is handled by the build system
e.g. make/ninja with -jN etc
pitust said otherwise
./configure tho
and if you want to build multiple packages in parallel at once you don't need threads
oh yeah I get what ur saying now
use fork
nvm
you can do something like this more or less ```
job_queue = []
... add jobs to queue ...
free_slots = N
in_flight = {}
while not job_queue.empty():
while free_slots > 0 and not job_queue.empty():
job = job_queue.pop_back()
pid = fork_and_exec(job)
in_flight[pid] = job
free_slots--
while free_slots != N:
pid = wait()
... add dependents of in_flight[pid] ...
in_flight.remove(pid)
free_slots++
and ig some logic to add dependents once a job is complete
marker
yeah I will do that soonβ’οΈ
but now I really want to get back to work on OBOS
but imo it's better to build packages one by one
and tell the package's build system to parallelize instead
you can parallelize configure or whatever but the build itself doesn't make sense imo
although even then configure doesn't take that long either
PSA: autotools sucks
i mean usually if it takes long then the package is large and takes even longer to build
so it's not a substantial amount of time compared to the whole build
sure true yeah
also, another problem with not doing -jN or similar, if the current job is a dependency of every other job after it you're only using 1/N of your system to build it
yeah I had thought of that
so it takes N times as long
consider a gcc cross compiler, where on my laptop with 6 cores it takes about minutes to build, but if i built it with -j1 it would be more like 30 minutes instead
for those packages I will probably do -jN
and i can't really build any packages alongside gcc (ig i can build some other tools but most don't take as long as gcc)
because it's not like the rest of the cpus are doing anything
for all the autocrap you can use a make jobserver
I now have recipes for x86_64-obos-gcc and binutils for obos-strap
I have also added a recipe for mlibc
and these recipes almost work
except gcc can't find any headers
so I guess I have to make mlibc spit it's headers and stuff into sysroot/usr/
and I will also be adding something else to obos-strap to make clean work better
specifically, I will add clean-commands to recipes
but for now I can just pass --wipe to meson
or not..
wait nvm I forgot to run install on mlibc
silly me
--- a/support/config.sub
+++ b/support/config.sub
@@ -1731,7 +1731,7 @@ case $os in
| os9* | macos* | osx* | ios* \
| mpw* | magic* | mmixware* | mon960* | lnews* \
| amigaos* | amigados* | msdos* | newsos* | unicos* | aof* \
- | aos* | aros* | cloudabi* | sortix* | twizzler* \
+ | aos* | aros* | cloudabi* | sortix* | obos* | twizzler* \
| nindy* | vxsim* | vxworks* | ebmon* | hms* | mvs* \
| clix* | riscos* | uniplus* | iris* | isc* | rtu* | xenix* \
| mirbsd* | netbsd* | dicos* | openedition* | ose* \
the patch command isn't enjoying my patch for bash
patching file /home/oberrow/Code/obos-pkgs/repos/bash-5.2.37/support/config.sub
Hunk #1 FAILED at 1731.
1 out of 1 hunk FAILED -- saving rejects to file /home/oberrow/Code/obos-pkgs/repos/bash-5.2.37/support/config.sub.rej
and I've no idea why
patch is part of coreutils right
it's something different
the bash I had when I made the patch and the bash I extracted are the exact same bash
and you didn't run autoreconf or anything?
no
weird
I even tried making it on a clean bash
making the bash patch
ok fixed it
somehow
/home/oberrow/Code/obos-pkgs/pkgs/lib/gcc/x86_64-obos/14.2.0/../../../../x86_64-obos/bin/ld: /home/oberrow/Code/obos-pkgs/pkgs/lib/gcc/x86_64-obos/14.2.0/crtbegin.o: relocation R_X86_64_32 against hidden symbol `__TMC_END__' can not be used when making a shared object```
bruh
fix ur crts
kk
bruh my crts aren't fixing themselves
you enable the pic crts in the config files right and use them in the LINK_SPEC?
idk I just did whatever osdev wiki does
what specifically
but I will check
my os-specific toolchain is basically just this but with obos
This tutorial will guide you through creating a toolchain comprising Binutils and GCC that specifically targets your operating system. The instructions below teach Binutils and GCC how to create programs for a hypothetical OS named 'MyOS'.
Until now you have been using a cross-compiler configured to use an existing generic bare target. This is ...
and an m68k target
ok I never change LINK_SPEC
I looked at another patch for gcc and I think I know what I need to change
@flint idol I got a question, why do u save IPL into thread
afaict the only way you could change thread contexts and come back with a diff IPL is if you yield
I forgor
lol fair and relatable
assuming you even make this legal
Yeah ^
which sounds mega scuffed
it does
but since u can only get preempted on one IPL...
and if you make yield just have some proper semantics
I guess back then I assumed IRQL was something I should save
I will probablt remove it soon
*probably
thats fair, and I am not saying there is no reason, I just cant think of one
it is sufficient to not save it in the thread
yeah I am not planning on it atleast rn
/home/oberrow/Code/obos-pkgs/repos/bash-5.2.37/examples/loadables/finfo.c:283:14: error: implicit declaration of function 'major' [-Wimplicit-function-declaration]

I get this with my new gcc build
lol
except luckily it's in bash
in that file:
so if major isn't in sysmacros, nor in mkdev
that's a bug with my sysdep
I think
ok I just got bash to build
by patching that file to check if major and minor actually exist
before using them
so now you can probably clone https://github.com/OBOS-dev/obos-pkgs
run ./obos-strap build-all
and you get all obos packages conviniently built for you
wait no
./obos-strap setup-env
./obos-strap install-all```
obos-strap is just a binary?
yes
fair enough
for obos-strap
fun
the compiled bash doesn't run
it segfaults
on a page that is lazily mapped
rather that, or it's a file page
how did it work before then 
I mean the build environment did technically change
because before crtbegin/crtend weren't working
nvm, the page does not exist
there were two syscalls to mmap
the range didn't fit in either of them
I think I am passing teh aux values incorrectly
__ensure(Library function fails due to missing sysdep) failededed```
I love it when my functions failededed
anyway I fixed that bug
it had something to do with alignment
anyway, time make fork
This is how fork will work if I do it userspace:
- Set *child=0
- Fork the current VMM context
- Make a new thread that starts at where ever the "return" statement of the sys_fork sysdep is at
- Start a new process, with the vmm context set to the previously forked one, and with is_fork=true
- Set *child to the process id
- Profit```
if you do it like that wouldn't you need a way to create an empty process and then the thread create function would take in a process?
that could actually be useful for something else too tbh
forking ur plate
though idk it might be slightly cursed creating threads in other processes context
but ehh
my thread create function doesn't work like htat
iirc the winapi can do that
yup
how do you know where it should start at tho lol
magic
unless you share the vspace with the process or smth
the thread will start straight in userspace
or well fork ig
at whereever the ret instruction is for sys_fork (not quite, but around there)
Why
you can take an address of a label, right?
if not, then my plan would've been foiled
nope
in GNU C you can actually
Labels as Values (Using the GNU Compiler Collection (GCC))
If ur doing that then you'll usually know for some reason like the entry point of the remote thread is in a library that's always loaded at the same place
although this is kind of scuffed actually, because I don't know where I would need to move the stack pointer
if I make the label at the end of the sys_fork function
ig, it doesn't seem very useful to me in normal use though
maybe in some kind of debugger
handle thread_ctx = create_thread_ctx_for_fork(..., &&label);
label:
if (*(child == 0))
return 0;
I could perhaps do that
or just do it in asm
true
which is actually what I will be doing because I don't trust the compiler
enough
just implemented sys_fork
now to test it (here we go)
let's see how many times does it panic
ENOSYS
ah yes
I need sys_waitpid
and I also need to mangle the symbol in assembly
luckily it only panics once
I fixed the panic
now it's in some weird loop
that causes it to hang
found a problem
through syscall logging
turns out I am using Sys_HandleClone wrong
basically, one syscall fails, then another fails, then that chains into a bunch of failed syscalls
until it finally hangs
wtf
I have managed to corrupt the irq handlers array
or wait no
I have managed to corrupt something
yeah the irq handlers array
it looks like a stack overflow to me
it is because gs_base is zero
well I fixed that
so the new process segfaults first thing
but that is certainly better than the new process causes the system to triple fault
but bash hangs after that
or the libc
only god knows
the thread had not syscalled once, it just SIGSEGVed
u need nyaux like
Fork is just a fucked thing in itself
Should add uacpi
me
malding
I have found a problem with my Mm_Fork function
I don't ever ref any physical page after having marked it as CoW
I have fixed the SEGV
but now it hangs
nvm
fixed the segfault
now I need to figure out what syscall 52 is doing
Sys_SigProcMask is being ran in a loop
wtf
it's with the same parameters each time
until it calls Sys_SigAction
then Sys_ProcessGetPID
then Sys_ThreadOpen
which, in turn, returned invalid handle
the function was passed a PID
pid_t sys_gettid()
{
return (pid_t)syscall1(Sys_ThreadGetTid, HANDLE_CURRENT);
}
pid_t sys_getpid()
{
return (pid_t)syscall1(Sys_ProcessGetPID, HANDLE_CURRENT);
}
pid_t sys_getppid()
{
return (pid_t)syscall1(Sys_ProcessGetPPID, HANDLE_CURRENT);
}
perhaps it is a bug with one of these functions
specifically sys_getpid seems sus
I'll make it return sys_gettid and see what that does
what uses Sys_ThreadOpen?
I believe it is sys_kill
that takes in a pid
so the getpid value or gettid value
getpid
ok
it takes in a process id and sends the signal to whatever thread that can accept it
handle Sys_ProcessOpen(uint64_t pid)
{
OBOS_UNUSED(pid);
// Unimplemented.
return HANDLE_INVALID;
}```
bruh

ok
also idk why but bash gets stuck in an infinite sys_sigprocmask loop
until it triple faults
triple faults?
fent
fent?
fent.
fent...
wtf is happening
the kernel
is mapping memory
in the user part of the address space
damn the person who designed fork
thank you for coming to my ted talk
bro what the actual fuck
WHY IS THE KERNEL ALLOCATING
KENREL MEMORY
BELOW 0xffff'8000'0000'0000
something has driven my kernel to total insanity
sentinece
Obos ascension
I think it was because of a slight change in how PIDs were made
yup
I made the kernel's struct process be pid zero
before it was pid one
[ LOG ] User thread 7 SIGSEGV (rip 0, cr2 0)
(install SIGSEGV handler?)
yes
which is done by libc
wait so the kernel wasn't supposed to do it?
it sends a signal
usually the kernel does it
yeah
huh
i thought it was glibc which printed "segmentation fault"
anyway, posix doesn't say where you do it
so you can do it there
SIG_DFL -> call libc signal handler (?)
idk
but idk what you'd gain from that
you can print stack traces
I define it as null and have a special handler for that in the code that sets up the interrupt frame for a signal
without it potentially crashing the kernel
use gdb?
for what?
stack trace
it becomes very difficult to use once you have 30 threads on 8 cores
bt
make a gdb stub
does it change anything?
you can choose specific threads instead of specific cores
idk
my kernel doesn't even have signals, so I have userspace thread do it
Yes
bru
(that's an address on the stack)
oops
I forgor to restore rbp
--- a/sysdeps/obos/x86_64/fork.S
+++ b/sysdeps/obos/x86_64/fork.S
@@ -113,6 +113,7 @@ fork_shim:
xor rax,rax
+ pop rbp
ret
#if MLIBC_BUILDING_RTLD
theoeretically this is the fix
we just love the fourth parameter passed to this function
anyway, after having fixed the SEGV in the forked program
[ LOG ] User thread 6 SIGSEGV (rip 2412500c8, cr2 2412500c8)```
before I debug this, I need a wall
to bash my head on
unrelated question - which gcc are you using in your toolchain?
how did you patch it?
Same way as OSDev wiki
it fails with make[1]: *** No rule to make target '../../gcc-pmos/gcc/config/pmos.opt.urls', needed by 's-options'. Stop.
But with same stuff taken from Elysium
Try taking obos' patches and modifying them to pmos
Those are my gcc patches if you want to compare
I'm not seeying anything that's much different
and related to it
hmm
I forgot about this
one thing I am noticing
is after a fork
read/writes from read only regions break
in both the parent and child
mostly page faults
How are you doing your CoW?
if (curr->cow && curr->un.cow_type == COW_SYMMETRIC)
{
info.prot.rw = false;
MmS_SetPageMapping(toFork->pt, &info, info.phys, false);
}
MmS_SetPageMapping(into->pt, &info, info.phys, false);
in short, basically just that
for each page
if (!curr->cow)
{
curr->cow = true;
curr->un.cow_type = COW_SYMMETRIC;
}```
this is before
How do you invalidate TLB?
invlpg
but what if process has several threads
this is on a uniprocessor build
it would send an IPI
telling other CPUs to invlpg this page
because afaik the fork is the way that it is because it was very easy to implement in unix
from what I've been taught, you just swap the whole process onto disk
and then fork
the idea behind fork is that you have like 1 byte of memory but need like 50 processes
*taught 
but your pages don't have refcount?
they do
page what = {.phys=info.phys};
page* phys = (info.prot.is_swap_phys) ? nullptr : RB_FIND(phys_page_tree, &Mm_PhysicalPages, &what);
if (phys)
{
MmH_RefPage(phys);
if (!(phys->pagedCount++))
{
Core_SpinlockRelease(&toFork->lock, oldIrql);
Mm_HandlePageFault(toFork, addr, PF_EC_RW|((uint32_t)info.prot.present<<PF_EC_PRESENT)|PF_EC_UM);
oldIrql = Core_SpinlockAcquire(&toFork->lock);
MmS_QueryPageInfo(toFork->pt, addr, nullptr, &info.phys);
// At this point, paged count is two.
}
}```
physical page(s) are referenced before mapping them
if they're paged out, then they're paged back in
I have an idea
that wasn't the problem
but it was a problem
found a bug with signals
frame->rflags &= ~ALLOWED_FLAGS;```
in sigreturn
I was clearing the allowed flags
although for some dumb reason everything be faulting on a null pointer access
and for some stupid reason, bash sends SIGSEGV to itself after receiving a SIGSEGV
[ LOG ] (thread 6) syscall Sys_ProcessGetPID(0xfe000000, 0x0, 0x0, 0x0, 0x0)
[ LOG ] (thread 6) syscall Sys_ProcessGetPID returned 0x0000000000000001
[ LOG ] (thread 6) syscall Sys_ProcessOpen(0x1, 0x0, 0x0, 0x0, 0x0)
[ LOG ] (thread 6) syscall Sys_ProcessOpen returned 0x000000000400000a
[ LOG ] (thread 6) syscall Sys_KillProcess(0x400000a, 0xb, 0x0, 0x0, 0x0)
[ LOG ] (thread 6) syscall Sys_KillProcess returned 0x0000000000000000```
sys_kill(sys_getpid(), SIGSEGV);
there also seems to be a bug with reading from cloned FDs
when I tested fork manually
#include <unistd.h>
#include <stdio.h>
int main()
{
printf("testing fork\n");
pid_t pid = fork();
if (pid == 0)
printf("in child, we are %d\n", getpid());
else if (pid > 0)
printf("in parent, child is %d\n", pid);
else
printf("error\n");
return 0;
}```
I have fixed a bug
because now it at least prints the message in the parent
[ LOG ] (thread 7) syscall Sys_FdWrite(0x1, 0x9fe015, 0x16, 0x8024d8, 0x0)```
apparently the child also tries to printf
or more accurately, the child tries to write(stdout, ...)
wait what
the child is the one printing this
[ LOG ] (thread 6) syscall Sys_HandleClose(0x5000003, 0x5000003, 0xffffffff801f1800, 0xb000004, 0x7ad65000)```
we just love it when we leak kernel addresses to usermode
found a bug
[ LOG ] (thread 6) syscall Sys_ProcessGetPID(0x4000006, 0x5000003, 0xffffffff801f1800, 0xb000004, 0x7ad61000)
[ LOG ] (thread 6) syscall Sys_ProcessGetPID returned 0x0000000000000002
[ LOG ] (thread 6) syscall Sys_HandleClose(0x4000006, 0x5000003, 0x0, 0xb000004, 0x7ad61000)
in between these two syscalls
there should be a page fault
because rdi should've been marked as RO
by Mm_ForkContext
which was called earlier
ok I believe I fixed it
no random PFs either
holy
except bash hangs after
are u talking to obos over serial?
yes
thats pretty cool
maybe it's because I don't send SIGCHLD
yes (it's definitely not because I couldn't be bothered to implement TTYs)
nor do I implement waitpid
OBOS_PAGEABLE_FUNCTION obos_status Core_ProcessTerminate(process* proc, bool forced)
{
OBOS_UNUSED(proc);
OBOS_UNUSED(forced);
return OBOS_STATUS_UNIMPLEMENTED;
}```
I suppose it is time to implement this
actually
I will remove that
and replace it with Core_ExitCurrentProcess
do u poll it or actually have irqs and stuff
IRQs
the UART driver is an actual uart driver
and I have /dev/COM1
which controls IO to the serial port
as well as opening a connection through an ioctl
nice
which means if:
- you can get obos to boot on real hw
- have a serial port
- and obos' uart driver doesn't shit itself
you can run obos bash
on real hw
it even uses uacpi to detect a UART
#include <uacpi_libc.h> 
ah yes
that's because I didn't have a strnlen in memmanip.h
lol
so I just used uacpi_strnlen
thats pretty cool
iirc, it also detects the ports that exist through resources
this tho
uacpi_find_devices("PNP0500", match_uart, nullptr);
uacpi_find_devices("PNP0501", match_uart, nullptr);
π€’
there's uacpi_find_devices_at btw which takes in a list
I probably wrote the driver before that existed
if it's something relatively new
very old
weird
yeah so I can detect devices using uacpi/pci
but I don't necessarily have a way
to pass that to the driver
so I need to do that until I decide to fix that
.acpiId.nPnpIds = 2,
.acpiId.pnpIds = {
"PNP0500", // Standard PC COM port
"PNP0501", // 16550A-compatible COM port
},
So this is not used basically?
nah it's used to detect if the driver exists
*device exists
y not do a thing where buses can discover their own devices and register them instead of searching for them (what I plan on doing when I redo my astral device driver stuff)
yup
IMO your DriverEntry should do a register_device(&pnp_id_list, com_probe)
then com_probe is called with the namespace node that matched
I don't quite enjoy the idea of loading a driver solely for the purpose of probing a device that it wants
anyway, I need to add a execve sysdep
you could have a separate manifest thing along with the driver too
that contains the devices that it supports (basically like windows ini)
I do that, but in the "driver header" which is embeded into the driver ELF
astral ass naming convention
oh no
I was just making it not be obos naming convention
the REAL function name is Sys_FdTellOff
typedef struct process
{
// threads waiting for our death
struct waitable_header waiting_threads;```
so for some reason
I think handling signals is causing all to go to shit
[ DEBUG ] (pid 1) Handling page fault at 0x0...
[ LOG ] User thread 6 SIGSEGV (rip 0, cr2 0)
[ DEBUG ] (pid 1) Handling page fault at 0x0...
[ LOG ] User thread 6 SIGSEGV (rip 400002, cr2 0)```
bruh
SIGMAX = 64
fixed
it was a bug with how I was 'dispatching' signals
and it turns out SIGCHLD is masked by bash
so that isn't the problem
I guess I need to implement sys_waitid
I basically have everything except for three things:
- I need to signal waiters on the
process*when a process exits (not really that hard) - I need to make process handles waitable in the syscall
Sys_WaitForObjects - I need some way to get a process handle for any child process (for the value -1 passed to waitid)
the first thing I just did
and the second thing I also just did
all I need is to do the third thing
which I will do in 5 minutes
ah yes I also need a syscall to get a process' exit status
I think I also need to make it so that this happens on signals
I need to signal a process object when:
- it terminates
- it receives
SIGCONTorSIGSTOP
then additionally, if it terminates because of a fatal signal, I need to encode that in the exit status
given how much stuff this does, maybe I should just do it in the kernel
anyway I will be back
wait what's the difference between sys_waitid and sys_waitpid
ok I think I figured that out
soon
holy shit
I can almost do shit
nvm I think it only works the first time
the 2nd time bash gets stuck in a waitpid loop
fixed the waitpid loop
but instead it just hangs
noice
2025 really is the OBOS year
fr
I love writing stuff like exit process:
// Disown all children.
for (process* child = proc->children.head; child; )
{```
[ LOG ] User thread 6 SIGSEGV (rip 4563db, cr2 0)```

I'm also able to get it to hang
Damn literal year of obos
or well, any others
the problem was it was picking a dead process to wait on if pid == -1
which would cause a hang
I kinda wanna see if I can run bash in bash
it complains about tcsetattr
then dies
well, it doesn't run the 2nd bash
how do I get my bash to do that
iirc there was an environment variable I had to set
but idr it
found it
it's the PS1 environment variable
something I've noticed is if I do it twice
bash just segfaults
before I port coreutils
I want to stub sys_tcsetattr
and sys_tcgetattr
and I also want to make it so bash recognizes that a child segfaulted and prints the nice "segmentation fault" message
memory corruption at it's finest
[ LOG ] (thread 7) syscall Sys_FdAlloc(0x0, 0x0, 0x0, 0x0, 0x0)
[ LOG ] (thread 7) syscall Sys_FdAlloc returned 0x000000000000000c
[ LOG ] (thread 7) syscall Sys_FdOpen(0xc, 0xbfefc0, 0x1, 0x0, 0x0)
[ LOG ] (thread 7) syscall Sys_FdOpen returned 0x0000000000000000
2
[ LOG ] (thread 7) syscall Sys_FdTellOff(0xc, 0x0, 0x0, 0x0, 0x0)
[ LOG ] (thread 7) syscall Sys_FdTellOff returned 0x0000000000000000
[ LOG ] (thread 7) syscall Sys_FdSeek(0xc, 0x0, 0x2, 0x0, 0x0)
[ LOG ] (thread 7) syscall Sys_FdSeek returned 0x0000000000000000
[ LOG ] (thread 7) syscall Sys_FdTellOff(0xc, 0x0, 0x0, 0x0, 0x0)
[ LOG ] (thread 7) syscall Sys_FdTellOff returned 0x00000000003f18f7
[ LOG ] (thread 7) syscall Sys_FdTellOff(0xc, 0x0, 0x0, 0x0, 0x0)
[ LOG ] (thread 7) syscall Sys_FdTellOff returned 0x00000000003f18f7
[ DEBUG ] (pid 2) Handling page fault at 0x0...
[ LOG ] User thread 7 SIGSEGV (rip 41213307, cr2 0)
also for some reason trying to start any child process that actually exists causes this to happen
I think it is a bug with sys_seek
while that is not the case
there was still a bug in sys_seek
[ LOG ] (thread 8) syscall Sys_FdAlloc(0x0, 0x0, 0x0, 0x0, 0x0)
[ LOG ] (thread 8) syscall Sys_FdAlloc returned 0x000000000000000d
[ LOG ] (thread 8) syscall Sys_FdOpen(0xd, 0xbfef80, 0x1, 0x0, 0x0)
[ LOG ] (thread 8) syscall Sys_FdOpen returned 0x0000000000000000
[ LOG ] (thread 8) syscall Sys_FdSeek(0xd, 0x0, 0x2, 0x0, 0x0)
[ LOG ] (thread 8) syscall Sys_FdSeek returned 0x0000000000000000
[ LOG ] (thread 8) syscall Sys_FdTellOff(0xd, 0x0, 0x0, 0x0, 0x0)
[ LOG ] (thread 8) syscall Sys_FdTellOff returned 0x00000000003f18f7
[ LOG ] (thread 8) syscall Sys_FdSeek(0xd, 0x0, 0x0, 0x0, 0x0)
[ LOG ] (thread 8) syscall Sys_FdSeek returned 0x0000000000000000
[ LOG ] (thread 8) syscall Sys_FdTellOff(0xd, 0x0, 0x0, 0x0, 0x0)
[ LOG ] (thread 8) syscall Sys_FdTellOff returned 0x0000000000000000
[ DEBUG ] (pid 3) Handling page fault at 0x0...
[ LOG ] User thread 8 SIGSEGV (rip 41212df4, cr2 0)```
although now it PFs somewhere else
I think my uart driver is broken 
oh no
it's not broken
you're about to find out a funny
what does that mean
like bash dies?
.


what are you guys hiding from me
reading in a backspace does not delete the character
yes
but this is in nc, which iirc, does it's own buffering
unless it doesn't, then I'll be damned
changing /bin/bash to /bin
becomes /bin/bash\b\b\b\b\b
trolled
check out this funny for example
I'm pretty sure netcat deals with backspaces
because it holds the write until enter is pressed
netcat is probably using cooked mode so yeah
guess my serial driver is buggy then
when I talk about it, it goes awau
*away
damn uart driver
I have found out the page fault is in sys_execve
it was in sys_seek
but for some reason
it still doesn't execve properly
it just does random shit
until it exits
I get EFAULT after execve
so it's a bug in my execve syscall
[ LOG ] (thread 7) syscall Sys_VirtualMemoryAlloc(0xfe000000, 0x0, 0x1017, 0x802dc0, 0x802db4)
[ LOG ] (thread 7) syscall Sys_VirtualMemoryAlloc returned 0x00000000003a4000
[ LOG ] (thread 7) syscall Sys_ExecVE(0x3a4000, 0x1017, 0x802e60, 0x410c7b40, 0x0)
[ LOG ] (thread 7) syscall Sys_ExecVE returned 0x000000000000001f```
0x000000000000001f is OBOS_STATUS_PAGE_FAULT
char** kargv = allocate_user_vector_as_kernel(ctx, argv, &argc, &status);
if (obos_is_error(status))
return status;```
it reports a PF here
after making a change, I get EINVAL
uhh
why is the argv passed to execve scuffed
and by that I mean
argv[1] == 1
'
wth
that's the string it passes me
in argv[0]
int sys_execve(const char *path, char *const argv[], char *const envp[])
{
int ec = 0, fd = 0;
ec = sys_open(path, O_RDONLY, 0, &fd);
if (ec)
return ec;
off_t off = 0;
sys_seek(fd, 0, SEEK_END, &off);
sys_seek(fd, 0, SEEK_SET, 0);
void* buf = nullptr;
ec = sys_vm_map(nullptr, off, PROT_READ|PROT_WRITE, 0, fd, 0, &buf);
if (ec)
return ec;
obos_status st = (obos_status)syscall4(Sys_ExecVE, buf, off, argv, envp);
switch (st)
{
case OBOS_STATUS_UNIMPLEMENTED: return ENOSYS;
case OBOS_STATUS_INVALID_ARGUMENT: return EINVAL;
case OBOS_STATUS_PAGE_FAULT: return EFAULT;
case OBOS_STATUS_INVALID_FILE: return ENOEXEC;
case OBOS_STATUS_NOT_FOUND: return ENOENT;
default: __builtin_unreachable();
}
}
my execve sysdep doesn't modify argv
execl("/bin/shutdown", "");```
that's my invocation of exec
some cursed shi is happenin bru
perhaps it is a problem with fork
yeah it turns out to be a problem with fork
because with that same call before calling fork
it doesn't return EINVAL
I mean not really
I have some kernel functions for posix compatibility
and my mlibc sysdeps are basically a kernel->posix translation layer
How many kernels using mlibc actually implement POSIX as native API? 
i do
what do you mean
POSIX does not specify anything relating syscalls, only what is exposed in the libc
there is no native API for the kernel
was that directed toward me or mishakov?
mishakov
meaning they generally map posix to syscalls 1:1
This
Like POSIX functions as syscall api
its common
if you are making a POSIX kernel theres little advantage for not doing POSIX-like syscalls
But there are at least 2 microkernels using it + a bunch of other operating systems which are also not Unix clones
then they translate a sysdep to whatever their kernel needs to do
obos_status st = (obos_status)syscall4(Sys_ExecVE, buf, off, argv, envp);```
I wonder if it's valid to pass arrays like that
this is in:
int mlibc::sys_execve(const char *path, char *const argv[], char *const envp[])```
it probably is correct, as execve works if I don't fork
so it's a problem with fork
i am personally skeptical of the approach managarm takes
and others
and I have voiced it for years, I dont really understand why you would have your own API with its own incompatibilities and rough edges for nothing to use it and have to use separate servers for translating to POSIX, instead of using POSIX directly and shaving layers
POSIX as a spec allows a lot of extensions on top of it, when I want to do something in Ironclad that is not in POSIX I just add my extensions, not make parallel layers
i mean for my OS I don't want POSIX to be the native interface and I'll only implement what I need for ports
so the managarm approach does make sense to me but one has to be careful
I feel like making POSIX native does impose certain restrictions or whatnot on your design
exactly
like in case of microkernels certain interfaces make no sense
I'm fine having a broken or lacking implementation of POSIX to allow for more freedom for my design
but you can certainly emulate them for programs that want it
and if somebody is complaining about that,
a) wtf are you seriously targeting my system
b) use the native interface instead
hmm this is weird, when I use execve instead of execl, nothing breaks
as seen here
maybe my usage of execl is just wrong
maybe you just implemented it so well that nothing wants to break
maybe it's has an extra bug which cancels the first one out 
[ LOG ] User thread 7 SIGSEGV
[ DEBUG ] Exitting process 2 after receiving signal 11

that's a GPF probably
otherwise it would've printed cr2
if it were a PF
[ LOG ] (thread 7) syscall Sys_ExecVE(0x3a4000, 0x1017, 0xbfefa0, 0xe7fe00, 0x0)```
last syscall before disaster struck
qemu-system-x86_64: hw/core/cpu-sysemu.c:76: cpu_asidx_from_attrs: Assertion `ret < cpu->num_ases && ret >= 0' failed.```
bruh
CHAT
execve works in bash now
time to port coreutils
configure: error: could not determine how to read list of mounted file systems```
checking for fs_stat_dev... no
checking for fs_info.h... no
checking for BEOS mounted file system support functions... no
configure: error: could not determine how to read list of mounted file systems```
@vale nymph
help
it seems like coreutils needs statvfs
look at the vinix or ironclad sysdeps, they have some file for that
since thats linux stuff but they build with the linux option disabled
thanks mathewnd
you are welcome struct thread* oberrow;
I got it to configure
In file included from src/stat.c:19:
./lib/config.h:4831:20: error: expression in static assertion is not an integer
4831 | # define alignof _Alignof
| ^~~~~~~~
src/stat.c:879:24: note: in expansion of macro 'alignof'
879 | static_assert (alignof (STRUCT_STATVFS) % alignof (fsid_word) == 0);
| ^~~~~~~
In file included from ./lib/stddef.h:80,
from ./lib/stdio.h:77,
from src/stat.c:31:
src/stat.c:880:24: error: invalid use of undefined type 'struct statfs'
880 | static_assert (offsetof (STRUCT_STATVFS, f_fsid) % alignof (fsid_word)
| ^~~~~~~~
src/stat.c:880:24: error: expression in static assertion is not an integer
src/stat.c:882:40: error: invalid use of undefined type 'const struct statfs'
882 | static_assert (sizeof statfsbuf->f_fsid % alignof (fsid_word) == 0);
| ^~
src/stat.c:882:24: error: expression in static assertion is not an integer
882 | static_assert (sizeof statfsbuf->f_fsid % alignof (fsid_word) == 0);
| ^~~~~~
src/stat.c:883:54: error: invalid use of undefined type 'const struct statfs'
883 | fsid_word const *p = (fsid_word *) &statfsbuf->f_fsid;
| ^~
src/stat.c:888:37: error: invalid use of undefined type 'const struct statfs'
888 | int words = sizeof statfsbuf->f_fsid / sizeof *p;
| ^~
src/stat.c:910:54: error: passing argument 1 of 'human_fstype' from incompatible pointer type [-Wincompatible-pointer-types]
910 | out_string (pformat, prefix_len, human_fstype (statfsbuf));
but alas
I do have statvfs in abi-bits
and it is installed through install_headers
same thing with statfs.h
oberrow@AcerAIO:~/Code$ x86_64-obos-gcc test.c
test.c: In function 'main':
test.c:5:12: error: variable 'fs' has initializer but incomplete type
5 | struct statfs fs = {};
| ^~~~~~
test.c:5:19: error: storage size of 'fs' isn't known
5 | struct statfs fs = {};
with my test program the same happens
statvfs works
in fact, I can't even find the header for statfs
man page says that
tried both headers, neither of them exist
ok I think I just need to copy them from the linux option
lib/freadseek.c: In function 'freadptrinc':
lib/freadseek.c:69:3: error: #error "Please port gnulib freadseek.c to your platform! Look at the definition of getc, getc_unlocked on your system, then report this to bug-gnulib."
69 | #error "Please port gnulib freadseek.c to your platform! Look at the definition of getc, getc_unlocked on your system, then report this to bug-gnulib."
fuck u
yeah gnulib is a piece of garbage
idk who though it was a good idea
you need to define SLOW_BUT_NO_HACKS
add -DSLOW_BUT_NO_HACKS to the CPPFLAGS variable when you configure coreutils
ok
horray
I have coreutils for obos
./configure --host=x86_64-obos CPPFLAGS=-DSLOW_BUT_NO_HACKS=1```
although that's how I added it to CPPFLAGS, idk if that's correct
patching file /home/oberrow/Code/obos-pkgs/repos/coreutils-9.5/build-aux/config.sub
Hunk #1 FAILED at 1745.
1 out of 1 hunk FAILED -- saving rejects to file /home/oberrow/Code/obos-pkgs/repos/coreutils-9.5/build-aux/config.sub.rej```
bruh
it configured
after doing some fnuy stuff
I did cp patches/bash/config.sub.patch patches/coreutils/config.sub.patch
then modified the line info in patches/coreutils/config.sub.patch
you could also patch automake and then copy the patched config.sub file from it to everywhere else
or run autoreconf with automake from your patched install in PATH, that should also regenerate it afaik
so for some reason
bash dislikes space
[ LIBC ] __cxa_guard_acquire contention```
bruh
I removed my stubs for tcsetattr and tcgetattr
to be greeted with that
then a SIGILL
before a batch prompt
well I'll be damned
diff --git a/sysdeps/obos/generic/sysdeps.cpp b/sysdeps/obos/generic/sysdeps.cpp
index 78106564..1965770d 100644
--- a/sysdeps/obos/generic/sysdeps.cpp
+++ b/sysdeps/obos/generic/sysdeps.cpp
@@ -453,7 +453,7 @@ int sys_vm_unmap(void *pointer, size_t size)
return sys_anon_free(pointer, size);
}
-int sys_tcgetattr(int fd, struct termios *attr)
+/*int sys_tcgetattr(int fd, struct termios *attr)
{
infoLogger() << __func__ << " is unimplemented" << frg::endlog;
return 0;
@@ -462,6 +462,6 @@ int sys_tcsetattr(int, int, const struct termios *attr)
{
infoLogger() << __func__ << " is unimplemented" << frg::endlog;
return 0;
-}
+}*/
} // namespace mlibc
these were my only changes
fuck this
[ LIBC ] __cxa_guard_acquire contentionοΏ½οΏ½
[ LOG ] User thread 6 SIGILL```
--- a/sysdeps/obos/generic/sysdeps.cpp
+++ b/sysdeps/obos/generic/sysdeps.cpp
@@ -453,15 +453,4 @@ int sys_vm_unmap(void *pointer, size_t size)
return sys_anon_free(pointer, size);
}
-int sys_tcgetattr(int fd, struct termios *attr)
-{
- infoLogger() << __func__ << " is unimplemented" << frg::endlog;
- return 0;
-}
-int sys_tcsetattr(int, int, const struct termios *attr)
-{
- infoLogger() << __func__ << " is unimplemented" << frg::endlog;
- return 0;
-}
-
} // namespace mlibc
meanwhile the diff
mlibc is trolling
a hello world program worked
fuck bash
Guys I got school tomorrow
So likely less osdev
And I gtg for the rest of the day probably
So yeah
If anyone has an idea of why the actual fuck this happens
It would be nice if you could suggest something
x/i 0x4124211a
0x4124211a: 0f 0b ud2

I suspect it is a problem within the kernel, and not because of some dumb thing I added to my mlibc sysdeps
I turned on debug mode, to be greeted by:
bruh
I set a breakpoint for before that node was made
set a watchpoint
after it's creation
then, to my dismay
Linked lists skill issue?
my linked lists are good, it's my
dare I say
||allocator||
wtf happened
the kernel was stable two days ago
stashing my latest changes causes the problem to disappear
so it's probably something stoobid I did
omg
the reason I was getting the mlibc error
was because I was somehow mismatching mlibc versions
[ LOG ] (thread 7) syscall Sys_FdSeek(0x1, 0x0, 0x1, 0x0, 0x0)
[ LOG ] (thread 7) syscall Sys_FdSeek returned 0x0000000000000002
in cat
0x0000000000000002=OBOS_STATUS_INVALID_ARGUMENT
which makes sense, what does seeking stdout even do
*makes sense for me
bash-5.2# /usr/bin/cat /test2.txt
cat: standard output: Operation not implemented (ENOSYS)
[ LIBC ] hit io_seek() error 22```
I get that log from mlibc too
yeah what is a seek on stdout supposed to do
for some reason it works when I put it in a debugger
I suppose I need sys_fstat and sys_stat
the former doesn't exist, so just sys_stat
while I'm doing that, I will be implementing the sys_opendir and sys_readentries sysdeps
fsfd_target fsfdt
I wonder what the point of that parameter is...
perhaps it is so that the kernel can verify that the stated file is actually what the program expects, since iirc, it's not in struct stat
figured out what that does
todo tomorrow probably: sys_fstatvfs
and probably also sys_statvfs
idk
[ LIBC ] In function fstat, file ../options/posix/generic/sys-stat.cpp:150
__ensure(Library function fails due to missing sysdep) failed```
as cat complains about that
[ LIBC ] In function fcntl, file ../options/posix/generic/fcntl.cpp:24
__ensure(Library function fails due to missing sysdep) failediled```
and that too
i donβt know where but i saw such a panic kernel somewhere
Bump
oberrow why you blocked me π
the duck is not so bad that it should be blocked
I can't send it to him friend and react him
but why idk
obos error codes
src/oboskrnl/error.h
I do it in mlibc sysdeps
Translate obos status to errno
oberrow doesn't love me π
I unblock you
Duck spam was getting annoying
I no more duck spamming
now it's just spamming
where
mOSs curse
lmao
How's OBOS going?
A mix of git merge and obos code style being terrible probably
Yeah I have no idea
When I looked at it
I will be fixing that
School started, less time to work on it
write code on the phone
Unfortunate
https://github.com/OBOS-dev/obos/blob/master/src/oboskrnl/locks/mutex.c#L45-L56 I was looking at this and noticed that what if success is set to false and then on the next test of the while condition you actually end up acquiring the lock, success is still false and u end up with a deadlock I think?
unlikely scenario obviously but
you need some whitespace in that code goddamn
Bru
There's a reason I don't look at OBOS code
Bruh
lmao
Lmao
nyaux.
real
meanwhile floppa os:
// Dispatch based on the operation
if (flopstrcmp(operation, "sin") == 0 && arg_count > 2) {
result = sin(flopatof(arguments[2]));
} else if (flopstrcmp(operation, "cos") == 0 && arg_count > 2) {
result = cos(flopatof(arguments[2]));
} else if (flopstrcmp(operation, "tan") == 0 && arg_count > 2) {
result = tan(flopatof(arguments[2]));
} else if (flopstrcmp(operation, "sqrt") == 0 && arg_count > 2) {
result = sqrt(flopatof(arguments[2]));
} else if (flopstrcmp(operation, "exp") == 0 && arg_count > 2) {
result = exp(flopatof(arguments[2]));
} else if (flopstrcmp(operation, "log") == 0 && arg_count > 2) {
result = ln(flopatof(arguments[2]));
} else if (flopstrcmp(operation, "pow") == 0 && arg_count > 3) {
result = pow(flopatof(arguments[2]), flopatof(arguments[3]));
} else if (flopstrcmp(operation, "deg_to_rad") == 0 && arg_count > 2) {
result = deg_to_rad(flopatof(arguments[2]));
} else if (flopstrcmp(operation, "rad_to_deg") == 0 && arg_count > 2) {
result = rad_to_deg(flopatof(arguments[2]));
} else if (flopstrcmp(operation, "abs") == 0 && arg_count > 2) {
result = fabs(flopatof(arguments[2]));
} else {
echo("Unknown or invalid 'flopmath' operation. Available operations:\n", RED);
echo("sin, cos, tan, sqrt, exp, log, pow, deg_to_rad, rad_to_deg, abs\n", WHITE);
return;
}
π
jesus
lol
you know you could make an array of strings+function pointers and loop over it
just an idea
they cant win
there is always shkwve
although i guess i actually use a code formatter because im too lazy to turn off format-on-save
and i have actual complex logic
like a 700 loc NFA generator
with 4 comments total
i do donβt worry this is being deprecated ππ
π
wth
time for statfs I think
nvm this
yeah so I don't have anything in my driver interface
for sys_statvfs
I am able to get cat to run
but not work
before it would complain about statvfs
now it doesn't, but when I type stuff, it doesn't work as expected (echoes stuff back at me)
trying to do a file causes EFAULT somewhere
statvfs can be implemented with statfs afaik
statfs is a linux sysdep
and I don't got linux sysdeps
I also implemented sys_statvfs
ah yeah
[ LOG ] (thread 7) syscall Sys_ExecVE(0x3a4000, 0x5a3e7, 0xc7efe0, 0xe7fe00, 0x0)
[ LOG ] (thread 7) syscall Sys_ExecVE returned 0x000000000000001f```
execve returned OBOS_STATUS_PAGE_FAULT

nvm, that is the content of test2.txt
I fixed that
and another bug with execve
this is an unrelated question but do you do lazy ipl in obos? because I'd be interested in knowing how does that work
or how you implement it if you do ig
#elif OBOS_LAZY_IRQL
irql irql_ = OBOS_IRQ_VECTOR_ID_TO_IRQL(frame->vector);
if (irql_ < CoreS_GetCPULocalPtr()->currentIrql)
{
CoreS_SetIRQL(irql_, CoreS_GetIRQL());
CoreS_DeferIRQ(frame);
CoreS_SendEOI(frame);
return;
}
if (!CoreS_EnterIRQHandler(frame))
return;
CoreS_SendEOI(frame);
irql oldIrql2 = Core_RaiseIrqlNoThread(irql_);```
This is in the IRQ dispatcher in my IRQ interface
if you can't see what that does, it first checks if the IRQL the vector can run at is less than what the current irql should be
if it is, then it continues on with it's life
otherwise it sets the IRQL in cr8 (CoreS_SetIRQL)
then defers that IRQ in an arch-specific way (CoreS_DeferIRQ)
sends an EOI, then returns
#if !OBOS_LAZY_IRQL
CoreS_SetIRQL(to, *Core_GetIRQLVar());
#endif
in raise irql it does that simple check
to see if it should set the IRQL in cr8
on x86_64 this does a self IPI on frame->intNumber
what does that ipi do?
it makes it so that when cr8 is lowered < the IRQL that the IRQ can run at, the IRQ gets run again
ah so you basically let the cpu handle re-running the irq after the irql is lowered
yup
that's actually pretty smart, thanks for the explanation
np
i fixed it
it's in the UART driver
I believe I fixed it
-smp cores=4,threads=1,sockets=1
0xffffffff800315d5 <+2069>: 48 8b 04 25 28 01 00 00 mov rax,QWORD PTR ds:0x128```
clang is being mysterious
driver->ftable.get_blk_size(to_stat->desc, &blkSize);
generated after this line of code
apparently driver is null
I think I found it
now it hangs for a bit then triple faults
anyway
I implemented the sys_open_dir and sys_read_entries sysdeps
year of the obos desktoip
fr
bruh
why is it trying to read_entries on stderr
[ LOG ] (thread 10) syscall Sys_OpenDir(0x0, 0x916dbc, 0x0, 0x0, 0x0)
[ LOG ] (thread 10) syscall Sys_OpenDir returned 0x0000000000000002
[ LOG ] (thread 10) syscall Sys_ReadEntries(0x2, 0xcff018, 0x800, 0xcff010, 0x0)
[ LOG ] (thread 10) syscall Sys_ReadEntries returned 0x0000000000000002```
interesting
oopsie
how fun
status = OBOSH_ReadUserString(upath, nullptr, &sz_path);
if (obos_is_error(status))
{
if (statusp)
memcpy_k_to_usr(statusp, &status, sizeof(obos_status));
return HANDLE_INVALID;
}```
returned from there in Sys_OpenDir
upath is nullptr

I think I know what it is
