Exemple #1
0
/*
*	copy_file_image
*		Function:	Copies a file image to physical memory
*		Inputs:		fname, charstring of filename to copy
*		Outputs:	none
*		Effect:		Copies the file to the physical memory specified for image start address
*/
uint32_t copy_file_image(uint8_t* fname)
{
	dentry_t dentry_curr;
	read_dentry_by_name(fname, &dentry_curr);
	uint32_t fsize=inodes_array[dentry_curr.inode].length; 
	uint8_t buf[ inodes_array[dentry_curr.inode].length];
	read_data(dentry_curr.inode, 0, buf, fsize);
	uint8_t* image_start_addr=(uint8_t*) IMAGE_START;
	memcpy(image_start_addr,buf,fsize);
	return 0;
}
/* int32_t open(const uint8_t* filename)
 *	calls open jump table
 *
 *
 */
int32_t open(const uint8_t* filename)
{
	// uint32_t flags;
	// cli_and_save(flags);
	
	/* Get the current process */
	pcb_t* cur_PCB = curr_process;

	file_t* farray = cur_PCB->file_fds;

	/* Find next open slot in the file array */
	uint32_t fd = 0;
	while(farray[fd].flags == 1)
		fd++;

	/* Check if there's space for the file and open a valid dentry*/
	dentry_t dentry;
	if(fd > 7 || -1 == read_dentry_by_name(filename, &dentry))
		return -1;

	file_t* cur_file = &(farray[fd]);

	// Fill the file array entry
	switch(dentry.file_type)
	{
		case 0: // RTC
			if(-1 == rtc_open(cur_file, filename))
				return -1;
			break;

		case 1: // Directory
			if(-1 == dir_open(cur_file, filename))
				return -1;
			break;

		case 2:	// File
			if(-1 == file_open(cur_file, filename))
				return -1;
			break;

		default: // Invalid type
			return -1;
	}

	 
	return fd;
}
Exemple #3
0
/*
*	open_file()
*		Function:	Checks if a file is valid and opens it
*		Inputs:		fname, charstring of the dentry to search for
*		Effect:		Initializes the file_array[8] depending on the file to be opened
*		Returns:	fd, the index of the newly created file descriptor (success)
*					-1, if we could not find a empty file decriptor in file_array[8]
*/
uint32_t open_file(const uint8_t *fname)
{
	int check_file=read_dentry_by_name(fname, &dentry);

	//checks for valid file
	if (dentry.fname == NULL || check_file == -1)
		{
			return -1;
		}
	
	uint32_t fd = find_free_fd( current_pcb ); 
	if(fd==-1)
		return -1;
	if(dentry.ftype==FILE_TYPE_RTC) //user level access to rtc
	{
		((current_pcb->file_array)[fd]).file_ops = &rtc_ops;
		current_pcb->file_array[fd].inode_ptr=0;
		current_pcb->file_array[fd].file_position=0;
		current_pcb->file_array[fd].flags=FILE_IN_USE;
	}
	else if(dentry.ftype==FILE_TYPE_DIR) //file type is directory
	{
		((current_pcb->file_array)[fd]).file_ops = &file_ops;
		current_pcb->file_array[fd].inode_ptr=0;
		current_pcb->file_array[fd].file_position=0;
		current_pcb->file_array[fd].flags=FILE_IN_USE;
	}
	else if(dentry.ftype==FILE_TYPE_REG) //file type is regular
	{
		((current_pcb->file_array)[fd]).file_ops = &file_ops;
		current_pcb->file_array[fd].inode_ptr=(int32_t*)&inodes_array[dentry.inode];
		current_pcb->file_array[fd].file_position=0;
		current_pcb->file_array[fd].flags=FILE_IN_USE;
	}

	return fd;
}
int32_t execute(const uint8_t* command)
{

	pcb_t* previous_pcb = curr_process;


	char* cmd = (char*)command;
	uint8_t* fname = (uint8_t*)parse(cmd);
	get_arg((char *)command, (int)strlen(cmd));
	
	/*	Looking for processes	*/
	uint8_t process_mask = MASK;

	// Calculating the process mask, which keeps track of open processes. Here we search for a 0 in the mask
	// and set it to 1, giving the index in the bitmap to process_id
	int i = 0;
	for(i = 0; i < 7; i++)
	{
		if((process_mask & open_processes) == 0)
		{
			open_processes |= process_mask;
			process_id = i;
			break;
		}
		else
			process_mask >>= 1;
	}

	// if(num_processes + 1 > 2)
	// {
	// 	cout("PROCESS LIMIT EXCEEDED. NOT ALLOWED TO EXECUTE\n");
	// 	//num_processes--;
	// 	sti();
	// 	asm volatile("jmp ret_halt");	
	// }

	// Check
	if(i == 7)
	{

		printf("Too many processes!\n");
		return 1;
	}

	/* Executable check */
	uint8_t elf_check[4];

	dentry_t dentry_temp;
	if(-1 == read_dentry_by_name(fname, &dentry_temp))
	{
		 
		return -1;
	}

	if(-1 == read_data(dentry_temp.inode_num, 0, elf_check, 4))
	{
		 
		return -1;
	}

	if(!(elf_check[0] == 0x7f && elf_check[1] == 0x45 && elf_check[2] == 0x4c && elf_check[3] == 0x46))
	{
		 
		return -1;
	}

	/* Find the address of the file's first instruction */
	uint8_t buf_temp[4];

	if(-1 == read_data(dentry_temp.inode_num, 24, buf_temp, 4))
	{
		 
		return -1;
	}
	int k = 0;
	uint32_t entry_addr = 0;
	for(k = 0; k < 4; k++)
		entry_addr |= (buf_temp[k] << 8*k);


	/* Set up paging */
	PDE_t* PD_ptr = task_mem_init(process_id);
	if(PD_ptr == NULL)
	{
		 
		printf("Too many processes!\n");
		return 1;
	}

	// Load program image into memory
	if(-1 == program_load(fname, PGRM_IMG))
	{
		 	
		return -1;
	}

	k_bp = _8MB - (_8KB)*(process_id) - 4;
	curr_process = (pcb_t *) (k_bp & 0xFFFFE000);
	// k_bp = _8MB - (_8KB)*(process_id);
	// curr_process = (pcb_t *) ((k_bp - 1) & 0xFFFFE000);
	curr_process->process_id = process_id;
	curr_process->PD_ptr = PD_ptr;
	curr_process->k_bp = k_bp;
	curr_process->k_sp = k_bp;
	
	// If initial shell, case should be handeled by making parent process the same shell
	if(initial_shell)
	{
		curr_process->parent_process = curr_process;
		curr_process->child_flag = 0;
		curr_process->parent_process->child = -1;
		initial_shell = 0;
	}
	else
	{
		curr_process->parent_process = previous_pcb;
		curr_process->parent_process->child_flag = 1;
		curr_process->parent_process->child = process_id;
	}
	
	// Initialize file descriptors
	for(i = 0; i < 8; i++)
	{
		curr_process->file_fds[i].file_op = NULL;
		curr_process->file_fds[i].inode_ptr = NULL;
		curr_process->file_fds[i].file_pos = 0;
		curr_process->file_fds[i].flags = 0;
	}	

	task_queue[next_available] = process_id;
	next_available = (next_available + 1) % 7;

	stdin(0);									//kernel should automatically open stdin and stdout
	stdout(1);									//which correspond to fd 0 and 1 respectively


	
	task_queue[next_available] = process_id;
	next_available = (next_available + 1) % 7;
	
	// Setting TSS
	tss.esp0 = curr_process->k_sp; 		// This is good code
	tss.ss0 = KERNEL_DS;

	if(previous_pcb != NULL)
	{
		asm volatile("movl %%esp, %0":"=g"(previous_pcb->k_sp));
		asm volatile("movl %%ebp, %0":"=g"(previous_pcb->k_bp));
	}

	// Jump to program and being executions
	jump_to_userspace(entry_addr);

	// Halt jumps here for finishing execute
	asm volatile("ret_halt:\n\t");				
	 
	return retval;
}