Mon 14 Oct 23:06:38 CEST 2024
This commit is contained in:
parent
ff9a118e25
commit
56fdbe77b3
107
kernel/page.c
Normal file
107
kernel/page.c
Normal file
|
@ -0,0 +1,107 @@
|
|||
/*
|
||||
Copyright (C) 2015-2019 The University of Notre Dame
|
||||
This software is distributed under the GNU General Public License.
|
||||
See the file LICENSE for details.
|
||||
*/
|
||||
|
||||
#include "console.h"
|
||||
#include "kernel/types.h"
|
||||
#include "page.h"
|
||||
#include "string.h"
|
||||
#include "memorylayout.h"
|
||||
#include "kernelcore.h"
|
||||
|
||||
static uint32_t pages_free = 0;
|
||||
static uint32_t pages_total = 0;
|
||||
|
||||
static uint32_t *freemap = 0;
|
||||
static uint32_t freemap_bits = 0;
|
||||
static uint32_t freemap_bytes = 0;
|
||||
static uint32_t freemap_cells = 0;
|
||||
static uint32_t freemap_pages = 0;
|
||||
|
||||
static void *main_memory_start = (void *) MAIN_MEMORY_START;
|
||||
|
||||
#define CELL_BITS (8*sizeof(*freemap))
|
||||
|
||||
void page_init()
|
||||
{
|
||||
int i;
|
||||
|
||||
pages_total = (total_memory * 1024 * 1024 - MAIN_MEMORY_START) / PAGE_SIZE;
|
||||
pages_free = pages_total;
|
||||
printf("memory: %d MB (%d KB) total\n", (pages_free * PAGE_SIZE) / MEGA, (pages_free * PAGE_SIZE) / KILO);
|
||||
|
||||
freemap = main_memory_start;
|
||||
freemap_bits = pages_total;
|
||||
freemap_bytes = 1 + freemap_bits / 8;
|
||||
freemap_cells = 1 + freemap_bits / CELL_BITS;
|
||||
freemap_pages = 1 + freemap_bytes / PAGE_SIZE;
|
||||
|
||||
printf("memory: %d bits %d bytes %d cells %d pages\n", freemap_bits, freemap_bytes, freemap_cells, freemap_pages);
|
||||
|
||||
memset(freemap, 0xff, freemap_bytes);
|
||||
for(i = 0; i < freemap_pages; i++)
|
||||
page_alloc(0);
|
||||
|
||||
// This is ahack that I don't understand yet.
|
||||
// vmware doesn't like the use of a particular page
|
||||
// close to 1MB, but what it is used for I don't know.
|
||||
|
||||
freemap[0] = 0x0;
|
||||
|
||||
printf("memory: %d MB (%d KB) available\n", (pages_free * PAGE_SIZE) / MEGA, (pages_free * PAGE_SIZE) / KILO);
|
||||
}
|
||||
|
||||
void page_stats( uint32_t *nfree, uint32_t *ntotal )
|
||||
{
|
||||
*nfree = pages_free;
|
||||
*ntotal = pages_total;
|
||||
}
|
||||
|
||||
void *page_alloc(bool zeroit)
|
||||
{
|
||||
uint32_t i, j;
|
||||
uint32_t cellmask;
|
||||
uint32_t pagenumber;
|
||||
void *pageaddr;
|
||||
|
||||
if(!freemap) {
|
||||
printf("memory: not initialized yet!\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
for(i = 0; i < freemap_cells; i++) {
|
||||
if(freemap[i] != 0) {
|
||||
for(j = 0; j < CELL_BITS; j++) {
|
||||
cellmask = (1 << j);
|
||||
if(freemap[i] & cellmask) {
|
||||
freemap[i] &= ~cellmask;
|
||||
pagenumber = i * CELL_BITS + j;
|
||||
pageaddr = (pagenumber << PAGE_BITS) + main_memory_start;
|
||||
if(zeroit)
|
||||
memset(pageaddr, 0, PAGE_SIZE);
|
||||
pages_free--;
|
||||
//printf("page: alloc %d\n",pages_free);
|
||||
return pageaddr;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
printf("memory: WARNING: everything allocated\n");
|
||||
halt();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void page_free(void *pageaddr)
|
||||
{
|
||||
uint32_t pagenumber = (pageaddr - main_memory_start) >> PAGE_BITS;
|
||||
uint32_t cellnumber = pagenumber / CELL_BITS;
|
||||
uint32_t celloffset = pagenumber % CELL_BITS;
|
||||
uint32_t cellmask = (1 << celloffset);
|
||||
freemap[cellnumber] |= cellmask;
|
||||
pages_free++;
|
||||
//printf("page: free %d\n",pages_free);
|
||||
}
|
Loading…
Reference in New Issue
Block a user