Annotation of funnyos/kern/kern_mem.c, Revision 1.1.1.1
1.1 init 1: /*
2: * $Id: kern_mem.c,v 1.1.1.1 2007/10/12 08:40:38 init Exp $
3: */
4: #include <sys/types.h>
5: #include <sys/mem.h>
6: #include <libkern/printf.h>
7:
8: #define KMEM_DEBUG
9:
10: #ifdef KMEM_DEBUG
11: #define DPRINTF(x...) do { printf(x); } while (0)
12: #else
13: #define DPRINTF(x...) { }
14: #endif
15:
16: /*
17: * Kernel memory.
18: *
19: * Our memory map looks like that (at least for testarm with 32MB):
20: * (0MB) 0x00000000 | interrupt vectors (actually kernel text)
21: * ...
22: * 0x00000020 | kernel text (continue)
23: * ...
24: * 0x000fffff | END of kernel text
25: *
26: * (1MB) 0x00100000 | kernel data
27: * ... (1MB of kernel data)
28: * 0x001fffff | END of kernel data
29: *
30: * (2MB) 0x00200000 | heap start (grows downwards)
31: * ... (28MB of heap)
32: *
33: * (30MB) 0x01e00000 <---- brk address
34: *
35: * ... (2MB of stack)
36: * (32MB) 0x01ffffff | stack pointer (grows upwards)
37: *
38: * XXX very-very tiny memory model for my at91sam7s64
39: */
40:
41: /* config.c exports us ammount of available physical memory. */
42: extern uint32_t physmem;
43:
44: /* break address */
45: //uint32_t brkaddr = (KMEM_HEAPBEGIN + (physmem - KMEM_HEAPBEGIN) / 2)
46: // + (physmem - KMEM_HEAPBEGIN)
47: uint32_t brkaddr;
48:
49: /* from where to allocate memory in kmalloc() */
50: uint32_t allocbase;
51:
52: /* stack pointer */
53: uint32_t sp;
54:
55: /* memory bit map pointer and its length */
56: uint8_t *membmap;
57: uint32_t membmaplen;
58:
59: /* pages statistics */
60: uint32_t totalpages;
61: uint32_t freepages;
62:
63:
64: void
65: kmem_init(void)
66: {
67: /*
68: * Initialize kernel memory (de)allocation subsystem.
69: * This allocates bit map, each BIT of it represents one kmem page.
70: * kmem page is KMEM_PAGESIZE bytes length and may be 0 (free) or 1 (not free) in membmap.
71: */
72: int32_t n;
73: uint8_t *bytep;
74:
75: /* set break address */
76: brkaddr = physmem - (physmem / 16); /* XXX top 2MB in testarm */
77:
78: /* bytes needed to hold bitmap */
79: membmaplen = ((brkaddr - KMEM_HEAPBEGIN) / KMEM_PAGESIZE) / 8;
80:
81: /* total pages that will be available to kernel */
82: totalpages = (brkaddr - (KMEM_HEAPBEGIN + membmaplen)) / KMEM_PAGESIZE; /* XXX what about potential modulo? */
83: freepages = totalpages;
84:
85: /* allocate space for membmap in the beginning of KMEM_HEAPBEGIN */
86: bytep = (uint8_t *) KMEM_HEAPBEGIN;
87: n = membmaplen;
88:
89: while(n) {
90: /* XXX what about errors? */
91: *bytep = 0;
92: bytep++;
93:
94: n--;
95: }
96:
97: membmap = (uint8_t *)KMEM_HEAPBEGIN;
98:
99: /* skip our map; all allocations will be done starting from this */
100: allocbase = KMEM_HEAPBEGIN + membmaplen;
101:
102: printf("kmem_init: membmap @0x%x size=%d pagesize=%d; %d total pages available starting from 0x%x\n",
103: membmap, membmaplen, KMEM_PAGESIZE, totalpages, allocbase);
104: }
105:
106:
107: void
108: *kmalloc(uint32_t nbytes)
109: {
110: /*
111: * Allocate nbytes bytes of memory
112: */
113: uint32_t pagesfound, npages, nmbmbytes, firstmbmbit;
114: uint8_t *mbmbyte, mask, nmbmbits, i, offbits;
115: uint32_t *firstpageptr, *lastpageptr, mbmbit, offbytes;
116:
117:
118: /* kmalloc(0) should return NULL */
119: if (! nbytes)
120: return(NULL);
121:
122: /* pages needed to hold requested bytes */
123: npages = nbytes / KMEM_PAGESIZE + (nbytes % KMEM_PAGESIZE != 0 ? 1 : 0);
124:
125: DPRINTF("kmalloc: requested %d bytes (%d pages) of %d free pages; ", nbytes, npages, freepages);
126:
127: /* check if we have enough free pages */
128: if (npages >= freepages) {
129: DPRINTF("not enough free pages\n");
130: return(NULL);
131: }
132:
133: pagesfound = 0;
134: nmbmbytes = 0;
135: /* look for contiguously available pages in memory bit map */
136: for (mbmbyte = membmap; nmbmbytes < membmaplen; nmbmbytes++) {
137:
138: mask = 0x01;
139: nmbmbits = 0; /* counts "free page" bits inside mbmbyte */
140:
141: /* check all 8 bits in mbmbyte */
142: while(mask != 0) {
143:
144: // printf("0x%x @ 0x%x & %x\n", *mbmbyte, mbmbyte, mask);
145: if ((mbmbyte[nmbmbytes] & mask) == 0) {
146: /* page is free */
147: pagesfound++;
148:
149: /* see if we need not to search more */
150: if (pagesfound == npages) {
151: /*
152: * Requested amount of pages have been found.
153: */
154:
155: /* calculate pointer to this (last) page */
156: lastpageptr = (uint32_t *)((allocbase + (8 * nmbmbytes * KMEM_PAGESIZE)) + (KMEM_PAGESIZE * nmbmbits));
157: DPRINTF("lastpageptr=0x%x\n", lastpageptr);
158:
159: /* rewind pointer to the first byte */
160: firstpageptr = lastpageptr - ((npages - 1));
161: DPRINTF("firstpageptr=0x%x\n", firstpageptr);
162:
163: offbits = mask ? mask - 1 : mask; /* XXX */
164: /* fill this (npages pages) region with zeroes */
165: while(firstpageptr <= lastpageptr) {
166:
167: /* TODO invalidate page in membmap */
168: offbytes = ((uint32_t)firstpageptr - (uint32_t)allocbase) / (KMEM_PAGESIZE * 8);
169: // printf("offbytes=%d\n", offbytes);
170: // printf("membmap[%d] |= 1 << %d\n", offbytes, offbits);
171: membmap[offbytes] |= 1 << offbits;
172:
173: /* zerofy page */
174: for (i = 0; i < KMEM_PAGESIZE; i++) {
175: *(uint8_t *)firstpageptr = 0xaa;
176: ((uint8_t *)firstpageptr)++;
177: }
178: /* TODO rework offbits calculation */
179: offbits++;
180: if(offbits == 8)
181: /* reset to the first bit */
182: offbits = 0;
183: }
184:
185: /* rewind pointer again */
186: firstpageptr = lastpageptr - ((npages - 1));
187:
188: /* got it */
189: DPRINTF("allocated, addr=0x%x\n", firstpageptr);
190:
191: /* decrement system free pages */
192: freepages -= npages;
193:
194: /* return pointer to the first byte of the allocated region */
195: return(firstpageptr);
196: }
197: } else {
198: /* encountered non-free page; reset pagesfound */
199: pagesfound = 0;
200: }
201:
202: /* shift to check next bit */
203: mask <<= 1;
204: nmbmbits++;
205: }
206:
207: }
208:
209: /* free pages haven't been found */
210: DPRINTF("not found contiguous region\n");
211:
212: return(NULL);
213: }
214:
215:
216: void
217: kfree(void *p, uint32_t nbytes)
218: {
219: /*
220: * XXX Free nbytes bytes
221: */
222: }
223:
CVSweb