Fix naming and mem bottom
This commit is contained in:
parent
a254a7cd71
commit
77b495e382
11
core/main.c
11
core/main.c
@ -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
|
||||||
|
86
core/mem.c
86
core/mem.c
@ -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)
|
||||||
{
|
{
|
||||||
// Align upper mem (in kB) on page size even if it does loose a page
|
list_init(freePage);
|
||||||
upperMem = ALIGN_DOWN(upperMem, PAGE_SIZE / 1024);
|
list_init(usedPage);
|
||||||
|
|
||||||
|
// Align upper mem (in kB) on page size even if it does loose a page
|
||||||
|
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;
|
||||||
|
@ -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);
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -52,9 +52,9 @@ int waitTimeout(struct wait_queue *wq, unsigned long msec)
|
|||||||
|
|
||||||
disable_IRQs(flags);
|
disable_IRQs(flags);
|
||||||
|
|
||||||
current = getCurrentThread();
|
current = getCurrentThread();
|
||||||
current->state = WAITING;
|
current->state = WAITING;
|
||||||
next = kthreadSelectNext();
|
next = kthreadSelectNext();
|
||||||
kthreadUnsched(current);
|
kthreadUnsched(current);
|
||||||
|
|
||||||
list_add_tail(wq->thread, current);
|
list_add_tail(wq->thread, current);
|
||||||
|
19
tests/test.c
19
tests/test.c
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user