#HelixOS (ARM64 OS, not dead project!)

1 messages Β· Page 2 of 1

spring sonnet
#

I've got a 64MB virtual range I'll be mapping my page tables at. After some calculations 8MB was the max space needed, but figured 64MB will be more than enough for my needs for now

#

This will make it easier for me to map/unmap and modify page table entries

unreal creek
spring sonnet
#

Currently working on dynamic paging. Gonna be a long day working on the VMM.

spring sonnet
#

I'm thinking I might need to setup two page tables. The first one being a "boostrap" page table so that I can map thee other othe into the reserved virtual range. Currently researching more about this.

spring sonnet
#

Think I'm going to want to do something like this, but I'll need to rework the VMM for something like this...

spring sonnet
#

okay I'm starting to get a little irritated with this. I can't think of a good way what so ever to handle mapping pages to a reserved region and not have to do recursive paging.

#

I don't want to map the entire physical region either.

#

I'll figure it out.

spring sonnet
#

I'll probably need to divide my VMM code into different types of setup.

#

Rather than stress myself out trying to fit shit all into one thing

spring sonnet
#

I'm going to need my PMM to return physcial address frames instead of virtual ones.

#

Tonight's going to be a hell of a lot of memory managment rework

spring sonnet
#

Brtual night of VMM rework...

#

I think it's time I implement a kernel heap. I think it's a better approach instead of trying to allocate general purpose memory with the PMM.

#

I'm gonna start on this in the morning. I've burned my brain enough for tonight.

#

I'll check out how SerenityOS implements theirs and come up with my own based off that. I may implement a slab-based allocator for this.

spring sonnet
#

Going to implement a kernel slab allocator kind of based off the current one I have, Then I can properly make kmalloc() use this.

#

And then I'll probably want to have my page tables allocated with this for easy management.

spring sonnet
#

Hell this is probably what I should have did to begin with.

spring sonnet
#

Time to implement the kernel heap.

unreal creek
spring sonnet
# unreal creek goid

It'll be roughly based off of the general purpose one that I currently use for variable sized allcoations, but this one is for the kerenl heaep instead...

#

Well in this case my kernel heap will be a slab allocator implementation

spring sonnet
#

It's going to have to be a bit more carefully crafted since I don't want to make any calls to pmm_alloc() for the slab objects themselves...

spring sonnet
#

Might have to to take a different approach for the heap allocation stuff instead of trying to use a slab allocation method.

#

I realize trying to do that with a 16MB heap and no exsting calls to stuff like pmm_alloc() will be a pain in my ass

#

Or I can still do a slab allocation method, but do a linked list implementation

spring sonnet
#

Had to rework the base a bit. Saw that Mint moved some stuff to codeberg, and wanted to ensure my base was cloning the correct repo's. This time I just forked them so if I need to make any edits for Helix I can do so

#

Currently reworking some suff.

#

Reworked the PMM ever so slightly, and I'm currently reworking my enitre VMM setup.

spring sonnet
#

Major PMM rework underway.

#

Next will be the VMM.

#

After.... I'll work on the VFS

unreal creek
spring sonnet
spring sonnet
#

For now I've also removed the slab allocator. The initial PMM, slab allocator, and VMM was just to get the kernel going. Now that I have interrupt handling in place, and have a simple timerr, and serial driver I can focus more on improving this stuff.

#

I'll have to rethink the slab implementation later down the road, but for now I want to focus on my PMM setup.

#

Well and VMM of course

spring sonnet
#

New PMM is now in place.

#

Time to get the VMM worked on next up.

spring sonnet
#

VMM is going to be undergoing a major rework to make it a bit more robust.

#

Or at least as robust as I can make it

spring sonnet
#

For being able to keep track of page tables, etc, and being able to access them I've decided to take a chunk of the end of physical memory for this. During some of my research I learned that this is probably a better way of being able to track tables. I think 64MB is kind of overkill since only like 8MB is probably the most that's needed, but allows for a little wiggle room. I've got a simple vmm_pt_alloc() that just turned a pointer to the page table pool region which a given index, and uses the PMM as a fallback if the pool gets fully used up. It might get changed around a little bit, but this was a way for me to be able to handle being able to modify/unmap pages or entire tables.

spring sonnet
# willow prism whats the reasoning

My original implementation would make calls to pmm_alloc() when a new frame was needed, but I struggled to implement a way to access the tables in virtual memory properly without falling into recursive page table mapping

#

I'm sure I could try again, and implement something though

willow prism
#

also are you on 64 bit

spring sonnet
spring sonnet
#

ARM64 though

willow prism
#

theres no problem at all

spring sonnet
#

Sounds good!

#

I'll definitely make use of recursive mapping of the tables though. So that way if I need to modify an existing entry I can do so

#

I had eventual plans to implement a vmalloc() to handle continuous virtual memory allocations

willow prism
#

you can just access the page tables by their physical address plus the hhdm offset

spring sonnet
#

That's true... My previous implementation didn't do a very good job of this, and I had ran into issues so I'll want to adjust that

#

It's good that I took time to clean things up a bit though. The last implementation was a bit of a mess, but at least it worked lol

willow prism
#

well

#

its just addition

spring sonnet
#

That's very true..

#

I realize too I can always do page swapping when needed when I get more towards getting a disk drive, and filesystem in place so I shouldn't worry too much on it...

spring sonnet
#

Working more on the VMM today. Currently improving my code to handle getting different page table levels, and also handling freeing of empty tables, etc.

spring sonnet
#
static void vmm_map_table(page_table_t *table, uint64_t virt, uint64_t phys) {
    vmm_map(table, virt, phys, PT_TABLE | PT_VALID);
}

void vmm_map(page_table_t *table, uint64_t virt, uint64_t phys, uint64_t flags) {
    uint64_t l0_idx = PGD_IDX(virt);
    uint64_t l1_idx = PUD_IDX(virt);
    uint64_t l2_idx = PMD_IDX(virt);
    uint64_t l3_idx = PTE_IDX(virt);




    assert(table != NULL);
    page_table_t *l0 = (page_table_t *)PHYS_TO_VIRT((uint64_t)table);




    if (!(l0->entries[l0_idx] & PT_VALID)) {
        page_table_t *l1 = pmm_alloc(1);
        assert(l1 != NULL);

        l0->entries[l0_idx] = (uint64_t)l1 | PT_TABLE | PT_VALID;

        vmm_map_table(l0, PHYS_TO_VIRT((uint64_t)l0), (uint64_t)l0);
    }

    page_table_t *l1 = (page_table_t *)PHYS_TO_VIRT(l0->entries[l0_idx] & ~0xFFF);
    
    if (!(l1->entries[l1_idx] & PT_VALID)) {
        page_table_t *l2 = (page_table_t *)pmm_alloc(1);
        assert(l2 != NULL);

        l1->entries[l1_idx] = (uint64_t)l2 | PT_TABLE | PT_VALID;

        vmm_map_table(l1, PHYS_TO_VIRT((uint64_t)l1), (uint64_t)l1);
    }

    page_table_t *l2 = (page_table_t *)PHYS_TO_VIRT(l1->entries[l1_idx] & ~0xFFF);
    
    if (!(l2->entries[l2_idx] & PT_VALID)) {
        page_table_t *l3 = (page_table_t *)pmm_alloc(1);
        assert(l3 != NULL);

        l2->entries[l2_idx] = (uint64_t)l3 | PT_TABLE | PT_VALID;

        vmm_map_table(l2, PHYS_TO_VIRT((uint64_t)l2), (uint64_t)l2);
    }

    page_table_t *l3 = (page_table_t *)PHYS_TO_VIRT(l2->entries[l2_idx] & ~0xFFF);

    if (!(l3->entries[l3_idx] & PT_VALID)) {
        l3->entries[l3_idx] = (uint64_t)phys | flags;
    }
}

Probably the ugliest way to recursive map page tables. I don't really want to map the entire usable memory at once if I don't need to.

#

I realize I already fucked up on mapping the tables.

tender acorn
#

lol

#

my map function

#

wasn't recursive

#

i think that's why it was troubling me

#

lol

spring sonnet
tender acorn
#

oh damn

#

im trying to do some other projects before getting onto my OS again

#

i did 1 commit today tho

#

but i just changed the makefile

spring sonnet
#

That's better than nothing

#

Well it looks like I finally managed to do it. It's kind of an ugly way of doing it, but it works.

#
void vmm_map(page_table_t *table, uint64_t virt, uint64_t phys, uint64_t flags) {
    uint64_t l0_idx = PGD_IDX(virt);
    uint64_t l1_idx = PUD_IDX(virt);
    uint64_t l2_idx = PMD_IDX(virt);
    uint64_t l3_idx = PTE_IDX(virt);




    assert(table != NULL);
    page_table_t *l0 = (page_table_t *)PHYS_TO_VIRT((uint64_t)table);




    if (!(l0->entries[l0_idx] & PT_VALID)) {
        page_table_t *l1 = pmm_alloc(1);
        assert(l1 != NULL);

        l0->entries[l0_idx] = (uint64_t)l1 | PT_TABLE | PT_VALID;

        vmm_map_table(pgd, PT_VIRT_BASE + l0_idx * PAGE_SIZE, (uint64_t)l0);
    }

    page_table_t *l1 = (page_table_t *)PHYS_TO_VIRT(l0->entries[l0_idx] & ~0xFFF);
    
    if (!(l1->entries[l1_idx] & PT_VALID)) {
        page_table_t *l2 = (page_table_t *)pmm_alloc(1);
        assert(l2 != NULL);

        l1->entries[l1_idx] = (uint64_t)l2 | PT_TABLE | PT_VALID;

        vmm_map_table(pgd, PT_VIRT_BASE + l1_idx * PAGE_SIZE, (uint64_t)l1);
    }

    page_table_t *l2 = (page_table_t *)PHYS_TO_VIRT(l1->entries[l1_idx] & ~0xFFF);
    
    if (!(l2->entries[l2_idx] & PT_VALID)) {
        page_table_t *l3 = (page_table_t *)pmm_alloc(1);
        assert(l3 != NULL);

        l2->entries[l2_idx] = (uint64_t)l3 | PT_TABLE | PT_VALID;

        vmm_map_table(pgd, PT_VIRT_BASE + l2_idx * PAGE_SIZE, (uint64_t)l2);
    }

    page_table_t *l3 = (page_table_t *)PHYS_TO_VIRT(l2->entries[l2_idx] & ~0xFFF);

    if (!(l3->entries[l3_idx] & PT_VALID)) {
        l3->entries[l3_idx] = (uint64_t)phys | flags;
    }
}
#

I'll clean it up a bit, but at least this will allow me to access tables in the virtual address region I reserved for page table mappings.

#

It's a 64MB region since I only really need 8MB for a 4GB physical memory.

spring sonnet
#

Okay that was a bad idea... I'll want to make it map to the same virtual address as it's physical address.

#

Ran into issues on that last one

spring sonnet
#

I can't really access the page tables without mapping the entire physical space. I've not yet found a good solution to this.

#

I think I better solution is to just map the beginning of physical memory up to 1GB for the kernel, and leave the rest for the eventual userspace.

#

At least then I can access the page tables...

willow prism
#

note that you only need to create mappings for ram that actually exists

spring sonnet
willow prism
spring sonnet
willow prism
spring sonnet
#

Fair enough.... I'lll just map the full physical region and be happy with it

willow prism
#

just map it in kernel space

#

and do global mappings for it

spring sonnet
#

That's what I have done now as well as the framebuffer, and some MMIO to handle serial, and interrupts, etc

willow prism
#

it should be way out of the way of userspace

#

and shouldnt affect that at all

spring sonnet
#

Then I should be good then in that case, and will start working on my kernel heap allocator

spring sonnet
#

Finally getting a new kernel heap allocator in place.

#

Then after I can start working on other parts of the kernel. I was thinking to maybe work on a VFS, implement a disk driver, and then work on a read-only EXT2 filesystem driver. Write support can always come later down the road

unreal creek
willow prism
unreal creek
spring sonnet
#

The kernel heap allocator will mostly end up being a simple slab allocator with a 4MB heap. Just to get things going..

#

I can always change this in the future, but for now this will work fine

unreal creek
spring sonnet
unreal creek
spring sonnet
#
    1. assert
#

But this is just a quick and dirt heap implementation for now...

spring sonnet
unreal creek
spring sonnet
#

Right now it's just a quick and dirty implementation to get the kernel going

unreal creek
spring sonnet
#

I agree

spring sonnet
#

But if I really need to I can increase the size from 4MB up to 16MB if needed, but I felt that 4MB should be plenty for my needs for right now

unreal creek
spring sonnet
#

Yes correct

unreal creek
# spring sonnet Yes correct

just one question do you round anything ? like you round to a power of 2 or something (allocation of 6 become 8 allocation of 24 become 32) to reuse slab ?

unreal creek
spring sonnet
# unreal creek have you push your slab allocator ?

I have some old commits of the original one that I implemented, but removed it. I'll be implementing a bit of a more improved version for the kernel heap, but will sort of be based off the original with additional improvments

spring sonnet
#

The old version wasn't too good, and would often have to re-allocate a new slab for different sizes if the one requested didn't exist instead of trying to do a best-fit for the requested size

spring sonnet
#

Decided to go ahead and get started on porting mlibc to HelixOS.

spring sonnet
#

Got it to configure... now to start getting the other shit in place...

#

I kind of like the meson build system

#

I almost like it better than CMake to be honest

spring sonnet
#

I'll worry about that later. Gonna continue working on the kernel.

#

Apparently my ADHD brain is taking over again.

spring sonnet
#

Working on virtio MMIO.

spring sonnet
#

Gotta fix a few slab allocator bugs

spring sonnet
#

Seems to be fine for now. It's quick and dirty for now just to get things going. I plan to clean the allocator up later

spring sonnet
#

Well apparently after resetting the virtio device for setting up features, etc, I never get the reset acknowldegment. It's kind of pissing me off.

spring sonnet
#

Got it.

spring sonnet
#

Turns out I was just doing it incorrectly.

spring sonnet
#

And maybe eventually networking, but not at this time

unreal creek
unreal creek
unreal creek
spring sonnet
#

Not right now. Once I get disk access going I planned to get a vfs going, then work on EXT2 and mount that instead

unreal creek
#

then you mbr/gpt driver scan for all block devices in /dev and create /dev/sda1 /dev/sda2 /dev/hda1 ...

#

and then with your ext2 driver you can mount(or chroot) /dev/sda2 as your new root

spring sonnet
#

I still do plan to get a ramdisk in place as well. I just really wanted to get disk access going

unreal creek
spring sonnet
unreal creek
spring sonnet
#

I gotta eventually figure out why my VMM doesn't map the first 1GB of physcial memory despie iterating the memory map. I have to manually do this outside of the four loop..

#

I'll worry about it tomorrow...

worthy lynx
lime sapphire
#

virtio gpu is nice for having multiple framebuffers

spring sonnet
#

But the important thing is that I've gotten the device initialized...

spring sonnet
#

Since using the ramfb device isn't the best thing to use haha

spring sonnet
#

I think I might have to re-implement my heap allocator

#

At that point might just bring back the old slab allocator...

#

Nah I'll just re-implement it...

#

Except I'm tired today so I probably won't get too much of it done.

spring sonnet
#

After a good nap I'm getting back to work on this kernel heap allocator

spring sonnet
#

I'm just going to fix the PMM, and bring back the old slab allocator for this.

#

Sick of making changes to the heap allocator, and end up with the exact same results

#

Let's hope the bitmap bug I had was setting the bitmap itself to 0xFF instead of 0x00.......

#

Yeah.... that happened

#

Okay no that was needed I forgot.

#

Gotta make sure I map the bitmap though...

spring sonnet
#

Ended up having to bring back the old allocators I had before. What a bullshit day of debugging.

#

I guess if the old allocators aren't broke don't "fix" them.

spring sonnet
#

Had to implement pmm_alloc_pages() for the slab allocator. Finally reached a stage where I need more than a single page frame...

#

It's not complete since I still need to implement pmm_free_pages() and handle a multi-page free. But right now this is just to get the virtio shit going.

#

At least to test and get the disk device geometry.

spring sonnet
#

Well this is some major progress.

spring sonnet
unreal creek
spring sonnet
#

Making good progress so far...

unreal creek
spring sonnet
#

I have to setup a descriptor request for it

spring sonnet
#

I need to cleanup some of the code though.... lol

lime sapphire
lime sapphire
#

how big are these slabs?

spring sonnet
#

This is true! 😁 It feels nice to gain that knowledge to be honest...

spring sonnet
# lime sapphire how big are these slabs?

The slabs were no larger than the length of a single page to try and device that page into smaller chunks of memory... But since I've been working on the virtio driver, etc, the vring allocation ended up being significantly larger than expected so I had to finally handle multi-page allocations...

spring sonnet
#

What's irritating though is that this virtio mmio doesn't fire off an IRQ. My other IRQ's are working fine, but for what ever reason the IRQ status stays zero, and nothing else happens despite setting up the test for a disk read several times to try different things.

spring sonnet
#

Getting this device working has been a real pain in my ass.

#

I'll keep at it till I get my reward. The nice things about this though is that when memory allocator bugs manafest I can introduce a fix for them

spring sonnet
#

Well one thing I do see if that the address of the QUEUE PFN is still virtual, and this expects a physical address.

spring sonnet
#

Never mind it was a physical address, but wasn't properly aligned.

unreal creek
#

it can be useful in a lot of situation

spring sonnet
#

Getting disk access going has been no easy task. Even for the lagecy MMIO device it's got a lot involved...

sly pebble
spring sonnet
#

So.... I've decided to go with the more well documented virtio device for disk access.....

spring sonnet
unreal creek
spring sonnet
unreal creek
spring sonnet
# unreal creek okay good

Trying to get the lagacy stuff going proved to be way more difficult. Especally with the fact I can only find one document on it compared to the newer version of this device

spring sonnet
#

The PCI configuration seems like it will be nice to work with...

#

I plan to spen several days reading the docs, and implementing what I'll need to get disk access going. Later down the road I'll look into the networking and GPU side of things

spring sonnet
#

Welp I see there's a way to force QEMU to not use legacy mode.

#

So to force QEMU to use newer version fo the virtio mmio you'd do this:

    -drive if=none,file=${HDD_IMG},format=raw,id=vda1 \
    -device virtio-blk-device,drive=vda1,bus=virtio-mmio-bus.0 \
    -global virtio-mmio.force-legacy=false \
#

V2 is now in use....

#

It'll be nice to take advantage of these features it provides.

#

Finally getting the device initialized, and ready to go...

#

This part is pretty easy

#
/*
 * Device initialization:
 *
 * - Reset the device
 * - Set the acknowledge bit
 * - Set the driver status bit
 * - Read the device features bits, and write a subset of them understood by the OS
 * - Set the features_ok status bit, read-read to ensure the bit is till set (otherwise feature(s) are not supported)
 * - Perform device-specific setup, includes virtqueues discovery, writing devices virtio configuration space, etc
 * - Set the driver_ok status bit (device should now be "live")
 */

Device initalization process... I made a comment for this to help me remember, but it has to be done in this order.

spring sonnet
#

As I study the documentation, and read existing sources for this I now am beginning to understand how the descripter queue, etc, works.

spring sonnet
#

It's nice to gain some knowledge about how this stuff works

unreal creek
spring sonnet
lime sapphire
#

ah you're dealing with the legacy interface, rip

#

aand you've sinced moved on to the 1.0+ interface lol - good progress πŸ™‚

spring sonnet
spring sonnet
#

Right now I've been trying to test the device to see if I can read from the disk, but so far absolutely no change in status occurs...

lime sapphire
#

change in status?

#

and the qemu trace events may be helpful here

#

you might get some hints as to where things are breaking down

spring sonnet
#

This is very true actually! I didn't even think about using trace events... This will definitely be useful. I had to make use of them during the development of the GIC earlier on

#

I notice no IRQ is pending, and it doesn't seem to acknowledge the fact it has a descriptor either so yes I'll want to use trace events here..

spring sonnet
#

So far according to the trace event logs it's doing exactly what it should be for pulling the deescriptors, etc. So that's a good sign

#

And the notify events are working too so this is also good

#

But... the IRQ's don't ever seem to fire though. Other IRQ's fire just fine so I'll want to look into this for a while

spring sonnet
#
virtio_mmio_setting_irq virtio_mmio setting IRQ 0

According to the trace logs it apparently sets the IRQ, but from further research IRQ 0 is apparently resereved in QEMU?

#
virtio_queue_notify vdev 0x618b1343bf00 n 0 vq 0x722b180d3010
virtio_queue_notify vdev 0x618b1343bf00 n 0 vq 0x722b180d3010
virtio_blk_handle_read vdev 0x618b1343bf00 req 0x618b13761ca0 sector 0 nsectors 1
virtio_blk_rw_complete vdev 0x618b1343bf00 req 0x618b13761ca0 ret 0
virtio_blk_req_complete vdev 0x618b1343bf00 req 0x618b13761ca0 status 0
virtio_queue_notify vdev 0x618b1343bf00 n 0 vq 0x722b180d3010
virtio_blk_handle_read vdev 0x618b1343bf00 req 0x618b13761ca0 sector 1 nsectors 1
virtio_blk_rw_complete vdev 0x618b1343bf00 req 0x618b13761ca0 ret 0
virtio_blk_req_complete vdev 0x618b1343bf00 req 0x618b13761ca0 status 0
virtio_queue_notify vdev 0x618b1343bf00 n 0 vq 0x722b180d3010
virtio_blk_handle_read vdev 0x618b1343bf00 req 0x618b13761ca0 sector 2 nsectors 32
virtio_blk_rw_complete vdev 0x618b1343bf00 req 0x618b13761ca0 ret 0
virtio_blk_req_complete vdev 0x618b1343bf00 req 0x618b13761ca0 status 0
virtio_queue_notify vdev 0x618b1343bf00 n 0 vq 0x722b180d3010
virtio_blk_handle_read vdev 0x618b1343bf00 req 0x618b13761ca0 sector 8388607 nsectors 1
virtio_blk_rw_complete vdev 0x618b1343bf00 req 0x618b13761ca0 ret 0
virtio_blk_req_complete vdev 0x618b1343bf00 req 0x618b13761ca0 status 0
virtio_queue_notify vdev 0x618b1343bf00 n 0 vq 0x722b180d3010
virtio_blk_handle_read vdev 0x618b1343bf00 req 0x618b13761ca0 sector 8388575 nsectors 32
virtio_blk_rw_complete vdev 0x618b1343bf00 req 0x618b13761ca0 ret 0
virtio_blk_req_complete vdev 0x618b1343bf00 req 0x618b13761ca0 status 0
virtio_queue_notify vdev 0x618b1343bf00 n 0 vq 0x722b180d3010
virtio_blk_handle_read vdev 0x618b1343bf00 req 0x618b13761ca0 sector 2 nsectors 32
virtio_blk_rw_complete vdev 0x618b1343bf00 req 0x618b13761ca0 ret 0
virtio_blk_req_complete vdev 0x618b1343bf00 req 0x618b13761ca0 status 0
virtio_queue_notify vdev 0x618b1343bf00 n 0 vq 0x722b180d3010
virtio_blk_handle_read vdev 0x618b1343bf00 req 0x618b13761ca0 sector 2048 nsectors 1

This seems to show it's processing my request.

#

But still no IRQ so this is just strange. And again other IRQ's fire as normal so I'm not too sure what's going on here for the MMIO

#

Time to go RTFM for a while

spring sonnet
#

Well I see I wasn't setting the queue_ready register after setting up the descriptors... whoops

#

qemu: virtio: bogus descriptor or out of resources

Well! That's certainly progress!!!!

#

I'll need to fix a few things, but this is good to see after many failed attempts...

spring sonnet
#

I need to fix my alignment as I suspected. But I seem to have issues with trying to use larger queue lengths. Apparently this all needs to fit within a page. I did read that this expects a contiguous block of memory though, and that the max queue length can be 32K in size of needed

#

I realize now that each descriptor needs to be aligned within it's own page....

#

Well fuck me sideways

spring sonnet
#

Well and the virtio desc, avail, and used structs must be aligned to cache sizes so I made some helpful macros for handling this...

#define VIRTIO_ALIGN(x, align) (((x) + align) & ~align)

#define VIRTIO_DESC_ALIGN(qsz)  VIRTIO_ALIGN((qsz), 16)
#define VIRTIO_AVAIL_ALIGN(qsz) VIRTIO_ALIGN((qsz), 2)
#define VIRTIO_USED_ALIGN(qsz)  VIRTIO_ALIGN((qsz), 4)
#

Alignment has been fixed. I can have my 128 queue size with a max size of 19K. Of course ensuring things are aligned on page boundaries

#

32K is the max allowed length as well so I can't exceed this

#

Also, the queue size itself MUST be a power of 2

unreal creek
spring sonnet
unreal creek
#

and then a response queue (it's not call like that)

frozen silo
#

in general a lot of "modern" (or well not even really that modern) hardware uses a similar mechanism with queues (high definition audio, xhci, nvme etc)

spring sonnet
#

Well learning this now is virtio I'm sure will really help me in the future with implementing other queue-based drivers

spring sonnet
#

MAJOR PROGRESS HAS BEEN MADE FOLKS

IRQ's FINALLY FIRE FOR THE DEVICE!!!

All that's left now is to track down what IRQ number this device is....

#

So it completes the request, fires the IRQ, etc... using the event traces for this has helped a ton!!!

#

Hmm I'm noticing that no IRQ ID's that I've enabled (0-1024) have shown up in my IRQ handler so far (it would tell me the particular IRQ ID is unregistered if it detects this)

#

YOOOOO LETS FUCKING GO I HAVE DISK ACCESS!!!!!

@frozen silo @unreal creek

I still need to figure out the IRQ ID for the handler to actually be called if this is the case, but otherwise it works!!!

#

0x55AA is the ending of the first sector.... and I can read the data!!!

#

@lime sapphire

#

Dude I'm excited as hell right now. I'll clean up the rest of the virtio driver today to better handle things, but for now this was a test to ensure the driver was working, and it is!!

spring sonnet
spring sonnet
#

Looks like the device configuration space might be where I need to handle setting this stuff up for IRQ's, etc.... time to look more into this. But hell yeah disk access is working!!! I gotta clean things up though....

#

Now that I understand how the device is setup as well I can even eventually inplement virtio-net support for networking...

spring sonnet
#

What's kind of irritating though is the IRQ for this device is never fired. The device completes the request, I'm able to see that the buffer was populated, the IRQ status gets set from 0x0 to 0x1 indicating an IRQ asserstion was sent, but... nothing..

#

I've also tested, and enabled literally every IRQ possible and none for this device got called for that partiular PPI.

#

I just noticed the HHPIR register goes from 1023 -> 48... maybe this is my IRQ??

#

I FUCKING GOT IT BABY!!!!!!!!

#

IRQ 48 was the IRQ ID....

#

@tender acorn

#

Now I can work on properly handling the used descriptors, etc, after the device fires an IRQ

tender acorn
#

nice

spring sonnet
# tender acorn nice

Figured out the IRQ being fired by reading the HPPIR1 register... that told me what IRQ was being asserted, but wasn't being handled...

#

Fuck yeah I have disk access!!!

tender acorn
#

hell yeah

spring sonnet
#

Now time to clean things up, and fixup my memory allocators... after that I'll work in a vfs, then implement vfat, and ext2

spring sonnet
#

Currently working on some virtio stuff now that I know the driver works. Working on some helpers to handle descriptor allocations/freeing, and submitting requests to the device.

#

That sure as well was well worth the effort, and debugging it took to get it working...

spring sonnet
#

Now that I have disk access I can cleanup my allocators a bit. It'll be good for my virtio driver...

lime sapphire
#

very nice, congrats on the milestone

spring sonnet
unreal creek
spring sonnet
unreal creek
spring sonnet
#

I'm reworking my slab allocator since the last implementation had a lot of bandaid "fixes" to test virtio lol

#

Getting disk access going was a huge goal of mine.... now that I've done it I feel really good about getting other thigns in place...

#

It's starting to feel like more of a kernel now hahahaha

unreal creek
spring sonnet
unreal creek
spring sonnet
#

I do already have the initial commit of it in the repo now (feel free to check it out, and tell me what you think). I've since cleaned things up a bit, and implemented some helper stuff. I also implemented some functions virtio_blk_read() and virtio_blk_write() to handle raw disk acceess

#

@unreal creek

fast sable
spring sonnet
forest timber
fast sable
#

alignlog of course is logarithm of your align. So to align at 512, you'd use `VIRTIO_ALIGN(x, 9)

forest timber
#

if you dont want to fix the macro you can do it like

#define VIRTIO_DESC_ALIGN(qsz)  VIRTIO_ALIGN((qsz), 15)
#define VIRTIO_AVAIL_ALIGN(qsz) VIRTIO_ALIGN((qsz), 1)
#define VIRTIO_USED_ALIGN(qsz)  VIRTIO_ALIGN((qsz), 3)
spring sonnet
#

Sounds good

forest timber
#

but i recommend you just fix the macro

spring sonnet
# forest timber but i recommend you just fix the macro

I went ahead and added the new change just to be on the safe side... I'll test to make sure things look fine, and then I can push the new change. I'm fixing my slab allocator right now since the previous implementation is a bit hackish...

spring sonnet
#

Ended up making my new version of my slab allocator a first-fit/best-fit hybrid so far.

#

Might not be the best thing, but it's better than the last version. The last version was a bit trashy, and was basically allocation a new slab or different sizes of objects instead of doing my new approach...

#

Currently working on handling when I run out of object to allocate a new slab object, and add this to the list.

#

I've made some really great progress lately, and I'm quite proud.

#

The biggest goal for me was getting that virtio driver going.... I really wanted to have disk access implemented as soon as possible

spring sonnet
# unreal creek good

I also decided to support a larger allocation size as well compared to the old version....

#

The pmm still needs to have pmm_free_pages() implemented though for handling multiple page frame deallocation

#

But after getting this stuff done the rest of the way tomorrow I'll get started on the VFS after testing the new virtio driver changes...

#

I'm looking forward to playing around with filesystem access

#

I want to take my time getting there of course.

unreal creek
spring sonnet
#

I should never code when tired. I just noticed I crashed in my slab allocator before I can use the last object before needing to allocate a new, and this is because I was decrementing the freelist itself instead of the free object count... whoooops

spring sonnet
#

Slab allocator rework is now completed, and tested...

#

It works quite well, and properly handles creating a new slab object as well as linking ONLY when we've run out of available objects..

#

And it returns the available objects accordingly properly too...

#

Now, to work on virtio a bit...

#

kmalloc() for now if lengths are larger than 4K it just falls back to the pmm to allocate X amount of frames... this will be changed in the future

#

Otherwise it uses the slab allocator

spring sonnet
#

Looks like the virito driver will need lots of work if I'm going to properly handle used/free descriptors....

spring sonnet
#

πŸ˜„

spring sonnet
#

The virtio disk driver has been cleaned up, and works flawlessly!!! I now have disk read/write access!!

#

@unreal creek I'll be pushing the new driver update today

#

The only thing I notice is that I can't apparently reuse the same buffer for reads/writes which I've yet to figure out. So I had to use seperate buffers for now

#

New commit it live

spring sonnet
#

I may have to implement something differet for buffers for the virtio stuff.... I'll work on that and the vfs both tonight so I can get the vfs started

spring sonnet
#

The virtio very much isn't the best, and does have much work that needs to be done to improve it though.

#

Looks like I was able to fix the seperate buffer access.

#

Took me all day, but it works now...

spring sonnet
#

Getting started on a minimum vfs implementation finally... this is what I was working on previously, but got some other things in place before hand. Now that I have disk access going I'm super excited to eventually implement ext2 and vfat support

unreal creek
#

for your devfs

unreal creek
spring sonnet
spring sonnet
#

Wanted to parse the MBR for the fun of it... @unreal creek

#

Disk access is working perfectly!!

#

Right now I'm just studying about the VFS a bit

#

The new virtio disk changes have been pushed so you're good to go check it out

#

Keep in mind it can probably be very much improved... but for now it's working great

unreal creek
unreal creek
spring sonnet
unreal creek
spring sonnet
unreal creek
spring sonnet
#

Once I get the vfs in place I'll implement tmpfs, then work on the /dev stuff, and then work on ext2. Later after that I'll work on vfat, but not at this time...

#

I planned to mount the EFI partiiton under the eventual /boot

unreal creek
spring sonnet
#

I eventually also need to implement a DTB lib for the kernel...

unreal creek
spring sonnet
#

For right now though my kernel only boots off QEMU's virt board

spring sonnet
# unreal creek okay

The main task as of right now is to get the VFS in place, then get a tmpfs implemented

unreal creek
spring sonnet
#

So I'll be spending the next few weeks working on this now that I've got things in place for it...

spring sonnet
spring sonnet
#

@unreal creek For the vfs file struct should it contain anything for inodes? Or should it just conatin stuff like the file name, length, etc?

spring sonnet
#

Sounds good!

unreal creek
spring sonnet
unreal creek
#

your node struct is really good

#

but first of all

#

vfs_inode_opts_t should not exist

#

vfs_file_t should not exist

#

and vfs_file_opts_t should be renamed to vfs_opts_t and contain function pointer for operation on file and directories

#

with something like this functions :
seek
read
write
close
lookup
readdir
symlink(optional)
setattr
getattr
readlink(optional)

#

also your node structure should have a pointer to the struct vfs it's mounted on

spring sonnet
unreal creek
#

you might not need setattr

#

but the sun paper as it

#

i think it is used because there aren't chown and chmod

#

so you set the uid and gid on the vnode then use setattr to change the owner

unreal creek
spring sonnet
#

And then flush those changes to the filesystem I'd assume

spring sonnet
unreal creek
#

i really like to see project starting from scratch
at the start there nothing then a PMM then a VMM then some drivers then a vfs

spring sonnet
unreal creek
#

just rename vfs_file_opts_t to vfs_opts_t

spring sonnet
#

Sounds good!

unreal creek
#

just make a custom sys/stat.h that can be reuse later for userspace program

#

and then use struct dirent

spring sonnet
#

I was thinking the VFS would need these flags, but now it makes more sense not having them the more I think about it haha

unreal creek
#

that when you start to have to make custom libc header

spring sonnet
#

Sound good to me! I'll just remvoe those definitions then

#

Once I get the VFS going I'll start on the tmpfs implementation

spring sonnet
unreal creek
#

in syscall.c they get converted when using stat or fstat

spring sonnet
#

Ahhh I see

unreal creek
#

and you can see it include <sys/stat.h>

#

wich is a custom stat.h that i made in my libc

spring sonnet
#

Is this for the userspace libc?

unreal creek
spring sonnet
#

Yes

#

Or is that the kernel header?

unreal creek
spring sonnet
#

Ohh I see

unreal creek
spring sonnet
#

How did you determine the permissions for your vfs if I may ask? Like to determine what's a flile, etc

unreal creek
#

and i have a perm field in my vnode for permission

spring sonnet
#

How did you determine them?

unreal creek
spring sonnet
#

In your VFS yes

unreal creek
spring sonnet
#

I was talking about these:


#define VFS_FILE  0x01
#define VFS_DIR   0x02
#define VFS_LINK  0x04
#define VFS_DEV   0x08
#define VFS_MOUNT 0x10
#define VFS_CHAR  0x20
#define VFS_BLOCK 0x40
#

I was wanting to see how you determined these so I could learn, and implement them as well

unreal creek
#

and VFS_MOUNT is set when using vfs_mount

#

it's when you do a lookup

#

wait let me show you for tmpfs

unreal creek
spring sonnet
#

Ahhh I see

spring sonnet
unreal creek
#

then you set the operation

#

and finally mount it as /dev/vda

#

that as simple as that

#

even better

#

you could make the data field point to the virtio_blk_dev_t

#

so you can have multiples virtio vnode

#

and so multiple virtio devices

spring sonnet
#

Oooo that's actually not a bad idea! Because in the future I'd like to eventually support multiple disks

unreal creek
# spring sonnet Oooo that's actually not a bad idea! Because in the future I'd like to eventuall...

the basic stuff is ```c

ssize_t virtio_blk_read(vnode *node,void *buf,size_t count){
virtio_blk_dev_t *dev = node->data;
//do actual read
}

vfs_opts_t {
.read = virtio_blk_read
} virtio_blk_opts;

void virtio_init(){
char c = 'a' ;
//scan pci device
for each virtio found :
vnode *node = kmalloc(sizof(vnode));
virtio_blk_dev_t *dev= kmalloc(sizeof(virtio_blk_dev_t));
vnode->data = dev;

//init your dev or whanever and reset the device

node->opts = &virtio_blk_opt;

node->type = VFS_BLOCK

char path[20];
snprintf(path,"/dev/vd%c",c);
vfs_mount(path,node);
a++;
}```

#

and like that you can have multiples devices

#

avalible under /dev/vda /dev/vdb ...

#

up to 26

spring sonnet
#

Ahh now I see how this would work

#

Wouldn't I so something like this when setting up for /dev?

unreal creek
unreal creek
#

and then setup root with something like vfs_chroot(new_tmpfs());

#

if you don't now what is vfs_chroot() it's a bit special

#

normally on UNIX like system you can't mount anything as root instead you sue chroot to change the root directory to another vnode

#

but some OSes have special case where when you do vfs_mount("/",XXX) it do the job of chroot

#

the biggest difference between chroot and mount is that for root you just have a global variable vnode *root; and you change this variable

spring sonnet
unreal creek
#

most of the time you setup you initrd as your temporary root

#

then mount the new partition

#

and chroot it

spring sonnet
#

In this case I was planning to mount the actual ext2 parititon as the root filesystem

#

I was wanting to do a ramdisk, but I was really just wasnign to mount the root partition directly

spring sonnet
# unreal creek yes

static vfs_root_t *vfs_root = NULL;




void vfs_init(void) {
    if (!vfs_root) {
        vfs_root = kmalloc(sizeof(vfs_root_t));
        assert(vfs_root != NULL);
    }

    vfs_node_t *root_node = kmalloc(sizeof(vfs_node_t));
    assert(root_node != NULL);

    strncpy(root_node->name, "/", sizeof(root_node->name));
    root_node->parent = NULL;
    root_node->children = NULL;
    root_node->siblings = NULL;
    root_node->fs_opts = NULL;
    root_node->uid = 0;
    root_node->gid = 0;

    strncpy(vfs_root->name, "root", VFS_MAX_NAME_LEN);
    vfs_root->mount = root_node;
    vfs_root->flags = VFS_TYPE_DIR;
}

So I believe this is how I can get the root node setup, right? This is what I at least remember from my old code. Well that, and trying to read docs, etc

unreal creek
#

just do root = NULL;

#

the root will be set when you will do chroot(new_tmpfs());

spring sonnet
unreal creek
#

i just don't do it to save a bit of memory

spring sonnet
unreal creek
#
  • chroot into a tmpfs
  • cd into root
  • mkdir test
  • chroot into test
  • you can still acces the old root via the cwd
spring sonnet
# unreal creek - chroot into a tmpfs - cd into root - mkdir test - chroot into test - you can s...
static vfs_root_t *vfs_root = NULL;




void vfs_init(void) {
    if (!vfs_root) {
        vfs_root = kmalloc(sizeof(vfs_root_t));
        assert(vfs_root != NULL);
    }

    vfs_node_t *root_node = kmalloc(sizeof(vfs_node_t));
    assert(root_node != NULL);

    strncpy(root_node->name, "/", sizeof(root_node->name));
    root_node->parent = NULL;
    root_node->children = NULL;
    root_node->siblings = NULL;
    root_node->fs_opts = NULL;
    root_node->uid = 0;
    root_node->gid = 0;
    root_node->ino = 1;
    root_node->nlink = 1;
    root_node->length = 0;
    root_node->atime = root_node->mtime = root_node->ctime = 0;

    strncpy(vfs_root->name, "root", sizeof(vfs_root->name));
    vfs_root->root = root_node;
    vfs_root->flags = VFS_TYPE_DIR;
    vfs_root->next = NULL;

    printf("VFS: Initialized root on: %s\n", vfs_root->root->name);
}

Here's my vfs_root mount setup... Since I'm doing a linked list of mounts, etc...

unreal creek
#

just never use open until you do chroot

#

cause your initial root don't have ops

spring sonnet
#

Right... otherwise things would go horribly lol

#

I'm so happy to have disk access going

spring sonnet
# unreal creek that work

And then implemeneding the read, write, etc, functions is as simple as this I believe?

int vfs_read(vfs_node_t *node, void *buf, size_t length, uint64_t offset) {
    if (node) {
        if (node->fs_opts->read) {
            return node->fs_opts->read(node, buf, length, offset);
        }
    }

    return 0;
}
unreal creek
#

instead of returning 0 return a error code

spring sonnet
unreal creek
#

else just return -EBADF if it don't support the op

spring sonnet
#

For the kernel

unreal creek
#

just like sys/stat.h

spring sonnet
#

Ahh that makes sense

sly pebble
#

I mean it's implementation defined how do you want to propogate errors if you're not going for posix

spring sonnet
sly pebble
#

Yeah it looks like a great progress! I'd stop and consider some design questions because until now its mostly the same, pmm and vmm doesn't have too many design choices rather then implementation choises imo.
You could think of an interface of the vfs, what functionally and how to signal errors etc.. quickly implementing things would very quickly restrict your options and if you'd want to change your design you would need to rewrite quite a lot of the implementation

spring sonnet
#

Thank you as well!! Later down the road once I've gotten other things in place, etc, I eventully wanted to support multiple disks, but for now just one is fine

sly pebble
#

Sure, just think whether your interface works for the rest of your design of the kernel (micro services/monolithic etc..), quickly implementing stuff could put you in a tangle without considering everything

spring sonnet
#

Oh absolutely!

#

For right now I'll spend some time learning, and implementing how I should signal errors in the vfs, etc.

#

So that if something fails I can return that specific error code. For example -EISDIR

spring sonnet
#

I beleive my vfs_opts struct should also contain function pointers for things like mknod, mkdir, etc?

#

Doing some research, and thinking about the error handling stuff right now

spring sonnet
#

I'll be taking my time with the vfs development

spring sonnet
#

Now that I have disk access I can start looking into page-swapping

#

Well... at least from what I'm reading right now the tmpfs filesystem implementation in linux does this

unreal creek
#

but you can merge in one create

#

you don't need mknod

spring sonnet
# unreal creek what ?

Ignore that it's something I thought of, won't actually be doing that right now. I'm currently working on some VFS stuff, and one things I'm trying to think about is how I'll mount the newly registered filesystem

unreal creek
#

you need a vfs_lookup and vfs_open

#

then you need to setup a directory cache

spring sonnet
unreal creek
#

btw i really recommand you to do a vfs_openat

#

and make vfs_open wrap around it

#
vnode *vfs_open(const char *path){
    if(path[0] == '/'){
        return vfs_openat(root,path);
    } else {
        return vfs_openat(cwd,path);
}```
#

so you can do something like that to support relative path

unreal creek
#

but later you will need a more complexe lookup for directory cache

unreal creek
#
  • parent
  • child
  • brother
  • linker node (used for mount point)
unreal creek
#

you are going to need that

spring sonnet
spring sonnet
# unreal creek and make `vfs_open` wrap around it

This is what I had in mind:

int vfs_open(vfs_node_t *dir, const char *name, uint64_t mode) {
    if (dir) {
        if (dir->fs_opts && dir->fs_opts->open) {
            return dir->fs_opts->open(dir, name, mode);
        }
    }

    return -VFS_ENOENT;
}
unreal creek
#

there no open op

#

to implent open you take the path and cut it

#

like /"dev/vda" become "dev" "vda"

#

then you take the specified node

#

and you call lookup on it

#

you get the vnode of the dev foldet

#

and you call lookup on it

#

you get /dev/vda

spring sonnet
#

The idea I had was having the registered filesystem handle this... so like tmpfs for example...

unreal creek
#

that would mean fs would have to implement itself mount point traversing

spring sonnet
unreal creek
unreal creek
spring sonnet
spring sonnet
unreal creek
spring sonnet
# unreal creek good

I do have stuff in my klibc like strtok() so that would make splitting the path into tokens a bit better

unreal creek
spring sonnet
#

Just program header loading, and section header parsing

unreal creek
spring sonnet
# unreal creek i can't understand i single shit about relocation it's so weird

Yes, ELF relocations do need to be aligned, especially in the context of specific relocation types and architectures. While the general structure of an ELF file emphasizes natural size and alignment, some relocation types, like those designed for unaligned memory access, might require specific considerations at the relocation stage.

unreal creek
#

this isen't aligned

#

is gcc bugged ?

spring sonnet
unreal creek
#

gcc make a non aligned relocation

#

i can't really align it

spring sonnet
unreal creek
#

i guess that normal

#

i just have to handle that

spring sonnet
#

Decided to get the the beginnings of tmpfs going, but wait to actually start development on it once I've got the vfs further developed.

spring sonnet
#

Trying to understand how things should be mounted, etc, has been a pain.

unreal creek
unreal creek
spring sonnet
lime sapphire
#

so that cache does have its uses, but you dont need it

#

the idea is you keep a map of directory names/paths to the vnodes they resolve to. So rather than the usual lookup sequence, you can skip straight to having the vnode.

#

thats handy for mount points because you can pin the root node for the mounted fs in the cache

#

I dont know if you've read the sunOS vfs paper yet, but I'll recommend it if you havent. There's a lot of good info packed into its few pages.

#

as for handling mountpoints: each node has space for a 'covered by' vnode, which would be root vnode for the fs thats mounted there. The root vnode also has a 'covering' vnode variable (these can be a union so save space, since you wont have both existing in the same place), which tracks the vnode covered by the fs root.

lime sapphire
spring sonnet
spring sonnet
lime sapphire
#

check the pins in #filesystems , the vnodes paper is linked there

#

there's also some stuff on namecache, which you might find interesting (but not essential to your implementation rn)

spring sonnet
#

I've found the other pin for the kleiman86vnode documentation so I'll be giving both a read before I proceed further

lime sapphire
#

that sounds right

spring sonnet
#

I think that would be the wise thing to do lol

spring sonnet
#

Time to read up more on the vnode stuff

spring sonnet
#
    int (*mount)(const char *target, const char *fs_name);
    int (*unmount)(const char *target);

I feel like I need to change these to actually take in parameters.

#

Well... by that I mean a vfs_root_t struct or just a vfs_node_t.

unreal creek
#

you don't implement mount in the vfs itself

#

you leave it the the fs

#

i mean yeah of course you can do that

#

it's just duplicating code

#

cause all your futures fs will have to implement it

spring sonnet
unreal creek
spring sonnet
#

Not the PCI part of it

spring sonnet
# unreal creek okay
int vfs_mount(const char *target, const char *fs_name) {
    vfs_root_t *curr = vfs_root;
    vfs_node_t *mount_node = NULL;
    int ret = 0;



    if (!target || !fs_name) {
        return -VFS_EINVAL;
    }

    if (!curr) {
        return -VFS_EINTERNAL;
    }

    mount_node = vfs_lookup(vfs_root->root, target);

    if (!mount_node) {
        return -VFS_ENOENT;
    }

    while(curr && strcmp(curr->name, fs_name) != 0) {
        curr = curr->next;
    }

    if (!curr || !curr->root || !curr->root->fs_opts) {
        printf("VFS: FS type %s not found!\n", fs_name);
        return -VFS_EINVAL;
    }

    if (!(curr->flags & VFS_TYPE_DIR) || !(curr->root->type & VFS_TYPE_DIR)) {
        printf("VFS: Target %s not a directory!\n");
        return -VFS_ENOTDIR;
    }

    
    return 0;
}

It's still a work-in-progress, but so far I'm able to locate the registered fs type. In this case the demo tmpfs I setup for testing...

#

void vfs_init(void) {
    spinlock_init(&s);

    vfs_root = kmalloc(sizeof(vfs_root_t));
    assert(vfs_root != NULL);
    
    strncpy(vfs_root->name, "root", VFS_MAX_NAME_LEN);

    vfs_root->flags |= VFS_TYPE_DIR;
    vfs_root->next = NULL;
    vfs_node_t *root_node = vfs_node_alloc();
    
    strncpy(root_node->name, "/", VFS_MAX_NAME_LEN);
    vfs_root->root = root_node;

    printf("VFS: Initialized!\n");
}

I setup an initial root node as well to mount on

unreal creek
#

noramlly a vfs_mount a node to the specified path

spring sonnet
#

I was wanting to make it so I provide a path to mount on, then specify the fs type

#

And then it handles the lookup for it

spring sonnet
#
    int (*mount)(const char *target, vfs_node_t **node);
    int (*unmount)(const char *target, vfs_node_t **node);

I guess I can always do something like this, and call the <root node>->fs_opts->mount(target, &node);

#

Still trying to understand how this should work.

spring sonnet
#

I understand that the vfs_mount() should invoke the fs_opts mount, and that will in turn setup the filesystem mount point, etc.

#

At least this is what I'm understanding

spring sonnet
#

I've got some design changes in mind I'm going to try out today...

spring sonnet
#
    ptr = (char *)name;

    while(*ptr == '/') {
        // Skip leading "/"
        ptr++;
    }

    if (*ptr == '\0') {
        // If no mounts like "/dev/" is provided then return the root node
        return vfs_root->root;
    }

Had to fix my vfs_lookup() to handle if the mountpoint provided was just "/"

#

Otherwise it would return NULL and cause issues...

spring sonnet
spring sonnet
#

Going to try something similar to Linux, and do some kind of vfs overlay mounting.

spring sonnet
#

Slowly getting stuff in place. It's not perfect, but I've been working on the mount/unmount stuff. I plan to start getting the other stuff in place for symlinks, etc as well...

#

πŸ‘€

spring sonnet
#

@unreal creek Slowly making some progress. I'll be taking my time with the vfs implementation of course...

#

But maaaan it's been brutal trying to think of a decent design lol

unreal creek
spring sonnet
unreal creek
spring sonnet
worthy lynx
#

@spring sonnet does your VFS follow a unix like design or is it custom?

#

@spring sonnet you don’t alloc virtual memory in kmalloc?

worthy lynx
unreal creek
worthy lynx
unreal creek
spring sonnet
#

Still gotta figure out why I'm still getting the leading "-//" though

worthy lynx
#

wait

#

nvm

#

it says. Created dev/shm under / wouldnt it be: Created shm under /dev

spring sonnet
worthy lynx
#

hmm

spring sonnet
#

For now anything larget than a single page it falls back to the PMM

worthy lynx
#

okay

#

Oh

#

wait

spring sonnet
worthy lynx
spring sonnet
worthy lynx
#

well each process in a single CPU system would still have their own pagemaps, right?? (idk how it is on arm and shit)

spring sonnet
spring sonnet
# unreal creek good

Working on vfs_create now, and then I'll start working on vfs_open() + vfs_close() after...

#

I've been taking my time with the design stuff, and doing a lot of testing..

#

Heyyy check that shit out!! Lol

#

I expected that to break to be honest...

#

I need to fix my permission checks though...

spring sonnet
#

Welp... I have a bug in my permission checks in that anything in the root directory that gets it's permissions set to all zero it causes everything else to fail...... whoops

unreal creek
#

btw what op need what permission

  • read : r
  • write : w
  • lookup : e
  • create : (w and e on the parent)
  • unlink : w
  • truncate : w
spring sonnet
#

I'm currently working on fixing my create(), and open() functions. I'm able to create the new node for the test file I set to be /dev/null, but I need to fix my logic in how I'm handling locating/returning this node..

spring sonnet
#

More VFS work today....

#

Need to figure out and fix my file node creation πŸ˜…πŸ˜…

spring sonnet
#

Got that worked out, but still need to work on permission checks. And by this I mean if I create a directory with 0000 (in octal) for exentually no access I don't currently have a check that prevents access to this

#

Which is not good

spring sonnet
#

I also think I found the bug I had when trying to check permissions for creating dirs, files, etc in "/", etc.... it's because the rootfs itself didn't have permissions set

#

A more "pretty printed" directory tree layout...

#

Oh lovely of course it's now I discover a bug in how I print the permissions too..

unreal creek
#

so only root can access it

spring sonnet
spring sonnet
#

The VFS is far from finished, and has much work... I've decided to maybe begin implementing EXT2 for mounting over "/". After lots of studying previously I see that SerenityOS does this as well.

#

The VFS is in place enough to be able to create directories, and files as well as mount things so it's enough to test EXT2 and test directory lookups...

#

The VFS code, etc, won't be pushed anytime soon while I'm working on this though as I'd like for it to be mostly complete before I do

#

For now I need to fix mounting over directories before I can start.

worthy lynx
spring sonnet
worthy lynx
#

epic

spring sonnet
#

That part of development I've been making sure to take my time with

#

I did a test on my kernel to see how low of memory it boots on, and it actually boots on 256MB of RAM, but anything lower causes an exception...

spring sonnet
#

But at least I know I can boot on lower amounts of RAM

spring sonnet
#

So may VFS bugs to fix today.... turns out the filesystem overlay idea I was using before was a terrible idea, and that was causing issues

#

I've since removed that logic, and things are working a bit better now, but I still need to make sure I can mount sub-mount filesystems as well

#

Yeah I can't have sub-mounts on things like /dev yet....

#

So I can only mount things to root "/"

#

At least I properly fixed how path lookups are handled as well.

spring sonnet
#

I think I got it......

#

Spent several days of debugging, and reworking everything for this, and I think I finally got it...

spring sonnet
#

Doing some more tests... VFS is finally working properly now πŸ‘€

#

I don't actually have a devfs right now... I just did a quick test with mounts, but currently working on VFS and tmpfs more...

tender acorn
#

damn

#

that is some crazy ammount of work in a small time

spring sonnet
#

Yes I've been pretty hard at work on it haha

#

I've got tons of free time right now too so I spend the day working on Helix

#

But I've been spending a lot of time with the vfs + tmpfs... I've been taking my time on this part to think about my design decisions

#

Had the idea to do some kind of mount overlay, and that ended up not being a good idea

spring sonnet
#

Time to finish implementing the VFS.

spring sonnet
#

I don't understand how I can read the MBR header fine, and get the information I need to locate the GPT, but when I parse the GPT everything is all zero.

#

Irritating as hell.

frozen silo
spring sonnet
# frozen silo what do you need from the mbr to be able to locate the gpt? its always at the sa...

I read the mbr to verify whether or not the disk has a GPT table or not. I then attempt to read out the GPT header from lba 1, but seems that reading it results in all values being zero. Running hexdump over it showed that the GPT was in fact intact, but reading from disk says otherwise. I've even parsed the partitions manually, and those readout fine so I get to spend today figuring out what's going on

spring sonnet
#

Better commit the change

#

I alsso need to ensure that the length passed to both read and write functions are 512 bytes minimum or it runs into IO errors

spring sonnet
#

Perfect!!!

spring sonnet
#

Now I can continue with the rest of todays task...

unreal creek
#

cool

spring sonnet
#

Working getting started on EXT2

unreal creek
spring sonnet
#

But it's really exciting to finally get started

spring sonnet
#

Looks Like I do need to pad lengths on 512 bytes boundaries when reading from the disk....

sly pebble
#

Im pretty weak at virtio devices and disc in general, but are you reading how many bytes the disc read from the device ring?

spring sonnet
spring sonnet
spring sonnet
#

The EXT2 superblock information is stored 1024 bytes into the partition. So when I offset the LBA by 1024 to read this get zeros???

#

I've tried without offsetting too, and still nothing.

#

Lovely.

spring sonnet
#

I think parts of my superblock structure are incorrectly setup.

#

I seem to have a correct number of inodes so this is a good sign.

#

I suspected this was the case anyways, but-

#

Apparently I forgot a single field, and that was the fuckin' fragments per group.

#

Apparently the signature is still showing zero, but my shit looks fine as per the wiki.

#

This is starting to piss me off a bit.

spring sonnet
#

Was able to finally read it properly.

#

What's kind of rediculous is that I have to read out the first 2K of the partition to properly get the superblock (offset 1K from the buffer). But if I offset this from the lba address I get zero.... wtf

#

At least it works...

#

I understand how it was supposed to work so when I tried to offset it by 1K that was entirely incorrect.....

#

I kind of forgot about that when I was working on my original bootloader

spring sonnet
#

Totally forgot about the lba2offset stuff.

spring sonnet
#

@unreal creek Finally reading out the EXT2 superblock, and getting started with stuff.

spring sonnet
spring sonnet
spring sonnet
#

I was properly able to read out and calulate the block descriptor table.

#

I previously wasn't taking into account that each table size is 32 bytes per entry

#

I guess the spec, and wiki talk about this, but I must of missed it before. Either way I've got that going finally

spring sonnet
#

Since it's a freshly formatted partition I only have the one entry, but I finally get some information. I can see that I have directory number of three as well so that would mean ".", "..", and "lost+found".

spring sonnet
#

What's starting to bug me a little is I'm not really sure how to get the inode count to use for the index. Like yeah the root directory is inode 2, but I want to understand how this is found/calulated.

spring sonnet
#

Apparently I'm getting an inode size of zero, and this doesn't exactly make sense since the other superblock data is correct. Including the signature.

#

Small hack to make the shit work till I figure it out....

uint32_t ext2_get_inode_size(void) {
    return sb->inode_structure_size ? sb->inode_structure_size : 128;
}
#

I'm going to spend some time looking over my stuff and see if I missed something. I don't think so, but you never know.

tender acorn
#

otherwise i think you are checking if the first bit is 0 or not

#

at least that is the behaivour on my -O3 compiles

spring sonnet
# tender acorn check if ==0

The inode size in the superblock seems to be zero from when I last checked. I'm not too sure why right now, but just did a small workaround till then

#

Unless this is the expected behavior of the filesystem?

tender acorn
#

yeah i just said that you check with ==0 because this will return a bool behaviour by just checking the first bit

#

its the magic of c lmao

spring sonnet
#

My superblock structure seems to be fine according to the wiki

tender acorn
#

now that you say that i might need to switch image builder someday

#

rn im using the queso fuego tool

#

that just makes a simple efi image

#

lmao

#

its minimal and that

#

but uhh

#

doesn't make fat partitions

#

or ext4

#

or any extra partitions

spring sonnet
#

The partition seems to come out as clean... that's really strange

spring sonnet
tender acorn
#

wait qemu has a image tool?

#

omfg

spring sonnet
#

It's a pretty simple too to make use of. And you can convert images from raw to qcow2, etc

#

Or vise versa...

#

Way faster than trying to DD an image too!

tender acorn
#

i cant really mesure it

#

the tool im using does a couple miliseconds at least

#

heck i think the printing of it takes longer than the actual building

spring sonnet
#

It's super helpful

tender acorn
#

yeah it does

spring sonnet
#

Hell yeah

tender acorn
#

i just wasnt aware of its existance

#

does it like

#

make the partitions?

#

or do you need another tool

spring sonnet
#

Oh yes it's really useful to be honest; It's nice for being able to generate large disk sizes quickly, and can handle convertion from raw to one of it's supported formats

spring sonnet
#

sgdisk \
    --new 1:0:+512M \
    --typecode 1:"ef00" \
    --change-name 1:"EFI" \
    --new 2:0:+ \
    --typecode 2:"8300" \
    --change-name 2:"Rootfs" \
    ${DISK_IMG} >/dev/null 2>&1
tender acorn
#

oh ok

#

i think i will roll out my own partition builder

#

because i think sgdisk doesnt exist lol

spring sonnet
#

You never know it might exist for Windows

tender acorn
#

well maybe

#

i dont want to add more deppendencies for building tho

#

so i think a standalone one will be my way to go

spring sonnet
#

Fair enough

#

So I think instead of trying to format the partition by it's offset.... I ended up needing to format it as root....

#

I can probably fix that later down the road, but for now I'll test and see if this fixes the inode issue

#

No.... no it does not wtf

#

I better make sure my struct is correct in this case.

spring sonnet
#

FIXED IT

#

Inode size: 256....

#

Turns out I didn't need to pack the struct with the padding, and had a missing field + incorrect padding....

sly pebble
#

I was taking a glence at your repo, you often times don't use volatile when using a shared pointer with device, this would cause you problems once you change your -O0

spring sonnet
sly pebble
#

I suggest to run with O2 and gdb, see if it works and if not where does it get stuck

#

It's not a sure way to find those cases of course, even moreso when its in qemu and not real hw, but it would get you going

tender acorn
#

be the danger and run with O3gyubnsed

spring sonnet
#

So far I can tell the virtio does need some work on this, but I did make a todo for it... Did a test with -O2, and it seems to fail around this point after the device gets initialized

#

For now it can wait till after I get the ext2 driver going, and fix up the VFS....

spring sonnet
spring sonnet
#

I don't think this second block group should have this many directory entries.....

#

I'm going to ignore it for now since I'm only interested in the root directory inode...

#

Well it looks like I was iterating the group block descriptor table incorrectly

#

fok

#

Okay nooooow I get the corret entries for the block group table including for the two directoriews I made in the filesystem

lime sapphire
spring sonnet
#

@hallow comet How did you manage to read the root directory inode from your EXT2 partition? Because no matter how I've tried to calculate anything or point the inode struct into the buffer I don't seem to get any good results. I'm doing this on a freshly formatted partition as well to keep things simple

#

It's slowly been driving me insane

#

I read out the superblock, then read out the full block descriptor table since it follows just after the superblock, and get the root directory entry from the very first entry of the descriptor table. So far no matter how I've tried to calculate or read the inode data I somehow end up with a type of it being a character device or something comepletely unknown

spring sonnet
#

Take your time

hallow comet
#

Okay, so I calculate the block group and local inode index (the calculation is in the ext2 spec), then I read the Block Group Descriptor Table, and then I read the inode using the bg_inode_table field of the BGDT

#

I can send a link to my implementation of it if you want (warning it may be a bit messy lol)

spring sonnet
hallow comet
#

the function is at line 100 I believe

spring sonnet
#

Thank you so much!!!

hallow comet
#

np!

spring sonnet
#

Turns out I was calculating the inode stuff incorrectly.....

#

UID/GID is zero, type is directory, and all seems to be well finally...

hallow comet
#

YAY! πŸŽ‰

spring sonnet
#

That was really brutal trying to figure out lol

#

I owe it to you though! Bless your kind soul

hallow comet
#

Glad my janky code could help someone lol!

spring sonnet
#

I'm so grateful hahaha

spring sonnet
unreal creek
#

i dosen't have unix permission and file owner

#

but ourside that it's really good

#

and understood by basicly everything

spring sonnet
#

Now that I understand how to get the inodes off the disk I can finally clean it up a bit.. I do eventually plan to work on the fat32 side of things later down the road

unreal creek
spring sonnet
#

That's the goal of my EXT2 driver is getting read-only support going for now

spring sonnet
#

Thank you!

#

Now I can move forward in learning about how I can use the direct data block pointers in the inode....

spring sonnet
#

πŸ‘€ @hallow comet @unreal creek

#

Ooooo

#

Apparently I didn't need to make the buffer 8K in size πŸ˜…

#

I'll wait till tommorrow to learn about the single, doubily, and triply linked stuff... apparnetly triply is only used if you have large files

spring sonnet
# unreal creek good

Going to attempt to read a file from the disk.... I gotta try it before I head to bed lol

#

Man that was a major pain though getting the inode calculations correct...

#

And now that I can get entries finally I see that I can just kind of repeat the process on the inodes for them too

spring sonnet
#

Never mind I'm going to bed... for some reason reading the test file's inode, and looking at the blocks in the inode show all zero which is not normal so I have no idea what's going on there

#

At least I got my reward of reading out the root directory contents

spring sonnet
#

Today's task: figure out why that test files inode data shows zero...

spring sonnet
#

I think the issue has to do with this line right here:

    inode = (ext2_inode_t *)(buf + inode_byte_index);
#

I'll need to adjust some of this so that it copies the inode data into it's own buffer and returns that...

#

Hmm no that changed nothing it seems....

#

Wha'ts irritating is debugfs shows block[0] is 1024, but when I read this out and check it shows 0. And I'm able to read out the root direcetory just fine so what gives....

spring sonnet
# hallow comet Awesome!

Have you already successfully read files inodes yet? I'm able to get the inode data for the file I placed in the root filesystem, but all blocks show to be zero, and according to debugfs the block 0 should be 1024...

#

Which don't really make sense since I'm able to read out the root directory inode, but trying to read the files inode data ends up showing zero for the blocks...

#

Unless I'm somehow not calculating something right again nooo

#

I'll debug for a while and recheck my stuff to see what's going on...

hallow comet
spring sonnet
#

Wtf I just now notice too it's reading again from the block descriptor region of the partition so I'm certain I'm calculating or reading something incorrectly here

spring sonnet
#

I'll spend some time looking over everything, and see where I went wrong...

#

I'm glad I noticed that...

spring sonnet
#

I'm wondering if it's how I'm reading the block descriptor table off the disk?

#

I'll want to check the values...

#

I'm just going to write a function that handles reading this off the disk when it's needed rather than trying to read the whole thing ahead of time...

spring sonnet
#

My bgdt logic seems to be correct, but I still end up reading out zeros... nooo

hallow comet
#

oof 😦

spring sonnet
#

I notice that everything is basically the same except for the index....

hallow comet
#

huh, that is kind of weird

spring sonnet
#

I'm not too sure if that's normal or not... or if my calculations are off a bit here, but I'll keep digging

#

It seems that that's normal since the test file is in the root of the directory...

unreal creek
spring sonnet
spring sonnet
#

So as I suspected when taking a look at debugfs I'm reading the inode correctly... fuck

#

I don't see how if I'm reading the root's inode just fine.

spring sonnet
#
ext2_inode_t *ext2_read_inode(uint32_t inode_num) {
    uint32_t ret = 0;
    uint8_t *buf = NULL;
    ext2_inode_t *inode = NULL;
    uint32_t ext2_part_idx = gpt_partition_get_index("Rootfs");
    uint32_t ext2_part_offset = gpt_partition_get_offset(ext2_part_idx);
    uint32_t sectors_per_block = ext2_get_sectors_per_block();

    ext2_block_group_t *bgdt = ext2_get_block_desc_for_inode(inode_num);
    assert(bgdt != NULL);

    uint32_t inode_size = ext2_get_inode_size();
    uint32_t block_size = ext2_get_block_size();
    uint32_t block_group = ext2_get_inode_block_group(inode_num);
    uint32_t local_index = ext2_get_inode_index(inode_num);

    uint32_t inode_table_start = bgdt->inode_table_start;
    uint32_t inode_table_offset_bytes = inode_table_start * block_size;
    uint32_t inode_offset_bytes = inode_table_offset_bytes + (local_index * inode_size);

    uint32_t inode_lba = ext2_part_offset + ext2_offset_to_lba(inode_offset_bytes);
    uint32_t inode_byte_index = inode_offset_bytes % block_size;

    buf = kmalloc(block_size);
    assert(buf != NULL);

    ret = virtio_blk_read(buf, inode_lba, sectors_per_block);
    assert(ret == 0);

    inode = kmalloc(inode_size);
    assert(inode != NULL);

    // Copy inode data
    memcpy(inode, buf + inode_byte_index, inode_size);

    kfree(buf, block_size);
    return inode;
}

@hallow comet Is there something I'm not calculating correctly? Because I'm able to read the root directory's inode just fine, but as soon as I go to read out the test fine I have which is inode 12 I end up with all zeros, and debugfs shows that block[0] = 1024

#

I've tried to re-caluclate this too many times, and have gotten no result

hallow comet
#

Lemme take a looksie

spring sonnet
#

Take your time!

hallow comet
#

It seems like you're calculating everything correctly, at least I don't see anything wrong.

spring sonnet
#

That's what I'm a bit confused on because I've re-calculated this a bunch, and have not gotten any results. I just think it's weird that debugfs shows something that I'm not getting, and that I can read the root inode fine, but reading the files inode ends up being zero...

spring sonnet
#

I'll take a look at existing implementations and see what I can probably do better on

hallow comet
#

Good idea

spring sonnet
#

I think so too; I'm pretty sure I'm doing something wrong with my inode calculation, so...

spring sonnet
# hallow comet Good idea

So it turns out I had a slight misalighment with my calculation that was causing me to read the wrong part of the partition. After fixing that I finally got my reward:

#

I can finally die happy

hallow comet
#

Yay! FINALLY!

spring sonnet
#

You should of seen the face I made when I seen the contents of the file finally lol

#

Now to clean things up a bit, and work on the driver some more. The VFS will go through some changes as well now that I can properly read files off the partition

spring sonnet
#

It'll also only be read-only for the mean time till I learn more about the filesystem

spring sonnet
#

I'll be redoing the VFS as well.

spring sonnet
#

My next plan is to start handling indirect blocks 0-11 for now. I planned to start getting a recursive lookup function going now that I understand how the inodes are read, etc, and I also plan to implement a lookup function for handling locating files, etc too...

#

But right now I plan to also redo the entire VFS from scratch

#

Or at least tomorrow I'll get a start on it...

#

But maaan I'm excited as hell to have a simple EXT2 driver going...

spring sonnet
#

Currently playing around with path lookups:


    ext2_inode_t *root_inode = ext2_read_inode(EXT2_ROOT_INODE);
    assert(root_inode != NULL);

    ext2_dirent_t *dev_dir = ext2_lookup(root_inode, "/dev");

    printf("Dev dir name:   %s\n", dev_dir->name);
    printf("Dev dir inode:  %lu\n", dev_dir->inode);
    printf("Dev dir type:   0x%lx\n", dev_dir->type);

#

I'm having fun lol

spring sonnet
#

Been playing around with inode lookups to get familiar with things, cleaned up a few things, and check this shit out....

spring sonnet
#

And considering the branch of the repo is a development branch this made sense...

#

I've did some cleanup since the commit, but won't push them till later... I just learned how to perform subdirectory lookups, and read their data

spring sonnet
# unreal creek okay

What do you think so far? It took me a few days to figure out why I wasn't able to read other inodes other than the root directory only to discover later that I had a misalignment...

unreal creek
#

i think that you didn't use device abstractions via vfs

#

while you have a vfs

#

why ?

spring sonnet
#

For now I'm getting familiar with the EXT2 filesystem, and I'll be getting started with the VFS tomorrow

unreal creek
spring sonnet
unreal creek
#

btw i just made a new PMM and it is o(1) to allocate and o(1) to free and don't waste a single byte of memory !

spring sonnet
#

I really wanted to spend some time learned how to read different inodes, and how to perform recursive lookups, etc... now that I'm understanding its quite simple

spring sonnet
#

I have future plans to clean all that up too, but for now it's to get the kernel going

unreal creek
#

about 60 lines

#

but it's so fast

spring sonnet
#

I've gotta change mine out for a freelist allocator... The current one is a shitty bitmap allocator, but it works for now haha

#

I guess I could do some combination of the two

unreal creek
#

it's the fasted

spring sonnet
#

I'll have to research about it because I'd like to start cleaning up my allocators... I also had some ideas for my kmalloc, and making use of paging, etc, for large allocations. The initial idea I have is since I do a direct mapping of all physical memory I could just take free pages that haven't already been marked as dirty and let kmalloc make use of them...

#

It's just my initial idea though

unreal creek
#

the stack use a lot of memory but with some modifications it can waste 0 bytes

spring sonnet
#

I really think I should consider implementing a kernel heap and reserving a part of physical memory for it...

willow prism
spring sonnet
# unreal creek i think

Right now my kernel just uses a combination of the pmm and slab allocator, but this all uses the lower region of physical memory

spring sonnet
willow prism
#

also why would you need to reserve part of physical memory for it

#

sounds inflexible

spring sonnet
#

That's something I thought I needed to do for the heap implementation

willow prism
#

no you can just add a page frame to the heap when you need to and free one when you can

spring sonnet
#

Then that means I can just rework my PMM for the job then it looks like. Or have an implementation that makes use of this

willow prism
#

no

#

this would be a client of your pmm

#

it asks your pmm for page frames and returns them to the pmm when it no longer needs them

#

that doesnt mean it should be part of your pmm

#

that means its an excellent candidate for abstraction

spring sonnet
#

That's what I had realized... I was thinking of something else for kmalloc() where if I needed larger allocations I just take non-dirty, free pages, and give those to kmalloc. This part was just an idea that I had though

willow prism
#

its common to special case allocations above a certain size (this threshold is often somewhere between half a page size and a full page size)

#

and for those you pop whole page frames from the free list and map them consecutively somewhere in kernel space

#

and return a pointer to the base of that

#

these are often called page-aligned allocations

#

free can tell the difference between a page-aligned allocation and one that came from the smaller block heap by checking whether the page offset of the pointer it was given is equal to 0

#

this will never be the case for most designs of a smaller block heap because you have some small metadata header before the block which always offsets the pointer some small amount, whereas the base of page-aligned allocations will always have a page offset of 0 because, well, theyre page aligned

#

but you can do it however works

#

this is just an example

spring sonnet
#

That's something I was wanting to do. Right now my kmalloc implementation just makes use of a slab allocator for lengths supporting all the way up to a single page, and if a larger size is needed it then calls to the pmm for page frames... It's ugly, and kind of hackish, but for now it works, and gets things going, but obviously I want to clean that up

spring sonnet
#

Going to fix the slab allocator a bit, and then start working on the VFS a little

spring sonnet
#

Yeah I think I'll be spending today working on the allocators instead. I just broke the slab allocator, and seen I'm running into some undefined behavior as well

#

I'm finally going to get this kernel heap implemented, and get rid of the shitty slab allocator

spring sonnet
#

Maaan what the fuck nooo

#

All that because kfree() was missing a fucking parameter...

#

Forgot the closing parentheses, and the compiler apparently shat itself

spring sonnet
#

Had a bug in my VMM that wasn't mapping the level 1 page table, but still somehow worked fine??

fast sable
spring sonnet
fast sable
# spring sonnet I use four levels πŸ™‚

Planning to run servers? 😁 I remember a funny incident with my paging function. I mistakenly put the line in which I applied page attributes and presence bit outside of the loop, that mapped pages. Once I sorted other bugs and my trampoline finally jumped into a kernel, I got data abort from accessing framebuffer. But the function accesses stack earlier and it worked! Both stack and framebuffer were mapped by tha same function in the loader, how could that happen that there it worked but didn't in the other place?!! And then I noticed that misplacement. The way it was written, it mapped only the last page. 😁 what coincidentally is just fine for the stack, but not anything else.

spring sonnet
#

Starting out with a 16MB kernel heap πŸ™‚
I'll be spending the day on designing, and testing to make sure things are good... It was time to get rid of the old crappy slab allocator, and calling back to PMM...

#

The slab worked great to get the kernel going, but the time has come for something better 😁

spring sonnet
#

Doing a little heap testing and so far all is well! I'm really excited for this new change. It was very much needed especially with the fact that a lot of this kernel data was stored in the lower region of physical memory. This was due to the slab allocator and the fact that kmalloc() also would fallback to the PMM if either the allocation failed or was too large for the slab.....

#

The initial heap implementation is quite simple, but it's better to keep things simple, functional, etc, and improve upon it as needed