#FrostyOS

1 messages ยท Page 5 of 1

lost schooner
#

i'll try with it off to make sure

#

and it fails very fast

#

of course it does

#

why wouldn't it

#

PMM test time

#

its very slow

#

this might take a while

#

its really weird that something that works well on kvm, fails instantly on plain tcg

#

the PMM test passes of course

#

why???

#

this doesn't make sense

#

maybe there is some memory corruption??

#

seems like there is something that a size in the PMM free list is not page aligned

#

there must be some edge case where that can happen

#

the error occurs at entry to the function

#

not at exit

#

which suggests corruption

#

its not being overwritten by a page table

#

maybe something else?

#

this is very annoying and strange

lost schooner
#

ubsan is off, so I'll try enabling it to see what difference it makes

#

it did something

#

the error is on free now

#

thats good

#

maybe

#

it might actually mean there is some ub

#

its at entry

#

so corruption it is...

#

a rewrite is definitely on my mind

#

If I don't figure this out soon, I might need to

#

theres no virtual memory overlap in PageManager regions

#

I think the VMM heap could be responsible

#

because, the bad region in the PMM free list looks a lot like a Heap ChunkHeader

#

I'm suspecting an use after free somewhere

#

I wonder if I disable PMM::FreePage/PMM::FreePages and just give it a lot of memory if it will work

#

yep

#

I'll try unmapping the pages as they get freed to see if I can catch the issue

#

there is some kind of assertion failure in Heap::Verify()

#

I'll deal with that when I work out this use-after-free

#

I'll disable larger pages for simplicity

#

doesn't catch it

#

maybe its something else

#

maybe I should try making a userspace program

#

and putting it in there

#

so I can use valgrind to find any bad accesses

lost schooner
dusky orbit
#

welcome back

#

more memory issues I see nooo

lost schooner
#

Yep

lost schooner
#

I've spent so much time debugging this, and still have no clue what the problem is

#

I'm still avoiding making a userspace test

lost schooner
#

i've wrote a userspace heap test

#

I'm currently running it normally

#

I'll also run it in valgrind

lost schooner
#

its not looking like valgrind is going to catch anything

#

it's at 1.7 million out of 10 million iterations of the test

#

with no errors so far

#

if I don't work this out soon, I'm just going to rewrite

#

I'm getting really frustrated with this

#

If I choose to rewrite, it won't be a full rewrite, but all new memory management

lost schooner
#

I have no idea what to do now

#

so the heap isn't responsible

#

what else could it be?

#

there is PMM corruption somehow

#

there are very few places that the PMM is used directly

#

vmm heap is one, which I have confirmed is fine

#

the other is the PageManager

#

and I previously confirmed that no pages are being double mapped

#

almost forgot about page mapping

#

that code could be responsible

#

i have an idea

#

I'm going to re-enable PMM freeing

#

but leave larger page sizes disabled

#

it fails

#

i thought for a moment that it could be bad freeing of unused page table levels

#

but that code is never reached

#

it fails during iteration 11653

#

the actual error is that the PMM reports a nodes size being not page aligned

#

its inconsistent

#

it varies each time

#

I've had enough of this for today

#

If anyone wants to have a look, all the memory management related code is in kernel/src/Memory/ and kernel/src/arch/x86_64/Memory/

#

I've left the test in the end of kernel/src/kernel.cpp

dusky orbit
#

Could it be something using the heap is going out of bounds?

#

Or maybe some buffer accessed through the hhdm is going out of bounds?

lost schooner
lost schooner
#

it could actually still be that

#

the heap itself is fine, but maybe something using it is being bad

lost schooner
#

I'll try doing what r4 once said about adding guard pages to allocations when I next have time

lost schooner
#

I might even try getting kasan working

dusky orbit
#

I've been meaning to take a look at your code too

lost schooner
#

I'll look into this again tomorrow

#

I haven't had time the last few days due to assignments

#

I don't like having 5 assignments all due at a similar time

lost schooner
#

I have time now, so I'll get back to debugging this

#

I'll be looking for vmm heap allocated objects going out of bounds

#

GCC's anaylser caught some stuff

#

I'm going to have to build uACPI as a separate library without -Wpedantic

lost schooner
#

one of the outputs is in kernel symbol loading

#

related to the possibility of new returning nullptr

#

maybe if I add an assert to new to ensure it cannot return nullptr it will go away

#

doesn't do anything

#

there must be some form of attribute I can give to new so GCC can realise that it cannot return nullptr

#

the other few outputs are related to lambdas, but aren't actually an issue

lost schooner
#

I've tried adding calls to PMM::Verify in more places

#

and it fails at entry to PageManager::FreePages

#

which indicates something else is stuffing things up as I suspected

dusky orbit
lost schooner
#

I might try aligning to the end

#

the test I did aligns to the start

dusky orbit
#

and I know noexcept new can return nullptr, but non-noexcept new throws (and I assume cant return null)? Unless thats what you're doing and its still complaining.

#

yeah try the end, that'll catch overruns. I have (had) an optional to toggle which end got checked

lost schooner
lost schooner
#

I found it strange that even with a guard page to either end of each individual allocation, the error still occurred

#

so maybe something else is causing it

dusky orbit
#

could it be a use-after-free?

#

oh you said you disabled freeing a while ago

#

so maybe not

lost schooner
#

I changed kmalloc_vmm to align the size to pages, and then allocate n+2 physical pages, then unmap the start and end pages. kfree_vmm does nothing

#

and the issues still occurs

dusky orbit
#

it happens on the latest commit of the testing branch?

lost schooner
#

i haven't pushed the test, but i don't think there was any other changes

#

I'm on windows rn, but I can quickly reboot and commit the test

#

I've committed it

dusky orbit
#

great ty, I'll have a look at it now

#

the corrupted state is happening in the kmalloc_vmm stuff?

lost schooner
#

no, the PMM

#

the free list data is being stuffed up by something

dusky orbit
#

ok cheers

#

hmm

lost schooner
#

stupid ovmf has renamed itself in the system directories from OVMF_CODE.fd to OVMF_CODE.4m.fd

#

oops, just noticed something in the run script

#

I was experimenting with different display modes and forgot to reset it

#

fixed

#

the ovmf stuff I'll keep local for now

#

I probably need to find a better solution

#

I think I might know what parts of the code is causing this

#

I changed the PageManager to just allocate a PMM region and return the HHDM address of it instead of the fancy stuff

#

and it seems to work

#

so maybe my mapping code is dodgy

#

I changed PageManager::AllocatePages back to normal and disabled PageManager::FreePages, and it seems to work

dusky orbit
#

nice, I'll start there (got distracted with cats)

lost schooner
#

cats can be very distracting...

#

btw, the g_i stuff is just for debugging purposes

lost schooner
#

don't know if it is direct or indirect

#

I made the VMM heap normal again, and same issue

#

so it is definitely that function call thats stuffs everything up

#

I tried re-enabling all the self verifying stuff in the VirtualMemoryAllocator and I ended up with a linked list looking like this:

#

that shouldn't be possible

dusky orbit
#

nice, that narrows it quite a bit

#

you'll want to flip the order of these calls:

m_vma->FreePages(address, pageCount);
m_regions.remove(address);

Since there is a race condition where the pages can be freed but the region still exists, and I dont see any locking around them that would prevent that

lost schooner
#

yeah, didn't think of that. This is currently all single threaded however

#

so it probably isn't the issue

dusky orbit
#

yeah I didnt think it was your issue

#

but as a general rule for releasing a resource you want to deny access and make sure no one is using it (and can get access to it) before freeing it.

lost schooner
#

makes sense

#

I've been comparing the page managers structures to the virtual memory allocator's ones, and it seems to be consistent

#

I've only checked the free list so far though

#

the all address tree appears to match as well

lost schooner
#

I can't work on this today, but I should be able to work on this a lot more after today

lost schooner
#

maybe I'll return to this soon

#

this bug has been really annoying

#

I had intended on playing minecraft today, but the server I play on isn't currently running

#

so I'll debug this while I wait

#

back to the bug

#

I had discovered that freeing the virtual page region would trigger the issue

#

so I need to work out why

#

it doesn't make sense why

#

unless maybe something in that function is going just enough out of bounds

lost schooner
#

I've got some time this weekend

#

So I'll investigate a bit more

#

Tomorrow not today though

lost schooner
#

I've been working on this issue for a while now

lost schooner
#

I'm starting to consider a partial rewrite

lost schooner
#

I don't know how far back I would go

#

Before PMM or after VMM heap

#

Or even after page mapping, but before VMA

#

Everything seemed fine until I tried porting uACPI and it all fell apart

#

This message was when I first thought that PageManager::FreePages is where the issue is coming from, and I was right

#

First mistake

lost schooner
#

I thought my extensive testing would be enough

#

but obviously not

dusky orbit
#

The real test was yet to come

#

A shame this bug is still plaguing you

lost schooner
#

Yep

lost schooner
#

I was just thinking

#

Maybe this bug is a data structure issue

lost schooner
#

i don't have much motivation for this project at the moment

#

I think maybe a partial rewrite is needed

#

the problem is that if it is a data structure issue, then a rewrite might not solve it

#

when I next feel motivated to work on this, I might try swapping my avl trees with the rb tree that oberrow was using

lost schooner
#

ok

hardy lake
#

sys/tree.h

lost schooner
#

I couldn't remember if it was freebsd or openbsd

dusky orbit
#

you also have some c++ trees out there if you want to use them: managarm/frigg, qwinci had one in crescent iirc, I've seen a few other fairly complete ones floating around.

#

although those are rbtrees iirc

lost schooner
#

The purpose of using a different tree structure is more to eliminate the possibility of it being the issue

lost schooner
#

I'll do this today

#

I've been avoiding it for too long

hollow trail
#

thats the attitude

lost schooner
#

the main issue was pmm data corruption

#

which was being caused in some way by VirtualMemoryAllocator::FreePages

#

never found out how or why

#

the idea I thought of 5 days ago was to use a different tree structure instead of my AVL trees incase it was the problem

#

they have caused problems in the past, so I wouldn't be surprised

#

wait no, it was 9 days ago originally

#

wow

#

I really have been avoiding this

#

school is finished for the year now, so I have nothing better to do

#

the last time I properly worked on this was 19 days ago

#

just reading through that function I don't see anything obvious, so I might try the tree change

lost schooner
#

I just noticed that if I disable merging of free regions in the VMA, the issue appears much faster

#

disabling freeing of the physical page also makes the problem disappear

#

interesting

#

maybe my PMM is an issue

#

but is only triggered in this situation

lost schooner
#

I've been working on one of my other projects a lot lately

#

A rewrite is really on my mind at the moment

#

I've been try to debug this for at least a month now

#

And I haven't really made much progress

#

All the components seem to work on their own

#

But not together

#

So some linking code is the issue

lost schooner
#

I did a little bit more investigating

#

The unmap code is fine

#

I suspect the virtual memory region allocator

#

so I'll be testing it properly again when I feel motivated to

lost schooner
#

I've been working on another project a lot lately

#

I started this rewrite back in august

#

So I think I should just rewrite again

#

It's probably a good idea

lost schooner
#

instead of doing that I've made a userspace test for the vma

#

and am currently running it through valgrind to see if it will catch anything

lost schooner
#

there were no errors

#

but there was a significant amount of leaks

#

that might be from not clearing the VMM at exit

#

vma*

#

now I have to wait another 20 minutes to see if that is where the leaks are coming from

#

I'm going to reduce the number of iterations

#

so I don't have to wait as long for a result

#

there are definitely leaks

real viper
#

meow

lost schooner
#

I should probably just rewrite at this point

dusky orbit
#

damn, hopefully this one has more success ๐Ÿ™‚

lost schooner
#

I hope it does

#

I'm not sure when I'll make a start

#

I've been mostly focused on another project lately

lost schooner
#

It has been a while

#

I've had a minecraft distraction over the last 4 or 5 days

#

And I've lost most of my motivation for my other project

#

And for the first time in a few weeks, I'm actually starting to feel motivated to work on this

#

I'm not sure how long the minecraft distraction will be full on for

#

But probably not for much longer

#

I want to properly design stuff this time

lost schooner
#

I guess I should start soon

#

First I'll just get Framebuffer printing, GDT, IDT out of the way

#

Then I'll do PMM I think

#

Then page mapping

#

Then basic scheduler, no preemption yet.

#

I guess then I can do VMM heap, virtual memory allocation, kernel heap, IRQ system, page cache

lost schooner
#

SMP will be at a similar time to the IRQ system

#

The current iteration failed when I tried to port uACPI for the irq system

#

So I think I'll need to do a different testing approach to avoid that happening again?

lost schooner
#

enough procrastination

#

I'm starting this rewrite now

hollow trail
#

thats the attitude

lost schooner
#

I've committed the latest code, and moved it to a new old-code branch

#

testing branch is gone

#

I'll clear out master in a moment

lost schooner
#

I've cleared it out mostly

#

I'm keeping all the basic TTY and graphics stuff

#

it triple faults though unfortunately

#

-d int doesn't print anything though

hardy lake
hollow trail
#

Yeah I kinda miss frosty os work

lost schooner
#

oh I know why this doesn't want to work

#

I need to do global constructors

#

finally:

#

GDT time

dusky orbit
#

its happening ๐ŸŽ‰ , good luck with this iteration

lost schooner
#

GDT is done

#

IDT time

muted blade
#

[GDT INIT] OK

lost schooner
#

and the IDT is done

#

PMM is next

#

first kernel was bitmap

#

next was freelist

#

I don't know which one I liked better

#

for bitmap, allocate was O(n) (could be optimised to be O(1) best case), free was always O(1)

#

for freelist, allocating a single page is O(1), allocating more than that is O(n), free unoptimised is O(n), but can be very easily optimised to be O(1)

lost schooner
#

I'll do a free list

#

I see that limine has a new base revision since I last looked

#

seems like the biggest change is that ACPI memory regions aren't mapped in the HHDM

#

which doesn't really have an impact since I'll remap it all anyway

#

I do like that idea though

#

I might do that when I do page mapping

#

since I'll be using uACPI, it doesn't really matter

#

this might be an issue though:

#

my previous iterations both used the 0th page for the SMP trampoline

#

but if I ever want to do something like suspend, that can't happen

#

so I guess I'll just find an alternative when the time comes

#

an alternative to using the 0th page that is

lost schooner
#

single page allocation and freeing is done

#

now I need to test it

#

I'm go to use a similar approach as before

#

I am going to quickly make a new bitmap implementation first since the old one was horrible

lost schooner
#

time to continue on this

#

yesterday, I ran the test and an assertion failed

#

specifically the one that checks the free list is in order

#

which it should be

#

iirc limine memory map entries are guaranteed to be in order

hollow trail
#

think so

lost schooner
#

yep, that isn't the issue

#

my free code is stuffing it up

#

this is not good:

#

an allocated object is in the free list

lost schooner
#

I've wrote a proper Verify() now

#

and there is a lot of uninitialised memory bugs which I keep finding

#

somehow there is 1 less node in the free list than there should be

#

it only happens when an object getting freed fits perfectly between 2 nodes

#

oh I'm stupid

#

I see why

#

the test looks like it is going well so far

#

it has to do 1 million test iterations

#

the test passed

#

next is multipage allocate/free

lost schooner
#

free is done

#

because it is almost identical to single page

#

allocate will be a little bit different though

#

maybe

#

yeah it will be

#

single page allocation just takes the first free region

#

but multipage will have to search for a region

#

I've made sure to make PMM::AllocatePages call PMM::AllocatePage if the page count is 1

lost schooner
#

multipage allocate/free worked first try

#

I think that means the PMM is done?

#

nevermind

#

it froze when I ran the test again...

#

oh I know why

#

it works again

#

alright, PMM is done

#

next is page mapping

lost schooner
#

I don't know why I need page mapping

#

scheduler doesn't need it?

#

A custom page map would be helpful though?

#

I guess I'll do page mapping anyway

#

I think I want to do a different approach this time

dusky orbit
lost schooner
#

Oh. I forgot to finish what I was saying

#

My previous 2 kernels just went through all the page table levels in one function

#

I was thinking of looping through the different levels

#

Probably with something like a GetNextLevel function

#

Which would make it possible to support 5 level paging

lost schooner
#

I forget to do system updates for a few days, and I end up with 272 packages needing to do an update...

#

qemu being about 100 of those

#

anyway

lost schooner
#

GCC is weird when it comes to inline assembly

#

just as a test I wrote a inline assembly cpuid function:

#

and GCC did this:

#

I just did this:

#

wait nvm, I just noticed an issue. This is what I actually do:

#

why is GCC generating so much extra stuff

lost schooner
#

I keep getting distracted by what it happening in the other threads

#

I'm trying to make this kernel support 5 level paging

#

but I just realised an issue with the way I was trying to approach it

#

I was trying to just enable 5 level paging as soon as it is checked that the CPU supports it, which won't work

lost schooner
#

I have to check for it, then later when I go to load the page tables, I have to disable paging, enable 5 level, then enable paging again

#

I could just have limine enable it for me...

#

I should just do that

lost schooner
#

time to get back to this

#

I've been getting distracted a lot today

dusky orbit
lost schooner
#

yesterday I didn't end up getting much done

#

but I did make some assembly functions for checking for 5 level paging, nx, 2MiB pages, and 1GiB pages

lost schooner
#

my host CPU doesn't support 5 level paging, so I will have to test it with KVM off

#

for obvious reasons, 5 level paging is an optional feature that will only be used if it is supported

#

same with the larger page sizes

#

nx is required though

#

I also discovered that the qemu64 CPU doesn't support 1GiB pages by default

#

with low RAM that is. I think I remember it supporting it with larger RAM sizes

#

nevermind, it doesn't

#

I wonder if that contributed to my old kernel having issues...

#

because I'm pretty sure it thought that the qemu64 CPU had 1GiB pages

#

and I know it isn't an issue with the way I check in this kernel because when I add +pdpe1gb to the cpu, they are supported

lost schooner
#

Starting today, I'll need to update the copyright years in any files I edit

lost schooner
#

My page mapping function is now done

#

the main 4KiB page one anyway

#

the larger page ones are very similar

lost schooner
#

all the map functions are done

#

I'll make sure these work before I worry about remap or unmap

#

looks like 5 level paging is getting enabled by limine which is good

haughty galleon
haughty galleon
lost schooner
lost schooner
haughty galleon
#

๐Ÿ‘

haughty galleon
lost schooner
#

I just followed what the license I use, GPLv3, told me to do, except that I changed the "c" to a "ยฉ" since at the time I think I had read that in Australia, something is only copyrighted if that symbol is used?

lost schooner
#

I feel like I've been getting distracted a lot over the past few days

lost schooner
#

I think I've made all the functions I need now to switch over to custom page tables instead of limine's

#

almost

#

I just realised I forgot the PAT

lost schooner
#

ok, PAT is done

lost schooner
#

I think mapping everything is done

#

time to test it...

#

I've obviously stuffed something up:

#

I stuffed up the CPUID function somehow

#

looks like my code for converting edx:ecx into rdx is wrong

hardy lake
#

show your cpuid function

hardy lake
#

I will have a look at this

#

you don't seem to restore rbx

lost schooner
#

just noticed that

#

same result

#

highest bit of ecx should be clear

hardy lake
#

well why do you merge edx:ecx into rdx

lost schooner
#

to build this struct:

hardy lake
#

ah

full needle
#

unless you want to force the alignment of the struct to 1 for some reason

lost schooner
#

wouldn't all the uint32_ts get promoted to uint64_ts?

full needle
#

why?

lost schooner
#

I thought that without packing all items in the struct are 8 byte aligned?

full needle
#

no

lost schooner
#

ah

full needle
#

they are aligned to their alignment

lost schooner
#

ok

full needle
#

which for integers is the same as their size

lost schooner
#

I got it to work by swapping the mov edx, ecx with an or rdx, rcx

#

I don't understand the difference

#

interacting with the low 32-bit portion shouldn't affect the high 32-bit portion?

#

anyway, there is now an OOM when building the page tables

#

I just noticed that the HHDM offset limine provides is different with 5 level paging

#

that does make sense

#

more virtual address space

full needle
#

but writing to the 16-bit register doesn't affect the higher parts iirc

lost schooner
#

that is weird

lost schooner
#

the one I am dealing with now is that memory that shouldn't be getting mapped into the HHDM still is somehow

#

ohhh

#

I see why

#

the size was too small, so it didn't want to work

#

1 bug down

#

how ever many more to go

#

still getting an OOM

#

I don't know why

#

it seems to be mapping multiple new page table levels each time

lost schooner
#

I accidentally crashed gdb...

#

I tried to access something out of bounds in QEMU

#

and it did not like it

#

gdb may be broken:

#

when I press up to get the previous command, it returns as if there were a 5 there

#

it gets increasingly more broken

#

I closed the terminal completely, I'll see if it works now

#

it seems to be working again

#

and these paging structures are completely messed up

#

gdb is still behaving a little weird though

#

so I'll do a raw memory dump from QEMU to see what it says

#

the font on the qemu monitor is so hard to read

#

I don't know why

#

it never used to be

dusky orbit
#

yeah i'm not a fan of the builtin qemu monitor, I always route to it some output I can hook up my own terminal too

lost schooner
#

stdio is being used by the debug console, so I don't know what I can route it to

#

I could try route it directly to one of the various pts consoles, but my terminal emulator would not like that

#

the raw memory dump contains an address, but it is at the wrong location

#

its at offset 0x3f8 in the page

#

when it should be at 0xff8

#

so highest 2 bits are missing?

#

I thought it may have been an operator precedence issue, but that appears to not be the case

#

I found the bug

#

I was on the right track

#

stupid off by 1

#

still haven't completely fixed the issue though

#

the highest page table level is no longer messed up

#

but all the others below still are

#

I just saw the next bug

#

what was I thinking

#

now it page faults

#

and the stack trace from gdb is a mess as always

#

it never prints it properly from an interrupt context no matter what I try

#

a forgot a to_HHDM

#

now there is a general protection fault even earlier

#

I've noticed that CR2 will contain the bad address if a GPF is due to a non-canonical address

#

oh I know why that was happening

#

the HHDM offset needs to be added only in the case when a new page table level wasn't allocated

#

now somehow the level index has wrapped around into a negative?

#

maybe it is trying to double map something and it doesn't go well?

#

but I have a check to prevent that from being possible

#

I'll add an assert(false); into the case where the x86_64_GetNextPageTable function gets an out of bounds index

#

It's when mapping a 2MiB page

#

I just found another bug similar to the one before

#

once again, what was I thinking:

#

and now it is back to mapping something outside of accessible physical memory

#

I'm going to make some changes to my region mapping function

#

to prevent this kind of issue

#

and that is done

#

but it is somehow back to trying to read page table level 0

#

how is that possible

#

it is the 2MiB page one, so it shouldn't even be reaching level 1

#

oh I see why

#

it is trying to map a 2MiB page at an unaligned address

#

I've added some safety checks to mapping of larger pages sizes to prevent it from trying to read more than it is supposed to

lost schooner
#

my approach is completely wrong

#

the size alignment doesn't matter, it's the address that does

#

finally it appears to work

#

triple faults though

#

probably when actually loading the tables

#

yep

#

the HHDM portion appears to be good

#

but the kernel itself is not

#

the region mapping function is still wrong

#

I don't feel like dealing with this right now

lost schooner
#

time to deal with this

#

it doesn't triple fault anymore

#

but it page faults

#

then page faults whilst trying to print the panic to the screen

#

so the kernel and its stack are being mapped properly, but the framebuffer isn't

#

original page fault is whilst trying to print to the screen

#

qemu has a really annoying bug with 5 level paging where the info mem monitor command doesn't print anything

#

looks like the entire framebuffer isn't being mapped

#

the page mapping functions are being called with the correct addresses though

#

appears like it isn't reaching level 1

#

maybe the page size bit is set incorrectly for some reason?

#

the offsets at each level appear to be correct for the single page mapping

#

I'll verify the ones for the 2MiB pages just in case the page size bit is being set in the wrong place

#

it all makes sense

#

this is weird

#

I did a memory dump

#

and the table entry causing the problem is zero

#

I found the bug

#

for some reason in the check for if the GetNextPageTable function returns nullptr due to a large page, I was using the 0th entry instead of the correct one

#

it finally works

#

so many bugs

#

I'll deal with remap and unmap tomorrow. Shouldn't take long as unmap is essentially an extension of remap.

#

I'll quickly test this with normal 4 level paging

#

it works

#

ok that is good

#

my kernel can do both 4 level and 5 level paging with no issues

lost schooner
#

I'll also need to do some real hardware testing tomorrow

brittle crow
lost schooner
hardy lake
#

move the debug console to file:/dev/stdout

#

and put monitor on stdio

#

which is enough to trick qemu into having both on there

lost schooner
#

That's what I was just thinking

#

Debug can probably go to a file

lost schooner
#

I'll change the run command to do that for debug mode

#

release mode doesn't have the debug console, so it would be weird for it to have the monitor

#

I set the RAM size to 16G and it still works, which means 1GiB pages must be working

#

I'll quickly test this on my laptop

#

it works

#

idk if my laptop supports 5 level paging, but it definitely supports 1GiB pages

#

I'll quickly see what linux says

#

no it doesn't

#

which means I don't have an x86 machine that supports it

#

because my PC doesn't

#

if 4 level works, then 5 level should as well because of the way it goes through the table levels

lost schooner
#

remap is essentially map but I don't need to create page table levels if they don't exist

#

I'll start with remap, then I'll deal with unmap

#

also need to make a function for getting a physical address at some point

lost schooner
#

remap for standard pages is done

#

I'll try make a test for it

#

I'll just remap the first page of the kernel as read-write-execute instead of read-execute and then just see what the QEMU monitor command info tlb says

#

it works

#

for testing 2MiB pages, I'll just remap the first page of the framebuffer as read-write-execute instead of read-write

#

and it works

#

I'm not going to bother with 1GiB pages since they are essentially the same process as 2MiB

#

unmap time

#

I just realised that the QEMU monitor command doesn't care if the TLB has been flushed or not

#

unmap is annoying because you have to go down the tables to find the entry, then you have to work back up the tables to delete unused tables

lost schooner
#

I haven't really decided on how to approach this

#

I'll need to do the normal process of going down the tables, clear the lowest entry

#

but then how do I work back up the tables?

#

I guess I could have a mini stack of the entries?

#

it was actually simpler than I thought

#

I need to test that it actually works

#

I'll test it by allocating a page from the PMM, mapping it into some address where all the table levels will need to be created, then unmapping

#

since the HHDM offset is 0xFF00'0000'0000'0000, I'll map it at 0xFF10'0000'0000'0000

#

this is the test:

#

I hope it works

#

the message is printed

#

the QEMU monitor says it isn't mapped anymore

#

I'll do a physical memory dump of the root page table to see if it is gone

#

I can just run the xp monitor command to read from an address

#

and the entry is empty at the root page table

#

which means unmap works correctly

#

I think this is the first time I've properly tested unmap

#

I just realised my unmap is going through the levels in reverse order when it is trying to delete the empty ones

#

it is a simple fix though

#

it works still

#

for larger pages, it is essentially the same, so there is no point in trying to make a test

#

I guess this means page mapping is done

#

actually no

#

I need to make some basic TLB flushing and getting a physical address

#

getting a physical address works

#

and basic TLB flushing works

#

both a full table reload and just invalidating individual pages are supported

#

now page mapping is done

#

everything still works with KVM on and the default CPU features

#

alright, scheduler time

lost schooner
#

I think first I'm going to make a basic PIT driver so I can do preemption

#

which does mean basic legacy i8259 PIC support

#

I needed to do it eventually anyway since they need to be disabled to be able to use the APICs

lost schooner
#

I've wrote PIC and PIT drivers

#

time to test

#

it works

#

first try

lost schooner
#

I want to make it easier for my scheduler to support multiple CPUs later, so I'll implement some cpu local stuff next

lost schooner
#

I'll need to make some changes later so that each processor gets its own GDT and IDT

#

I won't worry about that for now

#

so far I've just made some changes to abstract arch init a bit, but in a way that makes adding support for SMP later a bit easier

dusky orbit
#

Are you thinking of going multi arch this time, or is it an organisayion thing?

lost schooner
#

I'm trying to make it easier to go multi arch for when I want to.

#

Also an organisation thing

#

But other archs I had in mind are aarch64 and the m68k

#

aarch64 because I have some raspberry pi's to test it on

#

(So no one corrects me, I added a ' so it couldn't be confused with raspberry pis)

#

Also maybe my custom arch one day

#

That's if I can be bothered to finish the LLVM port

#

There's also some other things as well

brittle crow
lost schooner
#

Idk

brittle crow
#

flashing every time microsd or usb is terrible

dusky orbit
#

yeah fair, well good luck if/when you go ahead with aarch64 and m68k ๐Ÿ˜„

lost schooner
#

I haven't much time to work on this today

#

I'll have limited time over the next 2 weeks due to various things

#

most of that being because I'll be in a different part of the country starting on tuesday

#

anyway

#

so last night I made some abstraction for arch init

#

I didn't end up comitting it

#

I'll quickly do that now

#

I think it's time to start on the actual scheduler

#

I definitely want to go multi privilege level EDIT: I mean priority

#

not sure how many I want

#

the scheduler from my original kernel had 4: LOW, MEDIUM, HIGH, and KERNEL

#

I'll have a look at what mintia does

lost schooner
#

maybe some other OSes as well

lost schooner
#

mintia is too confusing

tired cedar
lost schooner
#

I didn't have any time today

lost schooner
#

Didn't have any yesterday either and probably not today as I'll be stuck in the car all day

#

I'm not sure how much time I'll have over the next 2 weeks as I won't be at home

lost schooner
#

Haven't had any time yet

#

And the place I was at yesterday has horrible mobile reception, so I couldn't do anything if I wanted to. Tomorrow I'll be busy exploring Sydney, but after that hopefully I'll have some time to start on my scheduler.

dusky orbit
#

oh nice, enjoy sydney - unfortunately the weather is awful this week (so much for summer lol)

lost schooner
#

I was thinking about a design for my scheduler last night

#

My original scheduler had priority levels, but they were weird

#

A lower level thread would be scheduled if a higher level thread had been run 3 times (only if there is an available thread in that level)

#

It was weird

#

I also didn't have thread-specific run time frames, it was just after a certain number of ticks, something would get scheduled

#

Unfortunately, I don't know when I'll have time to start

#

The scheduler for this kernel will be different

#

I haven't completely decided between priority or niceness

#

I'm not entirely sure how priorities are supposed to work

#

Niceness makes sense

lost schooner
#

I'm going to try make a start

#

I have a little bit of time

#

I haven't used my laptop in so long

#

i forgot how annoying my laptop's keyboard is

#

I guess I'll start by making the data structures for all the various parts of the scheduler

#

there will be processes, which then have a list of threads

#

I won't worry about the process stuff for now

#

since it will be annoying to make a list without a heap

#

the schedulers list will be a bit different

#

they will be using intrusive lists instead

#

I'll make them doubly linked so they can be traversed in either direction

#

wow the mobile reception here is so slow

#

I would expect it to be decent considering I'm in the capital of the country

#

but nope

#

vscode is taking ages to update extensions

#

why is microsoft c/c++ trying to install

#

I have clangd

lost schooner
#

finally it finished

#

picom has decided it doesn't want to work

#

just noticed I left a define in the kernel main file

#

I hope my gpg key is on my laptop

#

nope

#

I'm also signed in on the wrong git account

#

nevermind, the gpg key is there

#

I'm not dealing with this right now

dusky orbit
#

๐Ÿ˜ฆ

lost schooner
#

I have not work on this since then

#

Because git is annoying

#

I had to switch account for some reason

#

And I can't remember how I reset the auth keys

#

Because I use git credential manager via secret service to log in

#

The GPG stuff is easy

#

Switching account is a pain

lost schooner
#

I might just wait until I get home

#

I'm halfway through my trip now

lost schooner
#

I feel really motivated to do osdev, but demotivated at the same time because of git being a pain

#

I'm not home yet, but I really want to do osdev

#

The mobile reception where I am right now is actually decent

#

When I was in Sydney a week ago, my reception was good, but not that fast because the transmitters were too close...

#

Where I am now seems to be a good distance from one

#

I'm going to try get git to behave itself so I can work on this

#

I don't know how long I'll do it for though

#

As I've been awake since 4:30am

#

Its currently 8:44pm

lost schooner
#

that was simpler than I thought

#

for future reference, if using anything related to freedesktop secret service, use seahorse to manage credentials

#

I'm too tired for osdev

#

maybe tomorrow

lost schooner
lost schooner
#

osdev time

lost schooner
#

I made a basic kernel context switch function

#

which worked the first time I set the registers parameter properly...

lost schooner
#

I might actually do some work on my custom arch for the next little bit instead

lost schooner
#

So I did go ahead with that idea

#

I haven't really felt like working on this much

#

Partially because I'm too lazy to transfer some of the stuff I did on my laptop over to my PC

#

I'm also back at school

#

Which limits my time a lot

real viper
#

school? how old are you

#

yall are crazy bro

#

๐Ÿ˜ญ

#

if you are a high schooler making a kernel thats crazy

proud nova
#

And yes, while I don't know what the case is for Frosty, some of the OS projects here are indeed made by high schoolers.

lost schooner
#

I started osdev when I was 14

proud nova
lost schooner
#

I've been distracted by my custom CPU arch a lot over the last few months

real viper
#

๐Ÿ˜ญ

lost schooner
#

I find it more fun most of the time than this project

proud nova
#

Same EXACT thing ROFL

real viper
#

i probably had an iq of 4 at the age of 14

#

and now im 17, it hasnt changed

proud nova
#

Oh believe me I did goober shit when I was 14 too. And 16. And 18. And now.

lost schooner
real viper
#

we are not americans thankfully

#

:D

hardy lake
#

America is more like south Canada

proud nova
#

Every time I look over at America they have done something else that makes me go "WTF"

real viper
hardy lake
hardy lake
real viper
#

bro i am literally using a vpn to use discord right now

#

it is banned

#

does it sound cool now

hardy lake
#

Maybe being in Turkey isn't cool

lost schooner
#

Let's not flood this thread with off topic conversation please

real viper
#

sorry for chatting in your thread bro

proud nova
lost schooner
#

Huh?

proud nova
#

I hereby notify you of the existance of that Discord server.

#

You're welcome.

#

I wish I had that when I first started doing CPU crap

lost schooner
#

My CPU is purely virtual, no physical designs are planned

proud nova
#

I mean

#

So are all but one of mine

#

I made a breadboard CPU once but I don't think I'll do that ever again.

lost schooner
#

My custom design is 64-bit, so trying to make it on a breadboard wouldn't really be feasible, let alone making some form of physical design

lost schooner
#

Also, that server you mentioned is a massive pain to get in to

proud nova
#

It's worth it after the verification.

#

I haven't seen such a bot-free place filled with experienced digital designers anywhere else yet.

#

They certainly helped me multiple times, saving me loads of time on my projects.

#

If you decide not to join, you can always ask me questions instead ;)

lost schooner
#

I can't seem to get in to the server. I've gone through the verification process, but nothing has happened

proud nova
#

Is there an error message?

#

Hang on, I'll poke the mods for you.

lost schooner
#

It's working now

lost schooner
#

I'm not sure when I'll return to this project

lost schooner
#

I'm feel like doing osdev

#

I*

#

It's been a while

#

I finally could be bothered transferring the changes I made on my laptop 5 weeks ago

#

and I've had enough of dealing with llvm for a bit

#

so it is finally osdev time

#

the last thing I did was make a context switch function

#

and it worked first try

#

I think I had designed most of my scheduler in my head, but it has been 6 weeks, so I don't remember any of it

#

I do remember finally understanding the difference between priority-based and niceness-based

#

and I decided on niceness-based

#

since it seems more fair

#

I've been considering using limine's SMP feature to get the other processors online so I can make my scheduler support multiple CPUs from the start

#

and then later I switch over to a more custom system

#

since I want to make a scheduler that relies on the least amount of things I can

#

I have a basic PIT driver for preemption

#

I don't know if I mentioned this, but my old scheduler did it in a really dodgy way

#

it was very simple

#

every so many ms (40 iirc), the scheduler would just reschedule on all cores regardless of how long the current threads had run for

#

which is definitely wrong

#

I'm not doing that again

lost schooner
#

I'll be doing per-processor thread queues

#

and work stealing eventually

lost schooner
#

I just went to try get the value of CR3 and use that as the pagemap for threads, completely forgetting that I had done all the page mapping stuff

#

which means I could technically test the scheduler in user mode when it is time

#

all the surrounding stuff is mostly done, it is time to actually implement the algorithm

#

I have chosen to go with 16 nice levels

#

15 being the highest, and 0 being the lowest

#

I was thinking maybe making it so a thread with higher nice value is twice as likely to run as a thread with a lower nice value

lost schooner
#

I haven't completely decided on how to split kernel and user threads

#

kernel threads are probably just going to be used for DPCs mostly

lost schooner
#

I forgot some of the multi-processor stuff

#

but it'll have to wait until tomorrow

#

I'm out of time today

lost schooner
#

time to continue on this

lost schooner
#

I ended up getting distracted for a few hours by school shenanigans

lost schooner
#

I ended up wasting some time last night making an enum for a bunch of MSR names

lost schooner
#

I keep getting distracted whilst trying to do this, so progress is slow

lost schooner
#

I'm trying to design a way of picking the next thread without recursion

#

the checking system needs to be able to move down the list of levels if the run count for a level is >=2

#

but if it finds no levels below having any threads, it then needs to be able to move back up

#

it is fairly simple with recursion, but I'm not sure how to do it properly without

#

and it needs to work for an arbitrary amount of niceness values

lost schooner
#

I have an idea

#

maybe I could go through the niceness levels lowest to highest instead

lost schooner
#

time to continue on this

#

after I finish updating the linux kernel

#

I was using 6.12.10, when the latest is 6.13.5, so it was overdue

lost schooner
#

that is finally done

#

now I can do osdev

lost schooner
#

PickNext is done

lost schooner
#

I think it is time for a test

#

there is going to be 16 processes (1 for each niceness level), each with 4 threads

#

single processor for now

lost schooner
#

test has been made

#

time to see if this works

#

page fault

#

attempted write to nullptr

#

forgot some stuff so it doesn't try use the non-existant heap

#

nvm

#

something else as well

#

still that issue

#

fixed that

#

it appears to be stuck

#

it is stuck trying to get the length of a linked list

#

it is a looping list for some reason

#

why is next and previous equal to the node itself

#

the scheduler hasn't even started yet

#

oh I know why

#

I forgot to init the node pool

#

oops

#

I'll also make it a bit bigger since it is currently not big enough

#

QEMU seems to freeze when you try load a high address into CR3

#

it succesfully started the first task

#

but I forgot that the GS base gets cleared when the GS segment register is reloaded

#

I don't even really need to set that segment register anyway for a kernel mode switch

#

it is still page faulting

#

GS base is still 0?

#

oh, interrupt return sets it

#

I'll need to make some changes to that function

#

later

#

I'll just comment out the GS segment reload for now

#

it seems to be able to switch thread once

#

then it doesn't again

#

something is messing up one of the fields in the processor's state struct

#

so the scheduler thinks that the processor shouldn't be getting anything scheduled to it

#

I had set the stack addresses wrong

#

it is actually switching threads now

#

but it is wrong

#

the niceness pattern currently is 15 14 15 15 14 15 14 15 15 14, which is wrong

#

it should be 15 15 14 15 15 14 15 15 13 and so on

#

and now the pattern is 15 15 14 15 15 14 again

#

I'll try resetting the PIT ticks just before the scheduler is started

#

didn't change anything

#

every so often it seems to double up on picking in between printing what thread is running

#

which could be an stdio issue

#

wait nvm

#

I know what is causing that

#

I had made a makeshift sleep so it wouldn't spam the debug console

#

but replacing it with just a hlt is enough

#

it prints after every interrupt

lost schooner
#

here's the algorithm if anyone is interested:

hollow trail
#

only thing i dont like about it is the number of locks involved

lost schooner
#

What is bad about lots of locks?

#

I understand they make code more prone to deadlocks

hollow trail
#

a lot of locks means a lot of contention for said locks

lost schooner
#

But wouldn't more locks break it up so more stuff can happen at once instead of waiting ages for the one lock to be released

hollow trail
#

especially in places like the scheduer which should ideally be lock free

#

barring thread migration between cpus

lost schooner
#

I can understand on other fields by ensuring atomic reads/writes

hollow trail
#

a lot of ways, for example you can submit threads to run via an ipi

#

so only the cpu itself can modify its queue

lost schooner
#

I see

lost schooner
#

time to debug this

#

I think I understand the problem now

#

it is because of the way the run count for a level is reset

#

the pattern will be 15 15 14 15 15 14 15 15

#

in this case, both have run counts of 2

#

should*

#

but don't

#

since the run count for 14 is reset on the second last 15

#

when it shouldn't be

#

it's an issue with how the algorithm runs

#

the run count should only be reset when either when something of a lower nice runs, or there is nothing of a lower nice

lost schooner
#

it seems to be working now finally

#

maybe 1/3 is not frequent enough

#

it took 10 minutes to get down to level 6

#

that means level 5 will take 30 minutes

#

4 -> 90 minutes

#

3 -> 3 hours

#

2 -> 6 hours

#

wait no

#

3 -> 4 and a half

#

2 -> 13 and a half

#

1 -> roughly 1 and a half days

#

0 -> roughly 4 and a half days

#

maybe my chosen timeslice is too big?

#

or should nice also change the timeslice?

#

those numbers are considering there is at least 1 thread in every nice level

#

@red swift you're good with schedulers, what do you think?

red swift
#

having lots of locks where 99% of the time its a totally core-local lock and theyre only grabbed cross-core during thread migration is fine

#

this is commonly done

#

what ur describing doing instead is unusual and has drawbacks

red swift
#

if it had to spin on its core-local queue lock for a bit while you placed a thread into it

#

(and otherwise never contends on that spinlock)

#

and in the latter scheme you only need to ipi if you enqueue a higher priority thread than its currently running (or if its idle)

red swift
#

thats why i just ripped off ULE for the policy for mine

lost schooner
#

ok

#

what's ULE?

red swift
#

the freebsd scheduler, its well documented

lost schooner
#

ok thanks

hollow trail
lost schooner
#

I'm going to try get this scheduler working multi-core

#

which will be an interesting experience

#

considering I have no VMM or heap

#

I need to setup uACPI for tables

#

just early loading

#

I can probably just allocate a smallish region with the PMM

hollow trail
#

btw if you're willing to test, the PR for UACPI_BAREBONES_MODE is already available

lost schooner
#

I'll have a look

hollow trail
#

it basically does this

lost schooner
#

ok

lost schooner
#

clangd is being annoying. It's saying an include is unused, but if it isn't included, there is a not defined error

#

I've set everything up and get a page fault

#

reading a HHDM address

#

why

#

oh I know why

#

I don't map ACPI regions by default

#

I guess I'll change my uacpi_kernel_map to actually do something instead of just converting it to a HHDM address

#

@hollow trail should I be mapping ACPI regions as UC?

hollow trail
#

on x86 u can map as WB

#

since u have MTRRs

#

on other architectures (at least what linux does) is scan the memory map to see what it is being mapped, and then pick caching accordingly

lost schooner
#

ok

#

it works so far:

hollow trail
#

is this barebones_mode?

lost schooner
#

yep

hollow trail
#

nice

lost schooner
#

I don't think I've done a real hardware test on this version of my kernel yet

#

so I'll see if it works

#

it works

#

It has some interesting tables

#

like what is IHIS, LPIT, BDAT, DBG2, DBGP, NPKT, PRAM, DMAR, WDAT

bold timber
#

that's not flanterm is it?

lost schooner
#

no

#

custom

bold timber
#

ic, nice

#

i like the font

lost schooner
#

It's a random one I found on stack overflow 2 and half years ago

#

with some minor modifications to some letters

#

almost all of the tables seem to be page aligned

hollow trail
#

yeah cool font

hollow trail
#

DBG2 is debug table 2

#

with serial ports i think

bold timber
#

btw is it intended that there is no space before the ) on that one line that ends up being shorter than the rest?

#

seems weird

hollow trail
#

yes, RSDP has no OEM ID

bold timber
#

not RSDP

#

the other one towards the bottom

#

it's an SSDT

hollow trail
#

which?

bold timber
#

DpftTab one