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

📄 sysgen.cxx

📁 C++ 编写的EROS RTOS
💻 CXX
字号:
/* * Copyright (C) 1998, 1999, 2001, Jonathan S. Shapiro. * * This file is part of the EROS Operating System. * * 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, * 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 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */#include <getopt.h>#include <stdlib.h>#include <stdio.h>#include <string.h>#include <assert.h>#include <disk/DiskNode.hxx>#include <disk/PagePot.hxx>#include <erosimg/App.hxx>#include <erosimg/Parse.hxx>#include <erosimg/Volume.hxx>#include <erosimg/ErosImage.hxx>#include <new.h>class App App("sysgen");Volume vol;const char* targname;const char* erosimage;uint32_t nThreads = 0;FILE *map_file = 0;inline uint32_tmin(uint32_t w0, uint32_t w1){  return (w0 < w1) ? w0 : w1;}voidRelocateKey(DiskKey& key, OID nodeBase, OID pageBase,	    uint32_t nPages){  if ( key.IsType(KT_Page) ) {    OID oid = pageBase + (key.unprep.oid * EROS_OBJECTS_PER_FRAME);    if (key.IsPrepared()) {      key.InitType(KT_Page);      key.SetUnprepared();      oid += (nPages * EROS_OBJECTS_PER_FRAME);    }    assert (oid < 0x100000000llu);        key.unprep.oid = oid;  }  else if (key.IsNodeKeyType()) {    OID oid = key.unprep.oid;    OID frame = oid / DISK_NODES_PER_PAGE;    OID offset = oid % DISK_NODES_PER_PAGE;    frame *= EROS_OBJECTS_PER_FRAME;    frame += nodeBase; /* JONADAMS: add in the node base */    oid = frame + offset;    assert (oid < 0x100000000llu);    key.unprep.oid = oid;  }}intmain(int argc, char *argv[]){  int c;  extern int optind;  extern char *optarg;  int opterr = 0;    while ((c = getopt(argc, argv, "m:")) != -1) {    switch(c) {    case 'm':      map_file = fopen(optarg, "w");      if (map_file == NULL)	return 0;            App.AddTarget(optarg);      break;    default:      opterr++;    }  }    argc -= optind;  argv += optind;    if (argc != 2)    opterr++;    if (opterr)    Diag::fatal(1, "Usage: sysgen [-m mapfile] volume-file eros-image\n");    targname = argv[0];  erosimage = argv[1];    if ( !vol.Open(targname, true) )    Diag::fatal(1, "Could not open \"%s\"\n", targname);    vol.ResetVolume();    ErosImage image;  image.ReadFromFile(erosimage);  uint32_t nSubMaps        = 0; /* number of pages of submaps                    */    uint32_t nObjectRange = 0;  for (int i = 0; i < vol.MaxDiv(); i++) {    const Division& d = vol.GetDivision(i);    if (d.type == dt_Object) {      RangeKey rk(d.startOid, d.endOid);      NodeKey nk((OID)0);      image.SetNodeSlot(nk, 3 + nObjectRange, rk);      if (d.startOid == 0) {	/* FIX: this should use OBCOUNT_MAX */	if (d.endOid - d.startOid >= (uint64_t) UINT32_MAX)	  Diag::fatal(1, "Object range w/ start OID=0x0 too "		      "large for sysgen\n");	  	/* store information about the size of the maps that need	 * to be set up for the SpaceBank.	 */#define DIVRNDUP(x,y) (((x) + (y) - 1)/(y))        uint32_t framesInRange = (d.endOid-d.startOid)/EROS_OBJECTS_PER_FRAME;	nSubMaps = DIVRNDUP(framesInRange,8*EROS_PAGE_SIZE);#undef DIVRNDUP      }      nObjectRange++;    }  }      uint32_t nPages = image.nPages;  uint32_t nZeroPages = image.nZeroPages;  uint32_t nNodes = image.nNodes;  DiskKey key;    uint32_t nodeFrames = (nNodes + DISK_NODES_PER_PAGE - 1) / DISK_NODES_PER_PAGE;  /* Originally, Jon Adams had this doing the map initialization   * here.  That functionality has been moved to the space bank.  All   * we need to do here is make sure that we pre-allocate the right   * number of frames so that when the space bank initializes the free   * frame list it won't step on anything important.   */    OID nodeBase = EROS_OBJECTS_PER_FRAME * nSubMaps;  OID pageBase = nodeBase + (EROS_OBJECTS_PER_FRAME * nodeFrames);  /* Copy all of the nodes, relocating the page key and cappage key   * OID's appropriately:   */  for (uint32_t ndx = 0; ndx < nNodes; ndx++) {    DiskNode node;    image.GetNodeContent(ndx, node);    /* Relocate zero page keys: */    for (uint32_t slot = 0; slot < EROS_NODE_SIZE; slot++) {      DiskKey& key = node[slot];      RelocateKey(key, nodeBase, pageBase, nPages);    }        OID frame = ndx / DISK_NODES_PER_PAGE;    OID offset = ndx % DISK_NODES_PER_PAGE;    frame *= EROS_OBJECTS_PER_FRAME;    frame += nodeBase; /* JONADAMS: add in the node base */    OID oid = frame + offset;    node.oid = oid;        vol.WriteNode(oid, node);    if (map_file != NULL)      fprintf(map_file, "image node ndx 0x%lx => disk node oid 0x%08lx%08lx\n",	      ndx, (uint32_t) (oid >> 32), (uint32_t) oid);  }  /* Write the contentful pages: */  for (uint32_t ndx = 0; ndx < nPages; ndx++) {    uint8_t buf[EROS_PAGE_SIZE];        image.GetDataPageContent(ndx, buf);    OID oid = (ndx * EROS_OBJECTS_PER_FRAME) + pageBase;    vol.WriteDataPage(oid, buf);    if (map_file != NULL)      fprintf(map_file, "image dpage ndx 0x%lx => disk page oid 0x%08lx%08lx\n",	      ndx, (uint32_t) (oid >> 32), (uint32_t) oid);  }  /* Zero the non-contentful pages: */  for (uint32_t ndx = 0; ndx < nZeroPages; ndx++) {    /* Following is redundant, but useful until zero pages are     * implemented:     */        uint8_t buf[EROS_PAGE_SIZE];    memset(buf, 0, EROS_PAGE_SIZE);        OID oid = ((ndx + nPages) * EROS_OBJECTS_PER_FRAME) + pageBase;    vol.WriteDataPage(oid, buf);    if (map_file != NULL)      fprintf(map_file, "image zdpage ndx 0x%lx => disk page oid 0x%08lx%08lx\n",	      ndx, (uint32_t) (oid >> 32), (uint32_t) oid);#if 0    PagePot pagePot;    pagePot.flags = PagePot::ZeroPage;        vol.WritePagePotEntry(oid, pagePot);#endif  }  {    DiskKey k;    if (image.GetDirEnt(":ipl:", k)) {      OID oldOID = k.unprep.oid;      RelocateKey(k, nodeBase, pageBase, nPages);      vol.SetIplKey(k);      if (map_file != NULL)	fprintf(map_file, "image :ipl: node ndx 0x%08lx => disk node oid 0x%08lx%08lx\n",		 (uint32_t) oldOID,		 (uint32_t) (k.unprep.oid >> 32), 		(uint32_t) k.unprep.oid);    }    else if (nThreads == 0)      Diag::printf("Warning: no running domains!\n");  }    if (map_file != NULL)    fclose(map_file);  vol.Close();    App.Exit();}

⌨️ 快捷键说明

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