commited some changes and added README
[meinos.git] / kernel2 / memkernel.c
blob8f3504ad6812e0cddfefa401c34f31e9972b1c91
1 /*
2 meinOS - A unix-like x86 microkernel operating system
3 Copyright (C) 2008 Janosch Gräf <janosch.graef@gmx.net>
5 This program is free software: you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation, either version 3 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
19 #include <sys/types.h>
20 #include <memkernel.h>
21 #include <memuser.h>
22 #include <memphys.h>
23 #include <memmap.h>
24 #include <paging.h>
25 #include <malloc.h>
26 #include <debug.h>
28 /**
29 * Initializes kernel memory management
30 * @return 0=Success; -1=Failure
32 void *init_stack;
33 size_t init_stacksize;
34 void malloc_init(void *(*getpage)(size_t size),void (*freepage)(void *addr));
35 void malloc_donatemem(void *addr,size_t size);
36 int memkernel_init() {
37 malloc_init(memkernel_alloc,memkernel_free);
38 malloc_donatemem(init_stack,init_stacksize); // donate initial stack to memory allocator
39 return 0;
42 /**
43 * Finds free virtual pages
44 * @param pages How many pages wanted
45 * @return Address of first page
47 void *memkernel_findvirt(size_t pages) {
48 void *virt;
49 size_t found = 0;
51 for (virt = (void*)KERNELDATA_ADDRESS;virt<(void*)KERNELDATA_ADDRESS+KERNELDATA_SIZE;virt+=PAGE_SIZE) {
52 // check if enough pages are found
53 if (found>=pages) return virt-found*PAGE_SIZE;
54 if (ADDR2PTE(virt)==0) {
55 // check for PDE
56 if (!paging_getpde(virt).exists) {
57 found += 1024;
58 virt += 1024*(PAGE_SIZE-1);
59 continue;
62 // check for PTE
63 if (paging_getpte(virt).exists) found = 0;
64 else found++;
67 return NULL;
70 /**
71 * Allocates memory for kernel allocator
72 * @param size How many memory to allocate (should be devidable by PAGE_SIZE)
73 * @return Address of allocated memory
75 void *memkernel_alloc(size_t size) {
76 size_t pages = ADDR2PAGE(size);
77 size_t i;
78 void *virt = memkernel_findvirt(pages);
80 for (i=0;i<pages;i++) {
81 paging_map(virt+i*PAGE_SIZE,memphys_alloc(),0,1);
82 if (memuser_inited) memuser_syncpds(virt+i);
84 return virt;
87 /**
88 * Frees memory (one page) for kernel allocator
90 void memkernel_free(void *addr) {
91 memphys_free(paging_unmap(addr));