1
0

mm.c/h -> frames.c/h: Naming indicating dealing with physical not virtual memory

This commit is contained in:
Aaron Lindsay 2013-01-01 23:42:45 -05:00
parent e279d83d7d
commit 806d00f471
9 changed files with 79 additions and 66 deletions

View File

@ -20,7 +20,7 @@
#include <print.h> #include <print.h>
#include <types.h> #include <types.h>
#include <mm.h> #include <frames.h>
#define SCTLR 15,0,1,0,0 #define SCTLR 15,0,1,0,0
#define TTBR0 15,0,2,0,0 #define TTBR0 15,0,2,0,0

View File

@ -20,7 +20,7 @@
#include <print.h> #include <print.h>
#include <types.h> #include <types.h>
#include <mm.h> #include <frames.h>
extern uint32 kernel_start_phys, kernel_end_phys; extern uint32 kernel_start_phys, kernel_end_phys;
extern uint32 kernel_start, kernel_end; extern uint32 kernel_start, kernel_end;

View File

@ -20,7 +20,7 @@
#include <types.h> #include <types.h>
#include <framebuffer.h> #include <framebuffer.h>
#include <mm.h> #include <frames.h>
#include <math.h> #include <math.h>
#define PL110_CR_EN 0x001 #define PL110_CR_EN 0x001
@ -45,7 +45,7 @@ int pl110_init(struct fb *f, unsigned int color_depth) {
unsigned int width, height; unsigned int width, height;
unsigned int fb_size, power; unsigned int fb_size, power;
struct pl110_control *plio = (struct pl110_control*)PL110_IOBASE; struct pl110_control *plio = (struct pl110_control*)PL110_IOBASE;
struct page *p; struct frame *fr;
/* 640x480 pixels */ /* 640x480 pixels */
width = 640; width = 640;
@ -58,11 +58,11 @@ int pl110_init(struct fb *f, unsigned int color_depth) {
power = log(fb_size) - log(MM_PAGE_SIZE); power = log(fb_size) - log(MM_PAGE_SIZE);
if ((unsigned int)1<<power < fb_size) if ((unsigned int)1<<power < fb_size)
power++; power++;
p = mm_get_free_pages(power); fr = get_free_frames(power);
if (!p) if (!fr)
return -1; return -1;
plio->upbase = (uint32)p->address; plio->upbase = (uint32)fr->address;
if (color_depth == FB_COLOR_DEPTH_8) { if (color_depth == FB_COLOR_DEPTH_8) {
plio->control = 0x1827; plio->control = 0x1827;

View File

@ -21,7 +21,7 @@
#include <framebuffer.h> #include <framebuffer.h>
#include <init.h> #include <init.h>
#include <math.h> #include <math.h>
#include <mm.h> #include <frames.h>
#include <types.h> #include <types.h>
#include <drivers/fb.h> #include <drivers/fb.h>
@ -47,7 +47,7 @@ int pl111_init_dev(struct fb *f, unsigned int color_depth) {
unsigned int width, height; unsigned int width, height;
unsigned int fb_size, power; unsigned int fb_size, power;
struct pl111_control *plio = (struct pl111_control*)PL111_IOBASE; struct pl111_control *plio = (struct pl111_control*)PL111_IOBASE;
struct page *p; struct frame *fr;
/* 640x480 pixels */ /* 640x480 pixels */
width = 640; width = 640;
@ -60,11 +60,11 @@ int pl111_init_dev(struct fb *f, unsigned int color_depth) {
power = log(fb_size) - log(MM_PAGE_SIZE); power = log(fb_size) - log(MM_PAGE_SIZE);
if ((unsigned int)1<<power < fb_size) if ((unsigned int)1<<power < fb_size)
power++; power++;
p = mm_get_free_pages(power); fr = get_free_frames(power);
if (!p) if (!fr)
return -1; return -1;
plio->upbase = (uint32)p->address; plio->upbase = (uint32)fr->address;
if (color_depth == FB_COLOR_DEPTH_8) { if (color_depth == FB_COLOR_DEPTH_8) {
plio->control = 0x1827; plio->control = 0x1827;

View File

@ -18,23 +18,23 @@
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/ */
#ifndef MM_H #ifndef FRAMES_H
#define MM_H #define FRAMES_H
#include <list.h> #include <list.h>
#define MM_PAGE_SIZE 4096 #define MM_PAGE_SIZE 4096
struct page { struct frame {
void *address; void *address;
struct dlist_node list; struct dlist_node list;
char free; char free;
}; };
void mm_init(); void frames_init();
void mm_add_free_region(void *start, void *end); void declare_memory_region(void *start, void *end);
struct page* mm_get_free_pages(unsigned int power); struct frame* get_free_frames(unsigned int power);
int mm_put_free_pages(struct page *p); int put_free_frames(struct frame *p);
#endif /* MM_H */ #endif /* FRAMES_H */

View File

@ -19,37 +19,43 @@
*/ */
#include <list.h> #include <list.h>
#include <mm.h> #include <frames.h>
#include <print.h> #include <print.h>
#include <types.h> #include <types.h>
struct dlist_node mm_free_page_list; struct dlist_node free_frames_list;
void mm_init() { void frames_init() {
init_list(&mm_free_page_list); init_list(&free_frames_list);
} }
//presupposes mm_free_page_list is a properly initialized list /*
void insert_page(struct page *p) { * Adds a page frame struct to the list of free page frames. Presupposes
if (list_empty(&mm_free_page_list) || p->address < container(mm_free_page_list.next, struct page, list)->address) { * free_frames_list is a properly initialized list.
insert_after(&mm_free_page_list, &p->list); */
} else if (p->address > container(mm_free_page_list.prev, struct page, list)->address) { static void insert_page_frame(struct frame *p) {
insert_before(&mm_free_page_list, &p->list); if (list_empty(&free_frames_list) || p->address < container(free_frames_list.next, struct frame, list)->address) {
insert_after(&free_frames_list, &p->list);
} else if (p->address > container(free_frames_list.prev, struct frame, list)->address) {
insert_before(&free_frames_list, &p->list);
} else { } else {
struct page *it; struct frame *it;
for_each_list(it, &mm_free_page_list, struct page, list) { for_each_list(it, &free_frames_list, struct frame, list) {
if (p->address < it->address) { if (p->address < it->address) {
insert_before(&it->list, &p->list); insert_before(&it->list, &p->list);
return; return;
} }
} }
print("Error: failed to insert page\n"); print("Error: failed to insert page frame\n");
} }
} }
void mm_add_free_region(void *start, void *end) { /*
* Called to add a segment of memory to the frame allocation pool.
*/
static void add_physical_memory(void *start, void *end) {
unsigned int num_pages, usable_pages; unsigned int num_pages, usable_pages;
struct page *p; struct frame *p;
void *page; void *page;
//If region starts at 0x0, make it start at next page to not screw up null pointer detection, etc. //If region starts at 0x0, make it start at next page to not screw up null pointer detection, etc.
@ -73,39 +79,43 @@ void mm_add_free_region(void *start, void *end) {
//TODO we're potentially losing memory here because we're calculating //TODO we're potentially losing memory here because we're calculating
//the number of page structs we need even for those pages that will contain only page structs //the number of page structs we need even for those pages that will contain only page structs
num_pages = ((char *)end + 1 - (char *)start) / MM_PAGE_SIZE; num_pages = ((char *)end + 1 - (char *)start) / MM_PAGE_SIZE;
usable_pages = num_pages - num_pages * sizeof(struct page) / MM_PAGE_SIZE; usable_pages = num_pages - num_pages * sizeof(struct frame) / MM_PAGE_SIZE;
if (num_pages * sizeof(struct page) % MM_PAGE_SIZE) if (num_pages * sizeof(struct frame) % MM_PAGE_SIZE)
usable_pages--; usable_pages--;
p = (struct page *)start; p = (struct frame *)start;
for (page = ((char *)start) + (num_pages - usable_pages)*MM_PAGE_SIZE; page < end; page = (void *)(((char *)page) + MM_PAGE_SIZE)) { for (page = ((char *)start) + (num_pages - usable_pages)*MM_PAGE_SIZE; page < end; page = (void *)(((char *)page) + MM_PAGE_SIZE)) {
p->address = page; p->address = page;
insert_page(p); insert_page_frame(p);
p++; p++;
} }
} }
struct page* mm_get_free_pages(unsigned int power) { /*
* Attempt to get 2^power contiguous page frames. Returns the frame struct of
* the first frame on success or a null pointer on failure.
*/
struct frame* get_free_frames(unsigned int power) {
unsigned int num_pages = 1<<power; unsigned int num_pages = 1<<power;
struct page *it; struct frame *it;
if (list_empty(&mm_free_page_list)) { if (list_empty(&free_frames_list)) {
print("Error: Out of memory\n"); print("Error: Out of memory\n");
return (struct page*)0; return (struct frame*)0;
} }
if (!num_pages) { if (!num_pages) {
print("Error: mm_get_free_pages must be called with power from 0 to 31, inclusive (power=%d)\n", power); print("Error: mm_get_free_pages must be called with power from 0 to 31, inclusive (power=%d)\n", power);
return (struct page*)0; return (struct frame*)0;
} }
for_each_list(it, &mm_free_page_list, struct page, list) { for_each_list(it, &free_frames_list, struct frame, list) {
unsigned int curr_pages = 1; unsigned int curr_pages = 1;
struct page *it2; struct frame *it2;
for (it2 = container(it->list.next, struct page, list); for (it2 = container(it->list.next, struct frame, list);
it2->list.next != &mm_free_page_list && curr_pages < num_pages; it2->list.next != &free_frames_list && curr_pages < num_pages;
it2 = container(it2->list.next, struct page, list)) { it2 = container(it2->list.next, struct frame, list)) {
if ((char*)it2->address != (char*)container(it2->list.prev, struct page, list)->address + MM_PAGE_SIZE) { if ((char*)it2->address != (char*)container(it2->list.prev, struct frame, list)->address + MM_PAGE_SIZE) {
it = it2; //fast-forward 'it' to start of next contiguous section of pages it = it2; //fast-forward 'it' to start of next contiguous section of pages
break; break;
} else { } else {
@ -117,14 +127,17 @@ struct page* mm_get_free_pages(unsigned int power) {
return it; return it;
} }
} }
return (struct page*)0; return (struct frame*)0;
} }
int mm_put_free_pages(struct page *p) { /*
struct page *it; * Return pages allocated to the pool of unused pages.
for_each_list(it, &mm_free_page_list, struct page, list) { */
if (p->address < it->address) { int put_free_frames(struct frame *f) {
insert_splice_before(&it->list, &p->list, p->list.prev); struct frame *it;
for_each_list(it, &free_frames_list, struct frame, list) {
if (f->address < it->address) {
insert_splice_before(&it->list, &f->list, f->list.prev);
return 0; return 0;
} }
} }

View File

@ -20,9 +20,9 @@
#include <console.h> #include <console.h>
#include <framebuffer.h> #include <framebuffer.h>
#include <frames.h>
#include <kmalloc.h> #include <kmalloc.h>
#include <print.h> #include <print.h>
#include <mm.h>
#include <mmu.h> #include <mmu.h>
#include <types.h> #include <types.h>
@ -109,7 +109,7 @@ int main(void) {
serial_console_init(); serial_console_init();
//setup memory subsystems //setup memory subsystems
mm_init(); frames_init();
kmalloc_init(); kmalloc_init();
if (detect_memory()) { if (detect_memory()) {
print("Error: Failed to detect memory.\n"); print("Error: Failed to detect memory.\n");

View File

@ -6,11 +6,11 @@ include $(BASEDIR)/header.mk
OBJS_$(d) := $(d)/console.o \ OBJS_$(d) := $(d)/console.o \
$(d)/font.o \ $(d)/font.o \
$(d)/framebuffer.o \ $(d)/framebuffer.o \
$(d)/frames.o \
$(d)/init.o \ $(d)/init.o \
$(d)/kmalloc.o \ $(d)/kmalloc.o \
$(d)/list.o \ $(d)/list.o \
$(d)/math.o \ $(d)/math.o \
$(d)/mm.o \
$(d)/print.o $(d)/print.o
KOBJS += $(OBJS_$(d)) KOBJS += $(OBJS_$(d))

View File

@ -19,7 +19,7 @@
*/ */
#include <kmalloc.h> #include <kmalloc.h>
#include <mm.h> #include <frames.h>
#include <list.h> #include <list.h>
#include <print.h> #include <print.h>
@ -96,12 +96,12 @@ coalesce:
void *_kmalloc(unsigned int bytes, unsigned int tries); void *_kmalloc(unsigned int bytes, unsigned int tries);
void *grow_and_retry(unsigned int bytes, unsigned int tries) { void *grow_and_retry(unsigned int bytes, unsigned int tries) {
struct page *p; struct frame *f;
if ((p = mm_get_free_pages(curr_page_power))) { if ((f = get_free_frames(curr_page_power))) {
struct kmalloc_region *region = (struct kmalloc_region *)p->address; struct kmalloc_region *region = (struct kmalloc_region *)f->address;
//TODO don't throw away p, but keep it in a list (allocate a little at the beginning of this chunk for a list element), so we can free pages later if we want to //TODO don't throw away f, but keep it in a list (allocate a little at the beginning of this chunk for a list element), so we can free pages later if we want to
region->end = (char *)region + MM_PAGE_SIZE * (1 << curr_page_power) - 1; region->end = (char *)region + CONFIG_PAGE_SIZE * (1 << curr_page_power) - 1;
add_region(region); add_region(region);
curr_page_power++; curr_page_power++;
return _kmalloc(bytes, tries); return _kmalloc(bytes, tries);