⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mem.c

📁 一款类linux的操作系统源码
💻 C
字号:
/*  *  Roadrunner/pk *    Copyright (C) 1989-2001  Cornfed Systems, Inc. * *  The Roadrunner/pk operating system is free software; you can *  redistribute and/or modify it under the terms of the GNU General *  Public License, version 2, as published by the Free Software *  Foundation. * *  This program is distributed in the hope that it will be useful, *  but WITHOUT WARRANTY; without even the implied warranty of *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the *  GNU General Public License for more details. * *  You should have received a copy of the GNU General Public *  License along with this program; if not, write to the Free *  Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, *  MA 02111-1307 USA * *  More information about the Roadrunner/pk operating system of *  which this file is a part is available on the World-Wide Web *  at: http://www.cornfed.com. * */#include <errno.h>#include <stdio.h>#include <stdlib.h>#include <string.h>#include <sys.h>#include <sys/intr.h>#include <sys/mem.h>#include <sys/vm.h>//2002年09月12日修改/* Start and end of kernel ELF executable image loaded into memory */
extern char Image$$RO$$Base,Image$$RW$$Limit;

size_t kernsize;size_t memsize;region_t regiontab;region_t freelist, alloclist;voidmem_init(){    int regiontabsize, region_high, i;      memsize = RD_FIRST - REGION_LOW; // RD_FIRST 在 config.h 中有定义    /* Determine kernel size */    kernsize = ALIGN((u_long) & Image$$RW$$Limit - (u_long) & Image$$RO$$Base, PAGE_SIZE);    /* Allocate region table */    regiontab = (region_t) REGION_LOW;    regiontabsize = REGIONS * sizeof(struct region);    regiontabsize = ALIGN(regiontabsize, PAGE_SIZE);    /* Clear region table */    for (i = 0; i < REGIONS; i++)	region_clear(&(regiontab[i]));    /* High region begins after the kernel code and data */    region_high = ALIGN((u_long) & Image$$RW$$Limit, PAGE_SIZE);    /* Low memory is allocated for the initial region table */    regiontab[0].start = REGION_LOW;    regiontab[0].len = regiontabsize;    regiontab[0].prev = NULL;    regiontab[0].next = &(regiontab[2]);    /* Region below Kernel code is free */    regiontab[1].start = REGION_LOW + regiontabsize;    regiontab[1].len = (u_long)&Image$$RO$$Base - (REGION_LOW + regiontabsize);    regiontab[1].prev = NULL;    regiontab[1].next = &(regiontab[3]);    /* Kernel regions are allocated */    regiontab[2].start = (u_long)&Image$$RO$$Base;    regiontab[2].len = region_high - (u_long)&Image$$RO$$Base;    regiontab[2].prev = &(regiontab[0]);    regiontab[2].next = NULL;    /* Region above kernel is free */    regiontab[3].start = region_high;    regiontab[3].len = memsize - region_high + REGION_LOW;    regiontab[3].prev = &(regiontab[1]);    regiontab[3].next = NULL;    /* Initial free and allocated lists */    freelist = &(regiontab[1]);    alloclist = &(regiontab[0]);}void *mem_alloc(size_t size){    region_t r;    /* Increase size request to next multiple of page size */    size = ALIGN(size, PAGE_SIZE);    /* First-fit search for free region */    for (r = freelist; r != NULL && r->len < size; r = r->next);    if (r == NULL)	return NULL;    /* Split region into used and unused portions */    if (r->len > size)	region_split(r, size);    /* Move used portion from free to allocated list */    region_remove(r, &freelist);    region_insert(r, &alloclist);    /* Assign ownership of region to calling thread */    if (current != NULL)	r->proc = current->slot;    return (void *) r->start;}intmem_free(void *start){    region_t r, s;    if ((r = valid_region(start)) == NULL)	return EINVAL;    /* Move region from allocated to free list */    region_remove(r, &alloclist);    region_insert(r, &freelist);    /* Clear ownership */    r->proc = (-1);    /* Merge with previous regions */    for (s = r->prev;	 s != NULL && s->start + s->len == r->start; r = s, s = s->prev) {	s->len += r->len;	region_remove(r, &freelist);	region_clear(r);    }    /* Merge with next regions */    for (s = r->next; s != NULL && r->start + r->len == s->start; s = r->next) {	r->len += s->len;	region_remove(s, &freelist);	region_clear(s);    }    return 0;}voidmem_reclaim(proc_t proc){    region_t r;    /* Free all allocated regions owned by specified process */    for (r = alloclist; r != NULL;) {	if (r->proc == proc->slot) {	    mem_free((void *) r->start);	    r = alloclist;	    continue;	}	r = r->next;    }}intmem_transfer(void *start, proc_t proc){    region_t r;    if ((r = valid_region(start)) == NULL)	return EINVAL;    /* Transfer ownership of region to specified process */    if (proc == NULL)	r->proc = (-1);    else	r->proc = proc->slot;    return 0;}//2002年10月09日修改/*void *kmalloc(size_t size){    void *ptr;    struct vm_kmap_entry entry;    disable;    ptr = mem_alloc(size);    if (ptr == NULL) {	enable;	return NULL;    }    mem_transfer(ptr, NULL);    entry.start = ptr;    entry.len = size;    entry.attr = PTE_WRITE | PTE_PRESENT;    vm_kmap_insert(&entry);    enable;    return ptr;}voidkfree(void *ptr){    region_t r;    struct vm_kmap_entry entry;    disable;    if ((r = valid_region(ptr)) == NULL) {	enable;	return;    }    entry.start = ptr;    entry.len = r->len;    entry.attr = 0;    vm_kmap_remove(&entry);    mem_free(ptr);    enable;}*/void *malloc(size_t size){    void *ptr;    disable;    ptr = mem_alloc(size);    if (ptr == NULL) {	enable;	return NULL;    }        //2002年10月09日修改-vm    //vm_map_range((pt_t) current->context.tss->cr3, ptr, size,	//	 PTE_USER | PTE_WRITE | PTE_PRESENT);    enable;    return ptr;}voidfree(void *ptr){    region_t r;    disable;    if ((r = valid_region(ptr)) == NULL) {	enable;	return;    }    //2002年10月09日修改-vm    //vm_unmap_range((pt_t) current->context.tss->cr3, ptr, r->len);    mem_free(ptr);    enable;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -