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

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