SharedMemory * MemoryServer::insertShared(ProcessID procID, char *key, Size size, MemoryRange *range, bool *created) { SharedMemory *obj = findShared(key); bool needCreate = obj == ZERO; if (needCreate) obj = new SharedMemory; range->virtualAddress = findFreeRange(procID, size); range->bytes = size; range->access = Memory::Present | Memory::User | Memory::Readable | Memory::Writable | Memory::Pinned; /* Only create a new mapping, if non-existent. */ if (needCreate) { range->physicalAddress = ZERO; VMCtl(procID, Map, range); /* Create new shared memory object. */ obj->size = size; obj->key = key; obj->address = range->physicalAddress; /* Insert to the list. */ shared.append(obj); /* We created a new mapping, flag that. */ if (created) *created = true; } else { range->physicalAddress = obj->address; VMCtl(procID, Map, range); /* We didn't create a new mapping, flag that. */ if (created) *created = false; } /* Done. */ return obj; }
SharedMemory * MemoryServer::insertShared(ProcessID procID, char *key, Size size, MemoryRange *range, bool *created) { SharedMemory *obj; range->virtualAddress = findFreeRange(procID, size); range->bytes = size; range->protection = PAGE_PRESENT | PAGE_USER | PAGE_RW | PAGE_PINNED; /* Only create a new mapping, if non-existent. */ if (!(obj = findShared(key))) { range->physicalAddress = ZERO; VMCtl(procID, Map, range); /* Create new shared memory object. */ obj = new SharedMemory; obj->size = size; obj->key = new String(key); obj->address = range->physicalAddress; /* Insert to the list. */ shared.insertTail(obj); /* We created a new mapping, flag that. */ if (created) *created = true; } else { range->physicalAddress = obj->address; VMCtl(procID, Map, range); /* We didn't create a new mapping, flag that. */ if (created) *created = false; } /* Done. */ return obj; }
MemoryServer::MemoryServer() : IPCServer<MemoryServer, MemoryMessage>(this) { SystemInformation info; MemoryRange range; BootImage *image; BootProgram *program; /* Register message handlers. */ addIPCHandler(CreatePrivate, &MemoryServer::createPrivate); addIPCHandler(ReservePrivate, &MemoryServer::reservePrivate); addIPCHandler(ReleasePrivate, &MemoryServer::releasePrivate); addIPCHandler(CreateShared, &MemoryServer::createShared); addIPCHandler(SystemMemory, &MemoryServer::systemMemory); /* Allocate a user process table. */ insertShared(SELF, USER_PROCESS_KEY, sizeof(UserProcess) * MAX_PROCS, &range); /* Clear it. */ procs = (UserProcess *) range.virtualAddress; memset(procs, 0, sizeof(UserProcess) * MAX_PROCS); /* Allocate FileSystemMounts table. */ insertShared(SELF, FILE_SYSTEM_MOUNT_KEY, sizeof(FileSystemMount) * MAX_MOUNTS, &range); /* Also Clear it. */ mounts = (FileSystemMount *) range.virtualAddress; memset(mounts, 0, sizeof(FileSystemMount) * MAX_MOUNTS); /* We only guarantee that / and /dev are mounted. */ strlcpy(mounts[0].path, "/dev", PATHLEN); strlcpy(mounts[1].path, "/", PATHLEN); mounts[0].procID = DEVSRV_PID; mounts[0].options = ZERO; mounts[1].procID = ROOTSRV_PID; mounts[1].options = ZERO; /* Attempt to load the boot image. */ for (Size i = 0; i < info.moduleCount; i++) { if (strcmp(info.modules[i].string, "/boot/boot.img.gz") == 0) { range.virtualAddress = findFreeRange(SELF, PAGESIZE * 2); range.physicalAddress = info.modules[i].modStart; range.access = Memory::Present | Memory::User | Memory::Readable; #warning Dangerous value for bytes here? range.bytes = PAGESIZE * 2; VMCtl(SELF, Map, &range); image = (BootImage *) range.virtualAddress; break; } } /* Loop all embedded programs. */ for (Size j = 0; j < image->programsTableCount; j++) { /* Read out the next program. */ program = (BootProgram *)(((Address)image) + image->programsTableOffset); program += j; /* Write commandline. */ snprintf(procs[j].command, COMMANDLEN, "[%s]", program->path); /* Set current directory. */ snprintf(procs[j].currentDirectory, PATHLEN, "/"); /* Set user and group identities. */ procs[j].userID = 0; procs[j].groupID = 0; } }