Fix naming and mem bottom

This commit is contained in:
Mathieu Maret 2021-01-22 22:59:45 +01:00
parent a254a7cd71
commit 77b495e382
6 changed files with 68 additions and 59 deletions

View File

@ -37,7 +37,8 @@ void idleThread(void *arg)
// https://www.gnu.org/software/grub/manual/multiboot/html_node/Boot-information-format.html#Boot%20information%20format // https://www.gnu.org/software/grub/manual/multiboot/html_node/Boot-information-format.html#Boot%20information%20format
void kmain(unsigned long magic, unsigned long addr) void kmain(unsigned long magic, unsigned long addr)
{ {
unsigned long upper_mem = 0; unsigned long upperMem = 0;
VGASetup(BLACK, GREEN); VGASetup(BLACK, GREEN);
cursorEnable(14, 15); cursorEnable(14, 15);
@ -52,7 +53,7 @@ void kmain(unsigned long magic, unsigned long addr)
/* Are mem_* valid? */ /* Are mem_* valid? */
if (CHECK_FLAG(mbi->flags, 0)) { if (CHECK_FLAG(mbi->flags, 0)) {
printf("mem_lower = %dKiB mem_upper %dKiB\n", mbi->mem_lower, mbi->mem_upper); printf("mem_lower = %dKiB mem_upper %dKiB\n", mbi->mem_lower, mbi->mem_upper);
upper_mem = mbi->mem_upper; upperMem = mbi->mem_upper;
} }
/* Is boot_device valid? */ /* Is boot_device valid? */
@ -91,14 +92,14 @@ void kmain(unsigned long magic, unsigned long addr)
} }
} }
if (upper_mem == 0) { if (upperMem == 0) {
printf("Cannot get upper phy mem bound. Using default value 32MB\n"); printf("Cannot get upper phy mem bound. Using default value 32MB\n");
upper_mem = 32 * 1024; upperMem = 32 * 1024;
} }
printf("Setting up Pagination\n"); printf("Setting up Pagination\n");
paddr_t lastUserByMem; paddr_t lastUserByMem;
memSetup(upper_mem, &lastUserByMem); memSetup(upperMem, &lastUserByMem);
#ifdef RUN_TEST #ifdef RUN_TEST
testPhymem(); testPhymem();
#endif #endif

View File

@ -4,67 +4,71 @@
#include "list.h" #include "list.h"
#include "types.h" #include "types.h"
static struct mem_desc *page_desc = (struct mem_desc *)&__ld_kernel_end; static struct memDesc *pageDesc = (struct memDesc *)&__ld_kernel_end;
static struct mem_desc *free_page; static struct memDesc *freePage;
static struct mem_desc *used_page; static struct memDesc *usedPage;
static unsigned long bottom_mem; static unsigned long memBottom;
static unsigned long top_mem; static unsigned long memTop;
static unsigned long allocatedPage = 0; static unsigned long allocatedPage = 0;
int memSetup(paddr_t upperMem, paddr_t *lastUsedOut) int memSetup(paddr_t upperMem, paddr_t *lastPageUsedOut)
{ {
list_init(freePage);
list_init(usedPage);
// Align upper mem (in kB) on page size even if it does loose a page // Align upper mem (in kB) on page size even if it does loose a page
upperMem = ALIGN_DOWN(upperMem, PAGE_SIZE / 1024); upperMem = ALIGN_DOWN(upperMem, PAGE_SIZE / 1024);
unsigned long nbPage = ((upperMem) / (PAGE_SIZE / 1024));
printf("Available Mem from 0x%x to 0x%x: %dMB and %dPages(%d)\n", &__ld_kernel_end,
upperMem * 1024, (upperMem * 1024 - (uint32_t)&__ld_kernel_end) / (1024 * 1024),
nbPage, PAGE_SIZE);
printf("Available Mem from 0x%x to 0x%x: %dMB \n", &__ld_kernel_end, upperMem * 1024,
(upperMem * 1024 - (uint32_t)&__ld_kernel_end) / (1024 * 1024));
// Memory description is stored after the kernel. We need some place to store it // Memory description is stored after the kernel. We need some place to store it
unsigned long memdesc_end = unsigned long pageDescEnd = (unsigned long)pageDesc + nbPage * sizeof(struct memDesc);
(unsigned long)page_desc + ((upperMem) / (PAGE_SIZE / 1024)) * sizeof(struct mem_desc); uint lastPageUsed = (pageDescEnd >> PAGE_SHIFT) + 1;
uint lastUsed = (memdesc_end >> PAGE_SHIFT) + 1; memBottom = lastPageUsed << PAGE_SHIFT;
list_init(free_page); memTop = upperMem * 1024;
list_init(used_page); *lastPageUsedOut = pageDescEnd;
bottom_mem = lastUsed;
*lastUsedOut = memdesc_end; for (uint i = 0; i < nbPage; i++) {
top_mem = upperMem * 1024; struct memDesc *mem = &pageDesc[i];
for (uint i = 0; i < (upperMem / (PAGE_SIZE / 1024)); i++) { if (i < lastPageUsed) {
struct mem_desc *mem = &page_desc[i];
if (i < lastUsed) {
mem->ref = 1; mem->ref = 1;
list_add_tail(used_page, mem); list_add_tail(usedPage, mem);
} else { } else {
mem->ref = 0; mem->ref = 0;
list_add_tail(free_page, mem); list_add_tail(freePage, mem);
} }
mem->phy_addr = i * PAGE_SIZE; mem->phy_addr = i * PAGE_SIZE;
} }
return 0; return 0;
} }
struct mem_desc *addr2memDesc(paddr_t addr) struct memDesc *addr2memDesc(paddr_t addr)
{ {
if (addr > top_mem || addr < bottom_mem) if (addr > memTop || addr < memBottom)
return NULL; return NULL;
int idx = addr >> PAGE_SHIFT; int idx = addr >> PAGE_SHIFT;
return page_desc + idx; return pageDesc + idx;
} }
struct mem_desc *memFindConsecutiveFreePage(uint nbPage) struct memDesc *memFindConsecutiveFreePage(uint nbPage)
{ {
struct mem_desc *mem, *head; struct memDesc *mem, *head;
uint memIdx, count; uint memIdx, count;
if (list_is_empty(free_page)) { if (list_is_empty(freePage)) {
return NULL; return NULL;
} }
count = 1; count = 1;
memIdx = 0; memIdx = 0;
head = free_page; head = freePage;
mem = free_page; mem = freePage;
while (count < nbPage && (!memIdx || mem != free_page)) { while (count < nbPage && (!memIdx || mem != freePage)) {
memIdx++; memIdx++;
mem = mem->next; mem = mem->next;
if (mem->phy_addr == head->phy_addr + count * PAGE_SIZE) { if (mem->phy_addr == head->phy_addr + count * PAGE_SIZE) {
@ -83,7 +87,7 @@ struct mem_desc *memFindConsecutiveFreePage(uint nbPage)
paddr_t allocPhyPage(uint nbPage) paddr_t allocPhyPage(uint nbPage)
{ {
struct mem_desc *mem, *head, *next; struct memDesc *mem, *head, *next;
uint count; uint count;
head = memFindConsecutiveFreePage(nbPage); head = memFindConsecutiveFreePage(nbPage);
@ -96,9 +100,9 @@ paddr_t allocPhyPage(uint nbPage)
mem = head; mem = head;
next = head->next; next = head->next;
for (count = 0; count < nbPage; count++) { for (count = 0; count < nbPage; count++) {
list_delete(free_page, mem); list_delete(freePage, mem);
mem->ref = 1; mem->ref = 1;
list_add_tail(used_page, mem); list_add_tail(usedPage, mem);
mem = next; mem = next;
next = mem->next; next = mem->next;
} }
@ -108,15 +112,15 @@ paddr_t allocPhyPage(uint nbPage)
int unrefPhyPage(paddr_t addr) int unrefPhyPage(paddr_t addr)
{ {
struct mem_desc *mem = addr2memDesc(addr); struct memDesc *mem = addr2memDesc(addr);
if (!mem) { if (!mem) {
return -1; return -1;
} }
mem->ref--; mem->ref--;
if (mem->ref == 0) { if (mem->ref == 0) {
allocatedPage--; allocatedPage--;
list_delete(used_page, mem); list_delete(usedPage, mem);
list_add_tail(free_page, mem); // TODO find the right place to keep free_page sorted; list_add_tail(freePage, mem); // TODO find the right place to keep free_page sorted;
} }
return mem->ref; return mem->ref;
@ -124,15 +128,15 @@ int unrefPhyPage(paddr_t addr)
int refPhyPage(paddr_t addr) int refPhyPage(paddr_t addr)
{ {
struct mem_desc *mem = addr2memDesc(addr); struct memDesc *mem = addr2memDesc(addr);
if (!mem) { if (!mem) {
return -1; return -1;
} }
mem->ref++; mem->ref++;
if (mem->ref == 1) { if (mem->ref == 1) {
allocatedPage++; allocatedPage++;
list_add_tail(used_page, mem); list_add_tail(usedPage, mem);
list_delete(free_page, mem); list_delete(freePage, mem);
} }
return 0; return 0;

View File

@ -9,10 +9,10 @@
extern uint32_t __ld_kernel_begin; extern uint32_t __ld_kernel_begin;
extern uint32_t __ld_kernel_end; extern uint32_t __ld_kernel_end;
struct mem_desc { struct memDesc {
paddr_t phy_addr; paddr_t phy_addr;
long ref; long ref;
struct mem_desc *next, *prev; struct memDesc *next, *prev;
}; };
int memSetup(paddr_t upperMem, paddr_t *lastUsed); int memSetup(paddr_t upperMem, paddr_t *lastUsed);

View File

@ -22,7 +22,8 @@ unsigned long msecs_to_jiffies(const unsigned int m)
#endif #endif
} }
unsigned long usecs_to_jiffies(const unsigned int u){ unsigned long usecs_to_jiffies(const unsigned int u)
{
// This could overflow // This could overflow
return (u * HZ) / 1000000L; return (u * HZ) / 1000000L;
} }

View File

@ -14,14 +14,16 @@
void testPhymem(void) void testPhymem(void)
{ {
printf("Testing memory PHY\n"); printf("Testing memory PHY\n");
struct mem_desc *allocated_page_list; assert(refPhyPage((paddr_t)(&__ld_kernel_end)) == -1);
struct mem_desc assert(refPhyPage((paddr_t)(&__ld_kernel_begin)) == -1);
struct memDesc *allocated_page_list;
struct memDesc
*page; // Cast in mem_desc to use it. In fact it's the addr of 4K free memory *page; // Cast in mem_desc to use it. In fact it's the addr of 4K free memory
list_init(allocated_page_list); list_init(allocated_page_list);
int allocCount = 0; int allocCount = 0;
int freeCount = 0; int freeCount = 0;
while ((page = (struct mem_desc *)allocPhyPage(1)) != NULL) { while ((page = (struct memDesc *)allocPhyPage(1)) != NULL) {
page->phy_addr = allocCount; page->phy_addr = allocCount;
allocCount++; allocCount++;
list_add_tail(allocated_page_list, page); list_add_tail(allocated_page_list, page);
@ -35,7 +37,7 @@ void testPhymem(void)
} }
printf("%d pages freed\n", freeCount); printf("%d pages freed\n", freeCount);
assertmsg((page = (struct mem_desc *)allocPhyPage(1)) != NULL, "Cannot allocate memory\n"); assertmsg((page = (struct memDesc *)allocPhyPage(1)) != NULL, "Cannot allocate memory\n");
unrefPhyPage((ulong)page); unrefPhyPage((ulong)page);
} }
@ -49,6 +51,7 @@ static void *testAllocNSet(size_t size)
static void testAlloc(void) static void testAlloc(void)
{ {
assert(malloc(1410065407) == NULL);
for (uint i = 0; i < PAGE_SIZE / (sizeof(struct slabEntry)); i++) { for (uint i = 0; i < PAGE_SIZE / (sizeof(struct slabEntry)); i++) {
malloc(sizeof(struct slabEntry)); malloc(sizeof(struct slabEntry));
} }
@ -96,14 +99,14 @@ static void testAlloc(void)
static void testPaging(void) static void testPaging(void)
{ {
printf("Testing paging\n"); printf("Testing paging\n");
struct mem_desc *allocated_page_list; struct memDesc *allocated_page_list;
struct mem_desc struct memDesc
*page; // Cast in mem_desc to use it. In fact it's the addr of 4K free memory *page; // Cast in mem_desc to use it. In fact it's the addr of 4K free memory
list_init(allocated_page_list); list_init(allocated_page_list);
int allocCount = 0; int allocCount = 0;
int freeCount = 0; int freeCount = 0;
while ((page = (struct mem_desc *)allocPhyPage(1)) != NULL) { while ((page = (struct memDesc *)allocPhyPage(1)) != NULL) {
assertmsg(pageMap((vaddr_t)page, (paddr_t)page, PAGING_MEM_WRITE) == 0, assertmsg(pageMap((vaddr_t)page, (paddr_t)page, PAGING_MEM_WRITE) == 0,
"Fail to map page %d\n", allocCount); "Fail to map page %d\n", allocCount);
memset(page, allocCount, PAGE_SIZE); memset(page, allocCount, PAGE_SIZE);
@ -121,7 +124,7 @@ static void testPaging(void)
} }
printf("%d pages freed\n", freeCount); printf("%d pages freed\n", freeCount);
assertmsg((page = (struct mem_desc *)allocPhyPage(1)) != NULL, "Cannot allocate memory\n"); assertmsg((page = (struct memDesc *)allocPhyPage(1)) != NULL, "Cannot allocate memory\n");
unrefPhyPage((ulong)page); unrefPhyPage((ulong)page);
} }