Exemplo n.º 1
0
void cmd_create_task(struct pm_msg_create_task *msg, struct pm_task *ctask) 
{
	struct pm_task *tsk = NULL;
	UINT16 new_task_id = msg->new_task_id;
	UINT16 flags = msg->flags;
	UINT16 type = (flags & SERVER_TASK) / SERVER_TASK;
	UINT32 psize, ret;
	char *path = NULL;

	if(pman_stage == PMAN_STAGE_INITIALIZING)
	{
		cmd_inform_result(msg, ctask->id, PM_IS_INITIALIZING, 0, 0);
		return;
	}

	if(new_task_id != 0xFFFF) 
	{
		if (tsk_lower_bound[type] <=  new_task_id && new_task_id <=  tsk_upper_bound[type]) 
		{
			tsk = tsk_get(new_task_id);

			if(tsk != NULL) 
			{
				/* new_task_id is not free to be used */
				cmd_inform_result(msg, ctask->id, PM_TASK_ID_TAKEN, 0, 0);
				return;
			}
	    } 
		else 
		{
			/* new_task_id is out of range */
			cmd_inform_result(msg, ctask->id, PM_TASK_ID_INVALID, 0, 0);
			return;
		}
	}
	else 
	{
		/* search for a free task id */
		new_task_id = tsk_get_id(tsk_lower_bound[type], tsk_upper_bound[type]);
    
		if(new_task_id == 0xFFFF) 
		{
			cmd_inform_result(msg, ctask->id, PM_NO_FREE_ID, 0, 0);
			return;
        }
	}
  
	tsk = tsk_create(new_task_id);
    if(tsk == NULL)
    {
        cmd_inform_result(msg, ctask->id, PM_NOT_ENOUGH_MEM, 0, 0);
        return;
    }
	path = NULL;
	psize = mem_size(msg->path_smo_id);

	if(psize < 1)
	{
        tsk_destroy(tsk);
		cmd_inform_result(msg, ctask->id, PM_BAD_SMO, 0, 0);
		return;
	}

	path = kmalloc(psize);

	if(path == NULL)
	{
        tsk_destroy(tsk);
		cmd_inform_result(msg, ctask->id, PM_NOT_ENOUGH_MEM, 0, 0);
		return;
	}
	
	/* Read Path */
	if(read_mem(msg->path_smo_id, 0, psize, path) != SUCCESS) 
	{
        tsk_destroy(tsk);
		cmd_inform_result(msg, ctask->id, PM_BAD_SMO, 0, 0);
		return;
	}

	tsk->flags = (flags & SERVER_TASK)? TSK_FLAG_SERVICE : 0;

	if(path[psize-1] == '\0') psize--;
    
    tsk->creator_task = ctask->id;
	tsk->creator_task_port = msg->response_port;
	tsk->command_inf.command_req_id = msg->req_id;

	tsk->command_inf.command_ret_port = -1;
	tsk->command_inf.command_sender_id = -1;

	ret = loader_create_task(tsk, path, psize, msg->param, type, LOADER_CTASK_TYPE_PRG);

	if(ret != PM_OK)
	{
        tsk_destroy(tsk);
		kfree(path);
		cmd_inform_result(msg, ctask->id, ret, 0, 0);
	}
}
Exemplo n.º 2
0
/*
	ok, this is pman init stage two. we will execute this code, and then jump to the process 
	manager main processing loop.
	
	What we will do here, is setup the page pool. And initialize System services, along with structures.
	Notice, we are now task 0 on the system.
*/	
void pman_init_stage2()
{
	UINT32 linear, physical; 
	struct pm_thread *pmthr = NULL;
	struct pm_task *pmtsk = NULL;
	int i = 0;
    int init_size = 0;
    
	/* get rid of the init stuff */
	destroy_thread(INIT_THREAD_NUM);
	destroy_task(INIT_TASK_NUM);
	
	/*
	Open used ports
	*/
	for(i = 0; i <= 12; i++)
	{
		open_port(i, 3, PRIV_LEVEL_ONLY);
	}
	
	/* 
		Init stage 1 has placed bootinfo at PMAN_MULTIBOOTINFO_PHYS 
		before initializing the pool we need to know memory size
		and that information is there. So lets map it on our page table.
	*/
	linear = PMAN_MULTIBOOT_LINEAR + SARTORIS_PROCBASE_LINEAR;
  	physical = PMAN_MULTIBOOT_PHYS; 

	map_pages(PMAN_TASK, linear, physical, PMAN_MULTIBOOT_PAGES, PGATT_WRITE_ENA, 2);

	/* Reallocate init image */
	init_size = init_reloc();

    pman_print_set_color(0x7);
	pman_print("Mapping Malloc %i pages", PMAN_MALLOC_PAGES);
       
	/* Pagein remaining pages for kmalloc */
	linear = PMAN_MALLOC_LINEAR + SARTORIS_PROCBASE_LINEAR; // place after multiboot (this will invalidate the map src/dest linear address, 
                                                            // we cannot use that area anymore, but it's ok, we used it for init copy only.)
  	physical = PMAN_MALLOC_PHYS; 

	map_pages(PMAN_TASK, linear, physical, PMAN_MALLOC_PAGES, PGATT_WRITE_ENA, 2);

	pman_print("Initializing tasks/threads.");

    /* Show MMAP information */
	if(((struct multiboot_info*)PMAN_MULTIBOOT_LINEAR)->flags & MB_INFO_MMAP && ((struct multiboot_info*)PMAN_MULTIBOOT_LINEAR)->mmap_length > 0)
	{		 
		//Calculate multiboot mmap linear address.
		//Sartoris loader left MMAP just after multiboot info structure.
		
		((struct multiboot_info*)PMAN_MULTIBOOT_LINEAR)->mmap_addr = PMAN_MULTIBOOT_LINEAR + sizeof(struct multiboot_info);

		pman_print("Multiboot MMAP Size: %i ", ((struct multiboot_info*)PMAN_MULTIBOOT_LINEAR)->mmap_length);
		pman_print("Multiboot mmap linear address: %x", ((struct multiboot_info*)PMAN_MULTIBOOT_LINEAR)->mmap_addr);

		struct mmap_entry *entry = NULL;
		entry = (struct mmap_entry *)((struct multiboot_info*)PMAN_MULTIBOOT_LINEAR)->mmap_addr;

		int kk = 0, mmlen = ((struct multiboot_info*)PMAN_MULTIBOOT_LINEAR)->mmap_length / entry->size;
		for(kk = 0; kk < mmlen; kk++)
		{
			pman_print("Multiboot entry size: %i start: %x end: %x type: %i", entry->size, (UINT32)entry->start, (UINT32)entry->end, entry->type);		

			entry = (struct mmap_entry *)((UINT32)entry + entry->size);
		}
	}
	else
	{
		pman_print("No MMAP present.");
	}

    /* Initialize vmm subsystem */
	vmm_init((struct multiboot_info*)PMAN_MULTIBOOT_LINEAR, PMAN_INIT_RELOC_PHYS, PMAN_INIT_RELOC_PHYS + init_size);
	
    tsk_init();
	thr_init();

	/* Mark SCHED_THR as taken! */
	pmtsk = tsk_create(PMAN_TASK);
	pmtsk->state = TSK_NORMAL;

    pmthr = thr_create(SCHED_THR, pmtsk);
	pmthr->state = THR_INTHNDL;		// ehm... well... it IS an interrupt handler :D
	pmthr->task_id = PMAN_TASK;
	pmthr->state = THR_INTHNDL;	
    
	pman_print("Initializing allocator and interrupts.");
    /* Initialize kernel memory allocator */
	kmem_init(PMAN_MALLOC_LINEAR, PMAN_MALLOC_PAGES);
	
	/* get our own interrupt handlers, override microkernel defaults */
	int_init();
	
	/* Initialize Scheduler subsystem */
	sch_init();
    
	pman_print("InitFS2 Service loading...");
	
	/* Load System Services and init Loader */
	loader_init((ADDR)PHYSICAL2LINEAR(PMAN_INIT_RELOC_PHYS));

	//pman_print_clr(7);
	pman_print("Loading finished, return INIT image memory to POOL...");

	/* Put now unused Init-Fs pages onto vmm managed address space again. */
	vmm_add_mem((struct multiboot_info*)PMAN_MULTIBOOT_LINEAR
				,PHYSICAL2LINEAR(PMAN_INIT_RELOC_PHYS)
				,PHYSICAL2LINEAR(PMAN_INIT_RELOC_PHYS + init_size));
	
	pman_print("Signals Initialization...");

	/* Initialize global signals container */
	init_signals();

	pman_print("Commands Initialization...");

	/* Initialize Commands subsystem. */
	cmd_init();

	pman_print_set_color(12);
	pman_print("PMAN: Initialization step 2 completed.");

	/* Create Scheduler int handler */
	if(create_int_handler(32, SCHED_THR, FALSE, 0) < 0)
		pman_print_and_stop("Could not create Scheduler thread.");

	/* This is it, we are finished! */
	process_manager();
}
Exemplo n.º 3
0
int vmm_lib_load(struct pm_task *task, char *path, int plength, UINT32 vlow, UINT32 vhigh)
{
    struct vmm_slib_descriptor *lib = (struct vmm_slib_descriptor*)vmm_lib_get(path);
    struct vmm_memory_region *mreg = NULL;
    UINT16 libtask;
    int ret;
	struct pm_task *libtsk = NULL;

    pman_print_dbg("PM: vmm_lib_load %s l: %x h: %x\n", path, vlow, vhigh);

    vlow = TRANSLATE_ADDR(vlow,UINT32);
    vhigh = TRANSLATE_ADDR(vhigh,UINT32);

    if(ma_collition(&task->vmm_info.regions, vlow, vhigh))
        return FALSE;
        
    pman_print_dbg("PM: vmm_lib_load no collition\n");

    mreg = kmalloc(sizeof(struct vmm_memory_region));

    if(!mreg) return 0;

    if(!rb_free_value(&task->vmm_info.regions_id, &mreg->tsk_id_node.value))
	{
		kfree(mreg);
		return FALSE;
	}

    pman_print_dbg("PM: vmm_lib_load id %i\n", &mreg->tsk_id_node.value);

    if(!lib)
    {
        pman_print_dbg("PM: vmm_lib_load loading lib for the first time\n");

        lib = kmalloc(sizeof(struct vmm_slib_descriptor));

        if(!lib) 
        {
            kfree(mreg);
            return 0;
        }

        /* search for a free task id */
	    libtask = tsk_get_id(tsk_lower_bound[1], tsk_upper_bound[1]);
    
	    if(libtask == 0xFFFF) 
	    {
		    kfree(mreg);
            return 0;
        }
  
	    libtsk = tsk_create(libtask);
        if(libtsk == NULL)
        {
            kfree(mreg);
            return 0;
        }
	
        pman_print_dbg("PM: vmm_lib_load task created %i\n", libtask);

	    libtsk->flags = TSK_SHARED_LIB;
        libtsk->state = TSK_NORMAL;

	    if(path[plength-1] == '\0') plength--;
        	            
        lib->path = path;
        lib->references = 1;
        lib->regions = NULL;
        lib->task = libtask;
        lib->loaded = 0;

        // add it to the global loaded libs list
        if(vmm.slibs)
            vmm.slibs->prev = lib;
        lib->next = vmm.slibs;
        lib->prev = NULL;
        vmm.slibs = lib;

        mreg->owner_task = task->id;
        mreg->next = mreg->prev = NULL;
	    mreg->tsk_node.high = vhigh;
	    mreg->tsk_node.low = vlow;
	    mreg->flags = VMM_MEM_REGION_FLAG_NONE;
	    mreg->type = VMM_MEMREGION_LIB;
        mreg->descriptor = lib;

        lib->regions = mreg;

        pman_print_dbg("PM: vmm_lib_load invoke loader reg: %x\n", mreg);
   
	    ret = loader_create_task(libtsk, path, plength, (unsigned int)lib, 1, LOADER_CTASK_TYPE_LIB);

	    if(ret != PM_OK)
	    {
            tsk_destroy(libtsk);
		    kfree(mreg);
            return 0;
	    }
        
        pman_print_dbg("PM: vmm_lib_load loader create task ret OK\n");
        return 1;
    }

    pman_print_dbg("PM: vmm_lib_load lib is already loaded! ref: %i \n", lib->references);
    
    lib->references++;

    // complete the memory region for this task
    mreg->owner_task = task->id;
    mreg->tsk_node.high = vhigh;
	mreg->tsk_node.low = vlow;
	mreg->flags = VMM_MEM_REGION_FLAG_NONE;
	mreg->type = VMM_MEMREGION_LIB;
    mreg->descriptor = lib;

    lib->regions->next = mreg;
    mreg->prev = lib->regions;
    mreg->next = NULL;
	
    if(!lib->loaded)
    {
        pman_print_dbg("PM: vmm_lib_load lib is not loaded yet\n");
        return 1;
    }
    else
    {
        pman_print_dbg("PM: vmm_lib_load lib is loaded!\n");
         /* Add new_mreg on the task lists */
        ma_insert(&task->vmm_info.regions, &mreg->tsk_node);
        rb_search(&task->vmm_info.regions_id, mreg->tsk_id_node.value);
    }

    return 2;
}
Exemplo n.º 4
0
/// Create a thread and add it to Active Threads and set it to state READY.
/// \param[in]     thread_def    thread definition referenced with \ref osThread.
/// \param[in]     argument      pointer that is passed to the thread function as start argument.
/// \return thread ID for reference by other functions or NULL in case of error.
/// \note MUST REMAIN UNCHANGED: \b osThreadCreate shall be consistent in every CMSIS-RTOS.
osThreadId osThreadCreate (const osThreadDef_t *thread_def, void *argument)
{
	(void) argument;

	return tsk_create(thread_def->tpriority - osPriorityIdle, thread_def->pthread, thread_def->stacksize ? thread_def->stacksize : OS_STACK_SIZE);
}
Exemplo n.º 5
0
// slot_size MUST be a 4k multiple
// Creates a system service, based on the initfs image.
// Returns address of first page assigned to the task.
ADDR create_service(UINT16 task, UINT16 thread, INT32 invoke_level, UINT32 size, BOOL low_mem, BOOL load_all, char *image_name)
{
	struct pm_task *ptask = NULL;
	struct pm_thread *pthread = NULL;
	UINT32 psize = 0, first_page, i = 0;
	char *path = NULL;
	struct vmm_page_table *ptbl = NULL;
	struct thread mk_thread;
    BOOL isld = FALSE;
    
    if(strcmp(image_name,"ld"))
    {
        ld_task = task;
        isld = TRUE;
    }

	while(image_name[psize] != '\0'){ psize++; }

	path = kmalloc(psize);

	if(path == NULL)
		pman_print_and_stop("Could not allocate memory for path task: %s", image_name);
	
	while(image_name[i] != '\0'){ path[i] = image_name[i]; i++; }
	path[i] = '\0';
	
	// Create a service task
	ptask = tsk_create(task);
    if(ptask == NULL)
        pman_print_and_stop("Error allocating task for %s", image_name);

	if(loader_create_task(ptask, path, psize, 0, 1, LOADER_CTASK_TYPE_SYS) != PM_OK)
		pman_print_and_stop("Error creating task for %s", image_name);
	
	/* 
	Create task gave us a page directory, the first page table, and initialized task structure as a service. 
	But since sysservice is TRUE, it did not begin fetching from FS.
	*/
	ptask->flags = 0;
	ptask->flags |= TSK_FLAG_SYS_SERVICE;

    if(low_mem)
        ptask->flags |= TSK_LOW_MEM;

	/* Setup the task */
	ptask->creator_task = 0xFFFF;
	ptask->creator_task_port = 0xFFFF;
	ptask->command_inf.command_req_id = 0;
	ptask->command_inf.command_sender_id = 0xFFFFFFFF;

	/* Parse elf */
	if(elf_begin(ptask, pminit_elf_read, pminit_elf_seek) == -1)
		pman_print_and_stop("Elf parsing failed for %s", image_name);
	
    /* Put pages for the Service */
	UINT32 max_addr = put_pages(ptask, !load_all, low_mem, isld);

	/* Get first page */
	ptbl = (struct vmm_page_table*)PHYSICAL2LINEAR(PG_ADDRESS(ptask->vmm_info.page_directory->tables[PM_LINEAR_TO_DIR(SARTORIS_PROCBASE_LINEAR)].b));
	first_page = PG_ADDRESS(ptbl->pages[PM_LINEAR_TO_TAB(SARTORIS_PROCBASE_LINEAR)].entry.phy_page_addr);
	
    /* Setup first thread */
	if(!isld)
    {
        pthread = thr_create(thread, ptask);
    	
	    pthread->state = THR_WAITING;
    
	    /* Create microkernel thread */
	    mk_thread.task_num = task;
	    mk_thread.invoke_mode = PRIV_LEVEL_ONLY;
	    mk_thread.invoke_level = 0;
	    mk_thread.ep = (ADDR)ptask->loader_inf.elf_header.e_entry;
	    mk_thread.stack = pthread->stack_addr = (ADDR)STACK_ADDR(PMAN_THREAD_STACK_BASE);

	    if(create_thread(thread, &mk_thread))
		    pman_print_and_stop("Could not create thread for %s", image_name);
	
	    /* Schedule and activate thread */
	    sch_add(pthread);
	    sch_activate(pthread);
    }
    else
    {
        ld_size = max_addr;
        ptask->vmm_info.max_addr = max_addr;
    }
    
    ptask->state = TSK_NORMAL;

	return (ADDR)first_page;
}