Пример #1
0
DWORD xmaplineartophysical(const DWORD linearmemory,const DWORD physicalmemory,
   DWORD *pagedir,const DWORD attb) //ATOMIC
    {
     DWORD w=linearmemory;
     DWORD dirindex=(w&0xFFC00000) >> 22;
     DWORD pageindex=(w&0x3FF000) >> 12;
     DWORD *pagetbl;
     DWORD flags;
     dex32_stopints(&flags);
     disablepaging();
     if (pagedir[dirindex]&PG_PRESENT==0) //no page table allocated?
        {
         pagetbl=mempop();
         if (pagetbl==0) {dex32_restoreints(flags);enablepaging();return 0;};
         pagedir[dirindex]=(DWORD)pagetbl | 1;
        };
        
     if (pagedir[dirindex]&1)
      {
       pagetbl=(DWORD*)(pagedir[dirindex]&0xFFFFF000);
       pagetbl[pageindex]=physicalmemory | (attb&0xFFF);
       
       dex32_restoreints(flags);
       enablepaging();
       return 1;
      }
      
     dex32_restoreints(flags);
     enablepaging();
    return 0;
    };
Пример #2
0
/* This function maps the linear address to a physical address:
   The function automatically allocates a page for a page table
   the bottom 12 bits of the linear address is discarded since
   it is not used by the mapper*/
void maplineartophysical(unsigned int *pagedir, /*the location of the page directory*/
                              unsigned int linearaddr, /*the paged aligned linear address requested*/
                              unsigned int physical,   /*the paged aligned physical address to map to*/
									 unsigned int attribute /*used to specify the page attributes to be applied*/
					    )
   {
	  unsigned int pagedirindex,pagetableindex,*pagetable;
	  /*get the index of the page directory and the pagetable respectively*/
	  pagedirindex= linearaddr >> 22;
	  pagetableindex= (linearaddr  & 0x3FFFFF) >> 12;
	  /*get the location of the page table and mask the first 12 bits*/
	  pagetable=(unsigned int*)(pagedir[pagedirindex] & 0xFFFFF000);
	  if (pagetable==0)  /*there is no entry?*/
		     {
				 /*map a new memory location*/
				pagedir[pagedirindex]=(DWORD) mempop();
				pagetable=(unsigned int*)pagedir[pagedirindex];
				/*clear the locations of the page table to zero*/
				memset(pagetable,0,4096);
				/*set the present bit of the pagetable dir entry*/
				pagedir[pagedirindex]=pagedir[pagedirindex] | 1 | PG_USER | PG_WR;

             };
	  physical=(physical & 0xFFFFF000) | attribute;
      pagetable[pagetableindex]=physical;

      /*done!*/


   };
Пример #3
0
void exec(b32 *filename)
{
	b32 pcb_;
	b32 page;
	asm volatile(
			"jmp . \n\t"
			:::
			);
	procpop(&pcb_);
	getpageaddr(PCBAddr,pcb_,0x4c,&page);	//需要pcb块大小
	initpage(page);
	PCB * pcb=(PCB *)pcb_;
	printdword((b32)(pcb));
	pcb->esp=0x13FFFF0;
	pcb->status=READY;
	pcb->cr3=page;
	pcb->pid=(*(b32 *)PID)+4;
	pcb->edi=0;
	pcb->esi=0;
	pcb->ebx=0;
	pcb->edx=0;
	pcb->eflags=0;
	pcb->ss=user_stack;
	pcb->cs=user_code;
	pcb->eip=0;

	*(b32 *)PID=*(b32 *)PID+4;
	b32 phymem;
	filename[11]=0;				//得到格式化后的文件名
	mempop(&phymem);

	readfile(filename,phymem);
	linkpage(pcb->cr3,0x1000000,phymem);
	quenein(READYAddr,READYBottom,READYhead,READYtail,pcb_);
}
Пример #4
0
/*same as map linear to physical except that it does its tricks without
 modifying the paging bit   */
int maplineartophysical2(unsigned int *pagedir, /*the location of the page directory*/
                              unsigned int linearaddr, /*the paged aligned linear address requested*/
                              unsigned int physical,   /*the paged aligned physical address to map to*/
									 unsigned int attribute /*used to specify the page attributes to be applied*/
					    )
   {
	  unsigned int pagedirindex,pagetableindex,*pagetable;
      DWORD pg;
      DWORD *kicker=(DWORD*)SYS_PAGEDIR2_VIR;
      
	  /*get the index of the page directory and the pagetable respectively*/
	  pagedirindex= linearaddr >> 22;
	  pagetableindex= (linearaddr  & 0x3FFFFF) >> 12;
	  
	  /*get the location of the page table and mask the first 12 bits*/
	  pg=(pagedir[pagedirindex] & 0xFFFFF000);
	  
	  if (pg==0)  /*there is no entry?*/
		     {
				 /*map a new memory location*/
				pagedir[pagedirindex]=(DWORD) mempop();
                kicker[4]=(pagedir[pagedirindex]&0xFFFFF000) | 1;
                
                refreshpages();
                
                pagetable=(DWORD*)SYS_PAGEDIR4_VIR;

                tlb_address = pagetable;
                invtlb();                
				/*clear the locations of the page table to zero*/
				memset(pagetable,0,4096);
				/*set the present bit of the pagetable dir entry*/
				pagedir[pagedirindex] = pagedir[pagedirindex] | 1 | PG_USER | PG_WR;
				refreshpages();
				
				pg = (pagedir[pagedirindex] & 0xFFFFF000);
             };
             
    kicker[4]=pg | 1;
    refreshpages();
        

    pagetable=(DWORD*)SYS_PAGEDIR4_VIR;

    physical = (physical & 0xFFFFF000) | attribute;
    pagetable[pagetableindex]=physical;

    refreshpages();
    
    tlb_address = linearaddr;
    invtlb();
    
    /*done!*/
   };
Пример #5
0
//duplicates a process using COPY_ON_WRITE methods *NOT YET WORKING!!*
DWORD forkprocess(PCB386 *parent)
{
    int pages;
    DWORD *pagedir,pg,flags;
    DWORD parentpd = parent->pagedirloc;
    PCB386 *pcb = (PCB386*) malloc(sizeof(PCB386));
    
#ifdef DEBUG_FORK
    printf("fork process has been called.\n");
#endif

    dex32_stopints(&flags);
    memcpy(pcb,parent,sizeof(PCB386));
    strcat(pcb->name,".fork");
    totalprocesses++;
    pcb->size       = sizeof(PCB386);
    pcb->processid  = nextprocessid++;
    pcb->owner      = parent->processid;

    /*Allocate a new page directory*/
    pagedir=(DWORD*)mempop(); //obtain a physical address from the memory manager
    pg=(DWORD*)getvirtaddress((DWORD)pagedir); //convert physical address to a virtual address
    //initialize the new pagedirectory
    memset(pg,0,0x1000);

    pcb->regs.CR3   = pagedir;
    pcb->pagedirloc = pagedir;

#ifdef DEBUG_FORK
    printf("copying memory..\n");
#endif

    disablepaging();
    dex32_copy_pg(pagedir,parentpd);
    maplineartophysical((DWORD*)pagedir,(DWORD)SYS_PAGEDIR_VIR,(DWORD)pagedir    /*,stackbase*/,1);
    maplineartophysical((DWORD*)pagedir,(DWORD)SYS_PAGEDIR2_VIR,
    (DWORD)pagedir[SYS_PAGEDIR_VIR >> 22]&0xFFFFF000,1);
    maplineartophysical((DWORD*)pagedir,(DWORD)SYS_PAGEDIR3_VIR,
    (DWORD)pagedir[SYS_PAGEDIR_VIR >> 22]&0xFFFFF000,1);
    maplineartophysical((DWORD*)pagedir,(DWORD)SYS_KERPDIR_VIR,(DWORD)pagedir1    /*,stackbase*/,1);
    enablepaging();
    
#ifdef DEBUG_FORK
    printf("done. adding to process queue\n");
#endif

    //copies the memory allocation information of the parent to the child
    //(forked processes have the same virtual memory map at time of fork)
    copyprocessmemory(parent->meminfo,&pcb->meminfo);

    //add to the process list
    ps_enqueue(pcb);

    dex32_restoreints(flags);
    
#ifdef DEBUG_FORK
    printf("fork done.\n");
#endif

    return pcb->processid;
};
Пример #6
0
void *
memalloc(size_t nb, long flg)
{
    struct mempool  *physpool = &memphyspool;
    struct mempool  *virtpool = &memvirtpool;
    struct memmag  **magtab = (struct maghdr **)virtpool->tab;
    void            *ptr = NULL;
    size_t           sz = max(MEMMIN, nb);
    size_t           bsz;
    unsigned long    slab = 0;
    unsigned long    bkt = memcalcbkt(sz);
#if defined(MEMPARANOIA)
    unsigned long   *bmap;
#endif
    struct memmag   *mag;
    uint8_t         *u8ptr;
    unsigned long    ndx;
    unsigned long    n;
    struct membkt   *hdr = &virtpool->tab[bkt];

    mtxlk(&hdr->lk);
    if (bkt >= MEMSLABMINLOG2) {
        ptr = slaballoc(physpool, sz, flg);
        if (ptr) {
#if (!MEMTEST)
            vminitvirt(&_pagetab, ptr, sz, flg);
#endif
            slab++;
            mag = memgetmag(ptr, virtpool);
            mag->base = (uintptr_t)ptr;
            mag->n = 1;
            mag->ndx = 1;
            mag->bkt = bkt;
            mag->prev = NULL;
            mag->next = NULL;
        }
    } else {
        mag = magtab[bkt];
        if (mag) {
            ptr = mempop(mag);
            if (memmagempty(mag)) {
                if (mag->next) {
                    mag->next->prev = NULL;
                }
                magtab[bkt] = mag->next;
            }
        } else {
            ptr = slaballoc(physpool, sz, flg);
            if (ptr) {
#if (!MEMTEST)
                vminitvirt(&_pagetab, ptr, sz, flg);
#endif
                u8ptr = ptr;
                slab++;
                bsz = (uintptr_t)1 << bkt;
                n = (uintptr_t)1 << (MEMSLABMINLOG2 - bkt);
                mag = memgetmag(ptr, virtpool);
                mag->base = (uintptr_t)ptr;
                mag->n = n;
                mag->ndx = 1;
                mag->bkt = bkt;
                for (ndx = 1 ; ndx < n ; ndx++) {
                    u8ptr += sz;
                    mag->ptab[ndx] = u8ptr;
                }
                mag->prev = NULL;
                mag->next = NULL;
                if (n > 1) {
                    mag->next = magtab[bkt];
                    magtab[bkt] = mag;
                }
            }
        }
    }
    if (ptr) {
#if defined(MEMPARANOIA)
#if ((MEMSLABMINLOG2 - MEMMINLOG2) < (LONGSIZELOG2 + 3))
        bmap = &mag->bmap;
#else
        bmap = mag->bmap;
#endif
        ndx = ((uintptr_t)ptr - mag->base) >> bkt;
        if (bitset(bmap, ndx)) {
            kprintf("duplicate allocation %p (%ld/%ld)\n",
                    ptr, ndx, mag->n);

            panic(k_curproc->pid, TRAPNONE, -EINVAL);
        }
        setbit(bmap, ndx);
#endif /* defined(MEMPARANOIA) */
        if (!slab && (flg & MEMZERO)) {
            kbzero(ptr, 1UL << bkt);
        }
    }
    if (!ptr) {
        panic(k_curproc->pid, TRAPNONE, -ENOMEM);
    }
    mtxunlk(&hdr->lk);

    return ptr;
}
Пример #7
0
int coff_loadusermodule(
        char *module_name, //the name of the module
        char *coff_image,  //the location of the pe image
        DWORD base, //the desired base address to load the image so
                    //that dex can perform the necessary relocations
        int mode,   //Determines what kind of executable to load
        char *p,    //the parameters
        char *workdir,
        PCB386 *parent //the parent PCB for EXEs, the parent pagedirectory for DLLs
        ) //location of image to load
{
char temp[255],temp2[255];
FILHDR  *fhdr = (FILHDR*) coff_image;

 //a linked list used to keep track of the virtual addresses used
 //by this process so that it could be freed when the process
 //terminates
 process_mem *tmpr,*memptr;
 
 
//validate if this file is a coff format executable
#ifdef DEBUG_COFF
printf("dex32_coff_loader: started\n");
printf("dex32_coff_loader: magic number obtained [%s]\n",itoa(fhdr->f_magic,temp,16));
#endif

if (fhdr->f_magic==I386MAGIC)
  {
  	int i;
  	AOUTHDR *aouthdr = (AOUTHDR*)(coff_image + sizeof(FILHDR));
        SCNHDR  *section = (SCNHDR*)((DWORD)coff_image + sizeof(FILHDR)+sizeof(AOUTHDR));
        SYMENT  *symbols = fhdr->f_symptr;
        int totalsymbols = fhdr->f_nsyms;
        
  	DWORD *pagedir,*pg;
  	DWORD heapres=0,stackres=0;
  	DWORD *stackloc;
  	DWORD flags,pages,ret;
  	int totalsections = fhdr->f_nscns;
  	
        void (*entrypoint)(int,char**)=0;
        
	#ifdef DEBUG_COFF
		printf("dex32_coff_loader: magic number 2 obtained [%s]\n",itoa(aouthdr->magic,temp,16));
	#endif
	
	if (aouthdr->magic!=ZMAGIC) return 0; //check again
	printf("dex32_coff_loader: loading executable..\n");

	#ifdef DEBUG_COFF
		printf("dex32_coff_loader: entry point at %sH\n",itoa(aouthdr->entry,temp,16));
		printf("dex32_coff_loader: Total sections %d\n",totalsections);
	#endif

	entrypoint=(void*) aouthdr->entry;
	
	if (fhdr->f_flags&F_RELFLG)
	   {
	   	printf("dex32_coff_loader: Relocations have been stripped of the file\n");
	   };
	
	
	memptr=(process_mem*)malloc(sizeof(process_mem));
   	tmpr=memptr;
   	
   	pagedir=(DWORD*)mempop(); //obtain a physical address from the memory manager
        pg=(DWORD*)getvirtaddress((DWORD)pagedir); //convert to a virtual address so that
                                                          //we could use it here without disabling
                                                          //the paging mechanism of the 386

         //initialize the new pagedirectory
         memset(pg,0,0x1000);
        
         stackloc=(DWORD*)dex32_commitblock((DWORD)userstackloc-1000,
               1000,&pages,
               pagedir,PG_WR | PG_USER | PG_PRESENT);

               //take note of this so that we could free it later
               tmpr->vaddr=(DWORD)stackloc;
               tmpr->pages=pages;
               tmpr->next=(process_mem*)malloc(sizeof(process_mem));
               tmpr=tmpr->next;
               tmpr->vaddr=0;tmpr->next=0;


               //allocate the "reserve" user stack
               //this pages don't get a physical memory until it actually gets
               //accessed

               stackres=dex32_reserveblock((DWORD)stackloc-DEFAULT_STACKSIZE,
               DEFAULT_STACKSIZE,&pages,pagedir,PG_WR);

               //store the allocation information so that it could be linked to
               //the process PCB and then be able to free up the memory when app terminates
               tmpr->vaddr=(DWORD)stackres;
               tmpr->pages=pages;

               //create another node in the linked list
               tmpr->next=(process_mem*)malloc(sizeof(process_mem));
               tmpr=tmpr->next;
               tmpr->vaddr=0;tmpr->next=0;

               //calculate the position of the ESP pointer
               stackloc = userstackloc - 4 ;

               //allocate "commited" user heap
               //unlike the stack, this one goes up
               dex32_commitblock((DWORD)userheap,1000,&pages,
                        pagedir,PG_WR | PG_USER | PG_PRESENT);

               //take note of this, so that it wouldn't cause a memory leak later
               tmpr->vaddr=(DWORD)userheap;
               tmpr->pages=pages;
               tmpr->next=(process_mem*)malloc(sizeof(process_mem));
               tmpr=tmpr->next;
               tmpr->vaddr=0;tmpr->next=0;

               //calculate the position of the reserved heap
               heapres=userheap+(pages*0x1000);

               //allocate "reserved" user heap
               dex32_reserveblock((DWORD)heapres,
                      DEFAULT_HEAPSIZE,&pages,pagedir,PG_WR );


               tmpr->vaddr=(DWORD)heapres;
               tmpr->pages=pages;
               tmpr->next=(process_mem*)malloc(sizeof(process_mem));
               tmpr=tmpr->next;
               tmpr->vaddr=0;tmpr->next=0;

   	
	//examine the sections
	for (i=0;i<totalsections;i++)
		{
			
			int i2;
			char section_name[256];
			DWORD rawdata, vaddr,size,pages,relnum;
			RELOC *relocation;
			
			/* copy the name of the section to a temporary vriable */
			for (i2=0; section[i].s_name[i2]&&i2<8;i2++)
			{
				section_name[i2] = section[i].s_name[i2];
			};
			
			section_name[i2]=0; /*null terminator*/
			
			rawdata = section[i].s_scnptr;           //pointer to raw data in file
			vaddr   = section[i].s_vaddr;            //absolute address in memory
			size    = section[i].s_size;             //size of the section
			relocation = (RELOC*)section[i].s_relptr;  //relocation pointer
			relnum = section[i].s_nreloc;            //number of relocations
			
			#ifdef DEBUG_COFF
				printf("dex32_coff_loader: Section name   [%s]\n",section_name);
				printf("dex32_coff_loader: ** file offset [%d]\n",rawdata);
				printf("dex32_coff_loader: ** load at     [%sH]\n",itoa(vaddr,temp,16));
			#endif
                        
                        /*perform relocations*/
                        for (i2=0;i2<relnum;i2++)
                        {
                        	if (relocation[i2].r_type==RELOC_ADDR32)
                        	{
					DWORD *loc=symbols[relocation[i2].r_symndx].e_value;
                                        printf("dex32_coff_loader: ABSOLUTE RELOCATION Detected\n");
                        	}
                        	else
                        	if (relocation[i2].r_type==RELOC_REL32)
                        	{
                        		printf("dex32_coff_loader: RELATIVE RELOCATION Detected\n");
                        	}
                        	else
                        	printf("dex32_coff_loader: UNKNOWN RELOCATION TYPE\n");
                        	
                	};
                        
                        
                        /*allocate physical memory and assign a virtual address*/
                        #ifdef DEBUG_COFF                        
                        	printf("dex32_coff_loader: Commiting block..\n");
                        #endif
			tmpr->vaddr=(DWORD)dex32_commitblock((DWORD)base+vaddr,size,&pages,
               		pagedir,PG_WR | PG_USER | PG_PRESENT);
               		
               		#ifdef DEBUG_COFF
               			printf("dex32_coff_loader: Copying image at %s to %s..\n",
               			itoa(coff_image+rawdata,temp2,16),itoa(tmpr->vaddr,temp,16));
               		#endif
               		//copy the section to main memory			
  			memcpy(tmpr->vaddr,coff_image+rawdata,size);
 			
 			#ifdef DEBUG_COFF
 				printf("dex32_coff_loader: ***Done***\n");
 			#endif
 			//take note of the memory used so that we could free it up later
                        tmpr->pages=pages;
                        tmpr->next=(process_mem*)malloc(sizeof(process_mem));
                        tmpr=tmpr->next;
                        tmpr->vaddr=0;tmpr->next=0;
                                             
			
		};
		
	     
             dex32_stopints(&flags);
             
             
             ret=createprocess(entrypoint,module_name,pagedir,memptr,stackloc,
             1000,0x2000,signal,p,workdir,parent);
             dex32_restoreints(flags);
             dex32_freeuserpagetable(pagedir1);
             
	return ret; 
  };
return 0; //not a coff file or error loading file
};