From 4bbe08d8f5ce811936623328393748c726ed0e3f Mon Sep 17 00:00:00 2001 From: Mathieu Maret Date: Wed, 14 Nov 2018 14:28:06 +0100 Subject: [PATCH] Add count for allocated and mapped page --- core/mem.c | 16 ++++++++-- core/mem.h | 1 + core/paging.c | 87 +++++++++++++++++++++++++++++---------------------- core/paging.h | 1 + 4 files changed, 64 insertions(+), 41 deletions(-) diff --git a/core/mem.c b/core/mem.c index b57d432..5c95d5c 100644 --- a/core/mem.c +++ b/core/mem.c @@ -9,7 +9,9 @@ static struct mem_desc *used_page; static unsigned long bottom_mem; static unsigned long top_mem; -int memSetup(paddr_t upperMem, paddr_t * lastUsedOut) +static unsigned long allocatedPage = 0; + +int memSetup(paddr_t upperMem, paddr_t *lastUsedOut) { // Align upper mem (in kB) on page size even if it does loose a page upperMem = ALIGN_DOWN(upperMem, PAGE_SIZE / 1024); @@ -22,9 +24,9 @@ int memSetup(paddr_t upperMem, paddr_t * lastUsedOut) uint lastUsed = (memdesc_end >> PAGE_SHIFT) + 1; list_init(free_page); list_init(used_page); - bottom_mem = lastUsed; + bottom_mem = lastUsed; *lastUsedOut = memdesc_end; - top_mem = upperMem * 1024; + top_mem = upperMem * 1024; for (uint i = 0; i < (upperMem / (PAGE_SIZE / 1024)); i++) { struct mem_desc *mem = &page_desc[i]; if (i < lastUsed) { @@ -56,6 +58,7 @@ paddr_t allocPhyPage(void) struct mem_desc *mem = list_pop_head(free_page); mem->ref = 1; list_add_tail(used_page, mem); + allocatedPage++; return mem->phy_addr; } @@ -67,6 +70,7 @@ int unrefPhyPage(paddr_t addr) } mem->ref--; if (mem->ref == 0) { + allocatedPage--; list_delete(used_page, mem); list_add_tail(free_page, mem); } @@ -82,9 +86,15 @@ int refPhyPage(paddr_t addr) } mem->ref++; if (mem->ref == 1) { + allocatedPage++; list_add_tail(used_page, mem); list_delete(free_page, mem); } return 0; } + +unsigned long getNbAllocatedPage(void) +{ + return allocatedPage; +} diff --git a/core/mem.h b/core/mem.h index 900224b..fb8844b 100644 --- a/core/mem.h +++ b/core/mem.h @@ -21,3 +21,4 @@ int memSetup(paddr_t upperMem, paddr_t *lastUsed); paddr_t allocPhyPage(void); int unrefPhyPage(paddr_t addr); int refPhyPage(paddr_t addr); +unsigned long getNbAllocatedPage(void); diff --git a/core/paging.c b/core/paging.c index c1b4234..2b19d45 100644 --- a/core/paging.c +++ b/core/paging.c @@ -1,26 +1,31 @@ -#include "klibc.h" -#include "errno.h" -#include "mem.h" #include "paging.h" +#include "errno.h" +#include "klibc.h" +#include "mem.h" #include "stdarg.h" #include "vga.h" -// In a Vaddr, 10 first bit (MSB) are the index in the Page Directory. A Page Directory Entry point to a Page Table. -// The 10 next bits are then an index in this Page Table. A Page Table Entry then point to a physical address at which is added the remaining 12 bits. -// So they are 1024 entry in the PD, each of them pointing to a PT of 1024 entry. Each PTE pointing to 4K page. -// First address (up to page_desc from mem.c) are mapped such as Paddr == Vaddr. -// To make PD always accessible a (x86?) trick is used : The mirroring. A given entry N in the PD point to the PD (this is possible because PDE very looks like PTE in x86). -// So N << (10 + 12 = 4Mo) point to the Paddr of PD. Then, accessing N * 4Mo + I * 4Ko is accessing the PT of the Ieme entry in the PD (as MMU take the PD pointed by the PDE number N like a PT). -// More particularly, accessing N * 4Mo + N * 4ko is accessing the PD. +// In a Vaddr, 10 first bit (MSB) are the index in the Page Directory. A Page Directory Entry +// point to a Page Table. The 10 next bits are then an index in this Page Table. A Page Table +// Entry then point to a physical address at which is added the remaining 12 bits. So they are +// 1024 entry in the PD, each of them pointing to a PT of 1024 entry. Each PTE pointing to 4K +// page. First address (up to page_desc from mem.c) are mapped such as Paddr == Vaddr. To make +// PD always accessible a (x86?) trick is used : The mirroring. A given entry N in the PD point +// to the PD (this is possible because PDE very looks like PTE in x86). So N << (10 + 12 = 4Mo) +// point to the Paddr of PD. Then, accessing N * 4Mo + I * 4Ko is accessing the PT of the Ieme +// entry in the PD (as MMU take the PD pointed by the PDE number N like a PT). More +// particularly, accessing N * 4Mo + N * 4ko is accessing the PD. // // PD is at Vaddr N * 4Mo and take 4ko. Each PT are allocated dynamically. // Just make sure that N have not been used by identity mapping #define PT_SHIFT 12 -#define PTE_MASK 0x3ff //10bits +#define PTE_MASK 0x3ff // 10bits #define PD_SHIFT 22 #define PD_MIRROR_PAGE_IDX 1023U +static unsigned long mappedPage = 0; + struct pde { uint32_t present : 1; uint32_t write : 1; // 0 read - 1 RW @@ -61,7 +66,6 @@ struct pdbr { uint32_t pd_paddr : 20; } __attribute__((packed)); - // invalidate the TLB entry for the page located at the given virtual address static inline void __native_flush_tlb_single(unsigned long addr) { @@ -84,9 +88,9 @@ int pagingSetup(paddr_t upperKernelAddr) // Identity mapping up to upperKernelAddr for (paddr_t i = 0; i < upperKernelAddr; i += PAGE_SIZE) { uint pdEntry = i >> (PD_SHIFT); - uint ptEntry = (i >> PT_SHIFT ) & PTE_MASK; + uint ptEntry = (i >> PT_SHIFT) & PTE_MASK; struct pte *pt; - if (pd[pdEntry].present){ + if (pd[pdEntry].present) { pt = (struct pte *)(pd[pdEntry].pt_addr << PT_SHIFT); refPhyPage((paddr_t)pt); } else { @@ -94,31 +98,31 @@ int pagingSetup(paddr_t upperKernelAddr) memset(pt, 0, PAGE_SIZE); pd[pdEntry].present = 1; - pd[pdEntry].write = 1; - pd[pdEntry].pt_addr = ((paddr_t)pt >> PT_SHIFT); + pd[pdEntry].write = 1; + pd[pdEntry].pt_addr = ((paddr_t)pt >> PT_SHIFT); } pt[ptEntry].present = 1; - pt[ptEntry].write = 1; //TODO set Kernel code as RO + pt[ptEntry].write = 1; // TODO set Kernel code as RO pt[ptEntry].paddr = i >> PAGE_SHIFT; } // Setup mirroring pd[PD_MIRROR_PAGE_IDX].present = 1; - pd[PD_MIRROR_PAGE_IDX].write = 1; + pd[PD_MIRROR_PAGE_IDX].write = 1; pd[PD_MIRROR_PAGE_IDX].pt_addr = ((paddr_t)pd >> PT_SHIFT); - // Loading of the PDBR in the MMU: - asm volatile ("movl %0,%%cr3\n\t" - "movl %%cr0,%%eax\n\t" - "orl $0x80010000, %%eax\n\t" /* bit 31 | bit 16 */ - "movl %%eax,%%cr0\n\t" - "jmp 1f\n\t" - "1:\n\t" - "movl $2f, %%eax\n\t" - "jmp *%%eax\n\t" - "2:\n\t" ::"r"(cr3):"memory","eax"); + asm volatile("movl %0,%%cr3\n\t" + "movl %%cr0,%%eax\n\t" + "orl $0x80010000, %%eax\n\t" /* bit 31 | bit 16 */ + "movl %%eax,%%cr0\n\t" + "jmp 1f\n\t" + "1:\n\t" + "movl $2f, %%eax\n\t" + "jmp *%%eax\n\t" + "2:\n\t" ::"r"(cr3) + : "memory", "eax"); return 0; } @@ -128,19 +132,20 @@ int pageMap(vaddr_t vaddr, paddr_t paddr, int flags) uint ptEntry = (vaddr >> PT_SHIFT) & PTE_MASK; // Thank to mirroring, we can access the PD - struct pde *pd = - (struct pde *)((PD_MIRROR_PAGE_IDX << 22) + (PD_MIRROR_PAGE_IDX << 12)); + struct pde *pd = (struct pde *)((PD_MIRROR_PAGE_IDX << PD_SHIFT) + + (PD_MIRROR_PAGE_IDX << PT_SHIFT)); - struct pte *pt = (struct pte *)((PD_MIRROR_PAGE_IDX << 22) + (pdEntry << 12)); + struct pte *pt = + (struct pte *)((PD_MIRROR_PAGE_IDX << PD_SHIFT) + (pdEntry << PT_SHIFT)); if (!pd[pdEntry].present) { paddr_t ptPhy = allocPhyPage(); if (ptPhy == (vaddr_t)NULL) return ENOMEM; - pd[pdEntry].user = (flags & PAGING_MEM_USER) ? 1:0; + pd[pdEntry].user = (flags & PAGING_MEM_USER) ? 1 : 0; pd[pdEntry].present = 1; - pd[pdEntry].write = 1; + pd[pdEntry].write = 1; pd[pdEntry].pt_addr = (ptPhy >> PT_SHIFT); __native_flush_tlb_single((vaddr_t)pt); @@ -162,6 +167,7 @@ int pageMap(vaddr_t vaddr, paddr_t paddr, int flags) refPhyPage(paddr); __native_flush_tlb_single(vaddr); + mappedPage++; return 0; } @@ -171,11 +177,11 @@ int pageUnmap(vaddr_t vaddr) uint ptEntry = (vaddr >> PT_SHIFT) & PTE_MASK; // Thank to mirroring, we can access the PD - struct pde *pd = - (struct pde *)(PD_MIRROR_PAGE_IDX * (1U << 22) + PD_MIRROR_PAGE_IDX * (1U << 12)); + struct pde *pd = (struct pde *)((PD_MIRROR_PAGE_IDX << PD_SHIFT) + + (PD_MIRROR_PAGE_IDX << PT_SHIFT)); struct pte *pt = - (struct pte *)(PD_MIRROR_PAGE_IDX * (1U << 22) + pdEntry * (1U << 12)); + (struct pte *)((PD_MIRROR_PAGE_IDX << PD_SHIFT) + (pdEntry << PT_SHIFT)); if (!pd[pdEntry].present) return -EINVAL; if (!pt[ptEntry].present) @@ -185,11 +191,16 @@ int pageUnmap(vaddr_t vaddr) pt[ptEntry].present = 0; // PTE not used. Decrease refcount on it. Is PT not used anymore ? - if(unrefPhyPage(pd[pdEntry].pt_addr<< PT_SHIFT) == 0){ + if (unrefPhyPage(pd[pdEntry].pt_addr << PT_SHIFT) == 0) { pd[pdEntry].present = 0; __native_flush_tlb_single((vaddr_t)pt); } __native_flush_tlb_single(vaddr); + mappedPage--; return 0; - +} + +unsigned long getNbMappedPage(void) +{ + return mappedPage; } diff --git a/core/paging.h b/core/paging.h index e2b41a4..4bdcecc 100644 --- a/core/paging.h +++ b/core/paging.h @@ -9,3 +9,4 @@ int pagingSetup(paddr_t upperKernelAddr); int pageMap(vaddr_t vaddr, paddr_t paddr, int flags); int pageUnmap(vaddr_t vaddr); +unsigned long getNbMappedPage(void);