Paging code doesn't work.

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
guest

Paging code doesn't work.

Post by guest »

When I try to run this code in my OS, it gives me a PF when I try to write to 0x80000000. And yes, I tested if SAFE_BASE is 4K aligned.

Code: Select all

//////////////////////////////////////////////////////////////
//   Internal AUX Functions
void KeMapAddress(unsigned long* pagetable, unsigned long* virtaddr, unsigned long* physaddr, unsigned long flags)
{
   unsigned long offset = (unsigned long)virtaddr / 4096 ;
   *(pagetable + offset) = (unsigned long)physaddr | flags;
}

void KeFillPageDirectory(unsigned long* pagedirectory, unsigned long* pagetable, unsigned long dpl)
{
   unsigned long flags;
   if(dpl == 0)
      flags = 3;
   else
      flags = 6;
   unsigned long index = 0;
   for(;index < 1024;index++)
      *(pagedirectory+index) = ( (unsigned long)pagetable + (index * 1024)) | flags;
}

void KeInitPageTable(unsigned long* pagetable)
{
   memset(pagetable, 0, 0x00400000);
}

void KeInitPageDirectory(unsigned long* pagedirectory)
{
   memset(pagedirectory, 0, 0x4000);
}

//////////////////////////////////////////////////////////////////////
//   Exports
void KeCreatePageTable(unsigned long* pagetable, void* usrmem, unsigned long length, 
                  void* usrstack, unsigned long stacklen,
                  void* usrcode, unsigned long codelen,
                  unsigned long dpl)
{
   const unsigned long rwpflag = dpl == 0 ? 3 : 6;
   const unsigned long rpflag = dpl == 0 ? 1 : 5;

   void* virtaddr = 0;
   void* physaddr = 0;
   ////////////////////////////////////////////////////////////////////
   //   
   for(;(unsigned long)virtaddr < (unsigned long)&end; virtaddr+=4096, physaddr+=4096)
      KeMapAddress(pagetable, virtaddr ,physaddr , rwpflag);

   
   for(virtaddr=KePageDirAddr,physaddr=KePageDirAddr;
         (unsigned long)virtaddr < ((unsigned long)KePageTableAddr+0x00100000); virtaddr+=4096, physaddr+=4096)
      KeMapAddress(pagetable, virtaddr, physaddr, dpl == 0 ? rwpflag : rpflag);

   for(virtaddr=KeUsrPageDirAddr,physaddr=KeUsrPageDirAddr;
         (unsigned long)virtaddr < ((unsigned long)KeUsrPageTableAddr+0x00100000); virtaddr += 4096, physaddr+=4096)
      KeMapAddress(pagetable, virtaddr, physaddr, dpl == 0 ? rwpflag : rpflag);

   if(codelen != 0)
      for(virtaddr=(unsigned long*)0x60000000,physaddr = usrcode;
            (unsigned long)virtaddr < (0x60000000+codelen);virtaddr+=4096,physaddr+=4096)
         KeMapAddress(pagetable, virtaddr, physaddr, rpflag);

   if(dpl != 0 && stacklen != 0)
      for(virtaddr=(unsigned long*)0x70000000,physaddr = usrstack ;
         (unsigned long)virtaddr < (0x70000000+stacklen);physaddr+=4096,virtaddr+=4096)
         KeMapAddress(pagetable, virtaddr, physaddr, rwpflag);

   if(length != 0)
      for(virtaddr=(unsigned long*)0x80000000,physaddr = usrmem ;
            (unsigned long)virtaddr < (0x80000000 + length); virtaddr+=4096, physaddr+=4096)
            KeMapAddress(pagetable, virtaddr, physaddr, rwpflag);
}

void KeInitPaging(void)
{

   unsigned long *pagetable = (unsigned long*)PAGETABLEADDR;
   unsigned long *pagedir = (unsigned long*)PAGEDIRADDR;
   KePageTableAddr = (unsigned long*)PAGETABLEADDR;
   KePageDirAddr = (unsigned long*)PAGEDIRADDR;
   KeUsrPageTableAddr = (unsigned long*)USRPAGETABLEADDR;
   KeUsrPageDirAddr = (unsigned long*)USRPAGEDIRADDR;


   KeInitPageTable(pagetable);
   KeInitPageDirectory(pagedir);
   KeCreatePageTable(pagetable,SAFE_BASE,0x02000000,NULL,0,NULL,0,0); 
   KeFillPageDirectory(pagedir,pagetable,0);
   KeWriteCR3((unsigned long)pagedir);
   KeWriteCR0(0x80000000 | KeReadCR0());


   *((unsigned long*)0x80000000) = (unsigned long)SAFE_BASE;
   *((unsigned long*)0x80000004) = 0x02000000;
}   
User avatar
Pype.Clicker
Member
Member
Posts: 5964
Joined: Wed Oct 18, 2006 2:31 am
Location: In a galaxy, far, far away
Contact:

Re:Paging code doesn't work.

Post by Pype.Clicker »

if you're running in bochs or QEMU, you may want to use the "xp /64 0xcafebabe" command (where "cafebabe" is the physical address of pagetables and page directory) to check everything is in place as you expect it to be ...
Post Reply