Octacone wrote:
A slightly better option: the one I've chosen to implement. Enable PAE (physical address extension, something in those lines) and get access to the "upper upper" memory above 0xFFFFFFFF up to couple of TB, but that only reefers to physical memory access. You have to enable paging in order to use this method. You will still be limited to 4 GB of virtual address space but you will be able to map those 4 GB to any physical address you want. Then make your PMM super super smart. This is where it gets interesting... You can have a single bitmap (64 GB in size, assuming average maximum amount of physical memory that can be installed by user on a standard industry motherboard, server ones can have much more) which means you can just map your memory map accordingly and reserve all the areas that are not free. 64 GB = 64 * 1024 ^3 = 68719476736 / 4096 (4 KB pages) / 32 (32 bits in a bitmap (per uint32_t)) = 524288 bytes long bitmap = 512 KB / 0.5 MB. That is wasteful (@LtG thinks so.) What you could do is: have a set of different bitmaps each once for a different free region, allowing your master code to access those bitmaps as if they were contiguous, like check if there is space in bitmap no.1 then if there is no sufficient space (requested space) available search the next one (no.2) and so on. Virtually chaining those bitmap as if they were one. Also while doing that reclaim everything you can and store it somewhere safely, also make sure to map everything properly. If you get weird page faults, remember to map all of your bitmap entirely + areas that you want to reclaim and potentially use.
If I understood your math, you got it wrong, you shouldn't divide by 32. So if you use a bitmap to account for max RAM of 64GiB, where each bit represents a single 4KiB physical page, then the math should be:
64*1024*1024/4 bits = 16777216 bits / 8 bits = 2 MiB. That's not a huge amount, though for a low end system with say 64MiB I'd hate to lose 2MiB for no reason. Of course if you size it dynamically then there's no reason for an arbitrary 64GiB limit either.
My main point against a single bitmap is with systems that have, say 64GiB of RAM, but that RAM is dispersed over the entire 64-bit PAS (Physical Address Space). So the worst case scenario. How big bitmap do you need to be able to account for the entire 64-bit address space? Basically trying to use a single bitmap (efficiently) gets hard fast, and provides no real benefits, not even simplicity.
If you are going to use multiple bitmaps (each with different base) so as to not waste a massive bitmap to cover the potentially 64-bit PAS, then why not go all the way and have each bitmap sized zero and just record the base address of each 4KiB page, and thus you'll end up with a stack. I think a stack is actually a bit easier to implement, wastes no memory (maybe a few bytes), trivially manages any amount of RAM, etc. It easily also covers NUMA (if you're interested in that) and you can easily split the stack so each CPU (if you plan to support multi-core) can have their own stack (so no locking needed) and you can take the extra hit of locking when you want to rebalance the stacks between cores.
To put it simply, I'm not aware of any real benefit bitmap provides that stack doesn't, except the possibility of finding contiguous memory in a bitmap. But why would you need contiguous memory? The only reason I can think of is ability to use large pages, but even with a bitmap what do you think the odds are that after the system is up for a couple of hours that you'll ever again find a large page (whether it's a couple of MiB's or worse, GiB's) in a bitmap available either? I'd say pretty much zero.
Whether you both want to use bitmap is of course up to you, but presumably there's a reason your doing osdev and presumably you want to make your OS good. So try to "justify" to me or yourselves why you prefer bitmap? A stack is really easy, just hold a point to the top of the stack, store next available page there, that's it. The reason why the stack takes no memory is because the stack can give out the pages it uses when they are no longer needed for the stack. Which basically means that the stack actually does use memory, but only when the memory isn't used by anything else, once the apps request memory then the stack needs less memory, and ultimately when all memory is used the stack drops to zero bytes (or maybe the size of a single pointer).
I'd imagine a bitmap is favored because it's simple (though finding free page takes some effort, I think stack is easier, just pop the first thing off), and because it's more efficient vs a stack; stack uses full pointers (ie. 32-bit or 64-bit variables stored), but as I just explained above, it only uses memory when the memory isn't actually needed by the system, so it "virtually" uses no memory at all and is thus more efficient than a bitmap.
Osdev is all about design decisions, so why do you think a bitmap is better (aimed at both of you)?
PS. I really, really, am not trying to make you create an OS "in my image".. Just trying to offer advice. What you do with it is of course entirely up to you.