📄 sysgen.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 + -