Note: my actual issue is below the code...
I have a simple physical page allocator... it has two main functions
Code: Select all
mm_alloc(); = This returns the PAGE of the first free page over 16mb, if there are any availible;
mm_allocl(); = This returns the PAGE of the first free page...
Here is the code for my init function...
Code: Select all
unsigned long *kernel_pd; //This is the kernel Page Directory
int vmm_install()
{
int i;
char *test;
unsigned long *pt;
kernel_pd = (unsigned long *) (mm_allocl() * 4096);
for (i = 0; i < 1024; i++)
{
kernel_pd[i] = 0 | 2;
}
//Now, we will init the whole pd w/ 1 pt (1:1 for 0-4mb) and the rest blank
kernel_pd[0] = (mm_allocl() * 4096);
vmm_create_pt1to1(kernel_pd[0], 3, 0);
kernel_pd[0] = kernel_pd[0] | 3;
pt = (unsigned long *) (mm_allocl() * 4096);
for (i = 0; i < 1024; i++)
{
pt[i] = 0 | 2;
}
kernel_pd[128] = pt;
kernel_pd[128] = kernel_pd[128] | 3;
//Map in 2 pages (8k) at 1gb for use later w/ the kernel malloc...
vmm_map(262144,mm_alloc());
vmm_map(262145,mm_alloc());
vmm_set_pd(kernel_pd);
vmm_enable_paging();
}
Code: Select all
int vmm_map(unsigned long virt_page, unsigned long phys_page)
{
int pd_index;
int pt_index;
unsigned long *pt;
pd_index = virt_page / 1024;
kprintf("pd_index = %d\n", pd_index);
pt = (unsigned long *)kernel_pd[pd_index];
if (pt == (unsigned long *)2)
pt = (unsigned long *) vmm_new_pt(); //(mm_allocl() * 4096); create a new page table.
else
pt = (unsigned long *) (kernel_pd[pd_index] & 0xFFFFF000);
pt_index = ((virt_page * 4096) - (pd_index * 0x400000)) / 4096;
kprintf("pt address = %d\n", pt);
kprintf("pt_index = %d\n", pt_index);
kprintf("phys page = %d\n", phys_page * 4096);
pt[pt_index] = (phys_page * 4096) | 3;
kernel_pd[pd_index] = pt;
kernel_pd[pd_index] = kernel_pd[pd_index] | 3;
}
Code: Select all
unsigned long vmm_new_pt()
{
int i;
unsigned long *pt;
pt = (unsigned long *) (kernel_pd[128] & 0xFFFFF000); //Pointer for 512mb PT.
for (i = 0; i < 1024; i++)
{
if (pt[i] == (unsigned long *)2)
{
pt[i] = (unsigned long *) (mm_alloc() * 4096);
pt[i] = pt[i] | 3;
kernel_pd[128] = pt;
kernel_pd[128] = kernel_pd[128] | 3;
kprintf("\nReturning: %d\n", 0x20000000 + (i * 4096));
return (0x20000000 + (i * 4096));
}
}
}
Code: Select all
s1 = (char*)malloc(100);
strcpy(s1,"this is a test001\n\0");
kprintf("%d || %s",s1,s1);
Code: Select all
pt = (unsigned long *) vmm_new_pt(); //(mm_allocl() * 4096);
The issue is the first 4mb is mapped 1:1 and in this case mm_allocl * 4096 returns a value in the first 4mb, so its actually there. What I was trying to do in the vmm_new_pt function is set aside 512m - 516m (virtual) for the page tables. When a request for a new pt would come in, it would alloc a physical buffer and map it somewhere between 512 and 516, then return this 51x address. This way the PT could be placed there in virtual ram.
Big Thanks in Advance.
-Rich