OSを作る
メモリ管理の実装大体完了。マクロを使って以前のよりすっきり書いた(つもり。。)
メモリ管理も書いたし、次は頓挫してたFDCドライバーかな。
とりあえず1セクタの読み書きを目指そう。
memory.h
#ifndef _MEMORY_H #define _MEMORY_H #include "types.h" #include "bootmiddle.h" #define MAX_MHOLES 8192 #define KERNEL_MEMBASE 0x100000 #define MIN_MEMSIZE 32 #define KFREE_OK 1 #define KFREE_FAIL 0 typedef struct _MemHole { u_int32_t base; u_int32_t size; struct _MemHole* prev; struct _MemHole* next; } MemHole; MemHole memhole[MAX_MHOLES]; MemHole mfree_list; MemHole mhole_list; void init_mem(); MemHole* kalloc(u_int32_t size); int32_t kfree(MemHole* mem); void sysPrintMem(); #define MHOLE_REMOVE(p) do { \ p->prev->next = p->next; \ p->next->prev = p->prev; \ } while(0) #define MHOLES_REMOVE(to, from) do { \ to->prev->next = from->next; \ from->next->prev = to->prev; \ } while(0) #define MHOLE_CLEAN(p) do { \ p->base = 0; \ p->size = 0; \ } while (0) #define MHOLE_INSERT_HEAD(p, head) do { \ head.next->prev = p; \ p->next = head.next; \ head.next = p; \ p->prev = &head; \ } while(0) #define MHOLE_INSERT_TAIL(p, head) do { \ head.prev->next = p; \ p->prev = head.prev; \ head.prev = p; \ p->next = &head; \ } while(0) #define MHOLE_INSERT_BEFORE(p, ep) do { \ ep->prev->next = p; \ p->prev = ep->prev; \ ep->prev = p; \ p->next = ep; \ } while(0) #define MHOLE_INSERT_AFTER(p, ep) do { \ ep->next->prev = p; \ p->next = ep->next; \ ep->next = p; \ p->prev = ep; \ } while(0) #endif /* _MEMORY_H */
memory.c
/* * @File memory.c * @Brief manage the memory for kernel * * @Author Sodex * @Revision 0.1 * @License suspension * @Date creae: 2007/04/25 update: 2007/04/25 * * Copyright (C) 2007 Sodex */ #include "memory.h" #include "vga.h" static void merge_hole(MemHole* memfrom, MemHole* memto); static MemHole* newMhole(); void init_mem() { int i; for (i = 0; i < MAX_MHOLES; ++i) { if (i == MAX_MHOLES - 1) memhole[i].next = &mhole_list; else memhole[i].next = &memhole[i+1]; if (i == 0) memhole[i].prev = &mhole_list; else memhole[i].prev = &memhole[i-1]; } mhole_list.next = &memhole[0]; mhole_list.prev = &memhole[MAX_MHOLES-1]; memhole[0].prev = &mhole_list; memhole[MAX_MHOLES-1].next = &mhole_list; mhole_list.base = 0; mhole_list.size = 0; mfree_list.base = 0; mfree_list.size = 0; //initial mfree_list setting mfree_list.next = &mfree_list; mfree_list.prev = &mfree_list; MemHole* mem = mhole_list.next; MHOLE_REMOVE(mem); MHOLE_INSERT_HEAD(mem, mfree_list); mfree_list.next->base = KERNEL_MEMBASE; mfree_list.next->size = MAXMEMSIZE - KERNEL_MEMBASE; } int32_t kfree(MemHole* mem) { // We use the first-fit-algorithm for searching right base. MemHole* i; for (i = mfree_list.next; i != &mfree_list; i = i->next) { if (i->base > mem->base) { if (mem->base + mem->size > i->base) return KFREE_FAIL; MHOLE_INSERT_BEFORE(mem, i); } } /* Although mem->prev == &mfree_list, mfree_list's base + its size never * equal this mem base, because mfree_list's base and size is always 0 * and all mem's base is not 0. * Likewise, if mem->next == &mfree_list, this mem's base + size never * equal mfree_list's base. */ if (mem->prev->base + mem->prev->size == mem->base && mem->base + mem->size == mem->next->base) { merge_hole(mem->prev, mem->next); } else if (mem->prev->base + mem->prev->size == mem->base) { merge_hole(mem->prev, mem); } else if (mem->base + mem->size == mem->next->base) { merge_hole(mem, mem->next); } else { return KFREE_FAIL; } return KFREE_OK; } static void merge_hole(MemHole* memfrom, MemHole* memto) { MemHole *i, *j, *next; for (i = memfrom->next; i != memto->next; i = i->next) { memfrom->size += i->size; } i = memfrom->next; next = memto->next; while (i != next) { j = i->next; MHOLE_REMOVE(i); MHOLE_CLEAN(i); MHOLE_INSERT_HEAD(i, mhole_list); i = j; } } MemHole* kalloc(u_int32_t size) { MemHole *i, *new; for (i = mfree_list.next; i != &mfree_list; i = i->next) { if (i->size > size) { if (i->size - size > MIN_MEMSIZE) { new = newMhole(); if (new == NULL) sysPrints("newMhole() error\n"); new->base = i->base; new->size = size; i->base += size; i->size -= size; return new; } else { MHOLE_REMOVE(i); return i; } } else if (i->size == size) { MHOLE_REMOVE(i); return i; } } return NULL; } static MemHole* newMhole() { MemHole* ret; ret = mhole_list.next; MHOLE_REMOVE(ret); return ret; } void sysPrintMem() { u_int8_t count = 0; MemHole* i; for (i = mfree_list.next; i != &mfree_list; i = i->next) { sysPrints("Memhole base = "); sysPrintBin32(i->base); sysPrintc(' '); sysPrints("Memhole size = "); sysPrintBin32(i->size); sysPrintc('\n'); count++; } sysPrints("The num of mfree_list is "); sysPrintBin(count); sysPrints("\n"); }
kernel.c
メモリ管理テスト
#include "bootmiddle.h" #include "kernel.h" #include "descriptor.h" #include "vga.h" #include "memory.h" void startKernel() { init_setupgdt(); init_setupidthandlers(); init_setupidt(); init_mem(); sysScreenInitial(); //for memory test sysPrintMem(); MemHole *new1, *new2, *new3, *new4; new1 = kalloc(512); if (new1 == NULL) sysPrints("kalloc error\n"); sysPrintMem(); new2 = kalloc(256); if (new2 == NULL) sysPrints("kalloc error\n"); sysPrintMem(); new3 = kalloc(256); if (new3 == NULL) sysPrints("kalloc error\n"); sysPrintMem(); new4 = kalloc(1024); if (new4 == NULL) sysPrints("kalloc error\n"); sysPrintMem(); kfree(new2); sysPrintMem(); kfree(new3); sysPrintMem(); kfree(new4); sysPrintMem(); for(;;); }