Annotation of funnyos/kern/kern_mem.c, Revision 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