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

📄 address_space.c

📁 一个操作系统的源代码
💻 C
字号:
/** address_space.c ** ** Original Author: Guido de Jong ** Date: 11/16/99 ** ** Description: ** Address space management functions **  ** This program is free software, you can redistribute it and/or ** modify it under the terms of the GNU General Public License ** as published by the Free Software Foundation; either version ** 2 of the License, or (at your option) any later version. ** ** This program is distributed in the hope that it will be ** useful, but WITHOUT ANY WARRANTY; without even the implied ** warranty or 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 ** *********************************************************Apostle OS**/#include <address_space.h>#include <mapping.h>#include <paging.h>#include <types.h>#include <mem.h>#include <string.h>#ifdef DEBUG#include <debug/conio.h>#endif/* map * * Share page control with another address space. * If necessary page tables and node tables are created and initialized. */void map(dword *srcAddrSp, void *src, dword *destAddrSp, void *dest, size_t n, int flags){  uint i;  dword *srcPT, *destPT;  MappingNode **srcNT, **destNT;  dword srcPage = ((dword) src) >> 12, destPage = ((dword) dest) >> 12;  for (i = 0; i < n; i++)    {      /* Initializing page and node tables */      if (srcAddrSp[srcPage >> 10] & PAGE_PRESENT)        {          srcPT = (dword *)(srcAddrSp[srcPage >> 10] & 0xfffff000);          srcNT = (MappingNode **)((dword)srcPT + PAGE_SIZE);        }      else        {          srcPT = NULL;          srcNT = NULL;        }      if (destAddrSp[destPage >> 10] & PAGE_PRESENT)        {          destPT = (dword *)(destAddrSp[destPage >> 10] & 0xfffff000);          destNT = (MappingNode **)((dword)destPT + PAGE_SIZE);        }      else        {          destPT = p2malloc();          destAddrSp[destPage >> 10 ] = (dword) destPT \			| PAGE_USER | PAGE_WRITABLE | PAGE_PRESENT;          destNT = (MappingNode **)((dword)destPT + PAGE_SIZE);          memset(destNT, 0, PAGE_SIZE);        }      /* create source node if necessarry (1st time map) */      if (srcNT[srcPage & 0x3ff] == NULL)        srcNT[srcPage & 0x3ff] = NewMappingNode(srcAddrSp, src);      /* destination mapping node should not exist ... */      if (destNT[destPage & 0x3ff] != NULL)        flush(destNT[destPage & 0x3ff]->addrSpace,	      destNT[destPage & 0x3ff]->address, PAGE_SIZE, TRUE, TRUE);      destNT[destPage & 0x3ff] = NewMappingNode(destAddrSp, dest);      AddNode(srcNT[srcPage & 0x3ff], destNT[destPage & 0x3ff]);      /* do the actual mapping */      if (srcPT == NULL)        destPT[destPage & 0x3ff] = 0;      else          destPT[destPage & 0x3ff] = (srcPT[srcPage & 0x3ff] & 0xfffff000) \                                     | (flags & 0x0fff);      srcPage++;      destPage++;    }}/* grant * * Grant exclusive page control to another address space. * If necessary page tables and node tables are created and initialized. */void grant(dword *srcAddrSp, void *src, dword *destAddrSp, void *dest, size_t n, int flags){  uint i;  dword *srcPT, *destPT;  MappingNode **srcNT, **destNT;  dword srcPage = ((dword) src) >> 12, destPage = ((dword) dest) >> 12;  for (i = 0; i < n; i++)    {      /* Initializing page and node tables */      if (srcAddrSp[srcPage >> 10] & PAGE_PRESENT)        {          srcPT = (dword *)(srcAddrSp[srcPage >> 10] & 0xfffff000);          srcNT = (MappingNode **)((dword)srcPT + PAGE_SIZE);        }      else        {          srcPT = NULL;          srcNT = NULL;        }      if (destAddrSp[destPage >> 10] & PAGE_PRESENT)        {          destPT = (dword *)(destAddrSp[destPage >> 10] & 0xfffff000);          destNT = (MappingNode **)((dword)destPT + PAGE_SIZE);        }      else        {          destPT = p2malloc();          destAddrSp[destPage >> 10 ] = (dword) destPT \			| PAGE_USER | PAGE_WRITABLE | PAGE_PRESENT;          destNT = (MappingNode **)((dword)destPT + PAGE_SIZE);          memset(destNT, 0, PAGE_SIZE);        }      /* destination mapping node should not exist ... */      if (destNT[destPage & 0x3ff] != NULL)        flush(destNT[destPage & 0x3ff]->addrSpace,	      destNT[destPage & 0x3ff]->address, PAGE_SIZE, TRUE, TRUE);      /* Source node will never be created here. If it does not exist,       * there's no need for a destination node either. If it does exist,       * just swap pointers and update node attributes. */      if (srcNT[srcPage & 0x3ff] == NULL)        destNT[destPage & 0x3ff] = NULL;      else        {          destNT[destPage & 0x3ff] = srcNT[srcPage & 0x3ff];          destNT[destPage & 0x3ff]->addrSpace = destAddrSp;          destNT[destPage & 0x3ff]->address = dest;          srcNT[srcPage & 0x3ff] = NULL;        }      /* do the actual granting */      if (srcPT == NULL)        destPT[destPage & 0x3ff] = 0;      else          destPT[destPage & 0x3ff] = srcPT[srcPage & 0x3ff] & \                                     (0xfffff000 | (flags & 0x0fff));      srcPage++;      destPage++;    }}/* flush *  * Return mapped/granted of pages back to parent. * Any possible mappings to other processes are unmapped.  */void flush(dword *addressSpace, void *addr, size_t n, bool me_too, bool partial){  int i;  dword *PT, page = (dword)addr >> 12;  MappingNode **NT, *node;  for (i = 0; i < n; i++)    {      if (addressSpace[page >> 10] & PAGE_PRESENT)        {	  PT = (dword *)(addressSpace[page >> 10] & 0xfffff000);          NT = (MappingNode **)((dword)PT + PAGE_SIZE);	}      else        {	  PT = NULL;	  NT = NULL;	}      if (NT)        {	  if (NT[page & 0x3ff]) /* we don't want to crash on NULL pointers */	    {	      node = NT[page & 0x3ff];	      /* flush any children */	      while (node->child)	        flush(node->child->addrSpace, node->child->address, n, TRUE, partial);	      if (me_too) /* return this page to parent */	        {		  if (partial)		    PT[page & 0x3ff] &= ~PAGE_WRITABLE;		  else		    {		      PT[page & 0x3ff] = 0;		      /* delete the node */		      DeleteNode(node);		      NT[page & 0x3ff] = NULL;		    }		}            }        }      addr++;    }}

⌨️ 快捷键说明

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