Example #1
0
//========================
// Allocate a message port
//========================
struct MessagePort *AllocMessagePort()
{
	struct MessagePort *temp = (struct MessagePort *)AllocKMem(sizeof(struct MessagePort));

	temp->waitingProc = (struct Task *)-1L;
	temp->msgQueue = 0;
	return (temp);
}
Example #2
0
//==============================================
// Open the file "path" and assign an FCB to it
//==============================================
struct FCB *OpenFileByInodeNumber(u_int32_t inode)
{
	struct FCB *fcb = AllocKMem(sizeof(struct FCB));
	fcb->inode = AllocKMem(sizeof(struct ext2_inode));
	fcb->inodeNumber = inode;
	GetINode(inode, fcb->inode);
	fcb->nextFCB = 0;
	fcb->fileCursor = 0;
	fcb->bufCursor = 0;
	fcb->buffer = AllocKMem((size_t)block_size);
	fcb->bufferIsDirty = 0;
	fcb->inodeIsDirty = 0;
	fcb->index1 = fcb->index2 = fcb->index3 = fcb->index4 = 0;
	fcb->currentBlock = fcb->inode->i_block[0];
	ReadBlock(fcb->currentBlock, fcb->buffer);
	return fcb;
}
Example #3
0
void InitMem64(void)
{
	PMap = (unsigned short int *) PageMap;
	firstFreeKMem = (struct MemStruct *) OSHeap;
	firstFreeKMem->next = 0;
	firstFreeKMem->size = (long)(PageSize - sizeof(struct MemStruct));
	currentTask = (struct Task *) AllocKMem(sizeof(struct Task));
	nextpid = 3;
	runnableTasks = (struct TaskList *) AllocKMem(sizeof(struct TaskList));
	runnableTasks->next = NULL;
	runnableTasks->task = currentTask;
	allTasks = (struct TaskList *) AllocKMem(sizeof(struct TaskList));
	allTasks->task = currentTask;
	allTasks->next = 0;
	deadTasks = 0;
	lowPriTask = NULL; //0L;
	blockedTasks = NULL; //0L;
	memorySemaphore = 0;
	canSwitch = 0;
	tenths = 0;
	pass = 0;
}
Example #4
0
//==============================================
// Open the file "path" and assign an FCB to it
//==============================================
struct FCB *OpenFile(char *path)
{
	struct FCB *fcb = AllocKMem(sizeof(struct FCB));
	fcb->inode = AllocKMem(sizeof(struct ext2_inode));
	fcb->inodeNumber = GetFileINode(path);
	if (!fcb->inodeNumber)
	{
		DeallocMem(fcb);
		return (struct FCB *) -ENOENT;
	}
	GetINode(fcb->inodeNumber, fcb->inode);
	fcb->nextFCB = 0;
	fcb->fileCursor = 0;
	fcb->bufCursor = 0;
	fcb->buffer = AllocKMem((size_t)block_size);
	fcb->bufferIsDirty = 0;
	fcb->inodeIsDirty = 0;
	fcb->index1 = fcb->index2 = fcb->index3 = fcb->index4 = 0;
	fcb->currentBlock = fcb->inode->i_block[0];
	ReadBlock(fcb->currentBlock, fcb->buffer);
	return fcb;
}
Example #5
0
//================================================
// 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);
}
Example #6
0
//=========================================================================
// Fork the current process.
// Return the pid of the new process
//=========================================================================
unsigned short DoFork()
{
	unsigned short pid;
	struct FCB *fcbin, *fcbout, *fcberr;

	// Copy task structure, with adjustments
	struct Task *task = (struct Task *) AllocKMem(sizeof(struct Task));

	memcpy((char *) task, (char *) currentTask, sizeof(struct Task));
	pid = task->pid = nextpid++;
	task->currentDirName = AllocKMem(
			(size_t) strlen(currentTask->currentDirName) + 1);
	strcpy(task->currentDirName, currentTask->currentDirName);
	task->parentPort = 0;

	// Create Page Directory
	task->cr3 = (long) VCreatePageDir(pid, currentTask->pid);

	Elf64_Ehdr *header = (Elf64_Ehdr *)UserCode;
	if ((header->e_ident)[1] != 'E')// Not the best of tests, but good enough
		CopyPages(UserCode, task);
	else
	{

		Elf64_Phdr *pheadertable = (Elf64_Phdr *)(UserCode + header->e_phoff);
		int i;

		for (i = 0; i < header->e_phnum; i++)
		{
			if (pheadertable[i].p_type == PT_LOAD)
			{
				CopyPages(pheadertable[i].p_vaddr, task);
			}
		}
	}

	// Copy user stack and kernel stack
	CopyPages(UserStack, task);

	//Page Tables to allow access to E1000
	/*CreatePTEWithPT((struct PML4 *) task->cr3, registers, (long) registers, 0, 7);
	 CreatePTEWithPT((struct PML4 *) task->cr3, registers + 0x1000,
	 (long) registers + 0x1000, 0, 7);
	 CreatePTEWithPT((struct PML4 *) task->cr3, registers + 0x2000,
	 (long) registers + 0x2000, 0, 7);
	 CreatePTEWithPT((struct PML4 *) task->cr3, registers + 0x3000,
	 (long) registers + 0x3000, 0, 7);
	 CreatePTEWithPT((struct PML4 *) task->cr3, registers + 0x4000,
	 (long) registers + 0x4000, 0, 7);
	 CreatePTEWithPT((struct PML4 *) task->cr3, registers + 0x5000,
	 (long) registers + 0x5000, 0, 7);*/
	task->forking = 1;

	// Create FCBs for STDI, STDOUT, and STDERR

	// STDIN
	fcbin = (struct FCB *) AllocKMem(sizeof(struct FCB));
	fcbin->fileDescriptor = STDIN;
	fcbin->deviceType = KBD;
	task->fcbList = fcbin;

	// STDOUT
	fcbout = (struct FCB *) AllocKMem(sizeof(struct FCB));
	fcbout->fileDescriptor = STDOUT;
	fcbout->deviceType = CONS;
	fcbin->nextFCB = fcbout;

	//STDERR
	fcberr = (struct FCB *) AllocKMem(sizeof(struct FCB));
	fcberr->fileDescriptor = STDERR;
	fcberr->deviceType = CONS;
	fcbout->nextFCB = fcberr;
	fcberr->nextFCB = 0;
	task->FDbitmap = 7;

	// Run the forked process
	asm("pushf");
	asm("cli");
	LinkTask(task);
	asm("popf");

	// We want the forked process to return to this point. So we
	// need to save the registers from here to the new task structure.
	SaveRegisters(task);

	// Return 0 to the forked process, the new pid to the forking one.
	if (pid == currentTask->pid)
		pid = 0;
	return pid;
}
Example #7
0
//===============================================================================
// 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;
Example #8
0
//====================================================
// Create a new file. entry for a file of type type
// Returns an FCB on success or a negative error code
//====================================================
struct FCB *CreateFileWithType(char *name, long type)
{
	char *parentDirectory, *fileName, *dirBuffer;
	u_int32_t parentINodeNo, inodeNo, i;
	u_int16_t recLength, sizeOfEntry, sizeOfNewEntry;
	struct ext2_inode *inode;
	struct ext2_dir_entry_2 *entry, *newEntry;
	struct FCB *dirFcb, *fcb;

	// Does the file already exist?
	if (GetFileINode(name))
		return (struct FCB *) -EEXIST;

	// Get the INode of the parentdirectory
	parentDirectory = AllocUMem((size_t)(strlen(name) + 1));
	strcpy(parentDirectory, name);
	fileName = strrchr(parentDirectory, '/');
	fileName[0] = 0;
	fileName++;
	parentINodeNo = GetFileINode(parentDirectory);
	if (!parentINodeNo)
	{
		DeallocMem(parentDirectory);
		return (struct FCB *) -ENOENT;
	}

	// Create an inode for the new file
	inode = AllocKMem(sizeof(struct ext2_inode));
	memset(inode, 0, sizeof(struct ext2_inode));
	inode->i_mode = (u_int16_t)(EXT2_S_IFREG | EXT2_S_IRUSR | EXT2_S_IWUSR | EXT2_S_IRGRP
			| EXT2_S_IWGRP | EXT2_S_IROTH | EXT2_S_IWOTH);
	inode->i_atime = inode->i_ctime = inode->i_mtime = (u_int32_t)unixtime;
	inode->i_dtime = 0;
	inode->i_links_count = 1;
	inode->i_blocks = 0;
	inodeNo = GetFreeINode(0);

	// Write the new inode to disk
	PutINode(inodeNo, inode);

	// Create a directory entry for the new file
	dirFcb = OpenFileByInodeNumber(parentINodeNo);
	dirBuffer = AllocUMem(dirFcb->inode->i_size);
	(void)ReadFile(dirFcb, dirBuffer, (long)(dirFcb->inode->i_size));
	sizeOfNewEntry = (u_int16_t)(8 + strlen(fileName) + 4 - strlen(fileName) % 4);
	entry = (struct ext2_dir_entry_2 *) dirBuffer;
	sizeOfEntry = (u_int16_t)(8 + entry->name_len + 4 - entry->name_len % 4);
	while (sizeOfEntry + sizeOfNewEntry > entry->rec_len)
	{
		entry = (struct ext2_dir_entry_2 *) ((char *) entry + entry->rec_len);
		sizeOfEntry = (u_int16_t)(8 + entry->name_len + 4 - entry->name_len % 4);
	}

	// There's room for the new entry at the end of this record
	recLength = entry->rec_len;
	entry->rec_len = sizeOfEntry;
	newEntry = AllocUMem(sizeof(struct ext2_dir_entry_2));
	memset(newEntry, 0, sizeof(struct ext2_dir_entry_2));
	newEntry->file_type = (u_int8_t)type;
	newEntry->inode = (u_int32_t)inodeNo;
	newEntry->name_len = (u_int8_t)strlen(fileName);
	newEntry->rec_len = recLength - sizeOfEntry;
	for (i = 0; i < newEntry->name_len; i++)
		newEntry->name[i] = fileName[i];
	memcpy((char *) entry + sizeOfEntry, newEntry, sizeOfNewEntry);
	DeallocMem(parentDirectory);

	// Write the directory buffer back to disk
	(void)Seek(dirFcb, 0, SEEK_SET);
	(void)WriteFile(dirFcb, dirBuffer, (long)(dirFcb->inode->i_size));
	DeallocMem(dirBuffer);
	(void)CloseFile(dirFcb);

	// Create a FCB for the new file
	fcb = AllocKMem(sizeof(struct FCB));
	fcb->inode = inode;
	fcb->inodeNumber = inodeNo;
	fcb->nextFCB = 0;
	fcb->fileCursor = 0;
	fcb->bufCursor = 0;
	fcb->buffer = AllocKMem((size_t)block_size);
	fcb->currentBlock = 0;
	fcb->index1 = fcb->index2 = fcb->index3 = fcb->index4 = 0;
	return fcb;
}
Example #9
0
//===============================================
// Delete the file name
// Returns 0 on success or a negative error code
//===============================================
long DeleteFile(char *name)
{
	char *buffer = AllocKMem(block_size);
	char *buffer1 = AllocKMem(block_size);
	__le32 *blocks;
	__le32 *iblocks;
	int i, j;
	char *parentDirectory, *fileName, *dirBuffer;
	u_int32_t parentINodeNo;
	struct FCB *fcb, *dirFcb;
	struct ext2_dir_entry_2 *entry, *prevEntry;

	// Get the INode of the parentdirectory
	parentDirectory = AllocUMem((size_t)strlen(name) + 1);
	strcpy(parentDirectory, name);
	fileName = strrchr(parentDirectory, '/');
	fileName[0] = 0;
	fileName++;
	parentINodeNo = GetFileINode(parentDirectory);
	if (parentINodeNo == (u_int32_t) -ENOENT)
	{
		DeallocMem(buffer);
		DeallocMem(buffer1);
		DeallocMem(parentDirectory);
		return -ENOENT;
	}

	// Now free the blocks allocated to this file
	fcb = OpenFile(name);
	if ((long)fcb < 0)
	{
		DeallocMem(buffer);
		DeallocMem(buffer1);
		DeallocMem(parentDirectory);
		return (long) fcb;
	}

	// Delete all direct blocks
	for (i = 0; i < EXT2_IND_BLOCK; i++)
		if (fcb->inode->i_block[i])
			ClearBlockBitmapBit(fcb->inode->i_block[i]);
	if (fcb->inode->i_block[EXT2_IND_BLOCK])
	{
		// Delete indirect blocks
		ReadBlock(fcb->inode->i_block[EXT2_IND_BLOCK], buffer);
		blocks = (__le32 *) buffer;
		for (i = 0; i < block_size / sizeof(__le32); i++)
			if (blocks[i])
				ClearBlockBitmapBit(blocks[i]);
		ClearBlockBitmapBit(fcb->inode->i_block[EXT2_IND_BLOCK]);
	}
	if (fcb->inode->i_block[EXT2_DIND_BLOCK])
	{
		// Delete double-indirect blocks
		ReadBlock(fcb->inode->i_block[EXT2_DIND_BLOCK], buffer);
		blocks = (__le32 *) buffer;
		for (i = 0; i < block_size / sizeof(__le32); i++)
		{
			if (blocks[i])
			{
				ReadBlock(blocks[i], buffer1);
				iblocks = (__le32 *) buffer1;
				for (j = 0; j < block_size / sizeof(__le32); j++)
					if (iblocks[j])
						ClearBlockBitmapBit(iblocks[j]);
				ClearBlockBitmapBit(blocks[i]);
			}
		}
		ClearBlockBitmapBit(fcb->inode->i_block[EXT2_DIND_BLOCK]);
	}
	if (fcb->inode->i_block[EXT2_TIND_BLOCK])
	{
		// Delete triple-indirect blocks
	}

	// Find the directory entry for thefile
	dirFcb = OpenFileByInodeNumber(parentINodeNo);
	dirBuffer = AllocUMem(dirFcb->inode->i_size);
	(void)ReadFile(dirFcb, dirBuffer, (long)(dirFcb->inode->i_size));
	entry = (struct ext2_dir_entry_2 *) dirBuffer;
	prevEntry = entry;
	while (strlen(fileName) != entry->name_len
			|| strncmp(entry->name, fileName, entry->name_len))
	{
		if ((long)entry + entry->name_len - (long)dirBuffer
				> (long)dirFcb->inode->i_size)
		{
			DeallocMem(dirBuffer);
			(void)CloseFile(dirFcb);
			DeallocMem(buffer);
			DeallocMem(buffer1);
			DeallocMem(parentDirectory);
			return -ENOENT;
		}
		prevEntry = entry;
		entry = (struct ext2_dir_entry_2 *) ((char *) entry + entry->rec_len);
	}

	// Entry now points to the directory entry for this file, prevEntry to the previous one
	prevEntry->rec_len += entry->rec_len;
	(void)Seek(dirFcb, 0, SEEK_SET);
	(void)WriteFile(dirFcb, dirBuffer, (long)dirFcb->inode->i_size);
	DeallocMem(dirBuffer);
	(void)CloseFile(dirFcb);
	DeallocMem(buffer);
	DeallocMem(buffer1);
	DeallocMem(parentDirectory);

	// Finally, delete the inode
	memset(fcb->inode, 0, sizeof(struct ext2_inode));
	PutINode(fcb->inodeNumber, fcb->inode);
	ClearINodeBitmapBit(fcb->inodeNumber);
	(void)CloseFile(fcb);
	return 0;
}