Пример #1
0
/* dccvmm_read retorna a palavra de 32-bits apontada pelo endereco virtual
 * address na tabela de paginas atual. 
 * OU SEJA, dccvmm_read devolve a entrada da tabela de paginas apontada pelo endereço virtual address
 * OU SEJA, dccvmm_read vai na tabela de pagina, no endereco apontado por address e devolve o frame daquela pagina (16 bits)
 
 */
uint32_t dccvmm_read(uint32_t address) {

	//printf("\n\n(RETIRAR ESTE PRINT) Entrando na função \"dccvmm_read\"\n");
	//printf("(RETIRAR ESTE PRINT) address: %X\n", address);
    uint32_t perms = PTE_RW | PTE_INMEM | PTE_VALID; 
    /* A operação acima eh uma combinação de:
     * PTE_RW    0x00800000  o quadro apontado pelo pte tem permissao de leitura e escrita
     * PTE_VALID 0x00100000  o endereco virtual foi alocado pelo processo
     * PTE_INMEM 0x00400000  o quadro apontado pelo pte esta na memoria
     * resultado 0x00D00000 ou seja, a permissao eh de leitura e escrita + é do processo + está na memória
     */
    
    /*PTE1OFF(address) = Separa os bitos 23 a 16 de address e os coloca na posição 7 a 0
    dccvmm_get_pte(uint32_t frame, uint8_t ptenum, uint32_t perms, uint32_t address)
     */
     
    //printf("(RETIRAR ESTE PRINT) __pagetable: 0x%X\n", __pagetable);
    //printf("(RETIRAR ESTE PRINT) PTE1OFF(address): %X\n", PTE1OFF(address));
    //printf("(RETIRAR ESTE PRINT) perms: 0x%X\n", perms);
    uint32_t pte1 = dccvmm_get_pte(__pagetable, PTE1OFF(address), perms, address);
    if (pte1 == VM_ABORT) return 0;
    uint32_t pte1frame = PTEFRAME(pte1); /*Separa os 12 bits menos significativos de pte1*/ 
    
    /*PTE2OFF(address) = Separa os bitos 15 a 8 de address e os coloca na posição 7 a 0
    dccvmm_get_pte(uint32_t frame, uint8_t ptenum, uint32_t perms, uint32_t address)
     */
    uint32_t pte2 = dccvmm_get_pte(pte1frame, PTE2OFF(address), perms, address);
    if (pte2 == VM_ABORT) return 0;
    uint32_t pte2frame = PTEFRAME(pte2); /*Separa os 12 bits menos significativos de pte2*/ 
    uint32_t data = __frames[pte2frame].words[PAGEOFFSET(address)]; /*Separa os bitos 7 a 0 de address*/
    printf("vmm %x phy %x read %x\n", address,
            (pte2frame << 8) + PAGEOFFSET(address), data); /*Separa os bitos 7 a 0 de address*/
    return data;
}
Пример #2
0
/* fetch the pages addr resides in into pg and initialise sg with them */
int __get_userbuf(uint8_t __user *addr, uint32_t len, int write,
		unsigned int pgcount, struct page **pg, struct scatterlist *sg,
		struct task_struct *task, struct mm_struct *mm)
{
	int ret, pglen, i = 0;
	struct scatterlist *sgp;

	if (unlikely(!pgcount || !len || !addr)) {
		sg_mark_end(sg);
		return 0;
	}

	down_read(&mm->mmap_sem);
	ret = get_user_pages(task, mm,
			(unsigned long)addr, pgcount, write, 0, pg, NULL);
	up_read(&mm->mmap_sem);
	if (ret != pgcount)
		return -EINVAL;

	sg_init_table(sg, pgcount);

	pglen = min((ptrdiff_t)(PAGE_SIZE - PAGEOFFSET(addr)), (ptrdiff_t)len);
	sg_set_page(sg, pg[i++], pglen, PAGEOFFSET(addr));

	len -= pglen;
	for (sgp = sg_next(sg); len; sgp = sg_next(sgp)) {
		pglen = min((uint32_t)PAGE_SIZE, len);
		sg_set_page(sgp, pg[i++], pglen, 0);
		len -= pglen;
	}
	sg_mark_end(sg_last(sg, pgcount));
	return 0;
}
Пример #3
0
void os_alloc(uint32_t addr) {
    //search for a free frame
    if (PAGEOFFSET(addr)) {
        // offset must be *00;
        fprintf(stderr, "Invalid Alloc on address :[%x]\n", addr);
        return;
    }
    uint32_t dir, dirFrame, pt, ptFrame;
    //make page table point to the found frame
    dir = dccvmm_phy_read(procTable_ << 8 | currentPID_);
    dirFrame = PTEFRAME(dir);
    pt = dccvmm_phy_read(
            dirFrame << 8 | PTE1OFF(addr));
    ptFrame = PTEFRAME(pt);
    if ((pt & PTE_VALID) != PTE_VALID) {
        //pointed frame is not a valid frame 
        ptFrame = getFreeFrame();
        dccvmm_phy_write(dirFrame << 8 | PTE1OFF(addr),
                ptFrame | PTE_VALID | PTE_INMEM | PTE_RW);
    }

    if (dccvmm_phy_read(ptFrame << 8 | PTE2OFF(addr)) & PTE_VALID) {
        fprintf(stderr, "\tDouble Alloc Detected\n");
        return;
    }
    uint32_t freeFrame = getFreeFrame();
    // frame is not avaliable anymore;    
    //write on the page table the allocated Frame
    dccvmm_phy_write(ptFrame << 8 | PTE2OFF(addr),
            freeFrame | PTE_VALID | PTE_INMEM | PTE_RW);
}
Пример #4
0
    dccvmm_get_pte(uint32_t frame, uint8_t ptenum, uint32_t perms, uint32_t address)
     */
    uint32_t pte2 = dccvmm_get_pte(pte1frame, PTE2OFF(address), perms, address);
    if (pte2 == VM_ABORT) return 0;
    uint32_t pte2frame = PTEFRAME(pte2); /*Separa os 12 bits menos significativos de pte2*/ 
    uint32_t data = __frames[pte2frame].words[PAGEOFFSET(address)]; /*Separa os bitos 7 a 0 de address*/
    printf("vmm %x phy %x read %x\n", address,
            (pte2frame << 8) + PAGEOFFSET(address), data); /*Separa os bitos 7 a 0 de address*/
    return data;
}

/* dccvmm_phy_read retorna a palavra de 32-bits apontada pelo endereco
 * fisico phyaddr, transpassando o sistema de memoria */
uint32_t dccvmm_phy_read(uint32_t phyaddr) {
    assert((phyaddr >> 8) < NUMFRAMES);
    uint32_t data = __frames[phyaddr >> 8].words[PAGEOFFSET(phyaddr)];
    printf("vmm phy %x read %x\n", phyaddr, data);
    return data;
}

/* dccvmm_write escreve data na palavra de 32-bits apontada pelo endereco
 * virtual address na tabela de paginas atual. */
void dccvmm_write(uint32_t address, uint32_t data) {
	//printf("\n\n(RETIRAR ESTE PRINT) Entrando na função \"dccvmm_write\"\n");
    uint32_t perms = PTE_RW | PTE_INMEM | PTE_VALID;
    uint32_t pte1 = dccvmm_get_pte(__pagetable, PTE1OFF(address), perms, address);
    if (pte1 == VM_ABORT) return;
    uint32_t pte1frame = PTEFRAME(pte1);
    uint32_t pte2 = dccvmm_get_pte(pte1frame, PTE2OFF(address), perms, address);
    if (pte2 == VM_ABORT) return;
    uint32_t pte2frame = PTEFRAME(pte2);
Пример #5
0
/*
 * Translate a virtual address to a physical address by using 4 levels paging.
 */
unsigned long long
vtop4_x86_64(unsigned long vaddr)
{
	unsigned long page_dir, pml4, pgd_paddr, pgd_pte, pmd_paddr, pmd_pte;
	unsigned long pte_paddr, pte;

	if (SYMBOL(init_level4_pgt) == NOT_FOUND_SYMBOL) {
		ERRMSG("Can't get the symbol of init_level4_pgt.\n");
		return NOT_PADDR;
	}

	/*
	 * Get PGD.
	 */
	page_dir  = SYMBOL(init_level4_pgt);
	page_dir += pml4_index(vaddr) * sizeof(unsigned long);
	if (!readmem(VADDR, page_dir, &pml4, sizeof pml4)) {
		ERRMSG("Can't get pml4 (page_dir:%lx).\n", page_dir);
		return NOT_PADDR;
	}
	if (info->vaddr_for_vtop == vaddr)
		MSG("  PGD : %16lx => %16lx\n", page_dir, pml4);

	if (!(pml4 & _PAGE_PRESENT)) {
		ERRMSG("Can't get a valid pml4.\n");
		return NOT_PADDR;
	}

	/*
	 * Get PUD.
	 */
	pgd_paddr  = pml4 & PHYSICAL_PAGE_MASK;
	pgd_paddr += pgd_index(vaddr) * sizeof(unsigned long);
	if (!readmem(PADDR, pgd_paddr, &pgd_pte, sizeof pgd_pte)) {
		ERRMSG("Can't get pgd_pte (pgd_paddr:%lx).\n", pgd_paddr);
		return NOT_PADDR;
	}
	if (info->vaddr_for_vtop == vaddr)
		MSG("  PUD : %16lx => %16lx\n", pgd_paddr, pgd_pte);

	if (!(pgd_pte & _PAGE_PRESENT)) {
		ERRMSG("Can't get a valid pgd_pte.\n");
		return NOT_PADDR;
	}

	/*
	 * Get PMD.
	 */
	pmd_paddr  = pgd_pte & PHYSICAL_PAGE_MASK;
	pmd_paddr += pmd_index(vaddr) * sizeof(unsigned long);
	if (!readmem(PADDR, pmd_paddr, &pmd_pte, sizeof pmd_pte)) {
		ERRMSG("Can't get pmd_pte (pmd_paddr:%lx).\n", pmd_paddr);
		return NOT_PADDR;
	}
	if (info->vaddr_for_vtop == vaddr)
		MSG("  PMD : %16lx => %16lx\n", pmd_paddr, pmd_pte);

	if (!(pmd_pte & _PAGE_PRESENT)) {
		ERRMSG("Can't get a valid pmd_pte.\n");
		return NOT_PADDR;
	}
	if (pmd_pte & _PAGE_PSE)
		return (PAGEBASE(pmd_pte) & PHYSICAL_PAGE_MASK)
			+ (vaddr & ~_2MB_PAGE_MASK);

	/*
	 * Get PTE.
	 */
	pte_paddr  = pmd_pte & PHYSICAL_PAGE_MASK;
	pte_paddr += pte_index(vaddr) * sizeof(unsigned long);
	if (!readmem(PADDR, pte_paddr, &pte, sizeof pte)) {
		ERRMSG("Can't get pte (pte_paddr:%lx).\n", pte_paddr);
		return NOT_PADDR;
	}
	if (info->vaddr_for_vtop == vaddr)
		MSG("  PTE : %16lx => %16lx\n", pte_paddr, pte);

	if (!(pte & _PAGE_PRESENT)) {
		ERRMSG("Can't get a valid pte.\n");
		return NOT_PADDR;
	}
	return (PAGEBASE(pte) & PHYSICAL_PAGE_MASK) + PAGEOFFSET(vaddr);
}
Пример #6
0
static void
init_ram_segments(void)
{
	int i, errflag;
        FILE *iomem; 
	char buf[BUFSIZE], *p1, *p2;
	physaddr_t start, end;

	if ((iomem = fopen("/proc/iomem", "r")) == NULL)
		goto fail_iomem;

	while (fgets(buf, BUFSIZE, iomem)) {
		if (strstr(buf, "System RAM")) {
			console(buf);
			nr_segments++;
		}
	}
	if (!nr_segments)
		goto fail_iomem;

	ram_segments = (struct ram_segments *)
		GETBUF(sizeof(struct ram_segments) * nr_segments);

	rewind(iomem);
	i = 0;
	while (fgets(buf, BUFSIZE, iomem)) {
		if (strstr(buf, "System RAM")) {
			if (!(p1 = strstr(buf, ":")))
				goto fail_iomem;
			*p1 = NULLCHAR;
			clean_line(buf);
			if (strstr(buf, " "))
				goto fail_iomem;
			p1 = buf;
			if (!(p2 = strstr(buf, "-")))
				goto fail_iomem;
			*p2 = NULLCHAR;
			p2++;
			errflag = 0;
			start = htoll(p1, RETURN_ON_ERROR|QUIET, &errflag);
			end = htoll(p2, RETURN_ON_ERROR|QUIET, &errflag);
			if (errflag)
				goto fail_iomem;
			ram_segments[i].start = PHYSPAGEBASE(start);
			if (PAGEOFFSET(start))
				ram_segments[i].start += PAGESIZE();
			ram_segments[i].end = PHYSPAGEBASE(end);
			if (PAGEOFFSET(end) == (PAGESIZE()-1))
				ram_segments[i].end += PAGESIZE();
			console("ram_segments[%d]: %016llx %016llx [%s-%s]\n", i,
				(ulonglong)ram_segments[i].start, 
				(ulonglong)ram_segments[i].end, p1, p2);
			i++;
		}
	}

	fclose(iomem);
	return;

fail_iomem:
	fclose(iomem);
	nr_segments = 0;
	if (ram_segments)
		FREEBUF(ram_segments);

	return; 
}