Esempio n. 1
0
GFX_CONTEXT *_kgfx_new_context(int pid) {
    int context = -1;
    //check for existing context for this pid
    for (int i = 0; i < MAX_CONTEXTS; i++) {
        if (context_pid[i] == pid) {
            context = i;
            break;
        }
    }

    if (context == -1) {
        //take first unused context
        for (int i = 0; i < MAX_CONTEXTS; i++) {
            if (!context_pid[i]) {
                num_contexts++;
                context_pid[i] = pid;
                context = i;
                break;
            }
        }
    }

    _kmemclr(contexts[context].backbuffer->data, VGA_SIZE);
    _kmemcpy((uint8_t *)&palettes[context], (uint8_t *)&default_palette, PALETTE_SIZE);


    return &contexts[context];

}
Esempio n. 2
0
void _kgfx_init(void) {
    _kmemclr((uint8_t *)context_pid, sizeof(context_pid));
    _kgfx_delete_context(0); //delete all contexts
    num_contexts = 0;

    screen = create_bitmap(SCREEN_W, SCREEN_H, -1, (uint8_t *)VGA_START);
    font = create_bitmap(1024, 8, 255, font_data);

    for (int i = 0; i < FONT_BYTES; i++) {
        font_data_white[i] = font_data[i] == 255 ? 0 : 1;
    }

    font_white = create_bitmap(1024, 8, 0, font_data_white);


    cleartocolor(&screen, 5 * 16 + 8);
    text(&screen, "Welcome", 160, 75, 1);
    text(&screen, "to", 160, 85, 1);
    text(&screen, "ChemanOS", 160, 95, 1);

}
Esempio n. 3
0
/**
 * Initializes the gl library and the vga devices. Then initializes all of the 
 * memory required for the window manager, and sets all default values.
 * 
 */
void _win_man_init( void ) {
	int i = 0;
	int j = 0;
	void* bPtrOffset = 0;
	int dW, dH = 0;
	int x, y;
	Uint32 s_arr_size, buff_size;
	
	_vga_init();
	
	//setup the memory for the arrays and 
	// this module
	wm_memory = (void *)( 0x20000000 );
	//array of screen_infos
	screen_info_arr = (screen_info *)( ((Uint32)wm_memory) + WIN_MAN_MEM );

	//get screen info
	dW = vga_mode_info->XResolution / 2;
	dH = vga_mode_info->YResolution / 2;
	
	//begining of buffers
	s_arr_size = (DEFAULT_SCREENS) * sizeof( struct screen_info ); 
	buff_size  = (DEFAULT_SCREENS) * dH * dW * 4;

	bPtrOffset = (void *)((Uint32)screen_info_arr + s_arr_size );
	_vmeml2_static_address( (Uint32) _vga_get_start_mem(), (Uint32) _vga_get_end_mem(), TRUE );
	_vmeml2_static_address( ( (Uint32) wm_memory ), (Uint32) ( (Uint32) wm_memory ) + s_arr_size + buff_size + WIN_MAN_MEM , TRUE ); 

	_gl_init();
	
//	c_printf("\n%x %x\n", (Uint32) _vga_get_start_mem(), (Uint32) _vga_get_end_mem() );
//	c_printf("\n%x %x\n", ( (Uint32) wm_memory ), (Uint32) ( (Uint32) wm_memory ) + buff_size + s_arr_size + WIN_MAN_MEM);

//	c_printf("\nscrn: %x bOff: %x \n", screen_info_arr, bPtrOffset);
	//fill out the default screens [[ * vga_mode_info->LinbytesPerScanLine)/8) ]]
	for(i = 0; i < DEFAULT_SCREENS; i++) {
		screen_info_arr[i].buf_num = i;
		screen_info_arr[i].w = dW;
		screen_info_arr[i].h = dH;
		screen_info_arr[i].bPtr = (Uint32 *)(((Uint32)bPtrOffset) + (( i * dH * dW * 4 )));
		screen_info_arr[i].pid = 0;
		screen_info_arr[i].active = 0;
		screen_info_arr[i].blocking = 0;
		screen_info_arr[i].dirty = 1; //default dirty
		//gl_print stuff
		screen_info_arr[i].x_max = dW / FONT_WIDTH;
		screen_info_arr[i].y_max = (dH / FONT_HEIGHT)-1;
		screen_info_arr[i].curr_x = 0;
		screen_info_arr[i].curr_y = 0;
		screen_info_arr[i].buf_x = 0;
		for(y = 0; y < 200; y++){
			for(x = 0; x < 200; x++)
				screen_info_arr[i].lines[y][x] = '\0';
		}
		#ifdef WM_DEBUG
		c_printf("%d  - %x || ", i,  screen_info_arr[i].bPtr);
		#endif
	}
	//c_printf("%x %x %x %x size_struct:%x \n",  screen_info_arr[0].bPtr, buff_size, s_arr_size, WIN_MAN_MEM, sizeof( struct screen_info ));
	//clear buffer mem
	_kmemclr(screen_info_arr[0].bPtr, buff_size );
	
	#ifdef WM_DEBUG
	c_printf("\n-Total Memory(B): %d blocks(x64KB), %d\n", vga_vesa_info->TotalMemory, (vga_vesa_info->TotalMemory * 64)*1024);
	for(i = 0; i < DEFAULT_SCREENS; i++) {
		c_printf("%d - (%d, %d) - %x || ", 
		screen_info_arr[i].buf_num, 
		screen_info_arr[i].w, 
		screen_info_arr[i].h, 
		screen_info_arr[i].bPtr);
	}
	#endif
	//set the default displayed screens
	wm_memory->screens[0] = 0;
	wm_memory->screens[1] = 1;
	wm_memory->screens[2] = 2;
	wm_memory->screens[3] = 3;
	
	//test
	for(i = 0; i < screen_info_arr[0].w; i++) {
		for(j = 0; j < screen_info_arr[0].h; j++) {
			screen_info_arr[0].bPtr[ ( j * screen_info_arr[0].w ) + i] = 0x18181818;
		}
	}
	for(i = 0; i < screen_info_arr[2].w; i++) {
		for(j = 0; j < screen_info_arr[2].h; j++) {
			screen_info_arr[2].bPtr[ ( j * screen_info_arr[2].w ) + i] = 0xffffffff;
		}
	}
	wm_memory->active_quad = 0;
}
Esempio n. 4
0
Status _elf_load_from_file(Pcb* pcb, const char* file_name)
{
	// Need to copy the file_name into kernel land...because we're killing userland!
	const char* temp = file_name;
	file_name = (const char *)__kmalloc(_kstrlen(temp) + 1);
	_kmemcpy((void *)file_name, (void *)temp, _kstrlen(temp)+1); // Copy the null terminator as well

	serial_printf("---Elf: attempting to open: %s\n", file_name);
	if (pcb == NULL || file_name == NULL) 
	{
		return BAD_PARAM;
	}

	// Try to open the file
	Elf32_Ehdr* elf32_hdr = (Elf32_Ehdr *)__kmalloc(sizeof(Elf32_Ehdr));

	serial_printf("ELF header location: %x\n", elf32_hdr);

	Uint bytes_read = 0;
	VFSStatus vfs_status =
		raw_read(file_name, (void *)elf32_hdr, &bytes_read, 0, sizeof(Elf32_Ehdr));

	if (vfs_status != FS_E_OK /* Couldn't read the file */
		   || bytes_read < sizeof(Elf32_Ehdr) /* Clearly not an ELF file */
		   || elf32_hdr->e_magic != ELF_MAGIC_NUM /* Need the magic number! */
		   || elf32_hdr->e_type != ET_EXEC /* Don't support relocatable or dynamic files yet */
		   || elf32_hdr->e_machine != EM_386 /* Make sure it's for our architecture */
		   || elf32_hdr->e_entry == 0x0 /* Need an entry point */
		   || elf32_hdr->e_version != EV_CURRENT /* We don't support extensions right now */
		   || elf32_hdr->e_phoff == 0 /* If there are no program headers, what do we load? */
		   || elf32_hdr->e_phnum == 0) /* ... */
		// || elf32_hdr->e_ehsize != sizeof(Elf32_Ehdr)) /* The header size should match our struct */
	{
		if (vfs_status != FS_E_OK) { serial_printf("RETURN VALUE: %x\n", vfs_status); _kpanic("ELF", "Failed to open file successfully\n", 0); }
		if (bytes_read < sizeof(Elf32_Ehdr)) _kpanic("ELF", "Read too small of a file!\n", 0);
		if (elf32_hdr->e_magic != ELF_MAGIC_NUM) _kpanic("ELF", "Bad magic number!\n", 0);
		if (elf32_hdr->e_type != ET_EXEC) _kpanic("ELF", "Not an executable ELF!\n", 0);
		if (elf32_hdr->e_machine != EM_386) _kpanic("ELF", "Not a i386 ELF!\n", 0);
		if (elf32_hdr->e_entry == 0x0) _kpanic("ELF", "Bad entry point!\n", 0);
		if (elf32_hdr->e_version != EV_CURRENT) _kpanic("ELF", "Don't support non-current versions!\n", 0);
		if (elf32_hdr->e_phoff == 0) _kpanic("ELF", "No program headers found!\n", 0);
		if (elf32_hdr->e_phnum == 0) _kpanic("ELF", "Zero program headers!\n", 0);

		_kpanic("ELF", "Couldn't open file!\n", 0);
		// Problem opening the file
		__kfree(elf32_hdr);
		return BAD_PARAM;
	}

	if (sizeof(Elf32_Phdr) != elf32_hdr->e_phentsize)
	{
		_kpanic("ELF", "program header size is different!\n", 0);
	}

	/* Okay lets start reading in and setting up the ELF file */	
	// We need a new buffer of size of (e_phentsize * e_phnum)
	Uint32 pheader_tbl_size = sizeof(Elf32_Phdr) * elf32_hdr->e_phnum;
	Elf32_Phdr* pheaders = (Elf32_Phdr *)__kmalloc(pheader_tbl_size);

	serial_printf("---ELF: program headers location: %x\n", pheaders);

	serial_printf("ELF: Reading program headers\n");
	vfs_status = raw_read(file_name, (void *)pheaders, &bytes_read,
			elf32_hdr->e_phoff, pheader_tbl_size);

	if (vfs_status != FS_E_OK 
			|| bytes_read < pheader_tbl_size)
	{
		_kpanic("ELF", "error reading file!\n", 0);
		__kfree(pheaders);
		__kfree(elf32_hdr);
		return BAD_PARAM;
	}

	serial_printf("ELF: resetting page directory\n");
	// Cleanup the old processes page directory, we're replacing everything
	__virt_reset_page_directory();

	serial_printf("ELF: About to read the program sections\n");
	/* We need to load all of the program sections now */
	for (Int32 i = 0; i < elf32_hdr->e_phnum; ++i)
	{
		Elf32_Phdr* cur_phdr = &(pheaders[i]);	

		if (cur_phdr->p_type == PT_LOAD)
		{
			if (cur_phdr->p_vaddr >= KERNEL_LINK_ADDR || cur_phdr->p_vaddr < 0x100000)
			{
				_kpanic("ELF", "An ELF with bad addresses loaded", 0);
			}

			serial_printf("\tELF: loading program section: %d at %x size: %x\n", i, cur_phdr->p_vaddr, cur_phdr->p_memsz);
			if (cur_phdr->p_memsz == 0)
			{
				serial_printf("\tELF: empty section, skipping\n");
				continue;
			}
			// This is a loadable section
			//if (cur_phdr->p_align > 1)
			//	_kpanic("ELF", "ELF loader doesn't support aligned program segments\n", 0);

			// Map these pages into memory!
			void* start_address = (void *)cur_phdr->p_vaddr;
			void* end_address   = (void *)(start_address + cur_phdr->p_memsz);
			for (; start_address < end_address; start_address += PAGE_SIZE)
			{
				Uint32 flags = PG_USER;
				if ((cur_phdr->p_flags & PF_WRITE) > 0)
				{
					flags |= PG_READ_WRITE;	
				}

				serial_printf("Checking address: %x\n", __virt_get_phys_addr(start_address));
				serial_printf("Start address: %x\n", start_address);
				if (__virt_get_phys_addr(start_address) == (void *)0xFFFFFFFF)
				{
					serial_printf("ELF: Mapping page: %x - flags: %x\n", start_address, flags);
					__virt_map_page(__phys_get_free_4k(), start_address, flags);
					serial_printf("ELF: Done mapping page\n");
				} else {
					serial_printf("Address: %x already mapped\n", start_address);
				}
			}

			serial_printf("ELF: about to memcpy program section: %x of size %d\n", cur_phdr->p_vaddr, cur_phdr->p_memsz);
			// Lets zero it out, we only need to zero the remaining bytes, p_filesz
			// may be zero for data sections, in this case the memory should be zeroed
			_kmemclr((void *)(cur_phdr->p_vaddr + (cur_phdr->p_memsz - cur_phdr->p_filesz)), 
					cur_phdr->p_memsz - cur_phdr->p_filesz);

			serial_printf("ELF: done memory copying: %s\n", file_name);

			// Now we have to read it in from the file
			if (cur_phdr->p_filesz > 0)
			{
				serial_printf("\tAt offset: %x\n", cur_phdr->p_offset);

				vfs_status = raw_read(file_name, (void *)cur_phdr->p_vaddr,
						&bytes_read, cur_phdr->p_offset, cur_phdr->p_filesz);
						
				serial_printf("Read: %d - File size: %d\n", bytes_read, cur_phdr->p_filesz);
				
				if (bytes_read != cur_phdr->p_filesz)
				{
					_kpanic("ELF", "Failed to read data from the filesystem", 0);
				}

				if (vfs_status != FS_E_OK)
				{
					// TODO - cleanup if error
					_kpanic("ELF", "failed to read program section\n", 0);
				}

				//asm volatile("hlt");
			}
		} else {
			serial_printf("\tELF: Non-loadable section: %d at %x size: %x type: %d\n", i, cur_phdr->p_vaddr, cur_phdr->p_memsz, cur_phdr->p_type);
		}
	}

	// Setup the PCB information

	// Allocate a stack and map some pages for it
#define USER_STACK_LOCATION 0x2000000
#define USER_STACK_SIZE 0x4000 /* 16 KiB */
	serial_printf("ELF: Allocating stack\n");
	void* stack_start = (void *)USER_STACK_LOCATION;
	void* stack_end   = (void *)(USER_STACK_LOCATION + USER_STACK_SIZE);
	for (; stack_start < stack_end; stack_start += PAGE_SIZE)
	{
		__virt_map_page(__phys_get_free_4k(), stack_start, PG_READ_WRITE | PG_USER);
	}
	_kmemclr((void *)USER_STACK_LOCATION, USER_STACK_SIZE);

	// Throw exit as the return address as a safe guard
	serial_printf("ELF: setting up context\n");
	// Setup the context
	Context* context = ((Context *)(USER_STACK_LOCATION+USER_STACK_SIZE-4)) - 1;
	serial_printf("Context location: %x\n", context);
	pcb->context = context;

	context->esp = (Uint32)(((Uint32 *)context) - 1);
	context->ebp = (USER_STACK_LOCATION+USER_STACK_SIZE)-4;
	context->cs = GDT_CODE;
	context->ss = GDT_STACK;
	context->ds = GDT_DATA;
	context->es = GDT_DATA;
	context->fs = GDT_DATA;
	context->gs = GDT_DATA;

	serial_printf("ELF: setting entry point: %x\n", elf32_hdr->e_entry);
 	// Entry point
	context->eip = elf32_hdr->e_entry;

	// Setup the rest of the PCB
	pcb->context->eflags = DEFAULT_EFLAGS;

	serial_printf("ELF: about to return\n");
	__kfree(pheaders);
	__kfree(elf32_hdr);
	__kfree((void *)file_name);
	return SUCCESS;
}
Esempio n. 5
0
context_t *_create_stack( stack_t *stack ) {
	uint32_t *ptr;
	context_t *context;

	// sanity check!

	if( stack == NULL ) {
		return( NULL );
	}

	// start by clearing the stack

	_kmemclr( (void *) stack, sizeof(stack_t) );

	/*
	** Set up the initial stack contents for a (new) user process.
	**
	** We reserve one longword at the bottom of the stack as
	** scratch space.  Above that, we simulate a call to exit() by
	** pushing the special exit status EXIT_DEFAULT and the address
	** of exit() as a "return address".  Finally, we simulate a call
	** from the entry point of exit() to main().  Above that, we
	** place an context_t area that is initialized with the
	** standard initial register contents.
	**
	** The low end of the stack will contain these values:
	**
	**      esp ->  ?     <- context save area
	**              ...   <- context save area
	**              ?     <- context save area
	**              exit  <- return address for faked call to main()
	**              0     <- return address for faked call to exit()
	**              code  <- special exit status
	**              0     <- last word in stack
	**
	** When this process is dispatched, the context restore code
	** will pop all the saved context information off the stack,
	** leaving the "return address" on the stack as if the main()
	** for the process had been "called" from the exit() stub.
	** When main() returns, it will "return" to the entry point of
	** exit(), which will clean it up.
	*/

	// first, find the address following the stack

	ptr = ((uint32_t *) (stack + 1)) - 2;

	// assign the filler data

	*--ptr = 0;

	// assign the default exit status

	*--ptr = EXIT_DEFAULT;

	// assign the return address for the faked call to exit()

	*--ptr = 0;

	// assign the return address for the faked call to main()

	*--ptr = (uint32_t) exit;

	// next, set up the process context

	context = ((context_t *) ptr) - 1;

	// initialize all the fields that should be non-zero, starting
	// with the segment registers

	context->cs = GDT_CODE;
	context->ss = GDT_STACK;
	context->ds = GDT_DATA;
	context->es = GDT_DATA;
	context->fs = GDT_DATA;
	context->gs = GDT_DATA;

	// EFLAGS must be set up to re-enable IF when we switch
	// "back" to this context

	context->eflags = DEFAULT_EFLAGS;

	/*
	** Note that we do *not* assign EIP here; we leave that
	** to the calling routine
	*/

	// all done - return the context pointer

	return( context );

}