#OBOS (not vibecoded)
1 messages · Page 13 of 1
do you mean freezing all the other processors
yes
which freezes the processor
thats not that hard i did that in like an hour
not really
I find it annoying
just do it.
I'm basically done
then you are allowing it to wear you down.
only one cpu decides to freeze
the others don't wanna
oops
I really gotta stop writing code that's kind of critical to the kernel while I'm tired
now all the cpus are frozen
except for the interrupted one
and now my thread view is broken
how delightful
ok it's fixed
except the main thread and the bsp's idle thread have the same registers
wait I know why
I now get a correct snapshot of the kernel
when it's interrupted
*in gdb
gdb_ctx dbg_ctx = current_g_thread->masterCPU->arch_specific.dbg_ctx;
if (current_g_thread->masterCPU == CoreS_GetCPULocalPtr() && current_g_thread != Core_GetCurrentThread())
dbg_ctx.interrupt_ctx = current_g_thread->context;```
this is one cool thing about an nt-like irql hierarchy is that for one IPIs are always serviced almost instantly which is cool and for two that means the debugger can freeze everyone successfully even if someone was stuck deadlocked on a spinlock or something
because they didnt disable interrupts before trying to grab the spinlock they just raised irql
a bit
and IPI can still come in
speaking of spinlock, I (think) I need to change the default irql it raises to from IRQL_MASKED to IRQL_DISPATCH
whats the former
yeah that defeats the point cuz youre gonna be holding spinlocks a lot in like the scheduler
which is then no longer interruptible
if spinlocks mask all interrupts
iirc I set it to do IRQL_MASKED before the scheduler and never bothered to change it after
I did that without anything breaking
on the topic of locks, I need a mutex
I'll do that tomorrow
I can now continue execution in the kernel
all that's left for code execution is step
then there's also breakpoints
idk how that works
wait how does it work
I don't see any special packets here
it's sent on continue
the hashmap has decided it doesn't like the string 'vMustReplyEmpty'
as in it hangs if you try to touch the hashmap with that key
I'm too tired for this shit
wait it's not the key
it's the amount of elements in the hashmap
yeah taht was it
I seem to have forgotten to add in a calculation when I was making the hashmap use fixed point
which made the growat variable be some very large number
Threaded DPCs are passive level DPCs that run on a priority 31 (maximum) thread
They either work like this if globally enabled, or if disabled they work like normal DPCs
the gdbstub is basically complete
just needs some final packets
it can step
(albeit very slowly)
I also need to implement interrupting the kernel when gdb requests it
maybe I'll just throw a hook into the com driver
on irq, yell at the gdb stub to wake up
from these, I need:
M, G, and qRcmd
and then I also need to fix eflags
ok I fixed it
I also gotta fix some memory corruption bugs in the gdb stub
Yeah so additionally they form an extra (lower) dpc priority level
But they can't block or anything because they still need to be able to run as normal dpcs
If they could block they'd just be a worse version of work queue items
Well normal DPCs can preempt the threaded DPC function as well as APCs and other highest-priority real-time threads.
Tbh almost no one uses threaded DPCs and never has
They also require more irql checks around sync functions
I am pretty sure threaded dpcs can't be preempted by threads but I could be wrong
at least now they can identify long dpcs iirc
and do something like use normal thread? i forgot what resolution the long dpcs have
my recv packet code is kinda borked
the packet size is -3
in one specific case
the checksum offset is -1
I suspect the bug is somewhere here:
while(offset < szPacket && raw_packet[0] != '$')
{
raw_packet++;
offset++;
}
checksumOffset -= offset;
if (offset == szPacket)
{
ack = '-';
goto acknowledge;
}
uint8_t checksum = KdbgH_hex2bin(&raw_packet[checksumOffset], 2);
size_t packetSz = checksumOffset-2;```
szPacket (the raw packet) was 9
offset was 8
raw_packet was "$"
and of course I can't get the bug to reproduce
the exact commands to get this were:
target remote :1534
info reg
c
[crashes here]```
yeah that reproduces the bug
it's because there is utter bs being received
vCont?#+$
if you couldn't tell that isn't a valid packet
it seems to have disappeared
after changing something
so I tried to implement interrupting the kernel if gdb asks it
and it half-works
as in the kernel debugger does something
it sends the response
that it was interrupted
but then ignores everything else
o wait it crashes
ok I fixed it
gdb is being weird
thread one has died
it recognizes that
then when I do info thread it still shows the thread
probably just the kernel sending it despite it being dead
but goddamn is this slow
it takes half a second for it to tell me that the kernel was interrupted
next is terribly slow
so is step
that was it
KASAN is being stupid
I fixed this bug
by adding a check for szPacket-offset < minimumPacketSize
and sending NACK if it's true
now I want to implement more proper stepping
done
now if I step one thread, only that thread steps
I think the problem was the DPC init function thought that the dpc was already enqueued
since the cpu field was set
because it's never cleared in the dpc dispatcher
and
if (dpc->cpu && LIST_IS_NODE_UNLINKED(dpc_queue, &dpc->cpu->dpcs, dpc))
return OBOS_STATUS_DPC_ALREADY_ENQUEUED;```
holy shit with the com driver using DPCs, the gdbstub is slow af
how about I flush the data to be sent (only done when the com port's output buffer is full) in the dpc
and also break into the gdb stub if it was requested
in the dpc handler
implementing breakpoints rn
I just made the world's simplest disassembler:
uint8_t offset = 0;
if (*(uint8_t*)(frame->rip - 1) == 0xcc /*int3*/)
offset = 2; // ... int3 (0xcc xx)
if (*(uint8_t*)(frame->rip - 1) == 0x3)
offset = 3; // ... int 3 (0xcd, 0x03, xx)
if anyone was wondering, this is to adjust rip to before the int3 instruction for gdb
bruh
gdb just crashed trying to read symbols
I love it when the n command randomly breaks /s
it only breaks on int3
it seems
yeah I fixed it
I was setting the wrong rip
I just fixed wrong uses of IRQL_MASKED around the kernel
most of them should've been IRQL_DISPATCH
oh great
now it's broken
I fixed it it seems
and also all bugs related to this specific bug
now I get a recursive lock
ok I fixed that
TODO: Is keeping the irq interface unlocked while the irq dispatcher is running a good idea
idk if I'm just hallucinating, but the kernel is visibly faster when I removed that lock
well it's not removed, it's just not acquired within the irq dispatcher at all anymore
I think I know how to implement watch points
without hw breakpoints
I'll just use KASAN
since it captures basically every single read and write
amazing
they work*
*except it crashes when you try to continue
fixed
it was because the rip was being incorrectly set
nvm I can't read
I think I fixed it
kernel has 16k loc
over 124 files
74 of which are compiled
41 of those files are from the kernel
the rest are from uACPI
50/50 chance of it working
nvm 0% chance
completely forgot about instruction cache
I modified the instruction through the hhdm to avoid having to set the page mapping
which was probably causing the cpu to be confused
on x86?
yes
no
x86's icache is coherent
fully
and it would need to be virtually tagged for accesses thru varying virtual addresses to confuse it
and its not
wdym virtually tagged
a thing that x86 does not do
dam
further information can be found on google
the kernel just imploded :)
here's my battle tested thing if interested
https://github.com/FlorenceOS/BED/blob/master/src/lib/gdb.zig#L28-L66
ty
ok I fixed it
I was doing something smooth-brained
I was setting the rip in the debug context in the bp instruction handler
instead of the rip in the frame
causing stoobid stuff to happen
this is so slow ðŸ˜
the gdb stub can be used
now
but I just need to:
- make it faster (specifically stepping and stopping)
- implement write to memory
- implement write registers
maybe if I give the s (step) packet a shortcut into getting handled (as in, it doesn't need to go through the hashmap), it'll run faster
oh god
it steps so much with the step command
many many instructions
and on each step, it queries the registers as well
that's not very fast
maybe a 130 byte format string isn't good for sprintf
// rax,rbx,rcx,rdx,rsi,rdi,rbp,rsp
"%016lx%016lx%016lx%016lx%016lx%016lx%016lx%016lx"
// r8-r15
"%016lx%016lx%016lx%016lx%016lx%016lx%016lx%016lx"
// rip, eflags, cc, ss, ds, es, fs, gs
"%016lx%08x%08x%08x%08x%08x%08x%08x"```
I changed that
and now everything's acting stoobid
except for the actual register view
all goes to shit
as to why all goes to shit, I suspect that the timeout for receive is too small, so it just sends a nack after like 3 seconds
confusing the shit outta gdb
making the timeout longer seems to aid it
I need to remove the timeout, but doing so causes it to hang occasionally
when I wake up I'll do that
rn I'm too tired to deal with this shit
I think I might just rewrite the recv packet
*function
Since it's so unreliable
Basically how it'll work now is it it will discard all bytes until it finds a $ (start of packet), then it'll read all into a buffer, and change any escaped chars back to normal. While the chars are being read, the mod256 checksum is being calculated. It stops reading when it finds a # (start of checksum), then it reads the next two bytes into the a remote checksum variable. At that point, it verifies the checksum, if they match the function sends an ACK and returns, otherwise it will send a NACK and try again.
I implemented that
the kernel doesn't go to shit
but instead the gdbstub gives up on responding to gdb after a bit
I made the tlb shootdown ipi async
which was of course the reason of the gdb stub hanging
now step is being funny
probably after I fixed the H packet
because gdb chose all threads when it sent the s command
Hc-1
which causes the gdb stub to do this when the step command is set:
for (size_t i = 0; i < Core_CpuCount; i++)
{
Core_CpuInfo[i].arch_specific.dbg_ctx.interrupt_ctx.frame.rflags |= RFLAGS_TRAP;
Core_CpuInfo[i].arch_specific.dbg_ctx.interrupted_thread->flags &= ~THREAD_FLAGS_DEBUGGER_BLOCKED;
}```
and for some reason I get random traps
and also the gdb stub gives up eventually:
w +$qsThreadInfo#c8
r <Timeout: 2 seconds>
w $qsThreadInfo#c8
r -
w $qsThreadInfo#c8
r <Timeout: 2 seconds>
w $qsThreadInfo#c8
r -<Timeout: 2 seconds>
w -
r <Timeout: 2 seconds>
w -
r <Timeout: 2 seconds>
w -+```
(r is received packet, w is sent packet)
I fixed it
I forgot to put in a
goto retry;
stupid gdb
well lldb hasn't crashed yet
(I wonder why)
except the back trace is broken (doesn't exist)
that was because there was no symbols loaded
I'm almost done implementing the M packet
it works
now to see if it works within gdb
*lldb
this stack trace doesn't quite make sense
ah yes, flush idt called initialize irq interface
actually that might make sense
except it doesn't
ah yes thread starvation prevention (todo: rename to priority booster) called the LAPIC default irq handler

gdb doesn't have the same issue
I've implement the monitor command:
technically
it works
now for the G (write registers) packet

that's done
ok VFS is next after I make the gdb stub faster
of course it is
based plan
indeed
now where to find m68k bootloader
@ornate ginkgo you said you had a limine stub
I won't bother learning m68k asm
because hopefully I won't need too much of that
hopefully I didn't make the kernel too unportable
the entirety of the keyronex m68k codebase appears to use only move, movec, movem, add, sub, jsr, pflush, ptest, rts, and rte
that isn't much at all
so I think I'll be fine
also where can I find a m68k btldr
I don't want to make my own (but I will if I have to)
i would use r4's for now
and where is that
it's considered by most to be by far the most enjoyable assembly language ever devised so it will be a pleasant experience
which one of the m68k processors had an mmu
I think it was the '040
Right now I need:
- A bootloader
- A cross compiler
I'll compile the cross compiler while I look for r4's bootloader
@devout niche Will I need libgcc for an m68k-elf toolchain?
I'm trying to compile it and I am getting:
checking for suffix of object files... configure: error: in `/home/serveradmin/m68k-gcc/build-gcc/m68k-elf/libgcc'```
gcc and binutils compiled
very useful to have
what's it erroring on?
this
make all-target-gcc is the command I ran
how's the error log look?
I'll check
configure: error: in `/home/serveradmin/m68k-gcc/build-gcc/m68k-elf/libgcc':
configure: error: cannot compute suffix of object files: cannot compile
See `config.log' for more details
make: *** [Makefile:13847: configure-target-libgcc] Error 1```
I need to scp config.log
then I'll paste it
libisl isn't installed it seems
yeah that was it
I got a m68k toolchain compiled
now time for qemu
I got qemu
that finished really quickly
@devout niche Do I need to emulate 16 IRQL levels on the m68k
or can I map the 8 it has to the 16 IRQL levels needed
actually maybe that was some random thing
if you want 16 you'd have to emulate
the -M virt of qemu unfortunately has quite an inflexible interrupt controller (the so-called GoldFish, which actually comes from the android emulator) and doesn't allow useful things like the ability to raise a softint
on the other hand the amiga's CIA interrupt controllers do
ok
it's actually quite nice that my IRQ interface has an enterirqhandler
because I can use that to emulate the IRQLs
I'm able to get cmake to compile m68k code
except nothing compiles
because of some kasan option
-fasan-shadow-offset
I set that to zero (TODO: set it to something proper)
I need to add a 32-bit elf header
this'll be fun
currently 101 errors reported (so far)
I fixed a couple
these are mainly from macro/struct defines not existing
since some are arch-specific
well I found it
I don't understand it one bit though
ok I get it now
northport is MIT license
so I'm snatching the loader
Go for it, that's the beauty of open source
Currently I've stolen two stuff from northport
Things to know about it:
- I recall that getting a PIE kernel running was a bit flaky, depending on which version of binutils it was linked with. The generated relocations were wrong.
- it doesn't do 8k pages, even if you request them.
Bootloader and panic ascii art
Well neither of those should be a problem for me
I'm slowly infiltrating your codebase
O_O
Ah and of course it uses some limine protocol defs I just made up for m68k, theyre available around here https://github.com/DeanoBurrito/northport/blob/master/kernel/include/boot/Limine.h#L256 and https://github.com/DeanoBurrito/northport/blob/master/kernel/include/boot/Limine.h#L362
Okie
I got the kernel to compile
but not link
because there's no libgcc
but after I get that I'm getting bombarded with linker errors
to "solve" those, I'm marking the target-specific symbols as weak
so I can gradually implement them
while I'm waiting for libgcc I'll mark them as weak
and theoretically, I'll get a working kernel once I implement all arch-specific stuff for the m68k
You can also implement them with a call to panic("not implemented")
That way you'll know how far you're getting
nullptr is basically the same thing
Lol
It does not
The only framebuffer on m68k right now is virtio, bewides board specific stuff
Ramfb is coming in a future patch though
b r u h
b r u h
b r u h
b r u h
ok
Future patch for qemu I should say*
so how do I get logs again?
For logs there's the goldfish devices
Take a look at the tty
Also the documentation is completely wrong about some of the goldfish stuff (the pic and timer I think), so don't be afraid to reference northport/keyronex/qemu
I have a very minimal implementation of using it in the NPL_LOG macro in the loader, iirc its in until.h
okie
I'll take a look at it as soon as I fix libgcc
rn my priority is getting it to link
checking for suffix of object files... configure: error: in `/home/serveradmin/m68k-gcc/build-gcc/m68k-elf/libgcc':
configure: error: cannot compute suffix of object files: cannot compile
See `config.log' for more details
make: *** [Makefile:13847: configure-target-libgcc] Error 1```

some random stack overflow answer said to add this:
LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/lib/x86_64-linux-gnu/```
nope
How are you configuring gcc?
../gcc/configure "--target=$TARGET" "--prefix=$PREFIX" --disable-nls --enable-languages=c,c++ --without-headers```
TARGET is m68k-elf
Non solution, but have you tried using clang in the meantime?
nope
(doesn't mean I will, too much work)
I think it worked after reconfiguring it
nope
I ran distclean
then reconfigured
and am now waiting for it to finish
this is so slooooooooooooooooooow
ahhhhhhhhhhhhhhhh
nvm smth is happening
nvm
god damn it
same error
considering it decided to rebuild gcc, it wasn't actually too slow
I'll just recompile gcc
then compile libgcc
and see what happens
flip
since I was compiling gcc's master branch
I decided to checkout the gcc 14.2 tag
and see what happens
it's currently compiling
yeah I wouldnt use master for a project like gcc
I'll keep the thread updated
when the build finishes
bruh
I'm just going to delete all my build stuff but the source
WAIT
it could've been some files were owned by root
so it couldn't modify them
welp
it's too late now
it compiled+linked
which is cool I guess
except it can't really do shit
I need to compile the loader
which I will continue tomorrow
as I need to port it to be freestanding enough
I shall now start making r4's loader work without northport utility libraries
rather that or I'll just copy+paste them
obvious solution is to make OBOS a fork of northport 
hyper m68k stub when
bet
once I learn more about m68k, it could be fun to do that
but now I'm pretty clueless when it comes the m68k processor
same but i think its relatively close to x86
the i386 one
at least the abi from what ive seen
r4 what's LoaderEntryNext
barring big endianness 
and why is it undefined
based
there's a handful of oddities to it, but its a very easy arch to work with
its in Main.cpp
definitely defined lol
its the high level entry function
is it soft refilled tlb?
so my build system is being stupid
nah
because I compile main.cpp
I found the interrupt handling to be the weirdest part
ah
what about them?
kind of
iirc the pml2 has 128 entries, while the pml1 is variable in size (depending on page size)
and there's indirect PTEs that let you refer to another set of page tables to complete a translation, rather than filling it in with a physical address directly.
uhhhh
well on arm these are variable size as well depending on the VA bitness u set
TO(NOT)DO: Arm
damn ok - I was thinking about arm as my next port
its TLB invalidation instruction has like 99999 permutations
u have to have a pHD to understand what they do
same with atomics
99999 trillion barrier types
u have to put in correct places
TO(DEFINITELY NOT)DO: Arm
lmao
just do aarch64
obos is unstable enough on x86-64
aarch64 is arm lol
x86 programmers are just too coddled by strong memory ordering 
yeah but the page tables are sane at least (with 48bit va), idk about 32-bit arm
its basically the same as on x86_64
yeah page tables are pretty good
if u set bit width to 48 yeah
even with 5 level paging it's still mostly the same as on x86_64
except that the topmost table has less entries because the address size is limited to 52 bits iirc
oh and manual dirty bit managment 
u will have infinite page faults until u figure that one out
just need to read the armarm carefully :^)
ah yeah I ran into that on riscv
just buy an expensive arm device that has automatic management
omw to buy an ampere server to run managarm on
that sounds retarted, why would it page fault if the dirty bit is set
apple M cpus have it iirc?
it page faults if its not set
so u can set it yourself
one annoying thing about arm in qemu is that if you happen to screw up exception handling somehow you end up in an infinite log spam because there is no triple fault equivalent
dirty you emulate by mapping as read-only
yeah
the access flag thing is a bit silly but since it has a separate exception type it's faster than having to walk the pts to figure out whether the page is not present or just not yet accessed
oh yeah that reminds me
decoding the reason for arm exceptions is also insane
is it?
eh
it's just a never ending list isn't it
I don't think its that bad
its just some bit fields
well okay not insane but kind of way way harder than x86
but yeah if you mean like understanding it just from the number itself
obvious solution is to never crash
i only know of esr.arm64.dev
what are the other 2
esr.arm64.dev has two other pages but it's for different things
exception syndrome 
like they even called it that
oh also the whole VHE and EL2 vs EL1
how registers alias each other
its not trivial
there's just a never ending list of includes I need to borrow from northport
oh yeah EL2 vs EL1 kinda sucks
yeah
because they decided kernels want to run at el2
but they all use el1
so now we alias them
its like
and there are corner cases
well the problem is that bare el2 only has the lower half
well
and el0 uses the el1 ttbrs
for that yeah
so its basically exactly like EL1
with extra control
otherwise the kernel is run at el1 with a stub at el2
kind of like a vm lol
like its interesting how the entire runtime is controlled by KVM basically
even for the bare kernel
anyway sorry for stealing the obos thread
should be in Syslib.cpp?
if you give me a sec I'm working on some ideas to simplify the header inclusion situation
ok I had a look, here's a few suggestions and the list I came up with. You will need formats/Elf.h (which requires formats/Elf[32|64].h), you only need the first two functions of that file (ValidateElfHeader and ComputeRelocation), the rest can be removed and so can the #include <containers/Vector.h> line.
containers/List.h is also needed, and brings in CppUtils.h, but it only needs the Swap() function from there (you can just copy-paste it at the top).
The following files you'll need as is: Maths.h, Memory.h, NativePtr.h, PlacementNew.h and NanoPrintf.h (although this is mostly the same as the upstream one, so you can just grab that).
I might be missing some things that get unintentionally propagated, but I think that should be everything.

uh I think so, I forgot what I do
and it loads the kernel in the asm global scope
asm("\
.global KERNEL_BLOB_BEGIN \n\
.global KERNEL_BLOB_END \n\
.section .rodata \n\
.balign 0x10 \n\
KERNEL_BLOB_BEGIN: \n\
.incbin \"../../out/oboskrnl\" \n\
KERNEL_BLOB_END: \n\
.previous \n\
");```
i know -initrd and -append work like you expect
ah yes, late night engineering
that looks right
why didn't you just make the kernel the first binary passed as a module or something
what does -append do
its for the kernel command line
ah
try arm when you dare, but i can attest that it's weird
either that or i missed something very important
it is but aarch32 (before it became aarch32) is even worse
aarch64 is at least somewhat sane and usable
the linux boot protocol is kinda annoying tho especially if you try to turn on the mmu and get the kernel to the higher half inside the kernel itself without a separate preloader
I think I might've done something wrong 
the PC isnt much help either, neither the loader or kernel should be there
what do the logs say?
it hung after saying the kernel physical base
then after a bit crashed
the kernel is being stupid
what does readelf -l say about your kernel?
there are some deranged phdrs
that want to be loaded at 0x00000000
they are set as LOAD
that'll do it
so the bootloader probably takes that as the base
yep it does
the offending phdrs in the linker script seem to be pageable_data and pageable_rodata
I fixed the deranged phdrs by adding something to those two sections
that's normal
or rather
that's what ld.bfd does
because reasons
ld.lld just omits the PHDRs like a sane linker
in any case a sane bootloader will ignore those 0-PHDRs :^) (Limine)
lol
I fixed your stuff
good to know though
wdym my stuff
oh
should've made that clear
mb
and by fix I mean add:
if (!phdrs[i].p_vaddr)
continue;
its still a fix
feel to PR it if you want, or I will add it at some point when I remember
ah
its not really a bootloader
i'm sorry for implicitly calling it not sane
lol
i thought we were still talking about Hyper
nah its ok, its just a hack really
cool, thats exciting
now I need to recompile my gdb to take xml register descriptions
hmm it should be printing each lbp request as it sees them iirc
oh ok, that would be why them haha
my goal yesterday would be to get something to "run"
while(1);```
and that technically counts
you'll have no trouble with that
now, since I unconditionally need 16 levels, I'll need to emulate IRQLs
because that's how many the kernel has on x86-64
and IRQL is basically entirely based on how x86-64 treats it
enum
{
IRQL_PASSIVE,
IRQL_DISPATCH = 2,
IRQL_TIMER = 3,
IRQL_MASKED = 0xf,
IRQL_INVALID = 0xff,
};```
but thats only 4 + invalid!
the arch gives you 8 (although one is interrupts disabled)
not sure about the gf pic
and how many interrupt vectors are there?
I've seen 256 vectors and 64 vectors
idk which one
I dont have my notes handy, but from memory the way it works is the gf pics route to the auto vectors
which there's 7 of, one for each interrupt priority level
iirc pic0 (lowest priority) only has the uart attached to it, pics 1-4 have the virtio interrupts connected to them, and pic5 (highest priority) has the timer interrupt connected to it.
pic6 is unused?
there's a diagram in a qemu source file somewhere
yeah
ah ok, they use 1-based numbering for the pics
so all the user-available vectors they list in the manuals are unused for the virt board
it sucks how the IPLs are fixed to a specific IRQ
it is annoying.
it worked out well for me because thats the order of my runlevels (irql)
clock above all other interrupts
my kernel does the literal opposite
the TIMER irql is one of the lowest priorities
so is dispatch (basically scheduler timer)
in fact, the scheduler IS the lowest priority
oh one thing I'll mention because I just saw it in my code: the pic registers that deal with enabling/disabling/pending stuff are bitsets.
oooooo
so you dont write the pic pin you want to mask to the disable register, you write 1s in the places of which pin to disable
hmm
you can just mask and unmask the clock and fake it
any power of two from 1-16
then the kernel will prioritize the IRQLs across different arches the same
despite them having a different literal IRQL value
the m68k port will do this
but then I remember reading somewhere
about something
#x86 message
nvm that's x86-only
assuming this bitmask is more sane than the x86 PIC's bitmask
I'll be fine
i think the goldfish rtc is at least wired to the highest IPL
2nd highest
what's highest?
reasonable
should I emulate IRQL or should I use the goldfish pic's irq mask bitfield
@devout niche
it's up to you, you can certainly emulate multiple hardware levels that way
I think I'll emulate it
shit
I accidentally just pushed a commit from the m68k port to master
git is being weird
ok there
I fixed the commit history
I was bored... Contribute to OBOS-dev/obos development by creating an account on GitHub.
new favorite archiecture: m68k
no PUNPCKLQDQ shit
VCVTNE2PS2BF16
those instructions looked like someone mashed their keyboard keys and called it an instruction
vdfsfdsgr
for all I know that could be an x86 instruction
VFMADDRND231PD
@devout niche
what's wrong with my instruction (I want to move d0 into sr)
move.l %d0, %sr```
Error: operands mismatch -- statement `move.l %d0,%sr' ignored
the length suffix
SR is 16 bits
you want move.w
oh yeaaaaaaah
ok it's good now
ty
is there an equivalent to the x86 int instruction on the m68k
to raise an irq
you can trap, there are specific vectors for those i should add
@devout niche is there a register I can use to store a pointer to the cpu local struct (one similar to gs_base on x86).
oh wait does it even have smp
it doesn't
ok that's good
nvm
the m68k is pretty based
movem.l %d0-%d7/%a0-%a6, %sp@-
if I knew about this when I started this rewrite, it would've initially been for the m68k /j
32-bit
@devout niche I saw that the m68k port of keyronex has screenshots, so I checked the source, and saw that your framebuffer was just normal memory
what qemu/shell commands do you use
to get the screenshot
it's by a (primitive) virtio-gpu driver
alt-prtscr
oof
I think I'll just stick with memsave for now
with the framebuffer address
first screenshot of OBOS on the m68k
tf is memsave
a qemu command
epic
does your current code structure hold well on multiple archa
green was more fun
idk why the text is cyan
I‘m just now noticing the weirdly coloured top row
looks quite aesthetic there
currently I'm trying to figure out where the hell the int number is pushed
I know where it is at IRQ entry
just I have no idea where it is after I push all my shit
oops
I misread the user manual
after gdb magic I got the offset
nvm I didn't
finally figured out the offset after a short break
it was bytes from my position 0x48 to the interrupt number
traps seem to work
hold up
this screenshot looks a bit wrong
the second log message is right
as trap 0 corresponds to the 32nd interrupt on m68k
and with that- the irq interface has been ported
TODO: SendEOI function
otherwise, assuming I didn't get any macro definitions wrong, the irq interface should work perfectly fine
its only dependencies are the arch-specific functions it defined
which there are 5 of
I think I'll port the scheduler next
the scheduler's only dependencies are ones to manipulate thread context
one to switch to a context
and one to save the current context and call the scheduler
that's all that's needed to run the scheduler
at the bare minimum
nah do memory stuff first
well you could do sched too actually
depends how intertwined they are
not interwined at all
also if the scheduler depended on the memory manager, it wouldn't be depending on arch specific functions of the mm
there is one thing in my vmm that I need to change
idk how to word it
so I won't
basically just an optimization
I mean ngl the m68040 mmu sounds goofy
and fun
@devout niche confirmation?
it is quite fun
the 030 mmu is much funner but qemu doesn't implement it
so I'll do that after my soccer game
*tomorrow
I'm far too tired rn to do osdev without doing some funky shit
I'll work on the scheduler first
I have implemented CoreS_SwitchToThreadContext
it had a couple bugs (mainly because of my infamiliarity with m68k asm and at&t syntax)
but I fixed those and can switch to a thread context
time to test yield I guess
(which directly tests the entire scheduler)
well the scheduler works...
BUT
it corrupts a bunch of global variables :)
just a slight problem
I fixed that
what was the problem?
I had my label for the temporary stack in the wrong place
Arch_TempStack:
.skip 0x10000
was pointing to the top of the stack already
then I added 0x10000 bytes when I was loading it into sp
Yielding works
now to port the MM
but, first, I need a pmm
(aka: copy and paste the x86_64's pmm)
why does the pmm even have to be arch specific?
because I'm too lazy to make it not
lol
anyway the pmm has been ported
time for virtual memory management
because I don't want to forget anything, I'll say the functions I need to implement for the VMM here:
- OBOSS_UnmapPage
- OBOSS_GetPagePhysicalAddress
- OBOSS_AllocatePhysicalPages
- OBOSS_FreePhysicalPages
- MmS_QueryPageInfo
- MmS_GetCurrentPageTable
- MmS_SetPageMapping```
Each of the 128 pointer-level table descriptors corresponds to a 256-Kbyte block of memory.
This isn't making sense
basically:
root_pt[i] points to a 256 kib block of memory
that's what I understood
yeah
root_pt[128] entries point to a pointer_pt[128] entries point to a pt[64]
a pt[64] describes 256 kib
all assuming 4kib pages
I understood that eventually
or as i call them pml3, pml2, and pml1
same
why did they pick such a strange format
so this all makes sense
no idea, the 030 you could configure the MMU very thoroughly
but for some reason r4's limine stub doesn't like my requests
anything from 2 to 6 level paging on the 030
the 040 i think just standardised on a compromise fixed scheme that should satisfy most 030 people
why in the world would one need 6 level paging for 32-bit addresses
wouldnt that level of indirection be super slow considering ram latencies on that stuff
it was for AI
i'm not joking
this is the application that the 030 manual suggests would be suited to many-level paging
well it only suggested 3 or 4 levels in that case
This sounds more like it's for lisp whose most common usage was AI
oh, i should mention, you can configure the page size to many reasonable powers of 2
it is for exactly that
the lists is a giveaway
Based lisp moment
but another subtler sign that the lisp adept would recognise is that many lisp implementations of that time partitioned virtual address space into regions dedicated to one kind of object
and then considered the high bits of a pointer to determine what kind of object it is
Sounds familiar
@ornate ginkgo your thing broke
time to make a hyper stub
cool thing in the 030 manual btw, they have pseudocode for a sample PMM and VMM in there
good idea
lol
so basically I have 4 limine requests
it has page swapping of course
two get filled
the other two are ignored
That's actually cool
all of the requests do exist in the stub's code
but two are never populated
I suspect the bug is in LbpNextRequest
well they did mention it was a limine stub and not a full impl 
I fixed by doing this:
uintptr_t* iter = (uintptr_t*)current;
if (!iter)
iter = (uintptr_t*)(kernelBase + kernelSlide);
else
iter++;
for (; (uintptr_t)iter < kernelTop; iter++)
if (sl::memcmp(iter, CommonMagic, sizeof(uint64_t)*2) == 0)
return (LbpRequest*)iter;```
in LbpNextRequest
instead of the code that was previously there
I can successfully map a page
now time to see if it'll still be successful when I set up the page tables
(probably not)
Are the requests 8 byte aligned?
idk
but I fixed it by removing that code, and replacing it with my own code to the same thing
they weren't
who needs it
what? brain or paging?
both tbh
oh wait paging isn't broken
I forgot that the pt I was mapping to wasn't in use
(intended)
ok I think mapping the kernel working
it doesn't crash
but I don't trust that it won't crash in the future
why is every kernel address mapped to zero
okie I fixed it
@devout niche does the m68k have smp
I don't think so
but might as well ask in case
only some very rare systems
ok
5/8 are done
*9
I also need to implement the pf handler
*10
I also need to implement something to act as swap
temporarily
the kernel's supposed to eventually use an AHCI disk driver to do that
but it can't because it doesn't have one
I have a slight problem
a very small part of the kernel wasn't designed to split kernel page tables and user page tables
like how the m68040 does (urp and srp)
i.e., it was designed around the idea that there is one pointer to the page table
except it's only two lines of code
this is because of a function with the signature:
page_table MmS_GetCurrentPageTable()
which didn't make a distinction between the current kernel pt and the current user one
but since it's only used during vmm init, I added a note that it always returns the current kernel pt.
@devout niche difference between access fault and address error?
nvm I found it
in the manual
but is there an equivalent to the cr2 register on the m68k
so that I can see the faulting address on access fault
so far I haven't been able to find such a thing
or really any info on where fault info is stored on access fault
You can load the same table into both
They even cover that in the manual
who even reads that thing
I figured that out
now I have a struct taken from keyronex
(md_intr_frame.format7)
hope you don't mind @ fadanoid
I really gotta stop pinging fadanoid lol
I can page fault successfully
I decided to test on x86_64 to make sure I didn't mess anything up
and I did!
I fixed a bug where the dirty+accessed bugs were never being cleared
and now the working set's exceeded its size
this math isn't mathing
if I only append pages to the working set if the current size of pages in the working set are less than its capacity
then why would-
race condition
but no other CPUs are running vmm code
and the vmm is locked
I fixed it
now a page in the working set was paged out
it doesn't seem to be exactly that
a page is in the working set's list
but it reports itself to not be in the working set (page->inWorkingSet=false)
this will break btw
cuz of shared pages
if you want to track something like that youll need a count of working sets rather than a boolean
forgot about those
I'll do that
so a count of the working sets the page is in
yeah
not to be confused with the refcount
a page could be referenced while in 0 working sets
imagine theres outstanding IO to the page and its pinned into an MDL, but got trimmed from the process working set after that
refcount 1, working set count 0
yeah
surely a 16-bit count will be enough
but if a library like libc is shared between 65536 processes, then that'd break
this seems to because the node doesn't want to be removed
idk how it got to choose that
it somehow has two lives
and by that I mean it's in the working set list twice
I fixed that
now this is back
the working set has exceeded its size by ONE page
