[BACK]Return to kern_mem.c CVS log [TXT][DIR] Up to [local] / funnyos / kern

Annotation of funnyos/kern/kern_mem.c, Revision 1.3

1.1       init        1: /*
1.3     ! init        2:  * $Id: kern_mem.c,v 1.2 2007/10/16 11:43:11 init Exp $
1.1       init        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:
                    158:                                        /* rewind pointer to the first byte */
                    159:                                        firstpageptr = lastpageptr - ((npages - 1));
                    160:
                    161:                                        offbits = mask ? mask - 1 : mask;       /* XXX */
                    162:                                        /* fill this (npages pages) region with zeroes */
                    163:                                        while(firstpageptr <= lastpageptr) {
                    164:
                    165:                                                /* TODO invalidate page in membmap */
                    166:                                                offbytes = ((uint32_t)firstpageptr - (uint32_t)allocbase) / (KMEM_PAGESIZE * 8);
                    167: //                                             printf("offbytes=%d\n", offbytes);
                    168: //                                             printf("membmap[%d] |= 1 << %d\n", offbytes, offbits);
                    169:                                                membmap[offbytes] |= 1 << offbits;
                    170:
                    171:                                                /* zerofy page */
                    172:                                                for (i = 0; i < KMEM_PAGESIZE; i++) {
1.3     ! init      173:                                                        *(uint8_t *)firstpageptr = KMEM_FILLBYTE;
1.1       init      174:                                                        ((uint8_t *)firstpageptr)++;
                    175:                                                }
                    176:                                                /* TODO rework offbits calculation */
                    177:                                                offbits++;
                    178:                                                if(offbits == 8)
                    179:                                                        /* reset to the first bit */
                    180:                                                        offbits = 0;
                    181:                                        }
                    182:
                    183:                                        /* rewind pointer again */
                    184:                                        firstpageptr = lastpageptr - ((npages - 1));
                    185:
                    186:                                        /* got it */
1.2       init      187:                                        DPRINTF("allocated, addr=0x%x len=0x%x [0x%x-0x%x]\n", firstpageptr, npages * KMEM_PAGESIZE, firstpageptr, lastpageptr);
1.1       init      188:
                    189:                                        /* decrement system free pages */
                    190:                                        freepages -= npages;
                    191:
                    192:                                        /* return pointer to the first byte of the allocated region */
                    193:                                        return(firstpageptr);
                    194:                                }
                    195:                        } else {
                    196:                                /* encountered non-free page; reset pagesfound */
                    197:                                pagesfound = 0;
                    198:                        }
                    199:
                    200:                        /* shift to check next bit */
                    201:                        mask <<= 1;
                    202:                        nmbmbits++;
                    203:                }
                    204:
                    205:        }
                    206:
                    207:        /* free pages haven't been found */
                    208:        DPRINTF("not found contiguous region\n");
                    209:
                    210:        return(NULL);
                    211: }
                    212:
                    213:
                    214: void
                    215: kfree(void *p, uint32_t nbytes)
                    216: {
                    217:        /*
                    218:         * XXX Free nbytes bytes
                    219:        */
                    220: }
                    221:

CVSweb