#OBOS (not vibecoded)
1 messages · Page 5 of 1
Have you looked at what allocators other OSes use?
I used liballoc at one point
Idk, like what allocation systems use professonal OSs
my previous kernel's allocator was based on it
and my current allocator is based on my previous kernel's allocator
oh no
pages are getting reallocated
when they already are allocated
This of course has to only happen now
I'll just set the kernel off with a million passes of the allocator
I should probably make the test function multithreaded
anyway I gtg now though
110,000 passes doesn't fault or anything
or break
I should just uncurse my VMM
It's the part that's cursed
the rest of the kernel is fine
the allocator isn't the problem, the VMM is
well both were the problem at one point
This is what happens when instead of making a PAGE_ROUND_UP helper you write the same logic ad hoc in multiple places
You're bound to get it wrong at one point
Is it a Linux allocator?
Why must everything I fix cause another bug
Page fault in kernel-mode at 0xffffffff8000e7f2 (cpu 0, pid 0, tid 0) while trying to read a non-present page. The address of this page is 0x0000000000000006. IRQL: 0. Error code: 0. whileInScheduler = false
Dumping registers:
RDI: 0xffffffff800471c0, RSI: 0xffff8000fee00000, RBP: 0xffff8000fee47b58
RSP: 0xffff8000fee47af8, RBX: 0xfffffffffffff000, RDX: 0x0000000000000000
RCX: 0x0000000000007000, RAX: 0x0000000000000006, RIP: 0xffffffff8000e7f2
R8: 0x0000000000000000, R9: 0x0000000000000000, R10: 0x0000000000000000
R11: 0x0000000000000000, R12: 0xffff8000fee4795c, R13: 0x0000000000000000
R14: 0xffff8000fee4795c, R15: 0x0000000000000000, RFL: 0x0000000000200206
SS: 0x0000000000000010, DS: 0x0000000000000010, CS: 0x0000000000000008
CR0: 0x0000000080010015, CR2: 0x0000000000000006, CR3: 0x000000000009e000
CR4: 0x0000000000040620, CR8: 0x0000000000000000, EFER: 0x0000000000000d00```
I fix one bug
That comes up from the VMM
The only thing I can think that could cause that is:
allocator returning bogus address (unlikely, 0x6 isn't aligned to 0x10)
memory corruption
♫ 99 little bugs in the code ♫
♫ 99 little bugs ♫
♫ take one down, patch it around ♫
♫ 137 little bugs in the code ♫
(trust me, I'll fix them eventually)
Rather that, or I'll start rewrite 5
This time, with a working VMM™
I have a feeling something isn't respecting the red zone not existing
ahem ahem libgcc ahem ahem
and that's causing stack corruption
Causing the address accessed to be 0x6
I use a special build of libgcc that doesn't use the red zone. I think you just need to modify one config file in libgcc before building.
I'm going to run the kernel's build with -fanalyzer
and see how the compiler yells at me
It found a bug with my intergration of stb sprintf
and with stb printf itself
use of uninitialized values
while calling the callback to print
All I'm getting is useless diagnostics about new() returning nullptr
It seems like memory corruption
In the VMM
How fun
So, I got pretty bored of debugging that bug
and the allocator does work when not under heavy load (uACPI)
So I decided to start making the kernel debugger
So, it almost can give pong from the ping command
lmao
now it doesn't page fault, just it still doesn't work
is that like a gdb stub or something?
gdb stub is too much work
it's going to be a very basic debugger in the kernel
#1141057599584878645 message
i can promise u in the end you will end up doing more work
except my hardware doesn't have any serial port of any sort, and I don't want to make a nic/usb driver for the sole purpose of running a gdb stub
well
a usb driver with basic serial-over-usb is probably less work than a full blown kernel debugger
and you will need usb code anyway
the ping command works
does anyone know how to make netcat not echo the characters I type
ok I got it to do that
how will you implement this
x86 debug registers
like the breakpoint for example
duh
would be simpler to just replace the first byte with int3
Well, I'd need to change the protection of the page first
so I can write to it
that's probably more complicated then just using a hardware breakpoint
or querying if a breakpoint was hit on every debug exception (assuming EFLAGS.TRAP is set)
well if it works it works
step is the next simplest, so I'll just implement that
yeah but steps.. what exactly
instruction
where
step
Steps one instruction
one instruction forward?
which out of 100 kernel threads
current
how do u set current
lol
I said simple kernel debugger
enough to be able to see rbp on panic or something
Currently, debugging on real hardware is printf
After this, it'll be fancy printf
and getline
and if a panic happens, it's printf+me recording the output of the kernel until the panic happens so I know where the panic originated
I have a slight feeling you're telling me it's not complex so I try to do it and end up ditching this and making a gdb stub
lol
I've implemented step and finish, time to test them
They will most definitely fail first try
But I might as well
step worked first try
at least the first step command did
step works
I just thought of a bug with finish
If it just goes to the next ret
the function will probably call something else
Making finish go to another function's ret
It's a pretty simple fix though
I made a very, very, very, minimal disassembler for the finish command.
It supports disassembing the entire x86 call and ret instructions (without identifying any operands)
Basically if it sees a call instruction before a finish command finishes, it increments a counter, and when it sees a return instruction, it decrements that count. If there is a ret instruction, and the count is zero, then the finish command is done executing
Well it almost works
I think
Yeah it doesn't work
Well step still works so I at least didn't break that
I fixed
it
I got finish and step working
What next
I guess continue
That's pretty simple
Just one line of code
or it should be at least
dbg_state.shouldStopAtNextInst = false;
Well it works
except it's slow af
solution: idk
I can't solve it by disabling the trap flag because of how breakpoints will work
or I could just change how breakpoints work
oh wait I messed up
I made the debugger state global
and not cpu-local
whoopsie
or thread-local
I'll make it cpu-local
in case I need to debug the scheduler or something
some parts of the state should be global, such as breakpoint info
others should be cpu-local
or I could use the scheduler in this and make it process breakpoints, but that wouldn't be very reliable because the scheduler works on every timer interrupt and not instruction
I'll need to make breakpoints use hardware breakpoints
#1141057599584878645 message
instead of that
step has a "small" bug
It steps a "bit" more than one instruction
It was a bug where the trap flag wasn't set
well it was set
but never restored in the actual context
if that makes sense
I will now implement dump registers
it's the simplest out of all commands
just a printf statement
Done:
I think I'll implement the examine memory commands
next
I'll copy my strtoull function from my previous kernel's uACPI implementation to decode those
#1141057599584878645 message
underrated and traditional feature
Nothing complicated at all
Just useful enough to debug real hardware without wanting to shoot yourself
also it's c++
It is kind of easy-to-port
As long as you have printf and some other misc stuff
RaiseIRQL/LowerIRQL
a way to get into exception handlers
ie. isr handlers
Support WinDbg 
lol
x/dec and x/hex work
I think
it does indeed work
that leaves me with:
- break
- break_at
@real pecan What happened to this?
Anyway, breakpoints will be global, not cpu-local. They will use the x86 debug registers to work because of reasons stated above
But before I get to that, I'll implement print
There is a bug with x/* that I accidentally just discovered
If there is one argument instead of the two needed
it prints all it can from the address until it decides to page fault
If there are no arguments passed it just page faults
I might also want to implement a command for setting registers and writing memory
That would be useful
I got the print command done
That only leaves me with the breakpoint commands
and the writing commands
ie. writing to memory and registers
I added a command to set the value of a register
I am now going to implement 4 commands for writing memory:
wb (write byte)
ww (write word)
wd (write dword)
wq (write qword)
Then I will implement breakpoints
Then I need to test whether the ps/2 keyboard interface works
(I added two ways to input commands, rather from serial, or from the keyboard)
Then I can consider the kernel debugger complete for now
of course after testing on real hardware
I might eventually make it a bit more complex
Right now, it's sitting at 618 lines
not including io code
that's an additional 326 lines
I just implemented breakpoints
I just need to do two more things with them
I just need to implement function name->rip conversion
It'll be simple enough
I just need to loop through the symbol table until I find the function name and I got the rip
All that's left for me to do after that is to test this on real hardware with the PS2 keyboard
Interesting...
While using the makeshift ps/2 keyboard driver
I'll fix it tomorrow
wdym
You said this would be more work than writing a GDB stub
and now I'm almost done
gdb stub can do source line stepping
and arbitrary struct views
you can only do insn level stepping which isnt useful
yes
But this is more for examining memory and system state on crash
or before a crash
In real hardware
On qemu I'd just use the gdbstub for that
I fixed the bug with the makeshift ps/2 keyboard driver
and now the debugger should be testable on real hardware
Does it work?
It indeed does
I just implemented break with function symbol names
Bruh
My power just went out
ok it's back
I got all commands implemented, but it still feels a bit incomplete
I think I'll add a disassembly
and stack trace
I'll first add a stack trace because that's easier
Then I'll use a library I used in my 2nd kernel that I used to disassemble
"ZyDis"
I got a basic stack trace command
All that's left is the disassembler
CMake was being a bitch and now I need to rewrite part of my CMakeLists.txt
No way
It DELETED some of my new files
(example: everything since the last commit)
How does this happen?
What fucking sequence of events caused this to happen?
Who asked CMake to git reset --hard HEAD?
You're implementing gdb without gdb?
Well I'm implementing it
then testing it
and if it doesn't work I use gdb
then I fix it
Anyway, I got some files to rewrite/restore
Like don't you just love it when cmake git reset --hard HEADs everything
for no apparent reason
🫠
One of the the only files that I hoped was still in the editor, kdbg.cpp, the file that has the actual debugger, wasn't in the editor
So it's lost forever

This happened while writing the dependency file for ZyDis
I would've lost my new kernel allocator if it weren't for the fact that I had it saved in another file because of the tests I made
Clion saves snapshots every time btw
I'm using notepad++ lol
It has saved me once because of accidental hard reset a few weeks worth of work
notepad++ isn't that complicated
but I'm hoping it's complicated enough to have that
the place where they'd be stored, %APPDATA%\Notepad++\backup\, has nothing
Well, if I don't want to rewrite the debugger (I don't), I could use Ghidra to decompile the debugger's functions from the usb
I do have io.cpp and init.cpp
I'm just lacking the debugger part
then I'll refactor the decompiled functions
Before I do that I need to rewrite some of the headers
and port back the allocator
I'm missing three files from the kernel debugger - 2 headers and one source file
Then I'm not missing anything else I can remember, except I need to reapply some bug fixes to the VMM and stuff
Mainly VMM bugs looking at the thread
The allocator I wrote had some bugs which I fixed but didn't document here
So I'll have fun rediscovering those
If I'm lucky, I might have debug symbols I can use to more accurately decompile the kernel
But I strip the binary before putting it into the isodir
and before I started messing with the dependencies, I had cleaned the build tree
I do however have symbol names
So I don't need to suffer and refind those
Ghidra doesn't understand else if, so I'm going to use another decompiler
Thank god I didn't use templates here
Not that I know a place where I might
but still
Yeah I ain't decompiling this
Time to rewrite the kernel debugger 
WAIT
I FOUND A STASH WITH THE KENRELE FFDEBUGGETR
*KERNEL DEBUGGER
FUCK YEAH
I GOT THE KERNEL DEBUGGER AND OTHER CHANGES BACK
Time to commit this so this doesn't happen again
also I'm backing it up here
The code is pushed for safety mesures
for future reference, if something ever accidentally git revert --hard HEADs your code, you can use git fsck --lost-found to find any lost files
Just if you ran git gc between then and the git fsck command, you have to hope the changes were stashed somewhere
I got disassembly working
(credits to ZyDis for the disassembler)
I got the syntax upside-down
I fixed the syntax to be x/i size [addr]
so that the size can be optional
why are you writing a disassembler in your kernel?
The debugger can be disabled in the kernel options
because debugging isn't very convenient without source, so this is the most I could do
add the disassembly
do you not have access to your own source code?
yeah, but I don't want to addr2line everything
why not use gdb?
just implement the protocol
I mean technically you can use the write commands to overwrite debugger state
and then you can choose the thread
I already told him he doesn't care lmao
note this
🤷♂️
This isn't supposed to be fully blown
having a kernel debugger is a good and accepted tradition, the fathers of many modern kernels incorporated one
linux is very unusual in not having one (the reason is because linux torvalds thought it made kernel dev too easy)
Fadanoid also supports Motorola 6800
you are fake news
i only support the 68000
Well windows only has kernel api stub implemented
And the actual debugging is done via a windbg app
Damn
i thought it had a bit more implemented in-kernel as the famous Kd
Tbh maybe im not that familiar with how its implemented
nor me so i don't want to give out so much rope that i hang myself with it, but it would fit in with what's been traditional in kernels
Windows also has drivers for usb, NICs, whatever communication device you can name. I don't, and I don't want to support those at the moment. If I had a USB driver, I probably would write a gdb stub instead, as gdb > than whatever I can come up with in terms of ease of use
I was also wasting time implementing uACPI so early and not getting onto the driver interface
and it took around the same time to complete the kernel api
do you not ever need uacpi?
Because you wanted to implement the driver interface in terms of it soo
Yes but its not throwaway code
Neither is this
i love to use acpi to get irq and i/o port assignments for ps/2 keyboards and such
(I hope)
so much nicer than hard-coding
depends on three things:
- If I ever implement those
- If I remember by then that I should implement a gdb stub for the kernel
- If I need a kernel debugger for real hardware by then
Now that I'm done the kernel debugger though, I can go back to figuring out why the hell there is memory corruption in the VMM when I try to initialize uACPI
any luck
Well, something is zeroing a node in the allocator
Which would be easy enough to find, except the allocator only zeroes in two places, ReAllocate when newSize < nodeSize and on most Allocate calls
nvm it doesn't in Allocate
ReAllocate is only called in the kernel debugger's getline function
I'll disable it to see if ReAllocate is the problem
or if it's something else
It isn't a problem with ReAllocate
or at least not with the kernel debugger being present
you know what would be easier?
what
oh I'm debugging on qemu right now
if that particular table causes your allocator to choke it will repro
Since I made this new allocator it did
i see
..or maybe actually read the code and figure out whats wrong
I am
Nothing is apparently wrong in the Allocate() function
So there shouldn't be a reason for the node of an object to be zeroed
at this point, I should use uACPI in user mode with Qemu's blob and my kernel's allocator
oh yeah I forgot that exists
yup
I just need to add that functionality to my kernel debugger, as it only supports code breakpoints
I'll just leave that as todo
this is the better idea
and put in a hardware breakpoint
I assume runner/CMakeLists.txt is the one I use for building uACPI's tests
acpidump -b
well should be trivial to debug now
Well that occurred because uACPI gave me a nullptr object to free
..did u not have a check for that?
somewhere
Yeah I do
In QueryObjectSize, which is used in this case to find whether an object is allocated or not, it fails automatically if !obj
Nope
It can't be the allocator if uACPI gives a null object
I've set breakpoints on the uacpi_kernel_alloc and uacpi_kernel_calloc if the value returned is nullptr
they weren't hit
no
its used everywhere in uacpi
bruh
dont tell me this entire time its been failing for u because of missing nullptr check
ive had huge issues that fall down to tiny things like that
one way is to just boot archiso or something, install acpica-utils, and run acpidump
for device trees qemu offers -M dump-dtb=filename but i'm not aware of anything like that for acpi
yeah there isn't one
how do I get the blob back onto the host
or what I do is dump the table in my kernel onto the serial port, and then have netcat piping into a file that will take the dsdt
sure
-drive file=fat:rw:some/directory/,format=raw,media=disk and mount the disk somewhere in the guest
carrier pigeon
lol
unexpected error: DSDT declares that it's bigger than dsdt.dat```

oh wait, I need to output the SDT as well
With the qemu's DSDT, it works in userspace
Time for hardware breakpoint
I put in a hardware breakpoint, and when it returns, it gives me stack corruption
The breakpoint was triggered once while the node was being allocated
and idk about anything past that because of the stack corruption
examining the region node at the time of the watchpoint being triggered, it's all zeroed
Which is.. interesting
(that should be impossible in this case, because it was already added to the list of regions of the allocator)
and it was being zeroed via a call to memzero, which only happens when the allocator object is that of the VMM
and it isn't; it's the general kernel allocator
Now I know something is trying to memzero one full page
at the region's address
I think it was here:
memzero((void*)newPd.virt, newPd.isHugePage ? OBOS_HUGE_PAGE_SIZE : OBOS_PAGE_SIZE);
for demand paging
Which explains:
a) why the stack is corrupted
b) why it's so out of the blue
c) why the allocator was still locked
but that still makes no sense
this is put at the end of Allocate:
if (freeNode == (void*)0xffff8000fee5e340)
setRWWatchpoint(freeNode);
The demand page handler would've been called by then

It seems as if the region gets freed
and then gets reallocated
so the demand page handler gets called
which makes sense looking at the logs
Just I need to confirm that actually ever happens
For future reference: debugging an allocator with a kernel debugger that uses the allocator you're trying to debug will be a bit unstable
I've decided I'm going to switch back to visual studio for developing the kernel. Even though visual studio and non-ms tools are like me with girls; they repel, it's honestly a lot more convenient than having to switch between three applications to write code (notepad++), build (wsl terminal), and debug (ddd)
Well, that wasn't the case
The problem was vmm::Allocate returned the same value twice in a row
ie. reallocated an already existing page
The only reason I think this could happen assuming my FindBase function isn't broken is memory corruption in the vmm allocator
the vmm push node function needs to push nodes in order
so it does some logic
that logic fails here
and slaps the page node at the end of the page node list
making the list out of order
causing FindBase to shit itself
That should be impossible, it changes if the address that it's trying to map can be allocated before mapping anything
and failing if it can't
I think the bug was a missing i - 1
in vmm::Free
endPd = i;
which caused the node to never be removed from the list of free nodes
causing the logic of the push node function to append the node at the end of the list even though that's not where it goes
causing FindBase to shit itself
Now I get this
This is another reason I wrote the kernel debugger
So I don't have to attach a debugger on cases like this
and so I can just get some quick info about the crash
not as a fully-fledged, source level, debugger, such as gdb
also gdb won't stop at cpu exceptions unless I tell it to
or kernel panics
and gdb can't stack trace through interrupt frames unless I do some goofy stuff in the assembly
I think that was because of a % in my PRI*64 macros
for uACPI
It finally works again
time to test on real hardware
It works
All this because of a missing - 1
Test subject one works
I shall test on dev computer (test subject 2)
then test subject 3
Test subject 2 doesn't receive keyboard input so I can't make the kernel debugger continue
I'll try test subject three
It works
I also saw some OSI calls in trace
Or whatever it was called
it also found some PCI root nodes
Idk why but it says 8 processors on a 4-core machine without hyper threading
2 thermal zones
And 135 devices
Now that my kernel is uncursed, I can continue on with the driver interface
Which I am hoping to start tomorrow
Because this screen doesn't show my reflection (I don't want you guys to know how I look), I sent a screenshot of the kernel
I'd send more screenshots but test subjects one and two have screens that show my reflection
The firmware asks if Linux is supported
Which it isn't because uACPI is based and works like the NT interpreter
not even linux says it's linux
What does linux say it is then?
windows
mainly because firmwares that check for linux usually have bugs in the linux codepaths
Yeah God forbid firmware developers test on anything but windows
Like a wise osdever said, firmware developers are the scum of the earth
#bootloaders message
I don't want you guys to know how I look
We don't really care tbh
That's just namespace devices, that don't have to match the number of CPUs that you have
But congrats on fixing it
Just pushed the bug fix
Time to work on the driver interface
if anyone want's qemu's dsdt, here it is:
@real pecan Regarding uacpi_kernel_install_interrupt_handler, is the irq parameter an interrupt vector number, or is it an IRQ for the IOAPIC or PIC? Looking the parameter passed to it from uacpi_initialize_events (FADT.SciInt), which in the ACPI documentation is said to be a vector for the PIC or the Global System Interrupt for the IOAPIC, I'm assuming the latter, an IRQ for the IOAPIC/PIC is what's passed.
The bulk of the loader is done
Mainly because I copied so much code from the previous kernel
I copied and pasted all relocation code
All that's left for the driver loader is processing the header and stuff
I got a test "driver" working
#include <int.h>
//#include <klog.h>
#include <driver_interface/header.h>
using namespace obos;
[[maybe_unused]] volatile
driverInterface::driverHeader __attribute__((section(OBOS_DRIVER_HEADER_SECTION))) g_driverHeader = {
.magic = driverInterface::g_driverHeaderMagic,
.type = driverInterface::driverType::KernelExtension,
.friendlyName = "Test driver",
.requestedLoader = {0},
.loaderPacket = nullptr
};
namespace obos
{
namespace logger
{
__attribute__((weak)) size_t log(const char* format, ...);
}
}
extern "C"
void _start()
{
(g_driverHeader);
logger::log("In test driver!\n");
while (1);
}```
I still need to finalize the driver loader function
But I'll commit now
Its the legacy number
I've finalized the driver load function
To set up a driver id and stuff
and add it to a list of drivers
I also added a separate function to start drivers
You'd call LoadDriver first with the driver's file data, then you'd use the id that the function returned to start the driver
driverInterface::StartDriver(driverInterface::LoadDriver(driverData, driverSize)->id);```
Just pushed the code for the driver loader
I can now start on the device discovery code
But it kind of depends on there being a VFS
I also added some documentation for the driver header
I think I'll start the VFS today
and merge the driver interface branch
when I'm done the VFS, I'll make a branch for device discovery
and by then, I should be able to start user mode stuff
like syscalls
then idk what I'll do
probably more userspace shit
Nice
whoops
I accidentally pushed code that doesn't compile
the kernel is sitting at 13400 loc
I just realized the names of the namespace that most functions/classes in most files in the kernel source match one of the parent directories' name
example: all functions in the vmm directory are in namespace obos::vmm
Kind of how I'm pretty sure NT organizes all functions in the kernel under a directory where the function prefix is. Like KeLowerIrql would be under $kernel_source_root/Ke
Except they did that purposefully, and I did it by accident
Anyway I should really get to my VFS
Accurate description of me coding my kernel
So, the driver loader only works on test subject one
Test subject three page faults in VerifyDriver
Test subject two panics
But it deadlocks in the printf locks
So idk what happened
And test subject 2's kernel debugger hangs in the ps/2 keyboard makeshift driver
So I had to disable it
Then when I went to test subject three I still had it disabled
So idk what happened there
Recompiling without changing any code actually DOES fix things sometimes
For example there may be an issue with the environment's header dependency tracking so it mistakenly compiles different versions of structs in a header for different compile units
so for some reason the kernel's build system isn't working on linux because path stuff
so I gotta fix that
I fixed that
Now I'm developing on my laptop to fix the makeshift PS/2 keyboard driver bug
So I added some logging to the initialization code
and it hangs while waiting for the write buffer to be empty
in the ps/2 controller
weird part is that this code was copied straight from my previous kernel
and the ps/2 keyboard worked there
just found a bug with the scrolling code?
for the kernel's console
It's a memcpy?
How does that fail?
other than page fault/gpf
Conclusion: The ps/2 keyboard emulation on test subject two sucks
I've added a contribution guide for the OS (not that anyone will, but I might as well)
btw no rust is allowed
or no pull request merge for you
I also added branch protection rules to master
So no more direct pushes to master
or github will yell at you
i find it useful to sometimes force push if i accidentally merge a pull request and forget to change something
I like how I made a branch called driver-interface-fixes, and continued to not modify the driver interface in there at all 
anyway, I did some work on the VFS
(design)
oh wow VFS design is a lot more fun than debugging the vmm and allocator
and copy+pasting driver code
trust me the vfs will be a lot cooler this time
I'm not necessarily proud of the previous one 
It'll be a node graph (which is how unix does chooses mount points) VFS
I hope
Something like that
I'll have something related to block devices
So mount points don't have to be referring to partitions
on disk
Block device registering and stuff will be the job of the driver interface though
While the VFS will use the node graph concept from unix, it won't be doing stuff the same way as unix. For example, index nodes will have a different meaning than on unix VFSes
Index nodes represent a file's data
the index node also contains user permission info
or a mount point
maybe I won't do that...
actually nvm I will
it makes enough sense
they're basically directory entries
but they also represent the file more directly
actually I think this may be unix VFS but with different names to structs
I'll read up on VFS design before going further
I might want to implement async io eventually
because cool
#filesystems message
but that might be dettering me a bit
(I've also never used async io personally)
hmmm seems interesting how sunos did mount points
I think I'll do it like that
Basically, if an index node represents a mount point, its children will be kept intact, but the data will be pointing at another inode where the search is continued
actually no it'll still point at a struct mpoint
but the struct will contain the children
where traversal will begin
my mount point structure looks like this:
struct mpoint
{
struct block_device* dev;
index_node_list root;
};```
which should be sufficient
except I'll add a field to say what index node represents it
struct mpoint
{
struct block_device* dev;
index_node_list root;
index_node* representative;
};```
block_device will be left as a todo (for now)
my inodes seem to be vnodes
On the weekend I will work on opening, reading, and maybe writing files\
then mounting
I'll make a makeshift ramdisk-like filesystem as the filesystem it'll be operating on
it won't even be a filesystem
it'll be some if statements basically
anyway sounds like a problem for future me
jesus theres a lot of messages in this thread lol
It may have the most out of any thread here
keyronex is on par and im pretty sure mintia had more but it seems to me that the thread is gone nowadays
but u gotta respect the dedication
Time to spam in the Managarm thread 
Mintia has more, and it's gone because hyenasky was banned
A lot of the messages here might as well be me debugging shit
I just fixed a bug relating to the kernel not knowing the framebuffer is mapped. It wasn't ever triggered, but it's a good thing I caught it before it would've gotten triggered.
Basically the kernel never recognized the framebuffer being mapped in the kernel context
Making it possible for the kernel to unknowingly map the framebuffer region, even though it's already mapped.
I should probably add some debug-only sanity checks in the map function
If I did have those, the two weeks of debugging for it to turn out to be a VMM bug would've been a lot shorter
Assertion failed: !isMapped(addr, size)
Is a lot more descriptive than random memory corruption and free bugs
I just added that
and first thing I get
is
Function Allocate, File C:/Code/obos/src/oboskrnl/vmm/map.cpp, Line 478: Assertion failed, "!pd.present". Attempt to reallocate address ffff8000fee00000.```
as you can see, I have very stable code
I got other things I gotta do
So I'll fix this later
oh wait
I think it's because of the hack I used in the allocator
because it has an interdependency on the vmm
aight I fixed it
I compiled the kernel with optimizations
Shits itself while starting the other processors
ie. it triple faults
It gpfs in the smp trampoline on the segment 0x8
ie. the kernel code segment
It seems to be before switching to long mode
actually
while it's switching to long mode
while reloading the descriptors
anyway, enough guess work, more jmp $
adding jmp $ makes the kernel continue onto initializing the scheduler?
making jumped_to_bootstrap volatile makes the kernel continue on with uACPI
where it panics
uACPI, TRACE: initialized GPE block _GPE[0->64], 2 AML handlers (IRQ 9)
uACPI, WARN: event initialization failed: invalid argument
uACPI Failed in uacpi_namespace_load! Status code: 7, error message: invalid argument
While initializing uACPI

if (!IOAPIC_MapIRQToVector(irq, irqHnd->GetVector() + 0x20, true, triggerMode::LevelSensitive))
return UACPI_STATUS_INVALID_ARGUMENT;```
somewhere in there
rather the I/O APIC is uninitialized (probably not)
or the redirection entry has an invalid index
oh wow debug info + optimizations = 💩
why does g++ get rid of my frame pointers
I told it not to
I think
-fno-omit-frame-pointer
I indeed do
whoopsie
my IOAPIC registers aren't volatile
I fixed those bugs
Does it still? I had the same problem a while ago
Well I never did much problem solving related to that other than guaranteeing the compiler saw -fno-omit-frame-pointer
I'll check to see if it's something goofy with my build system
It isn't
actually it could be
why doesn't the compiler command line include any optimization options
oh wait
🤦
I'm compiling the debug build files as verbose
☠️
well glad u fixed it
Oh no the problem with the frame pointer still stands
Not a huge problem, only poses a problem with debugging release builds
im sure you'll figure it out eventually omar
Eventually
eventually
Surprisingly, the kernel only uses allocates dynamically 832 kib of bytes
According to the PMM
I'll add the kernel, modules, bootloader reclaimable, and the framebuffer's size to the count
It uses 6.25 mib including those + dynamic allocations
That's too much, time to microoptimize everything
why would framebuffer count lol
Because
uhhh
why not
I'm basing this off a nPagesAllocated count
It uses 2.273 mib while optimizing for size without the framebuffer counting
meow
I wouldn't
why 
What the fuck
whats wrong
Weird af convo
true
fine 
if you want meow, ask the staff for their secret channels
but you didn't hear it from me
.!unmute @thick jolt
Unmuted @thick jolt
thanks qookie!
idk why in my channel but ok
🤷♀️
i just happened to click here
It's not gone, you can still access it
But its owner is banned for saying something along the lines of "imagine having your nice white party disturbed" or sth to that effect regarding the October 7 attack
#987861125104300083 message here
Yeah
I tested OBOS on real hardware with optimizations and it works
I've compiled with the most vigorous optimization options, -Ofast and -Oz (not at the same time of course)
and it worked without problems
on qemu and real hardware
Thats great, you’re very likely bug free then
yep!
First stable release of obos
real
obos
What about it
look at him @flint idol, he is still trying to flex
im not
i actually wanna know his progress
i want this os to succeed yk
i like obos
I'm working on VFS
Just still no work on it but the structs and what they do
I'll start tomorrow probably
which vfs?
fat32?
ohh
Bruh
I get UBSan in my kernel
and it triple faults before initialization of the gdt
bruh
stb printf
Now I got a lot of UB to fix
(or ignore)
I got it to run to processor initialization
until it panics ofc
misalgined ptr
ignored
now it fails in the VMM
while allocating pages for the allocator
which was allocating for uACPI
Where this happens:
UBSan Violation handle pointer overflow in file C:/Code/obos/src/oboskrnl/vmm/map.cpp at line 206:9
Stack trace:
0xffffffff8002fbe3: _ZN4obos6logger13panicVariadicEPvPKcP13__va_list_tag+308
0xffffffff8002faaf: _ZN4obos6logger13panicVariadicEPvPKcP13__va_list_tag+0
0xffffffff80048b6f: __ubsan_handle_type_mismatch+0
0xffffffff80049149: __ubsan_handle_pointer_overflow_abort+0
0xffffffff80034b76: _ZN4obos3vmmL11CanAllocateEPNS0_7ContextEPvm+288
0xffffffff8003983b: _ZN4obos3vmm8AllocateEPNS0_7ContextEPvmmm+524
0xffffffff8003eae4: _ZN4obos10allocators14BasicAllocator17allocateNewRegionEm+424
0xffffffff8003ba16: _ZN4obos10allocators14BasicAllocator8AllocateEm+716
0xffffffff8003ae3a: _Znwm+349
0xffffffff8003afff: _Znam+24
0xffffffff80067695: uacpi_kernel_alloc+24
0xffffffff8004ff0a: item_array_alloc+140
0xffffffff8005a200: exec_op+467
0xffffffff8005b806: uacpi_execute_control_method+360
0xffffffff80053169: do_load_table+147
0xffffffff8005396e: uacpi_load_table+40
0xffffffff8004dccd: uacpi_namespace_load+163
0xffffffff800485dc: _ZN4obos5kmainEv+446```
Sounds like a problem for tomorrow
Y'know what UBSan is annoying (my code sucks)
It's somehow messing up pages that should be zeroed
Kind of useless too
I might as well implement ASAN
(tomorrow)
Just don't have UB for ubsan to detect 😎
Howd you port that
Do you have to provide some sort of api for it to work
I think the messing up zeroed pages was somewhere else
because I'm getting page faults/general protection faults (depending on whether it was the first boot or not) in CanAllocate
It's definitely a problem in the demand page handler
Because that zeroes the pages on page fault
But
memzero((void*)newPd.virt, newPd.isHugePage ? OBOS_HUGE_PAGE_SIZE : OBOS_PAGE_SIZE);
Should keep the bytes zeroed 
Maybe if I set them to like 0xaa
and see if that is the problem
Scheduler now hangs somewhere in init
Well I'll just not do that
and instead set memory to 0xAA in the allocator's free function
To fix those bugs
and of course I'll only do that if the kernel is being compiled as debug
As expected
An issue with non-zeroed memory while allocating
page descriptors/nodes
or even worse this is a use-after-free
It's even causing problems in the kernel debugger (because it calls the allocator which calls the VMM which might be using after free or not zeroing memory)
Maybe it has something to do with this
It seems to be a use after free
Nope
Just me forgetting to zero memory
I think
My kernel seems to be cursed again
actually nvm
There is a use-after-free
Static analyzers can help with that I guess
I found nothing that useful for my problem but I guess I found a bug in gcc's static analyzer
| 80 | if (!(--cur->referenceCount))
| | ~~
| | |
| | (2) following 'true' branch...
| 81 | delete cur;
| | ~~~~~~~~~~
| | | |
| | | (3) ...to here
| | (4) pointer 'cur' is checked for NULL here but it was already dereferenced at (1)```
It thinks I'm checking if cur is nullptr
but I'm in fact trying to check if the reference count decremented is zero
does your operator delete contain an if (ptr)?
it's saying that if you take the event 2 branch, event 3/4 checks for null but event 1 (and the check for event 2) already dereferenced the pointer so the compiler assumes it is non-null
The compiler wouldn't know what operator delete does though
Except assume it follows the standard
if it's inlined the analyzer could peek into it
It isn't
looks like an analyzer bug
it's in a separate definition in another file
event 4 is not pointing at the reference count check?
yeah I misunderstood that
oops
use after free
if (!(--cur->referenceCount))
delete cur;
vmm::Free(cur->addressSpace, (void*)cur->thread_stack.base, cur->thread_stack.size);```
oberrow and a memory bug? thats impossible
and a possible nullptr dereference somewhere else
in driverIdList::Remove
It calls Find(id)
then it assumes it was found
(it returns nullptr on failure to find the id)
Now in driverInterface::LoadDriver I got a possible nullptr dereference
Rather that or it's a false-positive
false positive
Is that as trivial as ubsan
I dont know where you are finding references on how to implement these
nope
After some stubbing and implementation of the __asan_load/__asan_store functions
I got it to link
But not to run
(Far from it)
I get a triple fault
Before initialization of the GDT
Bruh
It assumes that the framebuffer request is broken
(Which would be a safe assumption if it weren't for limine filling in the structure)
Then it triple faults because ASAN tries to break into KDBG
and of course no IDT
Holy
The binary is a mb with KASAN
on
gcc kasan replaces every load and store with a function call so
Does it not on clang?
no on clang it uses the shadow space, and you have to provide an address delta to compute the shadow space address
Well that makes more sense
Where can I find the documentation
Though
Interesting
if kasan
# The shadow memory offset is calculated as:
# ShadowMemoryBase - (StartOfHigherHalf/ShadowScale).
# This ensures that the first shadow byte of the higher half ends up at ShadowMemoryBase.
# Lower half addresses become non-canonical by design
# (and KASAN should not instrument lower-half access anyway).
args += [
'-DTHOR_KASAN',
'-fsanitize=kernel-address',
'-mllvm', '-asan-mapping-offset=0xdfffe00000000000',
'-mllvm', '-asan-globals=false',
]
endif
nvm I just don't know how to use KASAN
Now I got some debugging to do
did u implement it?
Almost
I just need to some things with posioning or whatever it's called for a full implementation
nice
I have a LOT of things in the VMM I need to mark as "don't KASAN pls"
If only CMake provided a way to modify compiler options for specific files
oh wait it does
Well doing that is too much work
Even the smallest functions in the VMM have to have it disabled
(MapToHHDM)
After doing that
I get to the kdbg screen
Now a hang while starting processors
It'd be a good idea to disable KASAN in the SMP bootstrap function
The kernel's performance is 💩 right now
But I fixed the bug with my KASAN implementation that caused processor startup to hang
Maybe it's a bad idea to allow KASAN to run in the spin lock's lock/unlock functions
kasan on linux is like 3% overhead?
Maybe not in the allocator either
Well I can see the characters being printed one by one on the screen
lol
Solution is to stop KASAN from happening in the console's output routine
By the time I'm done with this, KASAN would be completely disabled everywhere lol
How is that possible if it hooks into every single load/store
Maybe linux's functions for KASAN are just really really fast
Or yours are just really really slow 
well this is the core function:
OBOS_NO_KASAN void asan_verify(uintptr_t at, size_t size, uintptr_t ip, bool rw, bool abort)
{
bool crossesPageBoundary = OBOS_CROSSES_PAGE_BOUNDARY(at, size);
if (crossesPageBoundary)
size += OBOS_PAGE_SIZE;
vmm::page_descriptor pd{};
bool present = false;
size_t ps = 0;
at -= (at % OBOS_PAGE_SIZE);
if (size % OBOS_PAGE_SIZE)
size += (OBOS_PAGE_SIZE - (size % OBOS_PAGE_SIZE));
for (uintptr_t addr = at; addr <= (at + size); addr += ps)
{
arch::get_page_descriptor((vmm::Context*)nullptr, (void*)at, pd);
if (!pd.present)
{
asan_report(addr, size, ip, rw, abort);
return;
}
#if OBOS_HAS_HUGE_PAGE_SUPPORT
ps = pd.isHugePage ? OBOS_HUGE_PAGE_SIZE : OBOS_PAGE_SIZE;
#else
ps = OBOS_PAGE_SIZE;
#endif
}
}```
Doesn't look like it'd be that big of an overhead
no idea, but i think its good enough that they even enable it in release
like ubuntu ships with it enabled i think
Well isn't that the entire point
Since literally every ubuntu user actively participates in debugging
Mine fails with VFS: Unable to mount root fs to block(0,0)
looks like it can be hardware accelerated https://docs.kernel.org/dev-tools/kasan.html
maybe thats how they do it so fast
Only on arm if I read it right
Welp,
[Error] ASAN Violation at ffffffff8001e56c while trying to write 160 bytes from 0x0000000000000000.```
In the allocator's allocateNewRegion function
Oh no
panics are slow af
because they fill the background colour
Now that I fixed that
I got some bugs to fix
My kernel is cursed again
Function Allocate, File C:/Code/obos/src/oboskrnl/vmm/map.cpp, Line 481: Assertion failed, "!pd.present". Attempt to reallocate address ffff8000feeb68d0.
Stack trace:
0xffffffff800140bd: _ZN4obos6logger9panicImplEPvbPKcP13__va_list_tag+237
0xffffffff80013f6f: _ZN4obos6logger20reportKASANViolationEPKcz+0
0xffffffff80013f42: _ZN4obos6logger13panicVariadicEPvPKcP13__va_list_tag+0
0xffffffff80016b95: _ZN4obos3vmm8AllocateEPNS0_7ContextEPvmmm+713
0xffffffff80018105: _ZN4obos10allocators14BasicAllocator17allocateNewRegionEm+255
0xffffffff80017763: _ZN4obos10allocators14BasicAllocator8AllocateEm+187
0xffffffff80017364: _Znwm+105
0xffffffff800173f2: _Znam+24
0xffffffff8004fa5f: uacpi_kernel_alloc+24
0xffffffff800382d3: item_array_alloc+140
0xffffffff800425c9: exec_op+467
0xffffffff80043bcf: uacpi_execute_control_method+360
0xffffffff8003b532: do_load_table+147
0xffffffff8003bd37: uacpi_load_table+40
0xffffffff80036096: uacpi_namespace_load+163
0xffffffff8001b054: _ZN4obos5kmainEv+232```
I disable KASAN and get that
since the nyaux guy fixed his bug now its on you

Why hast thou put thy beshrew upon me?
I reboot and I get a GPF
Of course
Average debugging experience of OBOS
reboot again
PF
All this might as well be caused by non-zeroed memory
or a use after free
sounds like a race or use of uninitialized memory

