#Techflash OS
1 messages · Page 3 of 1
Why do you need to print floats
I mean yeah, I could, but that's only precise to 2 decimals (could obviously be increased by multiplying by more), but then I lose size
that's... literally the entire reason floats were created, to avoid that
what do you need floats for in the kernel
He's been insisting he needs them for like 2 weeks now
ok but for what 😭
mainly user friendly output of stuff
currently the only reason is printing the sizes of each section of the memory map
but go look at the previous version (the non rewrite branch) for more examples, one of them was for a progress bar
it's mainly just for futureproofing, I don't absolutely need them right now, but more times that I might will eventually pop up
memory sizes are not floating point numbers
e.g. I can print that memory region 3 is
502.79MB
so there is no reason then
obviously, but they are once you divide them
use fixed point if you care about that
That's what I said lol
fixed point is enough for that and the progress bars (which you shouldnt have in the kernel anyway but whatever)
alternatively just print the number of pages and be done with it
write a cute little program in userspace with all the floats you want to display memory usage
yeah the progress bar was pretty dumb, I didn't implement it right and it totally fucked up any text behind it
userspace 🤣
the rewrite doesn't even have an actual memory manager yet
that's what I'm working on, and that's why I've been hung up for so long, trying to get it to print the sizes
userspace isn't happening for a LONG time
maybe it would if you weren’t so obsessed with printing the decimal number of megabytes available
You are possibly the most skill issued person here
U were trying to get ur allocator to work for like a week and then gave up iirc
Should be an afternoon or 2 days max even for a bit fancier one
You might not have the skill to do this yet
no it worked... mostly
it could keep track of what was allocated and what wasn't
and it could give you a valid address
an in fact, I did get the allocator working if I'm not mistaken
when I gave up is trying to get console output working
Also a triviality
I was just chipping away at an entirely broken codebase
You've been wrestling for weeks with the most trivial 0.1% of a kernel
I started the old version with, admittedly, not quite enough knowledge of C yet
I had just switched from working with C++ to C about (2?) years before that
this version was created specifically to avoid all of the crappy design that came with that
also, I did thing in entirely the wrong order
so yeah, I'm trying to do things in, at least a moderately more sensible way this time
previously I would just leave stuff broken, and say that I would fix it later (I never would)
and it led to everything just being a horrible mess
that's kind of why I've been stuck on SSE for so long now
I guess I'm taking "never leave stuff in a broken state, get it fixed before moving on" a little bit too seriously
you're spending way too much time trying to do the useless stuff
also +1 to the "no floating point in kernel pls" since its just asking for trouble
there is a reason linux and other operating system kernels DONT use them
I swear I remember Windows requiring SSE 1 & 2, at least on x86_64, idk about i386
might just be more BS like the "TPM requirement" in Win11
haven't looked into it
because applications use these instruction sets extensively
Windows, maybe
thats probably why
The kernel, no
oh yeah good point
Apps require it (so the kernel initializes it for tasks)
actually... who knows, isnt gdi partially implemented in the kernel? lol
But the kernel doesn't use it
windows is full of cursed shit
I doubt they do it tho
Would be bad for performance
well yeah, the kernel itself obv doesn't it's a microkernel, it wouldn't get any benefit from it at all
but the low level system apps (like winlogon.exe, csrss.exe, etc) might
again, haven't looked into it extensively so don't take my word for that

LMAO
win32k.sys has the majority of GDI and it's a kernel module, it was moved there from userspace in NT 4.0
I do not know if they use floating point in it but if they do it's still not a good example to base your design decisions off of
This is nonsense !
?
NT is a microkernel, so doing anything with SSE would just be detremental, since the kernel itself does so little, and saving the SSE state there would probably take longer than whatever it was called out to do
Nonsense again
☠️☠️☠️☠️
what
now I'm just confused
first yall say that SSE states take forever to save, and that it's a waste
but then NT doesn't follow that somehow? what
NT also isn't a microkernel
oh what
i havent reverse engineered the nt kernel to know whether they do or not use floating point arithmetic
but id advise against you doing that
It was sometimes called a microkernel in the 90s by things that are either wrong or lying depending on if it's a third party source or marketing
(using them)
oh, I didn't know that
The kernel proper probably doesn't use it but it's possible they do the things required for it if gdi used it
It's very likely gdi uses all fixed point internally for performance
But I honestly don't know
Yeah it's not even kind of a microkernel
I think part of the confusion comes from NT's distinction between "executive" and "kernel", the latter is sometimes confused for a microkernel but it's actually just the innermost layer that does scheduling and stuff
Both of which are linked together as a monolithic kernel in the ntoskrnl.exe binary
huh
interesting
well, I got it to compile, and swapped out the floats when printing the memory map for fixed point
results are uhh.... not great
the pointers there are corect, but the size to the right... well.. doesn't really match the pointers at all

this is it actually working
ok that is much better
yeah
.... how is it hitting those
... I forgot the , in between 2 of the strings
finally, it's done. A glorious memory map
... holy shit I spent 2 weeks of my life to get this
and now it can tally up all of the usabe regions
tbh it isn't even really necessary here
everything just works
I just wasn't even thinking of fixed point
but yeah, progress on this is gonna slow down
can't work on this as well from school
I'm gonna work more on things that I can do on a crappy AArch64 Chromebook running Arch
and I really don't want to try to build my cross toolchain on there
it would take hours
I'm also gonna really focus on networking, I need to be able to reach my home LAN from out there, so I might be able to do somethink sketchy with VNC, idk
if I have the opportunity, I might work on it from there, but I probably won't
so I'll probably be stuck only working on this when I'm home
just use clang
if it doesn’t work you did something wrong
there’re very few things GCC has that clang doesn’t copy
in general it only works with my cross compiler
the system compiler almost never works correctly
clang is a native cross compiler
mainly issues with types
I was never able to get it to work right with just gcc
never really tried clang though
host gcc should work if you pass the right flags
-nostdlib -ffreestanding and the right architecture stuff
but with clang just pass -target x86_64-unknown-none and whatever else you currently pass to your gcc
and it should work the same
sigh why is that even a warning.....
bad style
I hate how I always hear that "clang is a drop in replacement for gcc", when it literally isn't
given the same flags, including -std=gnu2x, it does this
it's basically saying that "this printf supports format specifiers that are GNU extensions"
but i guess clang doesn't support it
looks like it’s just an alias for printf in GCC
typical GNU must make themselves feel special 
sigh
why is it even bringing that up
I'm not using C99
it will never use C99
especially not anything before that
are you passing the proper -std=?
-std=gnu2x
show all the flags being passed
generally speaking this is why i strongly dislike people hiding make commands
because then you have absolutely 0 idea if your makefile is working properly
passing the right flags
# for testing with clang
CC=clang -target x86_64-unknown-none -Weverything -Wno-reserved-macro-identifier -Wno-declaration-after-statement -Wno-cast-qual
WARN=-Wall -Wextra -Wpedantic -Wshadow -Wstack-protector -Wformat=2 -Wconversion -Wformat-security -Wunused-parameter -Werror
FEAT=-ffreestanding -fpie
CFLAGS=-nostdlib -g -I../include $(WARN) $(FEAT) -march=x86-64 -mno-3dnow -mno-mmx -mno-sse -mno-sse2
oh wait
where's std in that one
fuck
I got this from the other one?
aaand this is why I hate maintaining 2 makefiles
alright I got the libc compiling
but now it dies trying to assemble the GDT code
o64 retf?
arch/x86/CPU/GDT.S:13:2: error: invalid instruction mnemonic 'o64'
o64 retfq
^~~
interesting
i know that gnu as likes o64 in some places, but clearly clang doesn't care
yeah, for now I just replaced it with a ret and I'm gonna hope it works
at least it assembles now
yeah it just doesn't work
arch/x86/CPU/GDT.S:13:2: error: invalid instruction mnemonic 'retf'
retf $0x08
^~~~
ugh thats annoying
I'll just put the bytes there directly
what about lretq?
Far call/jump instructions are ‘lcall’ and ‘ljmp’ in AT&T syntax, but are ‘call far’ and ‘jump far’ in Intel convention.
i figure the same applies to ret far
yeah, disassembling a test binary I made, it even turns into that:
Disassembly of section .text:
0000000000000000 <a>:
0: 48 ca 08 00 lretq $0x8
yup, it assembles now
nice!
but then....
LD arch/x86_64/111_entryPoint.o arch/x86_64/CPU/ISRASM.o arch/x86/COM/init.o arch/x86/CPU/GDT.o arch/x86/CPU/SSE.o SMP.o arch.o kernel.o COM.o panic.o tty.o mm/pmm.o log.o bootloaders/limine/SMP.o bootloaders/limine/check.o bootloaders/limine/memory.o bootloaders/check.o arch/x86_64/CPU/printRegs.o arch/x86_64/init.o arch/x86/CPU/exceptions.o arch/x86/CPU/GDT_IDT.o arch/x86/PIC.o arch/x86/COM/main.o libc.a ==> tfos_kernel.elf
/usr/bin/ld: ../build/kernel/arch/x86/CPU/SSE.o: relocation R_X86_64_32S against `.data' can not be used when making a PIE object; recompile with -fPIE
/usr/bin/ld: failed to set dynamic section sizes: bad value
collect2: error: ld returned 1 exit status
clang-15: error: linker (via gcc) command failed with exit code 1 (use -v to see invocation)
I... do use -fPIE
sse 
fair, anyway uhhh
I should just comment it all out
bruh
/usr/bin/ld: ../build/kernel/arch/x86/CPU/GDT_IDT.o: relocation R_X86_64_32S against `.data' can not be used when making a PIE object; recompile with -fPIE
/usr/bin/ld: failed to set dynamic section sizes: bad value
collect2: error: ld returned 1 exit status
clang-15: error: linker (via gcc) command failed with exit code 1 (use -v to see invocation)
How do these things work in GCC then
hmm so you just get the same error when linking other object files
oh yeah
fair
you can put your idrt/gdtr on the stack for all it matters
they are loaded once and the memory can be discarded
of course you still need the gdt and idt entries available at all times
oh damn
it works
I just made it leaq it into a temporary variable, and then lidt that variable
and it works perfectly
lmao, you could just put it on the stack instead 😄
after a few more tweaks, it works perfectly with clang
hmm, well that's not right
aw crap, I think I forgot to push my changes 2 days ago
I'm at school now, and it's late start, so I have ~1h
but I don't want to cause a merge conflict
aren‘t you the only one working on this? How can you cause a merge conflict
if you work from 2 different computers and you do commits on each starting from the same head will get you there
made that mistake of not pushing
Oh right lol
yeah
well I've started working a bit more on the PMM
and I was very much right when I said that progress would slow down
I'm writing on average a few 10s of lines of code per day
even though I still have maybe 3 hours per day to work on it, I'm pretty drained
finally got real work done on the PMM
It's a valid address at least
within the first region of memory
now I just need to test it more thoroughly
don't you want 0x1000 sized/aligned chunks of memory from a PMM?
yeah, ofc, I was looking into why that's happening, but I'm working on other stuff first
it only takes a number of pages to allocate, and is supposed to give you an address of that many pages, after setting them to used
so I don't know how it's getting that
What type of allocator have you implemented?
it's a simple bitmap
fr
then how can you even get an 0x8 out of that
it takes in addresses and sizes of the regions, and saves that info, and has a helper function to determine, from a byte and bit position in the bitmap, what the base address of the region of memory it's representing is
yup
yeah, but that only works if you memory starts at 0x0 if I'm not mistaken, or if you remap it to there (neither of which is the case here)
how and where do you store bitmaps?
it finds the smallest region of memory that's marked "usable", that is at least totalMem / 4096 / 8 bytes long, and puts the bitmap there
it's just a bunch of bits, as per the name
it also has the bitmapData structure, which stores an array of bitmapData_t's, which each hold a base address, and ending bit in the bitmap, of each memory region
(that structure is in the bss, not dynamically allocated)
it's a little more complicated than that, but basically, yeah
is base page-aligned
should be, it's just the base address from the memory map (except in the case of the memory region that holds the bitmap, in which case it is the first page-aligned address that's after the end of the bitmap)
alright that does sound correct
oh wait, no, I forgot, I changed it
for the region holding the bitmap, it just marks the pages with the bitmap as used
oh wait, hang on
I just noticed something after looking back at it now
the address the PMM gives back is entirely invalid
it's somehow before the first basePtr
that's gonna need way more work that I can put into it right now, I'm trying work on my server
might try to fix it later today, or tomorrow morning
why would that be needed
how else could you have multiple base addresses?
you would need to have some way to determine the actual address of the memory, like what I have
or you would need to remap the memory so that it's all lined up, (which would be a much better solution, but I just want it to work for now....)
how else would you address multiple regions of memory, aside from remapping it so that it's all one chunk (which again, I don't do yet)?
wdym remapping it
the whole point of the pmm is that it deals with physical memory
you cant just remap the physical memory
oh wait, no I was getting confused, nvm, I was thinking of virtual memory
then yeah how else would it even work then
without multiple base addresses, you would be limited to only using 1 region of memory
in my os i just used a single bitmap to represent the entire physical memory
its a really simple solution but it will waste a lot of ram if your memory ranges arent in sane places
I do that as well, but I keep a seperate array of data to handle converting from a location in the bitmap, to the physical address of the region it's in
that way it can use every memory region from the map
ah, so it'll only work with a section of memory where it's 1+ usable regions back-to-back?
uhhh i have no idea what you are doing
the whole point of having a simple bitmap like that is you can just multiply the index by 4096 to get the physical address
I don't get how that could possibly work
like this example from my memory map, here's the usable regions:
[PMM ] Entry 1 : 0x0000000000052000 - 0x000000000009F000; 308K; Type: Usable
[PMM ] Entry 4 : 0x0000000000100000 - 0x000000003FB18000; 1018.9M; Type: Usable
[PMM ] Entry 8 : 0x000000003FB3F000 - 0x000000003FF2B000; 4016K; Type: Usable
in my implementation, it makes a bitmap that can represent every page of each of those regions of usable memory
then, it saves the starting address of each region, and the final bit of the bitmap that represents that region
then, to get the physical address of a bit in the bitmap, it just finds the index of bitmapData (that saved data that I mentioned above), where the ending bit is more than the bit that we're trying to find
then it goes backwards, and gets the base address of that region
then, it finds the ending bit of the region that's before that, adds 1, and subtracts it from the bit that we're trying to find
then it multiplies that by 4096, and it adds that number on to the base address that was found previously
and it returns that
ah, the entire thing is broken, that's why
hey hey, this might actually be right
Recieved pointer: 0x0000000000096000
hmm, or not....
Is your code available?
yeah
also, framebuffer works
(really tiny, but I can set a white pixel in the top left corner)
oh yeah, also, it's on the rewrite branch (I should really make it the main branch tbh)
the whole build system including that configuration tool looks nice
ah, thanks
the configuration tool isn't really used atm
Since the current method (hardcoding every possible config option) isn't very viable long-term
I need a completely different method
trying to implement a basic 8x16 binary font renderer right now, so far my luck is that it page faults, and since it's the default TTY callback, it page faults while trying to print what went wrong, causing a triple fault after a few seconds...
make the callback on startup be e9 or serial or something
you seem to have a lot of trouble
It's serial by default, but then I change it to fb and it diess
debug debug debug
test printing to it directly without switching the callback then
you would probably benefit a lot from the "prototype in userspace first" development model
yeah, I would just use GDB, but again, at school using an AArch64 chromebook, GDB doesn't work on it
true, could do that
still doesn't really help me figure out what's wrong
would probably need to use gdb at my house in order to find out where it's dying asside from some just the registers from QEMU
I kind of do that as a last resort, because it often means porting over lot of kernel code
but I will admit, it is helpful to just run it through GDB and see where something is dying, and to tinker with it without needing to rebuild an entire ISO, and reboot a VM
well examine the qemu log
You could look at the RIP register‘s value, and use like addr2line
yeah, of course
still, gdb would be useful to examine what was actually going on before it dies
lldb should work
oh... uhh that might be why
(gdb) p y
$5 = 3831
(gdb) p x
$6 = 0
it's trying to print extremely far off the end of the framebuffer for... some reason, idk
fixed it by hardcoding the value of x and y to 0 every time, and harcoding the color to white
tried baking in the default VGA text mode font
it... didn't work all that well
alright this is... better... I guess?
its backwards
yeah...
not sure how
currently trying to fix some basic stuff
like porting back the ANSI escape codes stuff, and handling special characters
aha, the issue was not my fault!
my friend wrote a perl script for converting binary fonts into C, and somehow it was just... reversing the text
don't ask how
I don't know
and neither does he it seems
I had this problem
I can help
assuming you're using the drawchar function from here https://wiki.osdev.org/VGA_Fonts, reverse the mask array
It worked for me
Kernel execution 🦴. Hanging.
I'm not actually
I wrote a shitty for loop myself for it, and I'm confused at how byte 0, bit 0 of the font could be the top-right corner
oh wait
I'm fucking dumb
BECAUSE IT IS
yeah... the 3-5 hours of sleep per day from school is getting to me it seems
and now it page faults....
oh hey, I just got lldb working
well, the framebuffer console works
also, this is page faulting somehow....
fbCon.ptr[offset + (7 - j) + (i * fbCon.width)] = color;
sigh
it's page faulting, but it works
what
wtf
7-3 = 4
j = 3
7-j = -1 ??????
what is offset, j, and i
offset = offset to get to the top left corner of where to draw the character in the framebuffer
i = byte offset of the glyph, starts at 0, increments to 16
j = bit offset of the glyph, starts at 8, decrements to 0
what were their values?
not sure yet
currently about to switch classes, so I can't check
I fixed it
I don't know how I fixed it, but I fixed it
oh yeah, but the ANSI escape codes are still messed up
fixed it
it works
kind of been in a drought for tfos
everything depends on fixing the PMM
and that would take at least a solid day's worth of work probably
which is something that I just can't do atm
take your time
What happened to this project?
its probably still not dead yet
he has posted some more progress on ncommander's discord server
hes an active member on that server along with the seshos guy
it is in fact not dead yet
"The SeshOS guy" is mineman (used to be a mod here if I'm not mistaken)
and he's actually the one who convinced me to start work on the memory manager again
Testing PMM!
[1m[33m[[36mPMM [1m[33m][0;31m Failed to shift mem control blocks over - No empty blocks[0m
[1m[33m[[36mPMM [1m[33m][0;31m Failed to shift mem control blocks over - No empty blocks[0m
[1m[33m[[36mPMM [1m[33m][0;31m Failed to shift mem control blocks over - No empty blocks[0m
[1m[33m[[36mPMM [1m[33m][0;31m Failed to shift mem control blocks over - No empty blocks[0m
[0m[1m[31m !!! !!! !!! KERNEL PANIC !!! !!! !!![0m
Error: Invalid memory control block type: 0x1000
So far it's going uhhh.... interestingly
same with my kernel
alright well I fixed the "no empty blocks" error
I just forgot to set all of the blocks to 0 (empty) at init
but I have absolutely no idea where it's getting type 0x1000 from
that just makes 0 sense
the entire table is set to 0s
uhh
this is very wrong
it's running off the end of the table
what the heck
it's just not hitting my case for "oh shit we hit the end of the array"
neither, it's an else if (curInfoBlk->type == MEMINF_TYPE_END) {
it relies on the array being correct
which it very much should be
since it can follow MEMINF_TYPE_INFOPTR blocks down entirely different memory chunks, I can't just have a counter that checks if it's over 32 (the end of the starting array)
also, my design is very eh, because on one hand, it can infinitely scale to any amount of memory (granted it's less pages than the 64 bit unsigned integer limit, which I think should be fine for at least the next century, since that would be 4096 TB of RAM if my math is correct), while using the same low amount of RAM
but on the other hand the kernel memory used by it grows as you allocate more RAM
and can quickly become fragmented (although it's very easy to degragment)
also it's insanely inefficient at handling tons of tiny allocations
but at the same time very efficient at large ones
idk, maybe I should implement both it and a bitmap
- for allocations under a few pages, it goes in the bitmap
- for bigger ones, it goes in my "blocks" system
this still ha the issue though of if something spams a massive amount of tiny allocations, we could run out of bitmap space before running out of physical memory to give
although maybe the bitmaps could be dynamically allocated when necessary and pointers put in an array
This is where investing into your vmm and kernel heap can help you
Also I wouldn't worry about the worst case at this point in your kernel. Start with something that works and then you can move on to the next thing, and come back around later if you do actually run issues with your current implementation.
correct
uh oh
what the heck, I have like 4GB free
welp
I fixed a bunch of bugs, but it still does weird shit then explodes
Testing PMM!
[1m[33m[[36mPMM [1m[33m][0;31m Failed to shift mem control blocks over - No empty blocks[0m
Recieved pointers: 0x0000000000000000 and 0x0000000000000000
[0m[1m[31m !!! !!! !!! KERNEL PANIC !!! !!! !!![0m
Error: (#PF) Page Fault
Registers:
RAX: 0x0000000000000000 RBX: 0x0000000000000000 RCX: 0x00000000000000A5
RDX: 0x0000000000005000 RDI: 0x0000000000000000 RSI: 0x00000000000000A5
R8: 0x0000000000000000 R9: 0x0000000000000000 R10: 0x0000000000000012
R11: 0x0000000000000000 R12: 0x0000000000000000 R13: 0x0000000000000000
R14: 0x0000000000000000 R15: 0x0000000000000000
Int: 0x000000000000000E err: 0x0000000000000002 CR2: 0x0000000000000000
RIP: 0xFFFFFFFF80003BCC RBP: 0xFFFF80000FF69FC8 RSP: 0xFFFF80000FF69FC8
CS: 0x0000000000000008 SS: 0x0000000000000010 rflg: 0x0000000000000006
qemu: terminating on signal 2
yeah this just isn't going to work....
it's actually terrible, and I just realized my fatal flaw in the design
the entire point of this is that it's supposed to be way more efficient with large allocations, or groups of allocations that are directly next to each other
but it can't keep track of the size of every allocation like that, so how do we free just one piece of a block
welp, there goes like.... a lot of work
it's okay don't overwhelm yourself so much
try preplanning whatever is causing the headache
yeah, except that that's what caused this whole mess
I planned it out too hard, and made a terrible design that didn't even work
although now I think I might have a (maybe) working bitmap allocator
I can allocate memory, write to it, and free it
although I still need to test it more thoroughly
well then it sounds like you should try dividing the problem at hand into smaller subproblems
yeah
but now this allocator kind of works
all of the addresses it gives me are valid
yup
my tester code checks for that too
although somehow it's not page aligned when it gets to the 4th test
which makes no sense
I'll need to look into that when I get home
wasn't that your issue like weeks ago with your allocator
kind of
not really
it had.... way more issues
it never made it to the 4th test iirc
it just produced pointers that were entirely wrong
made a tiny progress bar for my malloc tester
it's also kinda broken
ah, actually I was just using it wrong
I forgot I set test #2 to only do half as many tests as normal, since it's so slow
the weird part is that this really should work
oh
I just realized why test #2 (allocate a lot then free it) takes so long
it's allocating 10MB of memory, then freeing it....
500 times
even under KVM, yeah, that's a little slow
oh
yeah I ported the tester to Linux (fixing some of the bugs in the process)
it completes an entire round of tests in like 3 seconds
my PMM is just slow lol
ah, also might have just fixed the page alignment
it seems it might have been related to the way that I handle the bitmap
i.e. it wasn't page aligned, and everything goes off of that address
well, it doesn't crap itself completely this time
it manages to stay running
but uhh
not very well
yeah its mineman
finally going back to this and uhhh
yeah my OS works fine what do you mean™️
welp
time to rewrite my memory manager for the 20th time and hope I get it right this time
idk why but "Refusing to allocate 0 pages of memory" sounds funny
yeah lol
ok, have been working on this for a bit, and I believe I finally have a (maybe) working design
haven't even tried to compile it yet, but so far it's looking good
oh no
I think I fucked up with git
this fbcon code is really old
oh god
it's worse
it's been broken all along and has just never cropped up
welp, works now
needless to say I have very low hopes that this will actually work
well
it doesn't crash
but I've somehow broken my framebuffer
never even initializes
oh
it would help if I would remove the infinite loop in PMM_Init()....
1st real attempt went very well
Tip: When you get a page fault, check cr2 for the address that faulted (ie. the address that was accessed)
nvm I didn't see it
yeah, I can see it's trying to mess with a NULL pointer
trying to add a stack trace to my panic handler so I can see exactly what's doing without needing to break out gdb every time
so you basically have a struct like this:
typedef struct __stack_frame
{
struct __stack_frame* next_frame;
void* rip;
} stack_frame;```
then
```c
stack_frame* frame = __builtin_frame_address(0);
/// ...```
welp, parents making me do stuff before I can finish....
will work on this more when I get back
back, and I got it working with the worst possible hack
__builtin_frame_address doesn't allow using a variable as it's argument, so I did this:
#define STACK(x) stack_frame* frame##x = __builtin_frame_address(x); \
if (frame##x != NULL) {\
printf(" #" #x ": %p\r\n", frame##x->rip);\
}
void panic(...) {
// ...
STACK(0)
STACK(1)
STACK(2)
STACK(3)
STACK(4)
STACK(5)
STACK(6)
STACK(7)
STACK(8)
STACK(9)
// ...
}
well... kinda working
it never becomes NULL, so it starts going outside the stack and dies
Thing is that I already do xor %rbp, %rbp before I load into C code, so it should have a final NULL entry in there (iirc it's what makes GDB backtraces work)
I had this working in the old version, let me go check if there's something else I'm missing
hmmm, there doesn't seem to be... weird
hmm, this is how I did it last time and I remember it working. Just grab the RBP register, save RIP from the frame, and then follow the saved RBP in said frame, and repeat until you hit NULL
uint64_t mem[20];
uint64_t *stackTrace(uint8_t max) {
(void)max;
DUMPREGS;
uint64_t *rbp = (uint64_t *)regs->rbp;
uint8_t i = 0;
while (rbp) {
uint64_t rip = *(rbp + 1);
rbp = (uint64_t *)*rbp;
mem[i] = rip;
i++;
if (!rip) {
break;
}
}
mem[i] = 0;
return mem;
}
well hey, it didn't page fault trying to do a stack trace this time at least
now if only I could get symbols resolving easily, that's definetly something to work on
my old implementation of that was absolutely cursed beyond belief
basically my old implementation was:
- Link the kernel with a dummy symbols table structure
- Use
nmto extract all of the symbols - Parse it, dump it into a C file with the right format (C struct)
- Link it a 2nd time with the real symbols table structure
- Iterate over it until it finds the 1st address that is below the address we are looking for. It is that symbol, and the difference is the offset
but making a better version of that is for another time
now I need to figure out how this died
hmmm this is worse than I thought
judging by my stack trace, it goes something like, from top to bottom:
main()
testMalloc()
malloc()
*PMM_AllocBytes()
some bogus address that doesn't have any debug info associated with it
x86_ISR_Handler()
everything leading up to panic() because it got a page fault
*: note that I can't see where in PMM_AllocBytes it died, the last frame before the interrupt handler was to get back to malloc() from PMM_AllocBytes()
this is great
oh wait I'm dumb.. the RIP value in the registers dump is where the fault occurred... 🤦♂️
wow I've really gotten rusty
just wrote some quick docs for how I want to implement my PMM
wondering if it's actually any good...
it's kind of a revival of my old blocks idea, but actually planned out in a way that makes it work
just use a freelist
yeah I looked into it, and... idk, maybe
if my idea doesn't work out then I might look into it more, but it seems that my idea actually works... until I go to split a block, which causes it to return some bogus number of bytes in a block, and then the next allocation dies
doing some maintenance on the build system
manged to get this:
error: unknown target triple 'unknown-unknown-none', please use -triple or -arch
bruh?
LD arch/x86_64/111_entryPoint.o arch/x86_64/CPU/ISRASM.o arch/x86/COM/init.o arch/x86/CPU/GDT.o arch/x86/CPU/SSE.o mm/pmm.o mm/debug.o COM.o tty.o panic.o tty/fbCon.o tty/ansi.o bootloaders/check.o bootloaders/limine/check.o bootloaders/limine/framebuffer.o bootloaders/limine/SMP.o bootloaders/limine/memory.o log.o SMP.o arch.o kernel.o arch/x86_64/CPU/printRegs.o arch/x86_64/init.o arch/x86/CPU/exceptions.o arch/x86/CPU/GDT_IDT.o arch/x86/COM/main.o arch/x86/PIC.o libc.a ==> tfos_kernel.elf
ld: ../build/kernel/tty/fbCon.o: in function `FBCON_Write':
/home/techflash/src/Techflash-OS/kernel/tty/fbCon.c:38:(.text+0xdf): undefined reference to `font'
Are you using make or something custom?
wrote my own set of Makefiles
it was previous a set of crappy bash scripts, but now I use make
so much better
also, memory manager progress
I am getting closer to figuring out what the issue is
the pointer is fine until it gets here, when it turns into whatever the crap that pointer that starts with 0x53DB is
log("nextblk", LOGLEVEL_VERBOSE);
currentTmp += nbytes + 1;
current = (memblk_t *)currentTmp;
printf("current2: %p\r\n", current);
wh-
I think I've found the problem
also just finally fixed the long standing issue with my fbcon driver so that I can scroll now, which is very epic
now stuff like that stack trace getting cut off won't happen anymore
hmm
I have isolated the issue
memblks[*whatever index*]->numBytesOrPages is getting set to nonsense by the first allocation, then the second allocation tries to skip 21834539991045 bytes ahead into random memory
what
oh my god
the issue was this currentTmp += bytes + sizeof(memblk_t) + 1;
the pointer calculation was wrong
I wasn't taking into account the size of the structure, just the size of the data (bytes + 1)
after adding the sizeof it just works perfectly
well
actually maybe not
but uhh, it's kind of close?
the first pointer is right in both cases, but the second one is just... what
(8 byte data structure at the beginning of each allocation. I know very well by now that the first usable memory block in the memory map here is 0x52000)