Portability of page attributes / flags
Posted: Wed Sep 14, 2016 3:07 am
In my kernel design, I have a separation between different levels of memory management: There is a physical page frame allocator ("chunker", because it manages chunks of memory, think of a buddy allocator, for example), a page table manager ("pager") and then there are "users" of these managers, such as the kernel heap, process / address space creation... In the last days, I was contemplating about the portability of page attributes / flags (access rights, caching policy, dirty / accessed), and the question: How should the pager (which manages virtual to physical memory mappings) communicate these flags to its "users" in such a way, that it can be ported between different architectures? For example, I had these thoughts:
- Expose the hardware flags to the "users" of the pager and let them pick the flags they want / need. Something like this:
Code: Select all
// User of the pager // INC_ARCH is a macro defined in config.h, which is generated at configure time, which the target architecture is chosen. #include INC_ARCH(Flags.h) Pager::Map(virt_addr, phys_addr, PAGE_USER || PAGE_RW);
Code: Select all
// arch/x86/ia32/Flags.h Enum PageFlags { // Flags such as PAGE_USER for IA32 architecture. }
- Define a set of abstract page flags (something like user readable / writeable / executable, supervisor readable / writeable / executable, write-back / write-through / uncached, dirty / accessed, global...), use them as parameters / return values of pager functions and let the pager translate between these abstract flags and whatever flags are supported by the underlying hardware. (IIRC, this is the way Linux handles it.)
- Define a set of specific, abstract memory types (user code / data, supervisor code / data, MMIO...), use them as parameters / return values of pager functions and let the pager choose appropriate flags.
- Let the pager provide specific functions to grant / revoke access rights, enable / disable caching, query dirty / accessed status...