Import backup from 2004-07-15

This commit is contained in:
josh committed 2017-07-25 22:23:47 -04:00
1 parent dfb71cc759
commit d4aadbea38
11 files changed
+390 -22

No files matched your search

+17 -10
View File
@@ -8,15 +8,16 @@
#include "multiboot.h"
#include "hos_defines.h"
u32_t mm_totalmem;
u32_t mm_megabytes;
u32_t mm_freepages;
u32_t mm_first_free_byte;
extern mb_info_t mb_info_block;
extern mb_mmap_t mb_mmap[MAX_MMAP];
extern u32_t mmap_entries;
extern mb_module_t mb_modules[MAX_MODULES];
byte page_bitmap[BITMAP_SIZE]; //used to store a bit for each page that is used, 0 if available
u32_t mm_totalmem;
u32_t mm_megabytes;
u32_t mm_freepages;
u32_t mm_first_free_byte;
byte page_bitmap[MM_BITMAP_SIZE]; //used to store a bit for each page that is used, 0 if available
//0x20000*(8 bits/byte)=0x100000 pages in 4gb total
//This function initializes the memory manager's linked list, filling it with the
@@ -24,7 +25,7 @@ byte page_bitmap[BITMAP_SIZE]; //used to store a bit for each page that is used,
void mm_init()
{
u32_t a;
for (a = 0; a < BITMAP_SIZE; a++) //mark all pages used
for (a = 0; a < MM_BITMAP_SIZE; a++) //mark all pages used
{
page_bitmap[a] = 0xFF;
}
@@ -107,10 +108,10 @@ void mm_preserve(u32_t base)
// This function allocates a single page, returning its physical address
void *mm_palloc()
u32_t mm_palloc()
{
u32_t bite;
for (bite = mm_first_free_byte; bite < BITMAP_SIZE; bite++)
for (bite = mm_first_free_byte; bite < MM_BITMAP_SIZE; bite++)
{
if (page_bitmap[bite] != 0xFF) //there is an available page within this 8-page region
{
@@ -122,7 +123,7 @@ void *mm_palloc()
mm_first_free_byte = bite; //start searching from here next time
mm_freepages--;
page_bitmap[bite] = page_bitmap[bite] | (1 << bit); //set page as used
return (void *)((bite << 15) | (bit << 12));
return ((bite << 15) | (bit << 12));
}
}
}
@@ -132,12 +133,18 @@ void *mm_palloc()
// This function reports the number of bytes of free physical memory
u32_t mm_freemem()
u32_t mm_getFreeMem()
{
return mm_freepages << 12;
}
u32_t mm_getFreePages()
{
return mm_freepages;
}
u32_t mm_getTotalMem()
{
return mm_totalmem;
+4 -3
View File
@@ -9,15 +9,16 @@
#include "kernel.h"
//The total amount of physical memory available (bytes, 1 bit per page)
#define BITMAP_SIZE 0x20000
#define MM_BITMAP_SIZE 0x20000
void mm_init();
void mm_pfreen(u32_t base, u32_t pages);
void mm_pfree(u32_t base);
void mm_preserven(u32_t base, u32_t pages);
void mm_preserve(u32_t base);
void *mm_palloc();
u32_t mm_freemem();
u32_t mm_palloc();
u32_t mm_getFreeMem();
u32_t mm_getFreePages();
u32_t mm_getTotalMem();
u32_t mm_getTotalMegs();
+192
View File
@@ -0,0 +1,192 @@
// vmm.c
// Author: Josh Holtrop
// Date: 09/30/03
// Rewritten from scratch: 12/23/03
// Modified: 07/13/04
#include "hos_defines.h"
#include "mm/vmm.h"
#include "asmfuncs.h"
#include "mm/mm.h"
extern mb_info_t mb_info_block;
extern mb_module_t mb_modules[MAX_MODULES];
extern u32_t mm_freepages;
HeapEntryQueue_t heapEntryQueues[VMM_HE_TYPES]; //sorted, linked queue of HeapEntry objects
HeapEntryBlock_t initialHEB; //block for initial 256 HeapEntry objects
// This is the initialization procedure for the Virtual Memory Manager
// It sets up the heap for dynamic memory allocation and virtual page allocation
void vmm_init()
{
int i;
for (i = 0; i < mb_info_block.mods_count; i++) //page in the kernel modules
vmm_map_range((void*)mb_modules[i].mod_start, (void*)mb_modules[i].mod_end- 1, mb_modules[i].mod_start - VIRT_OFFSET);
}
/* Allocate a physical page and map the virtual address to it, return physical address allocated or NULL */
u32_t vmm_map(void *virt)
{
u32_t phys = mm_palloc();
if (!phys);
return NULL;
vmm_map1((u32_t)virt, phys);
return phys;
}
// This function maps a virtual address to a physical address using the page directory / page table
void vmm_map1(unsigned int virt, unsigned int physical)
{
unsigned int pde = virt >> 22;
unsigned int pte = (virt & 0x003FF000) >> 12;
unsigned int *pageTables = (unsigned int *)0xFFFFF000; //this is the location of the page directory
if (!(pageTables[pde] & 0x01)) //the page directory entry does not exist, we must allocate a page for it
{
u32_t newpagetable = mm_palloc();
pageTables[pde] = newpagetable | 0x03;
invlpg_(virt); //in case it was cached, so we can fill page table safely
unsigned int *newpteptr = (unsigned int *)(0xFFC00000 | (pde << 12)); //points to first unsigned int of newly allocated page table
int a;
for (a = 0; a < 1024; a++)
*newpteptr++ = 0;
}
*(unsigned int *)(0xFFC00000 | (pde << 12) | (pte << 2)) = (physical & 0xFFFFF000) | 0x03;
invlpg_(virt);
}
// This function maps a variable number of pages in a row
void vmm_mapn(unsigned int virt, unsigned int physical, unsigned int n)
{
while (n > 0)
{
vmm_map1(virt, physical);
virt += 4096;
physical += 4096;
n--;
}
}
// This function removes the virtual address's entry in the page directory / page table
void vmm_unmap1(unsigned int virt)
{
*(unsigned int *)(0xFFC00000 | ((virt & 0xFFC00000) >> 10) | ((virt & 0x003FF000) >> 10)) = 0;
invlpg_(virt);
}
// This function removes multiple pages' entries
void vmm_unmapn(unsigned int virt, unsigned int n)
{
while (n > 0)
{
vmm_unmap1(virt);
virt += 4096;
n--;
}
}
int vmm_map_range(void *virt_start, void *virt_end, u32_t phys_start)
{
if (virt_end < virt_start)
return 1; //invalid region
while (virt_start < virt_end)
{
vmm_map1((u32_t)virt_start, phys_start);
virt_start += 4096;
phys_start += 4096;
}
return 0;
}
// This function allocates and zeros memory for the given number of objects,
// given the size of each object
/*
void *calloc(unsigned int number, unsigned int size)
{
void *mem = malloc(number * size);
if (!mem)
return NULL; //could not get memory
memset(mem, 0, number * size);
return mem;
}*/
// This function initialzes a Heap Entry Block to entries linked together
void vmm_heb_init(HeapEntryBlock_t *heb)
{
int a;
for (a = 0; a < 255; a++)
heb->entry[a].next = &heb->entry[a+1];
heb->entry[255].next = NULL;
}
// This function adds a HeapEntry structure list to the appropriate place in the queue
void vmm_addToQueue(u32_t queue, HeapEntry_t *he)
{
if (heapEntryQueues[queue].start == NULL) //queue is empty
{
heapEntryQueues[queue].start = he;
heapEntryQueues[queue].count = vmm_countHeapEntries(he);
return;
}
// TODO
}
// This function returns how many HeapEntry objects are in a queue starting from the object given
int vmm_countHeapEntries(HeapEntry_t *he)
{
int count = 0;
while (he)
{
count++;
he = (HeapEntry_t *)he->link;
}
return count;
}
// This function follows a chain of HeapEntry objects and returns a pointer to the last one
HeapEntry_t *vmm_followChain(HeapEntry_t *he)
{
while (he->link)
he = (HeapEntry_t *)he->link;
return he;
}
// This function breaks an unused chunk from its queue and returns a pointer to it
HeapEntry_t *vmm_getUnusedChunk()
{
if (heapEntryQueues[VMM_HE_UNUSED].count < 5)
{
heapEntryQueues[VMM_HE_UNUSED].count += 256;//not good idea
HeapEntryBlock_t *newHEB = vmm_palloc(); //INFINITE LOOP?
vmm_mcb_init(newHEB);
vmm_addToQueue(VMM_HE_UNUSED, newHEB);
heapEntryQueues[VMM_HE_UNUSED].count -= 256;
}
HeapEntry_t *he = heapEntryQueues[VMM_HE_UNUSED].start;
heapEntryQueues[VMM_HE_UNUSED].start = he->link;
heapEntryQueues[VMM_HE_UNUSED].count--;
return he;
}
+52
View File
@@ -0,0 +1,52 @@
// vmm.h
// Author: Josh Holtrop
// Date: 09/30/03
// Rewritten from scratch: 12/23/03, 07/13/04
// Modified: 07/15/04
#ifndef __HOS_VMM__
#define __HOS_VMM__ __HOS_VMM__
#include "hos_defines.h"
#include "multiboot.h"
#define VMM_HE_TYPES 4 //4 types of heap entries
#define VMM_HE_UNUSED 0 //available entry
#define VMM_HE_FREE 1 //free section of memory
#define VMM_HE_USED 2 //used section of memory
#define VMM_HE_HOLE 3 //a "hole" (unmapped/wilderness) section of virtual memory
#define VMM_MALLOC_GRANULARITY 4 //a power of 2, granularity for all memory requests
#define VMM_MALLOC_GRAN_MASK VMM_MALLOC_GRANULARITY-1 //mask for determining how much of a request is past granularity
typedef struct {
void *base; //virtual base address
u32_t length; //size in bytes
void *next; //link to next HeapEntry
u32_t padding;
} __attribute__((packed)) HeapEntry_t;
typedef struct {
HeapEntry_t entry[256]; //256 HeapEntry objects = 4kb (1 page)
} __attribute__((packed)) HeapEntryBlock_t;
typedef struct {
int count;
HeapEntry_t *start;
} HeapEntryQueue_t;
void vmm_init();
u32_t vmm_map(void *virt);
void vmm_map1(unsigned int virt, unsigned int physical);
void vmm_mapn(unsigned int virt, unsigned int physical, unsigned int n);
void vmm_unmap1(unsigned int virt);
void vmm_unmapn(unsigned int virt, unsigned int n);
int vmm_map_range(void *virt_start, void *virt_end, u32_t phys_start);
void vmm_heb_init(HeapEntryBlock_t *heb);
//void *calloc(unsigned int number, unsigned int size);
#endif