I'm hitting annoying problem related to INVLPG instruction. Here is my code:
Code: Select all
void * cr3_mem = mem_alloc();
void * workaddr = (void*)&kernel_pgsetup;
page_map(workaddr, cr3_mem, PSTRUCTP_STDPG_KERNEL);
asm("invlpg %0" : : "m" (cr3_mem));
pdir_init(workaddr, cr3_mem);
Generally, I always allocate a page for new directory, then I map it (always, maybe here the problem is) to &kernel_pgsetup (which is a symbol defined in linker script). When I allocate and map pdir for the first task, mapping works, but when I do it for the second time, the new memory (allocated by mem_alloc() directly after the first) is not changed and I think &kernel_pgsetup is still mapped to the previous. The problem may lay in mapping all new page directories to the same virtual page, but I'm not sure.
When I replace INVLPG with
Code: Select all
asm("movl %%cr3, %%eax\n"
"movl %%eax, %%cr3" : : : "%eax");
Where could the problem be? Is it incorrect to have always one page for editing new page directories and tables? Can I do something else?
(I'm testing everything in bochs+gdb)
Thanks,
Filip.