//================================================ // Read noBytes into buffer from the file fHandle //================================================ long ReadFromFile(struct FCB *fHandle, char *buffer, long noBytes) { long retval = 0; long bytesRead = 0; char done = 0; char *buff; struct Message *FSMsg; if (noBytes == 0) return 0; buff = AllocKMem(PageSize); FSMsg = ALLOCMSG; while (noBytes > PageSize) { FSMsg->nextMessage = 0; FSMsg->byte = READFILE; FSMsg->quad1 = (long) fHandle; FSMsg->quad2 = (long) buff; FSMsg->quad3 = PageSize; SendReceiveMessage(FSPort, FSMsg); copyMem(buff, buffer + bytesRead, (size_t) (FSMsg->quad1)); bytesRead += FSMsg->quad1; noBytes -= PageSize; if (FSMsg->quad1 < PageSize) done = 1; } if (!done) { FSMsg->nextMessage = 0; FSMsg->byte = READFILE; FSMsg->quad1 = (long) fHandle; FSMsg->quad2 = (long) buff; FSMsg->quad3 = noBytes; SendReceiveMessage(FSPort, FSMsg); copyMem(buff, buffer + bytesRead, (size_t) (FSMsg->quad1)); bytesRead += FSMsg->quad1; } retval = bytesRead; DeallocMem(buff); DeallocMem(FSMsg); return (retval); }
//=============================================================================== // This loads the program "name" into memory, if it exists. //=============================================================================== long DoExec(char *name, char *environment) { struct FCB *fHandle; long argv, argc; int retval = -ENOEXEC; struct Message *FSMsg = ALLOCMSG; char *kname = AllocKMem((size_t) strlen(name) + 6); // Enough space for "/bin" + name strcpy(kname, "/bin/"); strcat(kname, name); // Open file FSMsg->nextMessage = 0; FSMsg->byte = OPENFILE; FSMsg->quad1 = (long) kname; FSMsg->quad2 = (long) fHandle; SendReceiveMessage(FSPort, FSMsg); fHandle = (struct FCB *) FSMsg->quad1; if ((long) fHandle > 0) { char magic[5]; char executable = 0; (void) SeekFile(FSMsg, fHandle, 10, SEEK_SET); (void) ReadFromFile(fHandle, magic, 4); magic[4] = 0; if (!strcmp(magic, "IJ64")) { (void) SeekFile(FSMsg, fHandle, 0, SEEK_SET); LoadFlat(fHandle); executable = 1; } else { (void) SeekFile(FSMsg, fHandle, 0, SEEK_SET); (void) ReadFromFile(fHandle, magic, 4); if (magic[0] == 0x7F) { (void) SeekFile(FSMsg, fHandle, 0, SEEK_SET); LoadElf(FSMsg, fHandle); executable = 1; } } //Close file and deallocate memory for structures FSMsg->nextMessage = 0; FSMsg->byte = CLOSEFILE; FSMsg->quad1 = (long) fHandle; SendReceiveMessage(FSPort, FSMsg); DeallocMem(kname); DeallocMem(FSMsg); if (executable) { long *l; // Process the arguments for argc and argv // Copy environment string to user data space // It occupies the 81 bytes after the current first free memory currentTask->environment = (void *) currentTask->firstfreemem; memcpy(currentTask->environment, environment, 80); currentTask->firstfreemem += 80; argv = (long) currentTask->environment; argc = ParseEnvironmentString(&argv); argv += 80; // Adjust firstfreemem to point to the first free memory location. currentTask->firstfreemem += argc * sizeof(char *); // Build the first MemStruct struct. Is all this necessary? User tasks don't use the kernel memory allocation, do they? l = (long *) (currentTask->firstfreemem); *l = 0; *(l + 1) = -(long) (((sizeof(struct MemStruct) + currentTask->firstfreemem)) % PageSize); asm("mov %0,%%rdi;" "mov %1,%%rsi": : "r"(argc), "r"(argv):"%rax", "%rdi"); return 0; } else return retval;