#OBOS (not vibecoded)
1 messages · Page 38 of 1
was passing some bogus stuff to reallocate
I was able to connect to the gdbstub
but memory reading isn't quite working
yeah so
uh
the received packet from GDB that is querying the memory
is corrupted
this gdbstub seems to be dogshit
it can't even receive packets properly anymore
without completely trashing the kernel's state, of course
Why not just use qemu gdbstub?
okay I fixed that bug (I removed a printf and it magically started working again)
and I also fixed a bug with memory reading/writing (I think)
now breakpoints aren't working
uintptr_t phys = 0;
MmS_QueryPageInfo(Mm_KernelContext.pt, bp->addr, nullptr, &phys);
if (!phys)
{
response = "E.Page fault";
goto respond;
}
bp->at = *(uint8_t*)Arch_MapToHHDM(phys);
*(uint8_t*)Arch_MapToHHDM(phys) = X86_INT3;```
something tells me something like this might be a problem
because like instruction cache or something
but this is x86-64 where the cpu does all the caching work for me, right?
ah wait I'm dumb
uintptr_t phys = 0;
MmS_QueryPageInfo(Mm_KernelContext.pt, bp->addr, nullptr, &phys);
if (!phys)
{
response = "E.Page fault";
goto respond;
}
+ phys += (bp->addr & 0xfff);
bp->at = *(uint8_t*)Arch_MapToHHDM(phys);
*(uint8_t*)Arch_MapToHHDM(phys) = X86_INT3;```
iirc Arch_MapToHHDM doesn't align the passed physical address, so I should be fine there...
okay it works
and it's still just as slow as it was before, but alas
anyway this is only over serial
I am now going to implement the UDP backend for it
done
time to test it
bruh
no route to host
(gdb) target remote 192.168.100.2:1534
`/home/oberrow/Code/obos/out/oboskrnl' has changed; re-reading symbols.
could not connect: No route to host.```
oh
yeah it needs to be udp
oopsie
ok the remote receives the UDP packet, notifies the UDP backend that it got a packet, then nothing
wireshark shows no response from the remote
so it's probably hanging
and if the port were unbound it would've printed destination unreachable on the debug logs...
ok so this is going terribly
so for some reason
it only ever reads $
it does receive a full UDP packet
oopsies
const size_t nRead = OBOS_MIN(blkCount, hnd->curr_rx->sz);
- memcpy(buf, hnd->curr_rx->buff, nRead);
+ memcpy(buf, hnd->curr_rx->buff+hnd->rx_off, nRead);
printf("Read: %.*s\n", nRead, buf);
hnd->rx_off += blkCount;```
should be the solution
holy shit
I connected
to a gdbstub
over the internet
on OBOS
and also, it's faster than GDB stub over serial
for some reason
on real hw?
or like faster than qemu serial on real hw
faster than qemu serial on real hw with udp
yeah that makes sense considering literally every serial write is a vmexit
nice
I also want to see if I could use this interface for user input/output for bash
on real hw
also a gdbstub would only follow a specific thread could be useful
but that's gonna be an experiment for another time
okay so the gdb monitor command crashes the kernel
why
page fault
currently debugging
made a typo while memcpying something
I think
nvm
size_t commandLen = strchr(arguments, ' ');
if (commandLen != argumentsLen)
commandLen -= 1;
char* command =
(char*)memcpy(Kdbg_Calloc(commandLen+1, sizeof(char)), arguments, commandLen);```
commandLen = -1
arguments in this case should be "ping\0"
im starting to think oberrow is the reason they made memory safe languages 
argumentsLen = 4 in this case
I think my strchr has regressed
that, or arguments isn't null-terminated
char* arguments = Kdbg_Calloc(argumentsLen + 1, sizeof(char));
nvm
it's really stupid how the people at GNU thought "ah yes let's make the gdb server protocol send hex for the monitor command"
what if I
use my gdbstub
to debug my gdbstub
inb4 triple fault 
oh yeah btw the bug in particular is a buffer overflow
hmm why is commandLen = -1

yeah so basically
it's not reading the arguments properly
I fixed the bug
I forgot to initialize argumentsOffset in the packet dispatcher when I was fixing it
I was able to connect to the gdbstub on a different machine too
I just needed to forward a port
I should forward it on my router, what could possibly go wrong 
anyway so having a gdbstub on real hardware is pretty damn cool
it'd be interesting to see if this works after wake-from-suspend
although it wouldn't work until wake-from-suspend has completely woken the computer
cuz like
the r8169 driver would be dead
and drivers are waken up last
// in OBOS_Suspend
for (driver_node* node = Drv_LoadedDrivers.head; node; )
{
if (node->data->header.ftable.on_wake)
node->data->header.ftable.on_wake();
node = node->next;
}
Core_MutexRelease(&suspend_lock);
OBOS_Log("oboskrnl: Woke up from suspend.\n");
return OBOS_STATUS_SUCCESS;
}
Be careful since UDP does not guarantee packet delivery
ye
I did try
it hangs
and stops responding to ARP requests
I love it when the kernel randomly stops responding to ARP requests
and basically any requests
Just port Mesa, be the uDRM test kernel, and let it restore the framebuffer after sleep
i mean linux is already the uDRM test kernel
bruh
ok so for some reason
when a memory read in the gdbstub
passes a page boundary
it hangs
btw there is a nice thread safety analysis in clang (that korona originally mentioned about), https://clang.llvm.org/docs/ThreadSafetyAnalysis.html, basically it can warn you when you eg. acquire the same lock multiple times, when you call a function requiring a specific lock to be held or when you forget to release it (and there is also an attribute to make it warn if you access a specific field/variable without holding a lock though its kinda broken and doesn't report if you lock the lock of an another object and access the field in an other one, hopefully that gets fixed)
idk how much do you compile obos with clang but I though it's worth mentioning in case you are interested
@haughty abyss since OBOS seems to have at least semi-functional networking, a kernel pwn chall against OBOS would maybe be fun 
well it's a reversing challenge too (reading OBOS source code) 
no but like, function names and such
I tried reading the OBOS suspend code, and I genuinely couldn't tell at what line the actual suspend happens
(me skill issue)
line 92
of src/oboskrnl/power/suspend.c
if you started reading at suspend.h
it would lead you to OBOS_Suspend
in suspend.c
which starts a mysterious worker thread that starts in static void suspend_impl() (wonder what that could be doing)
static void suspend_impl()
{
if (OBOS_WokeFromSuspend)
{
// do shit
}
// NOTE: It is up to the arch to unsuspend the scheduler.
Core_SuspendScheduler(true);
Core_WaitForSchedulerSuspend();
// printf("good night\n");
OBOS_ECSave();
OBOSS_SuspendSavePlatformState();
uacpi_prepare_for_sleep_state(UACPI_SLEEP_STATE_S3);
UACPI_ARCH_DISABLE_INTERRUPTS();
// good night computer.
uacpi_enter_sleep_state(UACPI_SLEEP_STATE_S3);
while(1)
asm volatile("");
}```
huh what
it works until it tries to transmit the packet
the packet is 5022 bytes long...
I wonder if that has anything to do with it
/*
* From RFC791 (IPv4 specification)
* It is recommended that hosts only send datagrams
* larger than 576 octets if they have assurance that the destination
* is prepared to accept the larger datagrams.
*/
uint16_t packet_length;```

OBOS_NO_UBSAN obos_status Net_FormatIPv4Packet(ip_header** phdr, void* data, uint16_t sz, uint8_t precedence, const ip_addr* restrict source, const ip_addr* restrict destination, uint8_t lifetime_seconds, uint8_t protocol, uint8_t service_type, bool override_preferred_size)
{
if (!phdr || !data || !sz || !source || !destination)
return OBOS_STATUS_INVALID_ARGUMENT;
if (!override_preferred_size && sz > IPv4_PREFERRED_PACKET_LENGTH)
return OBOS_STATUS_INVALID_ARGUMENT;```
and IPv4_PREFERRED_PACKET_LENGTH = 576,
last time I checked, 5022 > 576
that still doesn't explain why it doesn't respond to arp requests
yeah so debugging this is boring as shit
so I'm just going to push the code
I think it's because for some reason DPCs don't really get called...
which is bizzare
theoretically on each timer IRQ it should be lowering irql to < IRQL_DISPATCH
triggering DPCs to be dispatched
but idk
yeah it's contantly being lowered to < IRQL_DISPATCH
on timer IRQs
there was some problem i ran into with using the actual lower irql function while leaving an interrupt handler
but i fixed it so long ago i dont remember what it was
irq/dpc.c
irq/irql.c
has everything relavant to dispatching DPCs n'stuff
irq/irq.c
has the code for my IRQ interface (main function in there is Core_IRQDispatcher)
my current hypothesis is the r8169 driver receives IRQs for incoming data, but the DPC it registers for actually processing the data never gets called
perhaps the kernel is spinning at >= IRQL_DISPATCH
somewhere
the 2nd packet is after a breakpoint is hit
but no further packets are received in the kernel after
at all
sent by the function Kdbg_NotifyGDB
which then calls Kdbg_GeneralDebugExceptionHandler
maybe a breakpoint being triggered at >IRQL_DISPATCH is the culprit, because then the entire GDB stub would be running at > IRQL_DISPATCH
I just noticed that acpi GPEs aren't being called
meaning that it's hanging at > IRQL_GPE (8)
but the only IRQL that is used above that is IRQL_MASKED (0xf)
which is only used in one place
irql oldIrql = Core_SpinlockAcquireExplicit(&target->dpc_queue_lock, IRQL_MASKED, false);
LIST_PREPEND(dpc_queue, &target->dpcs, dpc);
Core_SpinlockRelease(&target->dpc_queue_lock, oldIrql);```
in dpc.c
but that wouldn't be able to hang, to my knowledge
unless there is a deadlock
but the kernel would've said something about it by now, if that were the case
size_t spin = 0;
while (atomic_flag_test_and_set_explicit(&lock->val, memory_order_acq_rel))
{
OBOSS_SpinlockHint();
if (++spin >= 10000000)
OBOS_Panic(OBOS_PANIC_FATAL_ERROR, "lock hanging!\n");
}```
wait it's also used in the ec driver...
it'll probably be easier to debug this in qemu
I'm thinking about writing network subsystem in Rust for that reason
oh wait the bug only reproduces with UDP 
Why not TCP
because I don't have TCP?
anyway I feel like it'd be cool
to make the --enable-kdbg command line option better
so that it can specify stuff like serial:com1 or smth
udp:192.168.100.2:1534
although maybe that's out of scope for the kernel initialization function
Idk how sensitive GDB is, but UDP is like difficult to deal with
the bug itself is not because of UDP, but is a bug elsewhere
because at one point the kernel decides to stop receiving packets, for whatever reason that may be
anyway just pushed this code
since the most complaints about obos code readability seem to say that the naming convention is ass
I will be changing that after merging net-stack with master (which I will do after implementing TCP)
as long as it is consistently ass it is fine
or maybe not, depends on how lazy I am
it is consistent
static symbols are snake_case
structs are snake_case
any global symbols adhere to Namespace_NameOfFunction
usually it goes Namespace_NounVerb (noun is the object the function operates on, verb is the operation that should be done)
but it sometimes strays from that
and I do stuff like Core_ExitCurrentThread
even though other thread apis use CoreH_Thread*
note that namespaces also have suffixes, like S, and H
S standing for architecture Specific
H standing for Helper
marker
one note for that is that you don't actually need to disable interrupts at all, basically its enough to do smth like ```cpp
cpu_local->software_irql = new_irql
if (new_irql < cpu_local->hardware_irql) {
cpu_local->hardware_irql = new_irql
cr8 = new_irql
}
if it is interrupted before writing the new software irql then the if gets entered
if it is interrupted after writing the software irql then the interrupt will set cr8 to the new irql (which is fine if it happens either before that if or when inside it, though if its inside it then its done twice for no reason but still better than unconditionally doing it)
idk what I did and when I did it
but obos only gets 400k on master
on my PC
global Core_RaiseIrqlNoThread: function weak
Core_RaiseIrqlNoThread:
mov rax, [Arch_cpu_local_currentIrql_offset]
xchg [gs:rax], rdi
ret```
and it also seems as if my raise irql function has broken lol
oh wait I'm stupid
hmm I have an idea to optimize the allocator
that worked
changing uacpi to use the non paged allocator also speeds stuff significantly
[uACPI][INFO]: successfully loaded 1 AML blob, 1705 ops in 1ms (avg 1009939/s)
was able to get this score on my fastest machine...
do you support nested interrupts in obos?
and if yes how do you manage the stack use of them, wouldn't you need huge per thread kernel stacks for it?
a) yes
b) I don't manage that
although nested interrupts only happen with IRQs that have a greater IRQL than the IRQ before it
so most nested IRQs run at > DISPATCH level
so they won't end up doing much anyway
and currently all drivers almost immediately register a DPC to handle their IRQs
ah, ig that makes sense so then they don't really need that much space
probably the interrupt frame itself is the biggest thing at that point
ye
an example
it clears the IRQ status, starts a DPC, then returns
the uart driver does the exact same
nice
anyway, I plan to use attribute malloc to help track down memory leaks
and use after frees
statically
ok time to merge a PR that definitely does not change the allocator interface drastically just to optimize the uacpi score
git filter-branch
force push
what does that do
tbh I only use the basic subset of git
I forgor
its probably the most powerful history rewriting tool git has lol
i used it once to retroactively change my name in commits on an entire repo in one command
might learn about it then
dont
its basically never useful
and that level of rewriting history should be avoided where possible anyway
it can be nice to now ig but id at least wait until you end up with a problem that needs it lol
usually I make some changes which I then separate in 3-4 commits (because I don't like commiting unrelated changes at once, although sometimes it's fine to do a big commit)
then I push all commits
then I realize that I've introduced a bug in my first commit of this series, now I do git reset --soft <hash>, fix the bug, rewrite all the commit messages and force push
so yeah I should learn to properly rewrite history
cause that ^ works fine when you need to rewrite your last pushed commit
otherwise it's a pain and it's completely my fault for being lazy and not looking it up
hijacking obos thread cause yeah
yeah filter-branch isnt the tool for that
idk what is but it aint that one
filter-branch is for bulk rewrites
oh okay
I want to implement ICMP in obos
specifically RFC792
it shouldn't be too difficult
I will be doing some basic stuff for reception
mainly just ICMP echo replies
and notifying a user if a destination is unreachable
like if it tries to access a remote UDP port but the host returns destination unreachable or smth
I want to receive that (currently it's discarded), and abort any reads/unbind the port maybe
so currently ICMP is destroying the network stack
causes a hang
while sending a status message
in the UDP part of the stack
it's last seen sending an ARP request
ah wait that makes sense
ok so now I send an ICMP port unreachable reply
when the port is unreachable
but the only problem
is that linux doesn't give a shit
what I mean is that when I connect to other things and get a port unreachable reply back, nc exits
it does not do the same with obos
oh wait
oops
I was setting the wrong destination mac address 
okay now I am getting checksum problems
and I think wireshark is having a stroke
it's first trying to respond to this with port unreachable
Pretty cool dude
ah shi I forgot you were in this server
I think linux is discriminating against obos
update
when the ICMP packet's length is even it causes nc to stop
which means linux only wants to recognize packets with even lengths?
I want to make a change to obos-strap so that it rebuilds a package if it sees that a file dependency (and by that I mean a recipe or patch) gets modified
me when obos regression
wtf is happening
me when:
diff --git a/src/oboskrnl/mm/alloc.c b/src/oboskrnl/mm/alloc.c
index 383ea9d..1079f1b 100644
--- a/src/oboskrnl/mm/alloc.c
+++ b/src/oboskrnl/mm/alloc.c
@@ -592,6 +592,7 @@ obos_status Mm_VirtualMemoryFree(context* ctx, void* base_, size_t size)
page what = {.phys=info.phys};
page* pg = RB_FIND(phys_page_tree, &Mm_PhysicalPages, &what);
// printf("derefing physical page %p representing %p\n", info.phys, addr);
+ pg->pagedCount--;
MmH_DerefPage(pg);
}
MmS_SetPageMapping(ctx->pt, &pg, 0, true);
lmao
what the fuck
I was sure bash worked on this commit
fuck compiler optimizations and fuck gcc
Heavy on the fuck GCC
There’s alot going on here 😭
+ pg->pagedCount--;
MmH_DerefPage(pg);```
although I accidentally had that git diff command the wrong way
what would happen if multiple cores unref a page at once
destruction.
and the pg->pagedCount gets freaky
I'm just hoping _Atomic is normal
and does atomic shit
me: wants to take a small break from stuff and work on obos
meanwhile obos random regression #6547456435
there is quite fucking literally no reason
for this
I decided to change the crash to not be an assert anymore
it seems to be a bug with VfsH_PageCacheGetEntry
ok now fucking kvm
crashed
wtf is this
I can't fucking deal with this fucking shit right now
ok I figured out why
I think it's stack corruption 
or maybe a stack overflow 
there I go, fixed it
obos reminds me of like early 2021 mintia
konsole?
yuews
yes
honestly I think I now want to just make the pagecache rework thing I wanted to do a few months ago
but was busy with getting bash to work
yeah the more I think the more standby/dirty page lists make sense
and I'm here thinking, "wow my current pagecache system is absolute dogshit"
anyway
the more I read my old code the more I want to die
Read it less

why didn't I think that
so I finally got the kernel to build again
inb4 triple fault after mm initialization
surprisingly not
it hangs
sometime after loading the kernel symbol table
deadlocks on the kernel context lock
while makes perfect semse
*sense
since the dirty page writer was woken while the kernel context was locked
which is a bug
fixed that hang
now it crashes a bit later
pg = nullptr;
memcpy(buffer, MmS_MapVirtFromPhys(in->phys), pg->sz);```
I just love this code
I am getting closer to getting it to boot again
of course it hangs again
now somewhere after the COM driver finishes init, it seems
ah wait nvm
it was an infinite loop I had for debugging purposes
(it now crashes)
[ LIBC ] Unexpected PHDR type 0x464c457f in DSO libdl.so```
bruh
nice read from offset 0 in the file
yeah I was about to say that those bytes looked familiar
I think I have improved io performance a lot by making this page cache change
at the expense of the uacpi score
ok it boots
into bash
except for:
this is a bug in map view of user memory
it stopped page faulting
instead execve returns ENOEXEC
the behaviour that happens is mixed
ok yeah I'm just going to change my execve syscall
to take in a filename
😢
install libcjson-dev
on debian/ubuntu
idk what the arch package is
probably something similar
only cjson
install that ig
now it gives me this.
it would probably be a good idea to mention that in the docs
oops yeah
oh fuck no it wants to build a cross-compiler
well I'm training AI in the background
so that's not going to work
would you happen to have a .iso?
yes

also that's for building a full obos distro, if you jsut want the kernel, you should use method 2 of building
yeah but I want to test the full distro to see how badly I can break it
sure
obos built with clang when?
it takes a few commands until bash mysteriously crashes
the kernel can be built with clang
also that wouldn't change the fact that it'd need to build a cross compiler
since clang+llvm obviously won't accept obos into mainstream
ah I thought you needed a cross-compiler for the kernel too
it still builds the cross compiler
what you could do is
copy these two files into repo root/pkginfo
but the kernel has a configure option to build it using the x86_64-obos-gcc compiler
then do what you just did, but with x86_64-obos as the target triplet
whether it works or not, probably not
unless you change the sysroot
with that
wait what the fuck since when did that happen
oh yeah
I once fixed it but never upstreamed the changes
regression #TREE(3)
if your cpu doesn't have that, it's not an obos regression 
anyway
bash works over serial btw
use nc or smth and -serial whatever
yeah the (host) tty would need to be in cooked mode
I just need to implement
ttys one day
I don't even have to try to break it to break it 
it's not my fault you misconfigured it 
this is more of "unimplemented" than "broken"
anyway PRs for a ps2 keyboard driver and TTY support are welcome 
also that build does not have the network stack
@sweet compass did it work? (or did you give up?)
oops
obos for quantum computers

same thing happens after wake from suspend 
yeah but anyway
obos now has sys_sync
it probably wouldn't have been possible with the old page cache system
obos has a bug with the initrd driver where if the path starts with./ it kind of shits itself
which I found out when I wrote the oboskrnl recipe for obos-pkgs
it'd be interesting to see if I could get the obos package repo to work
for linux
sometimes I look at my code and wonder
what brought me to do all this
spend all this time
that could've been used to do anything else
there's nothing else better
obos is a great achievement
ye-```
)
( /( (
)()) ( ( ( )\ ) (
(()\ ))\ )( ( ))(() ) ( /( ( )\ ( (_ ((_)/((_)(()\ )\ ) /((_)_ /(/( )(_)) )\ )((_) )\ | |/ /(_)) ((_p) _(_/( (_)) | | ((_)_\ ((_)_ _(_/( (_) ((_) | ' < / -_) | '_|| ' \))/ -_)| | | '_ \)/ _ || ' ))| |/ |
||_\| || |||| _||_| | ./ _,||||| ||_|
|_|
Kernel Panic in OBOS b3f451c8534626837090ad27ee7446e2867016e9-dirty built on Feb 19 2025 at 20:17:24.
Crash is on CPU 0 in thread 6, owned by process 1. Reason: OBOS_PANIC_ASSERTION_FAILED.
Currently running on a Intel(R) Core(TM) i5-4590T CPU @ 2.00GHz. We are currently running on a hypervisor
Information on the crash is below:
Assertion failed in function Free. File: /home/oberrow/Code/obos/src/oboskrnl/allocators/basic_allocator.c, line 342. reg->alloc_size == nBytes
Address Symbol
ffffffff80015030 oboskrnl!Free+4d0
ffffffff80033749 oboskrnl!Sys_FdOpen+139
ffffffff8000c332 Unresolved/External
0000000000000000 End
Address Main TID Driver Name
ffff9000000ec000 -1 Initial Ramdisk (InitRD) Driver
ffff9000003a8000 -1 Bochs VBE Driver
ffff9000003d2000 -1 COM Driver
ffff90000022a000 -1 FAT Driver
I can't even read a doc to write something and your os is the first to implement suspend for one
yes
like it is pretty cool
it's just
yes
anyway brb
I need to make a FIXME list for obos soon
some drivers have been starting to regress
and I was "fixing" that by not loading them

I look at hobby osdev not as a thing to make something useful but as a learning process
I think I will do that
I'll use github issues
for easier tracking
anyway, I feel like implementing some sort of init program for obos
that just does (add something useful here) then starts a shell
or what it hands control to will be configurable
(add something useful here):
- fork-and-exec a graphical tty host
Fine. I will finally implement TTYs
nvm that was because the thing was being compiled in debug mode
-O0 
pass a pointer to it as an operand to an inline asm block with no instructions and it cant optimize it out
Lol
That's the proper fix for that
me: does nothing
meanwhile obos:
[ LIBC ] __cxa_guard_acquire contention
[ DEBUG ] (thread 7) syscall Sys_LibCLog returned 0x0000000000000000
[ LOG ] User thread 7 SIGILL
[ DEBUG ] Exitting process 1 after receiving signal 4
ah it only happens when I change one of the arguments passed to /init
fuck this shit
uh oh
the Mm_AnonPage page is kind of not all zeroes
either it was corrupted
or I forgot to zero it
it was corrupted 
so today I discovered a bug
I kinda accidentally added this to the standby list
did you fix it?
no

could it be this memzero? The kbase has been aligned down (from Mm_MapViewOfUserMemory) and when you add the phdrs[i].p_filesz to it you are missing the removed padding, essentially zeroing the wrong range. https://github.com/OBOS-dev/obos/blob/26aebb546fd794872c2f23dff1287bf53ae7cdcd/src/oboskrnl/elf/load.c#L224
The padding removed:
uintptr_t real_base = phdrs[i].p_vaddr;
real_base -= (real_base%OBOS_PAGE_SIZE);
so add it back
memzero((void*)((uintptr_t)kbase+phdrs[i].p_filesz+(phdrs[i].p_vaddr%OBOS_PAGE_SIZE)), phdrs[i].p_memsz-phdrs[i].p_filesz);
kbase = Mm_MapViewOfUserMemory(ctx,
(void*)real_base,
nullptr,
real_limit-real_base,
0,
false, // disrespect user protection flags.
&status) + (phdrs[i].p_vaddr % OBOS_PAGE_SIZE);```
the padding is indeed readded
ah ok nvm
BUT this will help finding the actual bug
yeah it's sometime after a Mm_MapViewOfUserMemory
probably happens at the memcpy above it
because of a bug in Mm_MapViewOfUserMemory
well well well...
it indeed is a bug in Mm_MapViewOfUserMemory
holy...
lol
although in no case is said memory writable...
it's somewhere in the elf loader
and that's all I know
what exactly is wrong here?
0x7a800000 is the physical address of the anon page
that was in map view of user memory
ok so it isn't in the elf loader
it happens at precisely line 117 of arch/x86_64/execve.c
in memcpy_k_to_usr
oh
anyway
so that bug was fixed
but fork seems to be broken
or rather execve
maybe this is the same bug
that crashes bash
holy
there is no way that bug in bash
this entire time
was caused because
of the rip of the entry being zero
when it shouldn't
what the fudge
I think the elf loader is failing...
I will test that theory in a bit
the bug is that
the user stack is the only thing that isn't nuked by execve
and then the program is trying to be loaded somewhere where the stack exists
therefore: OBOS_STATUS_IN_USE from Mm_VirtualMemoryAlloc
uh oh
for some reason
the kernel accidentally reallocates a handle
I fucking hate userspace
why can't it just be fucking normal
and not fucking crash
I hate this
I hate this.
[ DEBUG ] (thread 7) syscall Sys_FdSeek(0x2, 0x0, 0x1, 0x0, 0x0)
[ DEBUG ] (thread 7) syscall Sys_FdSeek returned 0x0000000000000000
[ DEBUG ] (thread 7) syscall Sys_FdTellOff(0x2, 0x0, 0x0, 0x0, 0x0)
[ DEBUG ] (thread 7) syscall Sys_FdTellOff returned 0x0000000000000000
[ DEBUG ] (thread 7) syscall Sys_FdRead(0x0, 0x915c5f, 0x1, 0x915c28, 0x0)
[ DEBUG ] (thread 7) syscall Sys_FdRead returned 0x0000000000000000
[ LOG ] User thread 7 SIGSEGV (rip 0x0, cr2 0x0, error code 0x00000014)
anyway
I just closed https://github.com/OBOS-dev/obos/issues/34
so nice to be able to run bash without constant crashes
ran kill -sKILL 3

I want to implement whatever is needed for getrusage one day
my friend said he is going to implement "minigames" for obos
so I am going to see where that goes
cc @candid cape
btw this code is still untested
lollll
I have come such a long way
idk why but I have an urge to add a c++ interface to the kernel for drivers
so I can make c++ drivers and abstract kernel objects behind OOP
based
This is the way
High level abstractions>
WTF IS AN EXO KERNEL
what was the bug
basically, sometimes stacks were allocated at the same place as where the ELF wants to be loaded
and I didn't unmap user stacks in execve
for some reason
what the fuck
therefore the elf loader failed
but I never checked for that
since I did a dry run beforehand
bruh
and then the aux values including the entry
were nullptr
so when control was handed off it jumped to nullptr
hmm for some reason
signals never get ran
when signalling the current thread
unless it's a bug with fork
it isn't any of that
basically OBOS_SyncPendingSignal is never getting called
for that specific user thread
because it's never actually leaving an IRQ handler, which is where that is usually called
void CoreS_ExitIRQHandler(interrupt_frame* frame)
{
if (~frame->cs & 0x3 && CoreS_GetCPULocalPtr()->currentThread)
CoreS_GetCPULocalPtr()->currentContext = CoreS_GetCPULocalPtr()->currentThread->proc ? CoreS_GetCPULocalPtr()->currentThread->proc->ctx : &Mm_KernelContext;
else
OBOS_SyncPendingSignal(frame);
cli();
}```
What if I do networking after the sleep stuff?
wrong thread?
where is DNS even usually done, kernel mode or userspace?
usually its done in the libc
pretty sure linux does dns in userspace (libc)
But you still need a bunch of stuff for it?
udp sockets
Like you probably want dnsmasq or something
does mlibc do it?
yes
ok so no need to worry about that
that's only required for server
usually for client the dns queries are sent to whatever nameserver, either the router or some public one like 1.1.1.1
when managarm dns server??
unless you want something like kgdb be able to connect via a hostname 
isn't kgdb usually the other way around
the kernel just has the gdb stub
and someone connects to it
what does the hostname have to do
ah yeah, klog would be a better candidate for that
though it could also be initialized by the listener side if it knows how to access the sender side
ok now I am pink
this thread will be locked now, as the OP has been banned (reason, see here: #modmail message)
#modmail message welcome back i guess
hi guys im back
wb
welcome back
^ Xorg and xeyes running on obos natively
that is my last progress report i posted on my obos server
last month
but what is happening now:
i am fixing ext2 driver bugs
and also getting mad at qemu because it's segfaulting
because of this
although luckily my ahci driver manages to relatively consistently reproduce the bug
which someone else (with my help) managed to narrow it down to a race condition in the ahci virtual device in qemu
I also wrote an audio server for obos
it aint the greatest but it's honest work
(it can be found here)
I did fix this bug pretty recently
void CoreS_ForceYieldOnSyscallReturn()
{
ipi_vector_info vector = {
.deliveryMode = LAPIC_DELIVERY_MODE_FIXED,
.info.vector = Core_SchedulerIRQ->vector->id + 0x20
};
asm volatile ("cli");
static ipi_lapic_info self = {
.isShorthand=true,
.info.shorthand=LAPIC_DESTINATION_SHORTHAND_SELF
};
Arch_LAPICSendIPI(self, vector);
}```
with this
and then this is called if it exists at the end of blocking syscalls
i also fixed a lot of posix compliance issues with pipes, etc.
and i also have a network stack and posix sockets (including AF_UNIX, SOCK_STREAM sockets, as well as AF_INET sockets)
I have also added file creation and hard link creation to this driver
but alas, symlink creation does not work
i have also recently ported ffmpeg
and it doesnt completely work yet which i will debug some other time
who just reacted with 🫃
💀
lol
infy, have u any idea how fast symlinks work in ext2
nope
the text is stashed where the data block pointers would usually be
hm
bool dirty = false;
int ea_blocks = le32_to_host(inode->file_acl) ? (hnd->cache->block_size>>9) : 0;
bool fast_symlink = !(le32_to_host(inode->blocks) - ea_blocks);
size_t path_len = strlen(to);
if (fast_symlink)
memcpy((char*)&inode->direct_blocks, to, path_len);
else
{
obos_status status = ext_ino_resize(hnd->cache, hnd->ino, path_len, false);
if (obos_is_error(status))
{
MmH_DerefPage(pg);
return status;
}
status = ext_ino_commit_blocks(hnd->cache, hnd->ino, 0, path_len);
if (obos_is_error(status))
{
MmH_DerefPage(pg);
return status;
}
status = ext_ino_write_blocks(hnd->cache, hnd->ino, 0, path_len, to, nullptr);
if (obos_is_error(status))
{
MmH_DerefPage(pg);
return status;
}
}```
i currently have this code to set the linked path but alas, it does not work
fsck.ext2 reports that the symlink on that inode is corrupted
ill just look at an inode for a fast symlink
and see what file_acl should be
i do see that 'size' is the path length
yeah that makes sense
yeah i set i_size equal to path_len and that fixes it
u just store it in the actual inode
// if the length of a symlink is larger than 60 bytes, its stored normally
// otherwise, its stored in the inode strucutre itself
if (linksize >= 60)
err = rwbytes(fs, node, buf, linksize, 0, false, true);
else
memcpy(buf, node->inode.directpointer, linksize);
actual astral code
💀
size_t path_len = strlen(to);
bool fast_symlink = path_len <= 60;
if (fast_symlink)
memcpy((char*)&inode->direct_blocks, to, path_len);
else
{
obos_status status = ext_ino_resize(hnd->cache, hnd->ino, path_len, false);
if (obos_is_error(status))
{
MmH_DerefPage(pg);
return status;
}
status = ext_ino_commit_blocks(hnd->cache, hnd->ino, 0, path_len);
if (obos_is_error(status))
{
MmH_DerefPage(pg);
return status;
}
status = ext_ino_write_blocks(hnd->cache, hnd->ino, 0, path_len, to, nullptr);
if (obos_is_error(status))
{
MmH_DerefPage(pg);
return status;
}
}
inode->size = path_len;```
dw this is what i ended up settling on
except when i have a long symlink
everything (including debugfs and obos and fsck) starts tripping
obos thinks the link is there but also doesnt at the same time
(stat and ls do not show it, but an attempt to make the link will say it already exists on obos)
(debugfs shows it existing but doesnt allow me to stat it)
(fsck shows the same amount of files existing)
nvm it works
i mean like non fast links
welcome back
so stupid
why does sys_rmdir exist
is AT_REMOVEDIR linux specific or something
no it isnt
i personally expected rmdir just to use unlinkat with that flag
you can compile mlibc as ansi-only, then it can't use unlinkat
sir
i did just end up making sys_rmdir return sys_unlinkat(AT_FDCWD, path, AT_REMOVEDIR)
ah, that's kinda stupid it uses sys_rmdir but then it also needs unlinkat for the full functionality anyway
though I guess given that it doesn't pass any flags to unlinkat and only cares about the path part it's possible to just implement that as a sys_remove_file or smth
welcome back
thanks
Welcome back
^
i remember this this would always piss me off so fucking much
iirc the bug was in my scheduling code after all (i had come to the premature conclusion that it wasnt)
i did end up doing that
oh yeah gcc+binutils works now
and obos also now has a file server
(update on this: i literally ended up rewriting pipes like twice because my implementation was so fuckin shit)
oh dear i still havent gotten formatting done
oh dear god what will the diff be now
the ms style though is the closest to obos' preexisting style
i remember the day i added this, t'was a nice day, went on a walk at some point
man i really want to make an xhci or some sort of usb driver
but ive no idea how usb works
yeah since february my kernel has changed a shitton, too much to cover easily
back then i had a good 15 packages (in obos-pkgs, does not mean 15 ports) at most
now there are 121 packages registered in the index
and i have a lot more ports (not every port works though because posix or something)
and man was i incompetent back when i was writing the base of the kernel
the amount of bug fixes that i have had to do because "why the fuck was that code here in the first place??"
is way too much
lol i still have the example code comments in my html doc
on a separate note, obos' io speed is so terrible it hurts
500 bytes a goddamn second
or 300 in that screenshot
omg obos it's a .5 megabyte file
the bottleneck seems to be in writing back the file
weird... timeouts do not seem to be working properly
curl is setting a 1s timeout for poll, and hte kernel is returning immediately
this is like 90s era download speed
or also perhaps because i set the rx window to 4096 bytes
(i should probably increase that)
operating system
uh yeah that's what this is
ok making the rx window 16KiB improves download speed a ton
like by literal orders of magnitude
increasing the rx buffer size in the e1000 driver also improves network speeds
i will say that xbps-fetch is a lot faster for some reason
Thanks for reminding me that I need to write a network stack for my own os
np
oh tip
when u write the tcp part of the stack
do not be overwhelmed by the rfc document
at the bottom
there is an entire guide on how to process an incoming segment
in rfc793
section 3.9, "SEGMENT ARRIVES"
it describes in detail what u should do in any case
it's what saved my tcp implementation from being absolute garbage
(to the point where it tells u shit like "increase rcv.ack by seg.len bytes")
although tcp has greatly changed since... september of 1981, rfc 793 still works with modern tcp implementations
maybe one day ill implement RFC9293
but until then my tcp stack is gonna stay 44 years in the past
more operating system
i wanted to comment something but like idk
this looks cool
thx
obos updates waiting room
oh yeah
currently about to debug this
ok that was simple
turns out i forgot to initialize the timer event in pselect
i fixed some dumb memory leaks
in the userspace
because not all user memory views were being unmapped fully
i feel like it could be worth it
to make it so IRPs can get a scatter gather list
instead of a virtual address
because rn the page cache does:
- needs data from disk driver
- has physical address
- before reading, it needs that address in hhdm since
read_synctakes a virtual address - in the disk driver, it needs a physical address
- it converts the virtual address back to a scatter gather list with physical addresses
- we're back where we started with the physical address
man did i forget how much i got distracted from this server
infy can u give me a random thing to do in my kernel
im bored and i dont wanna debug ext2 or xorg
"make a usb driver" does not count btw
i know
ill debug real hardware
because that always does not lose me the will to do osdev at all!
so for some reason
on real hardware
with OBOS_DEBUG_FREE_SIZE enabled
it will hang in teh allocator
during pci init
only if that's enabled
that's just about the MDL's purpose in NT, fwiw
do you think it would be worth my time
to implement such a thing
Yeah, I think it would
They boil down to "list of pinned physical pages"
someone is working on software entropy for obos
(or well they are porting their software etnropy thing to obos)
did bro have a stroke
lol
this is what I was talking about
Oh hey, oberrow's back! 
Indeed I am
where updates
this is literally marca 
i mean the pr u linked is literally by marca
yes it is
a few days ago he was asking me when im gonna get real rng for obos
and I said prs accepted
and well
here we are
lol
I only contribute to minecraft 
Marca is going to have his rng pr merged when he fixes the shit i said
char** ret = ZeroAllocate(OBOS_KernelAllocator, count+1, sizeof(char*), statusp);
// ...
obos_status status = OBOSH_ReadUserString(vec[i], nullptr, &str_len);
if (obos_is_error(status))
{
Free(OBOS_KernelAllocator, ret, count*sizeof(char*)); // <- here
just found a vulnerability
if the user passes 5 arguments in argv to execve, but argv[4] is an invalid pointer
the kernel will free 32 bytes, when it should be freeing 40 bytes
and like
i forgot how this is a problem
brain fart, freeing less won't ever cause a problem except for memory leaked
fvwm3 is getting ENOSYS on a file open
and i have no idea
where
it is from an ioctl
(then SIGSEGV)
it was failing on FIOCLEX
for some time after finals: get fvwm3 to work
todo fix bug there
memory leaks here
i might implement virtual page locking finally
what ill do is have a flag in the struct page saying the thing is locked
as well as a bit in the PTE signifying the page is locked
in anything to do with paging out, it will check the PTE bit first
then if it's true, it will not page it out
otherwise it checks the struct page and if that bit is set, it will not page it out, else it will remap the page with the PTE "page locked" bit set
else it goes on with consideration for paging out
either i will do that
or put the pages in the working set on lock, and remove them on unlock
but i dont like that because removing a page from the working set causes it to be paged out which could be bad
What would you use this for?
I would just use the page's reference count for that purpose
As in, if the page is free of references, it goes to the standby list, modified list, or I haven't decided for anonymous sections
I forgot why I needed it
I do know I will at least want it for posix
and iirc my kernel allows pages with a positive refcount to be put on standby
and then i do some special handling to make sure that if a standby page is taken off standby, that the referencers will know to search for the page in swap
fucking
great
my pc's wifi adapter no longer exists
wtf
like, the device doesnt exist on the pci bus
???
it reappeared
fack
the memory leak bug is back
again
or wait
it's not a leak
it's just a bug with the memory stats
ok i think that's fixed
i just implemented virtual page locking
no clue if it works, all i know is that it doesnt crash anything
ext2 is putting me on the edge of my sanity
oopsie
i forgot to check permissions in Sys_OpenDir
nvm i didnt forget
fixed le bug
oh yeah
i implemented this coolish capability thing for obos a few months ago
that uses the filesystem to get permissions for certain syscalls
e.g., shutdown
it's pretty simple
essentailly, it checks if accessing the capability file would not fail, and if that is the case, then it allows it
if the file doesnt exist it defaults to root UID allow, root GID allow, and other disallow (unless otherwise specified by the syscall)
and every file is under /sys/perm
so if one wanted to disallow the net/tcp cap for all non root users (idk why), they would make /sys/perm/net/tcp, and chmod that to 110
it also works to disable a capability entirely
by making the mode zero
i am yet to actually document what capabilities actually exist, though
(ill do it eventually, right?)
i do wonder what will happen to the kernel if i try to read /dev/power_button
also todo: fix uniprocessor obos on real hardware
also todo: fix ahci driver on real hardware
it hangs
wut
only on real hardware
it has nothing to do with /dev/power_button itself, but instead with obos' stability (or rather, its lack thereof)
Lol
oh yeah an http server works on obos
PUT /dev/sda HTTP/1.1
Host: obos-dev.ddns.net
Content-type: text/html
Content-length: 15
<p>trolled</p>
hold the fuck on do i have PUT requests disabled in apache
FUCK
oh wait the root isn't / for apache
instead of fucking around with obos i should PROBABLY finish that final project due in two days that i also am presenting in two days...
that i was supposed to spend all day working on instead of bed rotting and procrastinating
also i do gotta say that obos' tcp performance is surprisingly not bad as long as obos is the server
ok wish me luck yall im gonna go make the presentation
born to use .txt files, forced to use ms powerpoint 
Just present obos instead, smh
if only
i mean i dont technically have to do it, as long as i show up to the exam im passing with at least 70
but im not tryna get a 70
from a ~90
yknow
Yeah ofc, get the most of out of your education.
im also pretty much done the majority of everything i just need do the presentation
which im doing rn
how does this thread have 51 stars
a year ago I had like absolutely nothing to show for myself
(dont unstar)
((thx))
52 now 😝
I might want to port libpcap to obos
for packet capturing purposes
I think it'd be useful at the very least for debugging the loopback interface
wow 53 stars guys im flattered
obos work in two days
after I am done my final projects for my courses
(one due tomorrow, the other due after tomorrow, the other is for music and is simply a playing test i am doing tomorrow, for the curious)
the other course is math and my final mark is just the final exam as well as the standardized test we do in Ontario for people my age