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

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

1.1       init        1: /*
1.8     ! init        2:  * $Id: kern_mem.c,v 1.7 2007/10/26 13:15:20 init Exp $
1.1       init        3:  */
                      4: #include <sys/types.h>
                      5: #include <sys/mem.h>
                      6: #include <libkern/printf.h>
                      7:
1.5       init        8: /* #define KMEM_DEBUG */
1.1       init        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:
1.8     ! init       75: #ifdef ARCH_SAM7S64
        !            76:        /* XXX UGLY HACK */
        !            77:        brkaddr = 0x00203800;
        !            78: #else
1.1       init       79:        /* set break address */
                     80:        brkaddr = physmem - (physmem / 16); /* XXX top 2MB in testarm */
1.8     ! init       81: #endif
1.1       init       82:        /* bytes needed to hold bitmap */
                     83:        membmaplen = ((brkaddr - KMEM_HEAPBEGIN) / KMEM_PAGESIZE) / 8;
                     84:
                     85:        /* total pages that will be available to kernel */
                     86:        totalpages = (brkaddr - (KMEM_HEAPBEGIN + membmaplen)) / KMEM_PAGESIZE; /* XXX what about potential modulo? */
                     87:        freepages = totalpages;
                     88:
                     89:        /* allocate space for membmap in the beginning of KMEM_HEAPBEGIN */
                     90:        bytep = (uint8_t *) KMEM_HEAPBEGIN;
                     91:        n = membmaplen;
                     92:
                     93:        while(n) {
                     94:                /* XXX what about errors? */
                     95:                *bytep = 0;
                     96:                bytep++;
                     97:
                     98:                n--;
                     99:        }
                    100:
                    101:        membmap = (uint8_t *)KMEM_HEAPBEGIN;
                    102:
                    103:        /* skip our map; all allocations will be done starting from this */
                    104:        allocbase = KMEM_HEAPBEGIN + membmaplen;
                    105:
                    106:        printf("kmem_init: membmap @0x%x size=%d pagesize=%d; %d total pages available starting from 0x%x\n",
                    107:                                membmap, membmaplen, KMEM_PAGESIZE, totalpages, allocbase);
                    108: }
                    109:
                    110:
                    111: void
                    112: *kmalloc(uint32_t nbytes)
                    113: {
                    114:        /*
                    115:         * Allocate nbytes bytes of memory
                    116:         */
                    117:        uint32_t        pagesfound, npages, nmbmbytes, firstmbmbit;
                    118:        uint8_t         *mbmbyte, mask, nmbmbits, i, offbits;
                    119:        uint32_t        *firstpageptr, *lastpageptr, mbmbit, offbytes;
                    120:
                    121:
                    122:        /* kmalloc(0) should return NULL */
                    123:        if (! nbytes)
                    124:                return(NULL);
                    125:
                    126:        /* pages needed to hold requested bytes */
                    127:        npages = nbytes / KMEM_PAGESIZE + (nbytes % KMEM_PAGESIZE != 0 ? 1 : 0);
                    128:
                    129:        DPRINTF("kmalloc: requested %d bytes (%d pages) of %d free pages; ", nbytes, npages, freepages);
                    130:
                    131:        /* check if we have enough free pages */
1.6       init      132:        if (npages > freepages) {
1.1       init      133:                DPRINTF("not enough free pages\n");
                    134:                return(NULL);
                    135:        }
                    136:
                    137:        pagesfound = 0;
                    138:        nmbmbytes = 0;
                    139:        /* look for contiguously available pages in memory bit map */
                    140:        for (mbmbyte = membmap; nmbmbytes < membmaplen; nmbmbytes++) {
                    141:
                    142:                mask = 0x01;
                    143:                nmbmbits = 0; /* counts "free page" bits inside mbmbyte */
                    144:
                    145:                /* check all 8 bits in mbmbyte */
                    146:                while(mask != 0) {
                    147:
                    148: //                     printf("0x%x @ 0x%x & %x\n", *mbmbyte, mbmbyte, mask);
                    149:                        if ((mbmbyte[nmbmbytes] & mask) == 0) {
                    150:                                /* page is free */
                    151:                                pagesfound++;
                    152:
                    153:                                /* see if we need not to search more */
                    154:                                if (pagesfound == npages) {
                    155:                                        /*
                    156:                                         * Requested amount of pages have been found.
                    157:                                         */
                    158:
                    159:                                        /* calculate pointer to this (last) page */
                    160:                                        lastpageptr = (uint32_t *)((allocbase + (8 * nmbmbytes * KMEM_PAGESIZE)) + (KMEM_PAGESIZE * nmbmbits));
                    161:
                    162:                                        /* rewind pointer to the first byte */
                    163:                                        firstpageptr = lastpageptr - ((npages - 1));
                    164:
                    165:                                        /* fill this (npages pages) region with zeroes */
                    166:                                        while(firstpageptr <= lastpageptr) {
                    167:
                    168:                                                /* TODO invalidate page in membmap */
                    169:                                                offbytes = ((uint32_t)firstpageptr - (uint32_t)allocbase) / (KMEM_PAGESIZE * 8);
1.7       init      170:                                                offbits = ((uint32_t)firstpageptr - (uint32_t)allocbase) / (KMEM_PAGESIZE);
                    171:
                    172:                                                if (offbits > 7)
                    173:                                                        offbits -= 8 * (offbits / 8);
                    174:
1.1       init      175: //                                             printf("membmap[%d] |= 1 << %d\n", offbytes, offbits);
                    176:                                                membmap[offbytes] |= 1 << offbits;
                    177:
                    178:                                                /* zerofy page */
                    179:                                                for (i = 0; i < KMEM_PAGESIZE; i++) {
1.3       init      180:                                                        *(uint8_t *)firstpageptr = KMEM_FILLBYTE;
1.1       init      181:                                                        ((uint8_t *)firstpageptr)++;
                    182:                                                }
                    183:                                                /* TODO rework offbits calculation */
                    184:                                                offbits++;
                    185:                                                if(offbits == 8)
                    186:                                                        /* reset to the first bit */
                    187:                                                        offbits = 0;
                    188:                                        }
                    189:
                    190:                                        /* rewind pointer again */
                    191:                                        firstpageptr = lastpageptr - ((npages - 1));
                    192:
                    193:                                        /* got it */
1.7       init      194:                                        DPRINTF("allocated, addr=0x%x len=%d [0x%x-0x%x]\n", firstpageptr, npages * KMEM_PAGESIZE, firstpageptr, lastpageptr);
1.1       init      195:
                    196:                                        /* decrement system free pages */
                    197:                                        freepages -= npages;
                    198:
                    199:                                        /* return pointer to the first byte of the allocated region */
                    200:                                        return(firstpageptr);
                    201:                                }
                    202:                        } else {
                    203:                                /* encountered non-free page; reset pagesfound */
                    204:                                pagesfound = 0;
                    205:                        }
                    206:
                    207:                        /* shift to check next bit */
                    208:                        mask <<= 1;
                    209:                        nmbmbits++;
                    210:                }
                    211:
                    212:        }
                    213:
                    214:        /* free pages haven't been found */
                    215:        DPRINTF("not found contiguous region\n");
                    216:
                    217:        return(NULL);
                    218: }
                    219:
                    220:
                    221: void
                    222: kfree(void *p, uint32_t nbytes)
                    223: {
                    224:        /*
                    225:         * XXX Free nbytes bytes
                    226:        */
                    227: }
                    228:

CVSweb