#Zag

1 messages · Page 3 of 1

languid canyon
#

Also colorful logging which u don't like

fallen bobcat
#

I have become everything 13 year-old me would hate

fallen bobcat
languid canyon
#

Boot allocator, same as linuxes memblock

fallen bobcat
#

right now I do this

languid canyon
#

Sure I have that but less hacky

fallen bobcat
#

but this is tricky because hardware might have lots of small memory entries, and I need to make pfndb entries while mapping them so those pages may get reserved

languid canyon
#

Its a proper memory map allocator

#

I just stole my bootloaders code essentially

fallen bobcat
#

how do you handle the case where you may be setting up pfndb entries from a memory map entry but also allocating from it (for mapping)

languid canyon
fallen bobcat
#

ah

languid canyon
#

As long as you set the reserved flag etc

heavy sandal
#

yeah, the pfn is just allocated in that case

fallen bobcat
#

is there a reserved flag

#

mhm

languid canyon
#

Linux has PG_reserved I think

#

But yeah

fallen bobcat
#

so you need another pass to put them in the freelist?

#

that checks the flags etc

languid canyon
#

Pfndb is orthogonal to buddy allocator

#

For buddy u just walk the memory map after building the pfndb

#

And build buddies

heavy sandal
#

its what i do

languid canyon
#

Or freelist or whatever

heavy sandal
#

and then i use page number for the links with maxint for terminator instead of pointers

#

to save bits

fallen bobcat
#

how do you know which pages the initial allocator pulled tho

#

like how does it mark them reserved or something if the struct page is not allocated

heavy sandal
#

and shrink it

#

as i allocate early pages

fallen bobcat
#

and then you iterate over those pfn entries and set them reserved?

heavy sandal
#

well in my case i just only add the leftover ones to the free list

#

i use the original entry to mark them as normal memory and the shrunken copy to only add to the freelist the still-free ones

languid canyon
#

Tbh im not sure why you have a problem here

fallen bobcat
#

yeah Ithink it's fine actually

languid canyon
#

Do u not build a freelist after building a pfndb?

fallen bobcat
#

worst case i over-allocate

#

yes

#

i just thought about it

#

the worst case is I allocate space for a pfndb entry but then that page is used for mapping it

#

and that's a small memory waste

heavy sandal
#

i keep pfndb entries for all normal memory even if its in use

#

personally

languid canyon
#

Thats the way

#

IMO all usable memory must be covered

#

Especially if you use 2m pages

#

You will have e.g. 128 meg blocks

heavy sandal
#

i dont do that but probably should lmao

fallen bobcat
#

I don't think the pages used for the pfndb are considered usable

languid canyon
#

Usable means reported as such by e820

heavy sandal
#

yeah

fallen bobcat
#

but I dont see why you would have pfndb entries for them

#

also linux larp

languid canyon
#

Convenience, plus its a fragile micro optimization

#

That is overshadowed if you use 2m pages anyway

fallen bobcat
#

I don't use them for the pfndb

#

only for the hhdm

heavy sandal
#

maybe one of these days ill use 2m pages for anything KEKW

languid canyon
#

U should I think

fallen bobcat
#

I think I cna have something like "large page" and "huge page"

#

per-architecture

#

and the large page is like 2mb and huge is 1gb on x86 for example

languid canyon
#

Riscv allows shortcutting all page table levels

heavy sandal
#

same sizes for aarch64 if your base granule size is set to 4k btw, which limine does

languid canyon
#

So 2 types won't cut it

fallen bobcat
#

and you can have arch_largest_page_size

fallen bobcat
heavy sandal
#

and yeah i think aarch64 also allows shortcutting at the 512gb level

languid canyon
heavy sandal
#

my plan for imaginarium is to stop at 2m and just not worry about even bigger pages

languid canyon
#

And the size is implied

fallen bobcat
#

ok well I can have "page level" then or something

#

which is like large page, huge page, and super page

languid canyon
#

E.g. in Linux u always have 5 levels of arch agnostic page tables, and each arch defines the values of like how much virtual memory a level covers etc

fallen bobcat
#

well I would have 4

languid canyon
#

If u dont want to support la57 etc sure

heavy sandal
#

i actually have 5 levels, the top level has two entries and the second level has 256 entries/table on x86

#

because on aarch64 theres two completely separate page table base registers one for lowmem one for highmem and this way i can encode that while still supporting x86 on the same abstraction

languid canyon
#

Yeah makes sense

#

Its kind of annoying on aarch64

fallen bobcat
#

actually I think the only issue I need to fix is the largest usable entry thing

#

I dont think the mapping thing is a problem

#

for that I can just drain free entries one by one

heavy sandal
#

tbh i should do that too

fallen bobcat
#

imma do a quick&dirty thing for now then I will figure out a proper abstraction for the page tables

heavy sandal
#

my solution was to just make the page tables recursive tbh

fallen bobcat
#

that doesnt work on riscv

heavy sandal
#

rip

#

then youll need something proper yeah

fallen bobcat
#

whats tricky is making the abstraction powerful enough so I can do cool things but portable enough so it works on any pagetable format hopefully

fallen bobcat
heavy sandal
weary jetty
#

There are no more buddies. There is only LLFree.

#

4 KiB sucking is part of why Babaoğlu-Joy page clustering is such a good idea.

#

There's CASing round the bitmaps in my LLFree.

weary jetty
weary jetty
weary jetty
#

Frankly it could well be worth using allocation units of 128 KiB so there's always a properly aligned 64 KiB page no matter the virtual offset of the mappings.

fallen bobcat
weary jetty
#

The paper is extremely sparse on detail, sadly.

weary jetty
# fallen bobcat Can you link a paper on that

As a first approximation, when you're using a pfndb, you don't need to really care that much about there being a 1:N page:pte relation because each pte holds a refcount to the page structure. From there most of the rest is just adjusting offsets into the page around the rest of the operations so long as you're not too aggressively trying to combat internal fragmentation.

heavy sandal
weary jetty
# heavy sandal yeah the contiguous pte thing is great

With Babaoğlu-Joy page clustering, the 4 KiB ABİ can be kept while never having 64 KiB allocation units be fragmented & so there's never any danger of allocation failures due to external fragmentation thwarting 64 KiB. In fact, on MIPS, some cores have 1 KiB pages and from there page sizes at every power of 4. With that, 64 KiB allocation units could have promotions depending on mapping up from 1 KiB → 4 KiB → 16 KiB → 64 KiB all within an allocation unit before external fragmentation ever becomes a factor, which is only promoting from 64 KiB → 256 KiB → 1 MiB → 4 MiB → 16 MiB → 64 MiB → 256 MiB and I'm unsure where the largest page size is.

#

The 1 KiB ABI is vaguely cost-free given pagetable (entirely software) structures being able to be condensed when larger mappings are used.

fallen bobcat
#

@weary jetty looking for feedback on this:
For the page frame allocator, you have one global treiber stack of "batches" of 64 pages. Every CPU has its own local set of batches (4 at most) which it allocates from, when they reach the limit of batches, they evict one (the coldest) to the global batch list. On memory pressure, all CPUs are asked to dump their batches to the global queue (which is doable since its lockfree so no issue there)

#

i think this is fairly straightforward but might be good to get feedback on this

#

I dont plan on supporting allocations larger than one page size for now

#

might be interesting to benchmark this with different batch sizes and a lock on the global list

weary jetty
fallen bobcat
#

yeah pretty much meme

weary jetty
#

Even if your global allocator structures are lockfree, magazining is still worth doing, because exclusive ownership of the cachelines is still involved even if spinlocks etc. aren't.

fallen bobcat
#

I guess I do get the progress guarantee tho

weary jetty
fallen bobcat
#

also wondering how I could avoid cache misses if I store the linkage in the physical memory itself

#

I could allocate out-of-line metadata but not sure which and how

#

mhm could just store the PFN

weary jetty
#

Hardware cacheline acquisition can still be pretty bad. I debugged a livelock in '04 where a sampling profiler was livelocking. The sampling profiler had an array for code positions with atomic counters in each array position. The atomic counters were stuck in a cacheline bounce so long that another timer tick would come in before it finished.

fallen bobcat
#

quick benchmark shows that lockfree is slightly faster

weary jetty
fallen bobcat
#

having a lock over the global batch list

#

both are way faster than the base freelist without magazines tho

weary jetty
fallen bobcat
#

yes

#

perhaps qspinlock would be even better than lock-free

#

🤔

weary jetty
#

Typo?

fallen bobcat
#

no

#

do you know what qspinlocks are? I assume you do

#

might exhibit better cache behavior in this case

weary jetty
#

You might be describing MCS locks.

fallen bobcat
#

yes

#

linux calls them qspinlocks

#

essentially

heavy sandal
#

qspinlocks are a hyper-optimized version of mcs locks yeah

#

theres a bit more to it because of the optimization

weary jetty
fallen bobcat
#

they keep a 2-bit index of per-cpu MCS nodes

heavy sandal
#

yeah dont they fit the whole thing in 32 bits somehow with qspinlocks?

fallen bobcat
#

yes

weary jetty
#

That kind of defeats the point of trying to avoid the sharing of cachelines.

heavy sandal
fallen bobcat
weary jetty
#

You don't even need SMP for false sharing, but anyway.

fallen bobcat
#

mhm is a 32-bit PFN enough

#

what if it's running on a supercomputer with like 200TB of ram

heavy sandal
#

i did 36 bit but 32 is probably fine in practice

#

its just most of the bitfields are 36 so that was best for me

fallen bobcat
heavy sandal
#

lmao

fallen bobcat
#

should I align(1) it

heavy sandal
#

no?

fallen bobcat
#

idk why not meme

#

ok bad for perf fine

heavy sandal
#

that was replying to the did i

#

idk about the should

#

i basically never store it outside of a bitfield or an enregistered local

#

i crammed by pfndb entry into 4 64-bit bitfields with a whole lot of union hell too lmao

fallen bobcat
#

because for my allocator design I will use PFNs instead of pointers for the chaining

heavy sandal
#

yeah thats what i do too

#

and thats part of why i could cram the thing into 256bits

fallen bobcat
#

for free pages I need one next pointer, one next batch pointer and one count (byte) field

fallen bobcat
heavy sandal
#

the entry

fallen bobcat
#

wait

heavy sandal
#

the entire entry with all metadata

#

and i said bits thats four qwords

fallen bobcat
#

yeah ok

#

thats not much

#

well I think since this is a free state I can cram as much as I want basically

#

so I could make them like 64 bits

heavy sandal
#

do you use hhdm?

fallen bobcat
#

ok maybe not

#

like 48 bits

fallen bobcat
heavy sandal
#

ok so you can save 63 bits over my setup at least

fallen bobcat
#

why

heavy sandal
#

i dont have an hhdm

#

so each pfm has a pointer to its pte

fallen bobcat
#

why not pfn of pte

heavy sandal
#

because i cant go from pfn to pte that way

#

i can go from pte to pfn by just reading it

fallen bobcat
heavy sandal
#

how would i?

#

if i dont have an hhdm

#

go from phys to virt

fallen bobcat
#

ah right

#

well ok for now I'll keep them 32 bits but might change in the future

#

also now zls has just given up

#

doesnt even launch

heavy sandal
#

my four qwords of the entry are

  • pte pointer with lower bit used for locking the entry
  • basic metadata (status enum, refcount)
  • union of backward link pfn, index in vmem working set for once i make that, and pointer to a waitable io event used when using io to resolve a page fault
  • union of forward link pfn and share count (number of usermode processes sharing the page)
#

i save 16 bytes over windows by using pfns for the linked list instead of pointers and by not deciding to put a whole intrusive avl tree node in there for some fuckin reason idk why nt does that

#

it continues to make me upset that the nt/windows pfn struct doesnt evenly divide into a page

heavy sandal
#

yeah i just dont know what it is KEKW

fallen bobcat
#

I could probs use pointers for the list and it wouldnt matter

#

would be like 20 bytes but thats just for the "free state"

#

should I do the ultimate meme and use a packed struct for the pagetables trl

heavy sandal
#

the tables or the entries?

#

the entries yes imo

fallen bobcat
#

entries

heavy sandal
#

i use a packed struct for the entries and its pretty nice

#

so i would recommend that

#

(i actually use a packed union - one of the union fields is the "valid pte" packed struct and the others are for stuff stored in the ptes that have the present bit set to false)

languid canyon
heavy sandal
#

just never felt a need for one?

languid canyon
#

Well u did since u have recursive paging, but u decided to go with that instead ig?

heavy sandal
#

yeah i went with recursive paging instead of an hhdm for getting access to the page tables easily

#

also when ive had to deal with an hhdm (when i used to use limine) i found it annoying to manage, likely because of having to fight it to convert to my own page tables anyway plus the stuff that limine doesnt put in the hhdm that i needed more than any actual issue with hhdms conceptually, but it put me off on the concept a bit in general

fallen bobcat
#

oh yeah @languid canyon what was the MTRR thing again

languid canyon
#

I see

fallen bobcat
#

like I cant map reserved mem over 4 gib or something

languid canyon
#

You can

#

Allegedly there is an AMD cpu where mapping random phys addresses as WC caching blows up the cpu

fallen bobcat
#

ah I see

languid canyon
#

Which is a typical hhdm pattern

#

Usually its not an issue because mtrrs override WC

#

Well and also cpu doesn't randomly dereference memory on its own

fallen bobcat
#

wonder if phys_to_virt makes sense to put in mm

#

or in platform code

#

it should be in mm

weary jetty
#

48 bits is 256 TiB. I'm foggy on whether PiB RAM SSI SMP systems exist yet. Another consideration on pfns is software e.g. Babaoğlu-Joy page size. That trims bits off the low end. With that a 36-bit pfn can be for 64 KiB pages even if the hardware is only doing 4 KiB, for 52-bit i.e. 4 PiB RAM.

#

If willing to do e.g. 256 KiB pages, the RAM capacity goes up further still even with a 36-bit pfn.

#

03:38 MESZ here… just a middle-of-the-night trip to the loo, so if ppl take a while to get back to me, I might already be back to sleep.

fallen bobcat
#

yeah that makes sense, I'm not looking to abstract over page sizes though. I'm assuming/sticking to 4kib

#

and if the hardware page size is different idc meme

weary jetty
weary jetty
# fallen bobcat yeah that makes sense, I'm not looking to abstract over page sizes though. I'm a...

The Babaoğlu-Joy technique isn't that far out. It was trickier for me because I was working both without a pfndb/mem_map and while handling superpaging and with shared pagetables on radix tree hardware pagetable architectures (well, I haven't gone back & done pagetable-free implementations for inverted pagetable & software refill TLB architecture yet). I made it harder for myself in most ways possible.

heavy sandal
#

those numbers are waaay too big to actually worry about in a hobby os imo

#

but also i dont see how any software technique can expand physical address space beyond what the hardware supports

#

shrink below the hardware width for software optimization sure but if the hardware only supports 48 bit physical addresses on 4k pages i dont see how you can make it any bigger

weary jetty
heavy sandal
#

ah ok, my misunderstanding then

weary jetty
#

Boxen were being made in 2003 with 52-bit physical addressing, so there's real potential for manufacturers to make boxen with larger physical address spaces.

heavy sandal
#

yeah

fallen bobcat
heavy sandal
fallen bobcat
heavy sandal
#

lol fair

fallen bobcat
#

I think it's fun to try to design something fairly scalable

heavy sandal
#

yeah it def can be

fallen bobcat
#

I should buy an old xeon server to test scalability

weary jetty
#

Well, „page” in the sense of kernel allocation unit whilst handling smaller units for memory mapping.

heavy sandal
#

yeah

#

id call one granule and the other page but then arm comes around and throws the naming backwards from what id instinctively do

fallen bobcat
#

Ugh I'm going so slow

#

Well I've finished the mapping pfndb part I think

#

And that's all for tonight

weary jetty
heavy sandal
fallen bobcat
#

I do think I've done quite a lot for like two weeks

heavy sandal
#

yeah you have

fallen bobcat
#

But rn I just need more free time to finish this lol

#

This long weekend I can hopefully get fireworks on amd64

heavy sandal
weary jetty
fallen bobcat
#

And I'm not even doing much school stuff on nights these days

heavy sandal
weary jetty
#

I'm hoping ppl will say „Wow. Your kernel is awesome. Have a new Blue Card sponsorship and a job.” Perhaps I had better do the Windows system call personality as a higher priority.

heavy sandal
fallen bobcat
weary jetty
weary jetty
weary jetty
heavy sandal
#

the other 10% is split between rtl utility functions and adapters for emulating old removed syscalls using newer ones

weary jetty
#

Then it mostly comes down to speed.

#

From there things can march toward replacing more of WINE with bespoke stuff that runs very slightly faster.

heavy sandal
weary jetty
heavy sandal
# weary jetty Not a whole lot. Are there also gdi & user libraries?

so the tldr is that theres a set of dlls that are dynamically loaded and linked into every process unconditionally, and the bottom-most is ntdll.dll which is thin syscall wrappers. each higher level thing builds on that, often with the help of IPC stuff for some of the super high level stuff like UI things

#

so when you use the normal createfile function in kernel32.dll, that fowards to kernelbase.dll which forwards to NtCreateFile in ntdll.dll which invokes a syscall that calls NtCreateFile in the kernel which does arg validation and then calls ZwCreateFile in the kernel which does the actual thing

weary jetty
#

By a long longshot, even.

heavy sandal
#

if you use networking with advapi.dll or whatever the thing is called that opens a device object using the open function in ntdll and then does ioctls on it

#

if you use security functions that does an IPC to csrss.exe which does the security things

#

the actual ipc mechanisms are windows specific mailbox and named pipe stuff

#

also sorry security does ipc to lsass.exe

#

not to csrss.exe

#

csrss.exe is what you do ipc to if you want to create windows or do ui things

weary jetty
#

Telix file operations largely look like sendmsg() where message descriptor structures describe a particular file operation. Getting results like recvmsg() with some trickiness surrounding port sets etc. NT has M:N threading & real asynchronous IO, so what it's done for those matches what's already in Telix.

#

Semantically NT is a closer match to Telix than Linux.

heavy sandal
#

mhm

weary jetty
#

Is there a decisively identified system call API/ABI for NT or is it sort of endlessly expanding?

heavy sandal
#

the base principle is a requirement for perfect backwards compatibility

#

but only for the functions exposed by the dlls

weary jetty
#

So it's endlessly expanding?

heavy sandal
#

the actual internal syscall abi is opaque

heavy sandal
#

so internally not necessarily

#

but externally yes

weary jetty
#

Okay, so it's not endlessly expanding but it's also mysterious from not being directly observable.

heavy sandal
#

yes

#

also most functions are built around taking options structs with a length and/or revision field if they expect to add params later

#

the main example of a syscall getting replaced with a wrapper around a new syscall is the mapviewoffile series

#

which has FOUR versions

#

because it took them three tries to get the interface to satisfaction and then they had to add a numa variant

heavy sandal
#

probably lmao

#

it is known that windows supports int 0x20 for interrupts on x86_64 but i believe they use the syscall instruction if available

#

but when people talk about syscall api for windows theyre generally talking about ntdll

#

(and friends)

#

zig's std is down to one (1) call into any dll other than ntdll on windows actually

#

this is because kernel32.createprocess isnt a thin wrapper and is very notoriously fragile to try and bypass using ntdll

weary jetty
#

It's notable that file & network IO look very similar (actually identical) in Telix. Asynchronous IO follows as it's network -like all the way through the kernel/microkernel servers.

heavy sandal
#

oh and the dlls are preloaded into memory during early os init and matched by name to prevent a MITM attack from replacing the dlls

heavy sandal
#

(and hash verified on load ofc)

heavy sandal
#

windows just used vdsos for all syscalls since the start

weary jetty
heavy sandal
#

if you have windows and install winobj you can actually check the list because windows uses the \KnownDlls object directory to find them, wherein they are a bunch of section (memory mapped file) objects

#

theres also KnownDlls32 which has the x86_32 versions for backcompat with 32-bit programs on x86. i wouldnt be surprised if they use the same folder for aarch32 stuff when running on aarch64

heavy sandal
#

extremely fair lol

#

heres what half of the dir looks like on my system, cant show the other half in the same shot for screen and font size reasons

weary jetty
#

What was his name? Culver?

heavy sandal
#

but yeah ig the tldr of all my ramblings about windows syscalls here is that the design is "what if we used exported symbols from vdsos instead of actually giving an abi"

weary jetty
#

„Get a byte, get a byte, get a byte byte byte!”

heavy sandal
#

lol

weary jetty
#

The guy said it in an interview. Designed VMS & NT.

heavy sandal
#

mhm

weary jetty
#

Dave Cutler

weary jetty
#

It's the right guy but the quote isn't in that interview.

fallen bobcat
fallen bobcat
#

ok locking in time

fallen bobcat
#

I think for now the pmap interface might just be a generic range-based thing, i.e pmap_map(vaddr_t start, paddr_t start_phys, size_t size, ...) and it will choose on its own the underlying page size based on alignment and size. Eventually I am thinking I can have a generic pmap implementation for radix-tree architectures and a different one for e.g. user-mode linux or ppc.

#

@long pendant Could you provide any insight on this?

#

I know you and will talked a bit about that and how that ties in with working set aging or something but I'm not sure what that's about

fallen bobcat
#

actually you might be able to provide insight too, I'm talking about the architecture-dependent mmu abstraction

#

pmap is the mach terminology (inherited to the BSDs)

weary jetty
fallen bobcat
#

not sure this is relevant

weary jetty
#

The API is great for mapping. I'm all for it.

fallen bobcat
#

what do you mean?

weary jetty
#

Virtually mapping an extent of physical memory is great for things.

fallen bobcat
#

yeah like a range-based API?

weary jetty
#

Virtual ranges aren't so atypical. Physical ranges are the rare part.

fallen bobcat
#

yes that is true, I suppose I could ask for an array of physical pages or something, but this might not be fun to work with for e.g identity mapping

fallen bobcat
weary jetty
pastel citrus
#

🤔

#

funny api

#

i prefer the one by abbix tho

long pendant
#

either the aging logic has to sit in pmap or you can provide a 'cursor' interface for reading/modifying PTEs whose method "next pte" is just "if incrementing the pte address gives an address within the same page table, just do so and return"

weary jetty
# long pendant either the aging logic has to sit in pmap or you can provide a 'cursor' interfac...

I'm using memory objects as the repositories for physical page data. There are obvious complications round COW sharing groups, but it keeps it out of reserved memory & able to have more done with it e.g. extent-based tracking for power of 2 -sized and -aligned physical memory extents. Using WSCLOCK the way I am seems unlikely to respond very directly or satisfactorily to memory pressure.

Plausibly, I need a long-term scheduler (swapper) to swap out whole processes for when there's too much pressure.

fallen bobcat
fallen bobcat
weary jetty
#

If you have a virtwin() that may need preservation too.

#

AIX had nutty stuff where all kinds of things needed to be pinned & released for the sake of swapping the kernel, or if not swapping outright, allowing eviction of kernel mappings from the inverted pagetable.

long pendant
fallen bobcat
#

okay that makes sense

weary jetty
#

I should've added refcounts to the swap ptes.

fallen bobcat
#

well at least my paging code works, now to design a nice API trl

heavy sandal
#

working is good

fallen bobcat
#

oh yeah the new API works

fallen bobcat
#

now a radix-tree architecture only needs:

pub const Impl = struct {
    pub const Pte = struct { ... };

    // level 0 = smallest page, last = root
    pub const levels = [_]Level{
        ...
    };

    pub fn activate(root_pa: b.PAddr) void { ... }
    pub fn make_table_pte(pa: b.PAddr) Pte { ... }
    pub fn make_leaf_pte(pa: b.PAddr, flags: mm.MapFlags, level: usize) Pte { ... }
};
fallen bobcat
#

I am thinking I can provide some kind of iterator interface as well

#

something like map_range(va: usize, pa_iterator: anytype) and basically the iterator would return an address for a given offset or something

#

so for mapping a range of allocated memory the iterator would return alloc_page()

heavy sandal
#

one thing i would recommend doing earlier than later is figuring out how you want to handle alternate ptes (ones with valid false used for storing metadata like where a swapped-out page is)

fallen bobcat
#

wdym

#

I have the impls provide a Pte bitfield

heavy sandal
#

yeah

#

if the valid/present bit in a pte is false the hardware ignores the rest though

#

so you can store whatever the hell you want there

fallen bobcat
#

yes

heavy sandal
#

are you making that per-impl too?

fallen bobcat
#

idk maybe

heavy sandal
#

and if so what will the api be for storing stuff there?

fallen bobcat
#

not sure

heavy sandal
#

and if not how will you handle it?

fallen bobcat
#

I think I can just ask impl to have a few defined fields

#

in the bitfields

heavy sandal
#

i use a packed union for it

#

and one of the union fields is the normal arch pte

fallen bobcat
#

idrc about that for now

heavy sandal
#

yeah but itll be hard to kludge it in later if you dont think about it at least a little now

heavy sandal
#

nice

fallen bobcat
#

pmap only needs to implement

 pub fn map_from(self: *Self, va_start: b.VAddr, size: usize, source: anytype) void

and I can implement any policy on top of that

#

@rocky yoke I think this is similar to managarm's MemoryView right?

#

I know you mentioned something about how adding arbitrary page sizes to this would work but I forgot

rocky yoke
#

is source an iterator here?

#

Not sure if I understand the question

fallen bobcat
#

so yeah

#

the problem now is figuring out how to tie in larger page sizes to this, it's a shame I cant find the conversation but I swear you mentioned having a plan for managarm for that

rocky yoke
#

Ah. The plan would be to not only return the physical address from your next() but also the page size (or log2(page size))

fallen bobcat
#

but then the next() would be architecture-dependent no?

#

mhm well I guess this is not really an issue, I can return  arch_largest_page_size() or something for identity mapping sources

heavy sandal
fallen bobcat
#

why tf does it have that

#

for page_allocator?

#

i dont plan on using that

heavy sandal
#

im not sure where else its used

fallen bobcat
rocky yoke
#

Or similar, a 64K page as 16 4k pages

fallen bobcat
#

ah so the page size can be completely arbitrary

rocky yoke
#

yeah. You need some care when interacting with your pfn db but aside from that, it should be possible

fallen bobcat
#

but does that mean that e.g for a large identity mapping the "page size" (or rather view/source size) could be possibly like 4+ GiB and it's up to the hardware to decide how to do it

#

so in the case of an identity-mapping MemoryView/Source it would be something like:

next() -> (pa, size of mapping)
``` and in the mapping function you map and `-= size of mapping` until 0
fallen bobcat
#

ok finally I am done with this

#

now I can implement my fancy pmm nooo

fallen bobcat
#
   /// Map a virtual address range to physical addresses allocated on demand.
    pub fn map_range_allocating(self: *Self, va: b.VAddr, size: usize, flags: mm.MapFlags) void {
        const src = AllocatingSource{
            .flags = flags,
        };

        self.map_from(va, size, src);
    }
#

this kinda stuff is really powerful

heavy sandal
#

really is

fallen bobcat
#

nice

#

the fancy pmm is done

#

it's fancy but it's actually really simple

heavy sandal
#

always the best option

fallen bobcat
#

its just like 100 lines more

fallen bobcat
#

the way this works right now is that each CPU can hoard 1 MiB of memory maximum

#

which should be fine for now

#

more stuff to check off letsgo

#

@past dome rate this OOM handling code meme

#

better than mintia trust

fallen bobcat
#

ugh well imma do a sidequest to implement vmem

#

I dont think we're getting SMP this weekend 💀

languid canyon
#

Do u already have timer calibration?

fallen bobcat
#

no

#

that is platform code and that requires memory allocation

#

I have all the timekeeping infrastructure already tho

languid canyon
#

Why does it require allocation?

fallen bobcat
#

well idk maybe it doesnt but I do it along with other device initialization code (which includes ACPI and friends)

#

perhaps I can do it in early init I just need to check my code rq

languid canyon
#

Well the pm timer is just an io port, same goes for pit etc, tsc is an instruction, idk

fallen bobcat
#

yeah no I could totally do it

#

mhm

#

now you're making me wonder if i should do memory allocation or that kind of driver work

fallen bobcat
#

unless I can just assume theyre in the hhdm but I dont think that's sane

languid canyon
fallen bobcat
#

yes but then I would need to remap it after switching to my own page tables and stuff

languid canyon
#

And hpet is hardcoded at FD000000 or whatever

fallen bobcat
#

id rather set it up like 100ms later when the physical memory stuff is initialized at least

heavy sandal
#

no need to hardcode that

languid canyon
#

I mean in general it will end up mapped

heavy sandal
#

mhm

languid canyon
#

If you map the lower 4G

fallen bobcat
#

I do do that

#

is it guaranteed though

#

I know it is very likely

languid canyon
fallen bobcat
#

I think linux very recently added early timestamps

languid canyon
languid canyon
#

Even before those patches

fallen bobcat
#

stop trying to convince me!!!

#

yeah ok I'll do that

languid canyon
#

Lol

heavy sandal
#

timer (or at least tsc) cal actually a feature i wish limine had, but ig itd only be sane on efi

#

but efi boot services has a stall function

languid canyon
#

Yeah thats an interesting feature

heavy sandal
#

i use it to calibrate tsc in the bootloader

fallen bobcat
#

and no I'm not using uACPI early table bullshit 😎

languid canyon
#

Meanie

heavy sandal
#

smh

languid canyon
#

What are you using then

fallen bobcat
#

(I'd rather not import 30k lines of code for finding a timer)

#

i will use uacpi in the future

#

but for now I see no point in importing it if I'm just gonna use it for something I'd write like 100 lines for

languid canyon
heavy sandal
#

zuacpi even supports barebones mode if you want to use my bindings for it

fallen bobcat
#

keep pinging random people, I realized it brings people into the thread meme

languid canyon
#

Lol

heavy sandal
#

lmao

fallen bobcat
#

idk if you realized that too

#

but like if you ping someone they start showing up on the sidebar on the right

#

which means its like they're following it lol

languid canyon
#

Its kind of a strange system honestly

fallen bobcat
#

for now I can just define like 2 structs and I'll be fine

#

I dont have enough infrastructure to warrant a uACPI integration this early

granite kiln
heavy sandal
#

(note that tsc calibration in bootloader is mostly useful for x86 efi - it takes way too much extra work to do it on bios imo unless theres some bios interrupt for stall i dont know about and afaik most other arches provide sane ways to get the frequency without calibration)

languid canyon
granite kiln
#

i was actually adding tsc calibration in BIOS for internal use rn in Limine

fallen bobcat
languid canyon
#

U can have very early log timestamps

heavy sandal
#

getting tsc frequency from the bootloader slaps, speaking as i now have it on my bootloader

#

and if limine is already doing the cal...

fallen bobcat
#

I think it's cool the bootloader is doing stuff for you but then you kinda end up relying on it

#

its fine if its your own

heavy sandal
#

(again on efi its ez because you just have a stall function on boot services)

languid canyon
#

Does bios not have like a stall function

heavy sandal
#

i have no idea

pastel citrus
#

i dont think so bro

languid canyon
#

I mean it has thousands of functions so its possible

pastel citrus
#

yeah maybe there is one computer that properly implements it

fallen bobcat
#

is acpi a PC only thing

pastel citrus
#

no

#

but the PM timer is basically x86 only

languid canyon
fallen bobcat
#

I was going to put it in platform/pc/acpi

languid canyon
#

Other than super old ones

pastel citrus
#

and some mobile intel chips set the reduced hw bit

#

Lol

fallen bobcat
#

but I think it'll just be platform/acpi

languid canyon
#

Ofc lol

#

Its first class on itanium and x86

#

Other arches implement reduced hardware acpi

#

Like arm and riscv

heavy sandal
#

yeah

pastel citrus
#

it's also kinda first class on arm considering there are proper devices that have acpi

heavy sandal
#

and board support is sometimes sketchy

pastel citrus
#

unless first class = non-reduced hw acpi

fallen bobcat
#

omfg ZLS please stop crashing 😭

pastel citrus
#

too much to ask

fallen bobcat
#

I cant believe the maintainers are getting sponsored to work on zls and it still sucks

heavy sandal
#

youre the one trying to murder it with your project structure

pastel citrus
#

i just realized zls can't figure out the actual return type of a function if it depends on a comptime parameter

#

which is very disappointing

heavy sandal
#

yeah that is one big downside

fallen bobcat
#

well maybe if zig allowed for my shenanigans it'd be another story meme

pastel citrus
#

at least it gives you completions for all the possible types, but it's very disappointing

pastel citrus
fallen bobcat
#

not much

heavy sandal
#

iirc a bunch of modules that are all mutually dependant and in a shared dir?

fallen bobcat
#

I just have a base module because I cant have modules with aliases that are independent

heavy sandal
#

unless youve changed that?

#

ah

fallen bobcat
#

basically I want to be able to do @import("ke") but I cant do that since ke might depend on stuff which depend on it (and modules cant have cyclic dependencies), so it is simpler to have a base module from which you import ke, so @import("base").ke

heavy sandal
#

i still think you should just use @import("root") for that

fallen bobcat
#

tl;dr its a way to avoid relative includes

heavy sandal
#

since @import("root") always points to the main file of the root module of the compilation

fallen bobcat
#

yes but that breaks on um since the root file is the entry point since it exports main

heavy sandal
#

the root file doesnt have to export main

fallen bobcat
#

yes it does

heavy sandal
#

you can use

comptime {
_ = @import("something");
}
#

to force a file to include in compilation

#

and main can be anywhere

#

oh wait for um

fallen bobcat
#

yes

heavy sandal
#

yeah ig the std start.zig would depend on main being in root huh

#

dang

fallen bobcat
#

my base is just root but renamed

#

like its literally the same thing

heavy sandal
#

mhm

#

well i know theres some plans eventually to have a compiler server of some sort built into zig and im sure thatll help with lsp stuff its just super low priority for them because theres definitely bigger issues lol

fallen bobcat
#

yeah I'm sure

#

it's not that bad either, Zed still handles it better than emacs somewhat

heavy sandal
#

i use clion lmao

fallen bobcat
#

and zed has the vibecoding builtin so I have completions

heavy sandal
#

(theres an lsp plugin for clion and then a zig plugin called zigbrains that builds on top of the lsp plugin with zig features)

fallen bobcat
# heavy sandal i use clion lmao

I use emacs but for some reason their LSP support didnt like zls or something so I use zed for zig (kate also seems to handle it better, so it's def an emacs thing)

heavy sandal
#

mhm

fallen bobcat
#

clion tho 💀

#

jetbrains stuff is so slow

heavy sandal
#

im a neovim gal if im on cli for editing so i cant help on emacs things lmao

stray kelp
#

nah

#

i use CLion too

heavy sandal
#

and no the jetbrains stuff isnt slow at all ime

fallen bobcat
#

takes a while to start and it just feels slow

#

and i have a good machine

stray kelp
#

yeah, to start

#

but then it's fast

heavy sandal
#

yeah

#

that

#

plus im a windows gal anyway i got started doing dev work with a version of visual studio 2005 that i managed to extract from the school computers onto a flash drive to bring home, i feel most comfortable in my IDEs lmao

fallen bobcat
#

i am trying clion to see if it handles it better

heavy sandal
#

the zig plugin i recommend is zigbrains fwiw

#

the other zig plugin is abandonware 💀

fallen bobcat
#

yeah no ok it really is a zls issue

#

it just instantly crashes

#

lol

heavy sandal
#

rip

stray kelp
#

XD

heavy sandal
#

report it to the zls people ig

fallen bobcat
#

how do i explain this lol

#

nah what I'll do is I'll wait until the project gains more traction and then I will use my aura to get them to fix it

heavy sandal
#

lol

fallen bobcat
#

though for real AI inline completion is kinda helping a lot making up for zls

#

it's wrong a lot of times because zig is newer but it kinda replaces lsp

weary jetty
#

I'm still doing Linux binary compatibility.

fallen bobcat
#

sometimes it straight up outputs rust code lol

#

thanks zig

languid canyon
#

btw be careful with fadt stuff

#

revision cannot be trusted basically, only length matters

fallen bobcat
#

mhm how do you propose I do the ACPI GAS reads architecture-agnostic?

#

also is there anything but memory and port io really

languid canyon
#

in theory any address space is allowed

heavy sandal
#

oh that reminds me i recently learned theres a standard non-ecam mechanism for pci config space access on arm

#

its not guaranteed to be supported tho

languid canyon
#

yeah the view selector thing

fallen bobcat
#

bruh I just learned the zig naming convention for enum members is snake_case

#

I swear I thought it was PascalCase

heavy sandal
languid canyon
#

oh thats even worse

heavy sandal
fallen bobcat
#

I've been using PascalCase

heavy sandal
#

its far more important that youre consistent within your project tbf

fallen bobcat
#

yeah true

heavy sandal
#

not that you match up with what std does always

heavy sandal
fallen bobcat
#

ah uacpi only supports mem and io

#

it seems like

weary jetty
heavy sandal
languid canyon
#

as its the only place where it was seen thus far

fallen bobcat
#

I mean for GAS

languid canyon
#

reset_reg is a gas

#

but yeah

languid canyon
#

generic helper only supports those

fallen bobcat
#

I dont see it

fallen bobcat
#

ah ok but that's ad-hoc

languid canyon
#

yep

fallen bobcat
#

I think I will only support mem and IO for now we'll see later

languid canyon
#

other address spaces only matter for really niche gasses

weary jetty
#

What are you doing with ACPI here?

fallen bobcat
#

I'm just setting up early table traversal and timer initialization

weary jetty
#

Just early boot ACPI table scanning?

fallen bobcat
#

yeah

#

wtf is this

languid canyon
#

yeah a gas may be arbitrarily large, just like operation region registers

fallen bobcat
#

or I can panic if size > 8 trl

languid canyon
#

you can lol

fallen bobcat
#

this is literally just for early timer stuff

languid canyon
#

for the pm timer linux assumes io space anyway

#

note that u cant use the same revision check as linux because linux uses the sanitized acpica version of fadt which guarantees correct revision

#

or tbh u can just implement sanitization yourself

#

its just a table that matches revision to length

languid canyon
fallen bobcat
#

firmware devs smh

languid canyon
fallen bobcat
#

ok well I copied the uacpi logic for the revision trl

languid canyon
#

Fair

pastel citrus
#

@fallen bobcat i got kinda inspired by your pmap code and i found one bug in yours while writing mine - the advance function in radix pmap cursor struct stops at the first level that was invalidated, you have to do the loop backwards to find the last that was invalidated, or not stop after the first one that was invalidated

fallen bobcat
#

which project are you working on?

pastel citrus
#

the 1293812938th attempt at writing a kernel

fallen bobcat
#

stop getting inspired and start contributing meme

pastel citrus
#

this time (maybe (hopefully)) successfully

fallen bobcat
#

why does limine not map the first 4 gib anymore

pastel citrus
#

great question, it kinda annoyed me when i tried to access the lapic

fallen bobcat
#

and now I cant setup timers without allocations

pastel citrus
#

made me go on a whole ass tangent of implementing page table manipulation and now i'll do the virtual memory allocator

fallen bobcat
#

not sure why I added that

pastel citrus
#

yeah, in my version i just wrote the loop backwards

fallen bobcat
#

which language

pastel citrus
#

so it finds the largest level that changed and just breaks

#

but not that big of a deal

#

zig

fallen bobcat
#

makes more sense to do it the other way

fallen bobcat
#

did I have anything to do with thattrl

pastel citrus
#

nah, i've always leaned towards zig

#

my last working kernel was also written in zig, like 3 years ago atp

#

back when zig the language wasn't so shit

fallen bobcat
#

lol

#

how is my code mr. zig expert

pastel citrus
#

wouldn't call myself an expert but i did find a few things that could be written better

#

can't tell off the top of my head, i'd have to take a look again

#

i can do it in a bit

#

or take a look in general if you'd like, not necessarily just what i found from a quick look at pmap related code

fallen bobcat
pastel citrus
#

but in general the code looks pretty clean, you seem to have grasped zig pretty quick

#

it's not a complicated language, so that may be why

fallen bobcat
fallen bobcat
rocky yoke
languid canyon
granite kiln
#

the HPET table is mapped

#

the HPET itself isn't "ACPI stuff", just like the IO APIC and local APICs for example

languid canyon
#

Oh ok

granite kiln
#

though admittedly it's annoying to deal with them not being mapped

languid canyon
#

I mean yeah its kind of pointless to have the table mapped if you cant use the hpet anyway etc

granite kiln
#

well no

#

the idea to have the ACPI tables mapped wasn't about the HPET or the APICs or other similar MMIO devices that could be exposed via ACPI

#

that's just generic MMIO which we do not map by default in the HHDM

#

the idea to have the tables mapped was mostly something done in response to complaints by @rocky yoke

rocky yoke
#

yeah

languid canyon
#

nah i get it, im just saying it could be extended a bit further

rocky yoke
#

for example on systems where you need the tables to discover serial

#

mapping the MMIO to the hddm doesn't make sense though

granite kiln
#

yeah

languid canyon
#

surely it does

#

hpet is x86 specific anyway and u have mtrrs

#

plus limine could just specify the correct caching mode

#

the framebuffer is already mapped to the hhdm isnt it

granite kiln
#

the framebuffer is basically the only exception in terms of mmio

#

because early output

languid canyon
#

anyway its fine if u wanna keep it that way

#

i just dont see anything fundamentally wrong about mapping hpet and lapic etc

granite kiln
#

the fundamentally wrong part is: what is "etc"?

languid canyon
#

ioapic trl

granite kiln
#

is that it?

languid canyon
#

probably

rocky yoke
#

what about on !x86?

granite kiln
#

seems like a slippery slope

rocky yoke
#

yeah

granite kiln
#

eventually the request will be "map ALL mmio"

languid canyon
#

its not a slippery slope if its convenient for korona meme

granite kiln
#

which is not really feasible

#

well mapping ACPI isn't the same as mapping MMIO

#

same with the SMBIOS tables

rocky yoke
#

no, the tables need to be mapped in some cases, otherwise the system is unusable

languid canyon
#

and mapping hpet is not the same as mapping all mmio

granite kiln
#

why not? is it not MMIO? like sure, it's on the system bus, not PCI, but why does that matter?

#

that distinction may not even exist on !x86

languid canyon
#

anyway it's not really worth fighting about, i dont exactly gain anything from this even if u did do it

#

so w/e

granite kiln
#

i am not fighting

#

i am trying to understand your rationale

#

so if i am convinced about it, it is something that could be changed

languid canyon
#

you already map stuff pointed to by other fields in other tables like DSDT in the fadt

#

this is just another field in another table

#

0 diff imo

granite kiln
#

well, that's ACPI tables

#

not MMIO

languid canyon
#

whats so special about mmio that makes it unmappable

granite kiln
#

for one you would have to special case the HPET and APIC pages, because you cannot say "tables and all memory that they reference, MMIO or not", that's way too like uh, broad?

#

not to mention that for that you also need to know how to interpret every ACPI table, which is not forwards compatible

languid canyon
#

like for other arches, whats there to map from acpi tables other than the interrupt controllers

languid canyon
granite kiln
#

Limine explicitly lists what ACPI tables are mapped so it's not really a concern right now, it's about going "every table pointing to some memory that isn't in the tables will see that memory mapped to the HHDM" that is the issue

#

again, unless you special case HPET and APIC tables as "Limine knows about these and will map them"

languid canyon
#

well as you mentioned you can easily limit the scope in the spec just like you did already

languid canyon
#

or maybe the tsc frequency request could be an even better solution idk

granite kiln
#

which, sure, i guess it's convenient, but is there actually a case where it is strictly necessary to have the HPET/APIC mapped before having page tables code and allocator code?

languid canyon
#

hpet for tsc calib, apic not really i guess since limine provides all the info like ids via other means

granite kiln
#

yeah but do you need the TSC calibration either?

languid canyon
#

it's nice for timestamps

granite kiln
#

sure, but i am talking about, as i said, strictly necessary things, like sure, having the TSC frequency would be nice, but that's perhaps better served by its own request as you said

languid canyon
#

what was the original reason that managarm needed all tables pre mapped?

granite kiln
#

but beyond the timestamps, which are useful but not strictly necessary, what else?

#

fun fact, i don't actually remember it that well

#

korona mentioned tables to have serial output

languid canyon
#

ah

granite kiln
#

which i guess is more essential, for debugging and whatnot, than anything else discussed here

#

but we can cc @rocky yoke about it. what else was needed from the tables?

languid canyon
#

technically you may need early delays for device stuff as well

#

like timeouts or polling etc

rocky yoke
#

SRAT is needed to set up memory management

#

if you want to support NUMA

languid canyon
#

true

rocky yoke
#

and detecting CPUs early is also useful to determine the kernel memory layout etc

granite kiln
#

plus Limine already guarantees that DTBs are mapped on !ACPI

#

so having ACPI tables mapped mirrors that

rocky yoke
#

on RV, ACPI tables contain the isa string

#

= the supported cpu features

languid canyon
#

☠️

#

tbh hpet is just one alternative, u ofc have pit and the pm timer also which dont require mapping

granite kiln
#

yeah

languid canyon
#

well technically the PM timer is GAS but w/e

granite kiln
#

GAS?

languid canyon
#

generic address space

#

it could be mmio as well if they wanted to

granite kiln
#

yeah but like

#

you know

#

de facto it's always an IO port on x86

languid canyon
#

that is true

granite kiln
#

but in any case having a time stamp counter frequency request sounds useful, also on non-x86

languid canyon
#

yep

rocky yoke
#

x86 is the only arch where it needs to be calibrated though

languid canyon
#

itanium? trl

heavy sandal
#

the big ones for acpi to have early are srat, madt, and dbg2 yeah

#

and ig dbgp which is the older shittier version of dbg2

#

I actually have an (x86) laptop where the serial port is only discoverable by DBG2 and not in the aml

#

(probably because the serial port is also only accessible by the mobo and doesn't have an external connector on that laptop but still)

fallen bobcat
#

oooh I have a realized I can use the hhdm in the slab allocator for small objects, therefore segment allocation in vmem can be done through a slab cache

#

this solves a bunch of circular dependencies

heavy sandal
#

yup

fallen bobcat
#

vmem will only be used by large slabs

heavy sandal
#

thats effectively how i do it to but more complex and ive not gotten through to true vmem stuff yet

fallen bobcat
#

kinda crazy looking back at my code from like 3 years ago

#

4 years almost

#

💀

heavy sandal
#

damn

fallen bobcat
#

idk github says 4 years but it's 3

#

january 2023

#

I was 15 and innocent 😭

heavy sandal
#

yeah github rounds up to whatever unit its using

fallen bobcat
#

tbh i kinda dont like zig allocators

#

it's annoying to pass them around when i just wanna test something

#

oh well there's std.debug.gpa or whatever

heavy sandal
heavy sandal
fallen bobcat
#

no I mean I'm writing it in userspace and for allocating segments I just wanna use malloc

heavy sandal
#

ah

#

the std.debug allocator is meant for debug info/unwind related allocations and is an arena

#

i wouldnt use it for anything else even testing

heavy sandal
fallen bobcat
#

mhm well ok for now I have an allocator member variable

#

and I just pass init.gpa

heavy sandal
#

oh yeah if its structs storing an allocator in the struct is good

fallen bobcat
#

also I think I will use rbtrees instead of hashtables

#

kinda dont wanna mess with resizing hash tables

heavy sandal
#

if you wanna use avl trees instead of rb trees i got one in zig with unit tests you can steal if needed

fallen bobcat
#

I have an rbtree implementation already

#

I have an AVL one I can translate too

heavy sandal
#

alrighty, just figured id offer in case you didnt lol

fallen bobcat
#

i dont like using code from others

#

the code I do steal I rewrite

heavy sandal
#

thats extremely fair and im the same way so idk why i keep thinking others wouldnt be lmao

fallen bobcat
#

like the linux code

heavy sandal
#

every few months i get this itch to write an acpi library in pure zig instead of using uacpi for mostly that same sort of reason and then i squash that urge because holy shit that sounds like agony

fallen bobcat
#

we could do something collaborative

heavy sandal
#

true

#

maybe someday

#

if uacpi wasnt so good id be more interested in working on it

fallen bobcat
#

like i wouldnt mind working on an acpi library but I dont want to spend a shitton of time doing it, so maybe doing it as a collaborative thing would be better

heavy sandal
#

yeah same

fallen bobcat
#

but maybe in the future

#

idk

heavy sandal
#

but zig has good c integration and uacpi just works out of the box so theres so little reason to work on my own acpi lib

#

yeah idk

#

if i did do it id def steal infy's microcode setup for aml

#

at least in concept

languid canyon
#

Would be fun to see

fallen bobcat
#

we could just rewrite uacpi

heavy sandal
#

i legit would never have thought of implementing microcode to run aml ops but once you see it its so obvious

fallen bobcat
#

infy you can flex cuz you wrote uacpi and hyper

#

I cant

#

(for the bootloader I might do an efistub as an option eventually though)

languid canyon
#

I spent like 3 years on that tho 💀

fallen bobcat
#

yes true

#

and my kernel already does more than ultra

languid canyon
#

True

languid canyon
#

Just support efi only

#

Make a simple protocol for your kernel

#

Its nice I think

heavy sandal
#

yeah

#

highly recommend

#

efi slaps actually for booting

languid canyon
#

U can even use the simple fs protocol

heavy sandal
#

yep

languid canyon
#

So no need for fat drivers

heavy sandal
#

i was like 80% through a fat driver when i decided to ditch non-efi booting and then i just dumped the fat code in a folder for later and use simple fs protocol for everything

#

its actually an eventually™ goal of mine to get an implementation of zig's std.Io for uefi using it so you can just use the std

#

at least for the threaded std.Io in single_threaded mode

#

which is the only case that makes any sense on efi

fallen bobcat
#

Also I have a great bootloader name

#

Zap

heavy sandal
heavy sandal
fallen bobcat
#

I wrote the brutal one

fallen bobcat
heavy sandal
#

that is true

#

but zap still slaps

#

for a bootloader anyway

fallen bobcat
#

Yes

#

Yeah

heavy sandal
#

doesnt strike me as a good kernel name but def a good loader name

fallen bobcat
#

Zag booted by Zap written in Zig

languid canyon
languid canyon
fallen bobcat
#

It's in C and I wrote it like 3 years ago

#

I will probably reuse code tho

#

And it's very tied to brutal obviously

languid canyon
#

Didn't know you were related to brutal os

fallen bobcat
#

The authors speak French and so do I so I know them

languid canyon
#

Ooh

weary jetty
#

It's really about cacheline and page touches.

fallen bobcat
#

Well, not rely on allocations

weary jetty
#

I've got some intrusive things due to allocation constraints like for turnstiles.

#

Multiple and more than I'd like.

fallen bobcat
weary jetty
fallen bobcat
#

You don't have to

pastel citrus
#

oh hm

fallen bobcat
#

But ideally I try keeping the code high quality

pastel citrus
#

few things i found is places where you could use @intCast insteadf of @truncate

fallen bobcat
#

I use truncate where I'd write a mask manually and intcast

pastel citrus
#

i'd @intCast when putting the physical address into a pte

heavy sandal
#

same

pastel citrus
#

to make sure the user didn't pass in a bullshit physical address

heavy sandal
#

intcast there is a noop on its own and just asserts on safe modes

pastel citrus
#

technically not possible but it doesn't hurt

#

yeah

heavy sandal
#

whereas truncate doesnt assert and still has to do things on unsafe modes

fallen bobcat
#

truncate masks it no?

#

ah unless you mean like intCast is = to trusting the user

#

And masking it is hiding the problem

pastel citrus
#

basically

heavy sandal
#

intcast will panic if the user does something wrong

#

whereas truncate hides it

pastel citrus
#

truncate is fine if you do something like

#

const high: u32 = @truncate(u64_value >> 32);

#

there is nothing to assert, obviously

fallen bobcat
#

I see

#

Well thanks

fallen bobcat
#

I think vmem works letsgo

languid canyon
#

show code

fallen bobcat
#

it's a simplified implementation because I dont use a bunch of the stuff

#

like importing arenas

#

and phase and nocross

fallen bobcat
languid canyon
#

.rs lol

fallen bobcat
#

yes no zig highlighting

#

@lavish meteor I beat you to the punch

#

ok to be fair I mostly rewrote the code I already had but made it simpler and better

#

one possible improvement would be having a bunch of rbtrees instead of one (indexed by hash) but this is better than the fixed 16 entry hashtable + linked lists I had lol

languid canyon
#

whats the tldr of vmem

fallen bobcat
#

generic resource allocator where u have a bunch of power-of-two freelists

#

mhm actually I might want quantum caching in the future too

pastel citrus
# fallen bobcat

fyi i think zig enums already use the smallest possible int type that can fit all the tags, so you don't need to specify one yourself

fallen bobcat
#

ok thanks

#

also whats neat is I implemented next fit so I can allocate pids using that too

heavy sandal
#

im def interested in taking a look at this, i need a general "resource number" allocator at some point (plus vmem in general) and still just kinda dont have a clue how to do it

fallen bobcat
#

well it's called vmem but it's a generic resource allocator

heavy sandal
#

yeah

fallen bobcat
#

over any interval of integers

heavy sandal
#

and thats a thing i need at some point

#

that idk how to do

pastel citrus
#

just use an rbtree tf

fallen bobcat
#

rbtree doesnt work for stuff like pids I think

#

and is not constant time

fallen bobcat
#

annoying missing zig feature is no self referential globals

heavy sandal
#

wdym by self-referential?

fallen bobcat
#
const nil = Node{
    .left = &nil,
    .right = &nil,
    .parent = .init(&nil, 0),
};
#

I cant do this

pastel citrus
#

you can

fallen bobcat
#

so I have to have an ugly init function to make it work

fallen bobcat
heavy sandal
#

im p sure theres a way

pastel citrus
#

it literally worked for me last time i did it

heavy sandal
fallen bobcat
pastel citrus
#

give it a type

heavy sandal
#

use nil: Node = .{

pastel citrus
#
const nil: Node = .{
  .left = &nil,
  .right = &nil,
  .parent =.init(&nil, 0),
};```
fallen bobcat
#

wtf does it change

pastel citrus
#

nil has a type

#

lol

heavy sandal
#

yeah`

#

the issue is nil isnt typed the way you did it

fallen bobcat
#

damn

#

that works

pastel citrus
#

in the other case you're refering to something that hasn't been evaluated yet

#

so it has no type

fallen bobcat
#

that is kinda weird

pastel citrus
#

in the other case it doesn't have a value yet but it has a type

heavy sandal
#

(also thing: T = .{ is the preferred syntax and theyre trying to get rid of the other version partly because of issues like this)

#

the semi-technical thing is that the Node{...} expression has to be fully evaluated

pastel citrus
#

i prefer having an explicit type anyway so i never really ran into it :^)

heavy sandal
#

before it has a type

pastel citrus
#

mainy because the types are used a lot for stuff like casts

#

so you can do const x: u32 = @truncate(...); or whatever without using @as

heavy sandal
#

whereas if you do thing: Node = ... that has type Node when the initializer is being evaluated

fallen bobcat
#

well, thanks

#

very helpful

heavy sandal
#

np