Trying to support both VM Page size (not mixed)
Posted: Mon Apr 26, 2021 4:04 am
Hi everyone,
first some background info:
From what i understood, the PML4 and PDPR tables will remain the same so for them i don't need to change the code.
And technically i think the PD mapping code can be used for the Page table mapping code with few changes handled by some macro conditions
What i need if i want to support 4k pages is:
So what i thought to do was something like using an outer cycle in the that count up to X for now (where X is the number of page dirs i want to map, i am thinking to reserve at least 4mb for the kernel so it should be least 2), and do the mapping of the pd_entry and then use the inner cycle (called .map_p2_table that was used for the PD mapping in 2 mb) and fill the page table.
And here start all my doubts and problems
I defined two variables for holding the 2 ptable i want to use:
But the problem with this approach is that i need to find a way to identify what table to use in the outer cycle, so maybe i was thinking could be better do something like:
And was thinking of doing 2 nested cycles, and use the counter from the outer cycle in the mov instruction in something like that:
But in this case i'm getting an error that says i can't use two index registers (so i suppose this scenario can't be used as well).
The problem is that i need to compute the address and it is composed by two variables, and if i can't use two registers to do it, how should i do it?
Doing something like that should be the right approach?
(is just a draft, so there could be errors and as i said i'm not very fluent with asm, so i hope i haven't written any horror XD)
Otherwise what can be the easiest/best way to compute the address? (that so far is my blocker problem).
The actual bootloader code without is here https://github.com/dreamos82/Dreamos64/ ... asm/boot.s (it doesn't have any of the changes i'm trying to implement)
So is my idea bad? It is going to work? it worth the hassle of supporting both, or probably i'm just wasting my time (is nearly a week i'm already trying to figure out a solution, but at least i learned some new stuff about assembly)
One last question, i'm currently just mapping part of the framebuffer (just 2mb) in the bootloader, i'm wondering if i should map the whole framebuffer in the bootloader, or is better to map it piece by piece handling the #PF (i should just compute the size of it before) BTW i was expecting to find the framebuffer address on the grub MMAP data but apparently is missing, is there a reson why?)
Thanks for any help guys!
first some background info:
- What i'm trying to do is a boot loader code that can set-up the kernel to either set-up 2mb pages, or 4kb pages, i was thinking of doing it using some nasm macro conditions.
- The problem is that i'm not very fluent in writing assembly code (i have written the boot part, can read more or less it, but i'm still full of doubt when i have to add new stuff o start to do more complex things.
- I was thinking it could have been a good asm exercise to add that feature, but... (See the point above XD)
- The overall idea is that the page size is decided before compiling the os, so defining a flag (or setting a value for it) will decide which page size to use
- Currently i'm using 2mb pages (when writing the boot code, i was reading a tutorial, and it was using 2mb pages, it looked quicker to implement, so at that time i was happy with it)
- I have to admit that i'm not expecting much from my OS, so probably i could even decide to not implement this feature (but i think could be nice to have)
From what i understood, the PML4 and PDPR tables will remain the same so for them i don't need to change the code.
And technically i think the PD mapping code can be used for the Page table mapping code with few changes handled by some macro conditions
What i need if i want to support 4k pages is:
- The function that maps the page dir now will map the page table in the 4kb pages case
- And now i need to add the mapping of the ptables into the page dirs
So what i thought to do was something like using an outer cycle in the that count up to X for now (where X is the number of page dirs i want to map, i am thinking to reserve at least 4mb for the kernel so it should be least 2), and do the mapping of the pd_entry and then use the inner cycle (called .map_p2_table that was used for the PD mapping in 2 mb) and fill the page table.
And here start all my doubts and problems
I defined two variables for holding the 2 ptable i want to use:
Code: Select all
pt1_table:
resb 4096
pt2_table
resb 4096
But the problem with this approach is that i need to find a way to identify what table to use in the outer cycle, so maybe i was thinking could be better do something like:
Code: Select all
pt_tables:
resb 9128
Code: Select all
%ifdef SMALL_PAGES
mov ebx, 0
.outer_pd_cycle:
;pd loading stuff
%endif
.inner_pt_cycle:
;all the related stuff
%ifdef SMALL_PAGES
mov [(pt_table - KERNEL_VIRTUAL_ADDR) + edx * 0x1000 + ecx * 8], eax
%elifndef
mov [(pt_table - KERNEL_VIRTUAL_ADDR) + ecx * 8], eax
%endif
inc ecx,
cmp ecx, 512
jne .inner_pt_cycle
%ifdef SMALL_PAGES
inc ecx
cmp ebx, 2
jne .outer_pd_cycle
%endif
The problem is that i need to compute the address and it is composed by two variables, and if i can't use two registers to do it, how should i do it?
Doing something like that should be the right approach?
Code: Select all
mov eax, ebx ; assuming ebx contains the outer cycle counter
mul 0x1000 ; that should do ebx * 0x1000
push eax ; if i'm not wrong the result is in edx:eax
mov eax, ecx
mul 8
add eax, pt_tables - KERNEL_VIRTUAL_ADDR ; Is possible that?
pop edx ; popping ebx * 0x1000
add eax, edx
(is just a draft, so there could be errors and as i said i'm not very fluent with asm, so i hope i haven't written any horror XD)
Otherwise what can be the easiest/best way to compute the address? (that so far is my blocker problem).
The actual bootloader code without is here https://github.com/dreamos82/Dreamos64/ ... asm/boot.s (it doesn't have any of the changes i'm trying to implement)
So is my idea bad? It is going to work? it worth the hassle of supporting both, or probably i'm just wasting my time (is nearly a week i'm already trying to figure out a solution, but at least i learned some new stuff about assembly)
One last question, i'm currently just mapping part of the framebuffer (just 2mb) in the bootloader, i'm wondering if i should map the whole framebuffer in the bootloader, or is better to map it piece by piece handling the #PF (i should just compute the size of it before) BTW i was expecting to find the framebuffer address on the grub MMAP data but apparently is missing, is there a reson why?)
Thanks for any help guys!