Пример #1
0
void io_libraryRelease(io_library_t *library)
{
	spinlock_lock(&library->lock);

	if((-- library->refCount) == 0)
	{
		struct io_dependency_s *dependency = list_first(library->dependencies);
		while(dependency)
		{
			io_libraryRelease(dependency->library);
			dependency = dependency->next;
		}

		io_storeRemoveLibrary(library);

		if(library->vmemory)
			vm_free(vm_getKernelDirectory(), library->vmemory, library->pages);

		if(library->pmemory)
			pm_free(library->pmemory, library->pages);

		hfree(NULL, library->path);
		list_destroy(library->dependencies);
		return;
	}

	spinlock_unlock(&library->lock);
}
Пример #2
0
void dma_free(dma_t *dma)
{
	for(size_t i=0; i<dma->pfragmentCount; i++)
	{
		pm_free(dma->pfragments[i], dma->pfragmentPages[i]);
	}

	if(dma->vaddress)
		vm_free(vm_getKernelDirectory(), dma->vaddress, dma->pages);

	hfree(NULL, dma);
}
Пример #3
0
bool ir_trampoline_init(void *UNUSED(unused))
{
	// Map the trampoline area into memory
	vm_mapPageRange(vm_getKernelDirectory(), (uintptr_t)IR_TRAMPOLINE_PHYSICAL, (vm_address_t)IR_TRAMPOLINE_BEGIN, IR_TRAMPOLINE_PAGES, VM_FLAGS_KERNEL);

	// Copy the IDT section into the trampoline
	vm_address_t _idt_sectionBegin      = (vm_address_t)&idt_sectionBegin;
	vm_address_t _idt_sectionEnd        = (vm_address_t)&idt_sectionEnd;
	vm_address_t _idt_entryHandler      = (vm_address_t)&idt_entry_handler;

	memcpy(ir_trampoline_map->base, &idt_sectionBegin, _idt_sectionEnd - _idt_sectionBegin);
	ir_trampolineFixEntryCall(_idt_entryHandler - _idt_sectionBegin, _idt_sectionEnd - _idt_entryHandler);

	// Set IDT and GDT straight
	ir_idt_init(ir_trampoline_map->idt, IR_TRAMPOLINE_BEGIN - _idt_sectionBegin);
	gdt_init(ir_trampoline_map->gdt, &ir_trampoline_map->tss);

	return true;
}
Пример #4
0
io_library_t *io_libraryCreate(const char *path, uint8_t *buffer, size_t UNUSED(length))
{
	io_library_t *library = halloc(NULL, sizeof(io_library_t));
	if(library)
	{
		// Setup the library
		memset(library, 0, sizeof(io_library_t));

		library->lock = SPINLOCK_INIT;
		library->refCount = 1;

		library->path = halloc(NULL, strlen(path) + 1);
		library->dependencies = list_create(sizeof(struct io_dependency_s), offsetof(struct io_dependency_s, next), offsetof(struct io_dependency_s, prev));

		if(!library->path || !library->dependencies)
		{
			if(library->path)
				hfree(NULL, library->path);

			if(library->dependencies)
				list_destroy(library->dependencies);

			dbg("iolink: Couldn't allocate enough memory for %s\n", path);
			return NULL;
		}

		strcpy(library->path, path);
		library->name = (char *)sys_fileWithoutPath(library->path);


		// Get the basic ELF info
		elf_header_t *header = (elf_header_t *)buffer;
		if(strncmp((const char *)header->e_ident, ELF_MAGIC, strlen(ELF_MAGIC)) != 0 || header->e_type != ET_DYN)
		{
			hfree(NULL, library->path);
			list_destroy(library->dependencies);

			dbg("iolink: %s is not a valid binary!\n", path);
			return NULL;
		}


		// Parse the program header
		elf_program_header_t *programHeader = (elf_program_header_t *)(buffer + header->e_phoff);
		elf_program_header_t *ptload[2];

		vm_address_t minAddress = -1;
		vm_address_t maxAddress = 0;

		size_t segments = 0;

		// Calculate the needed size
		for(int i=0; i<header->e_phnum; i++) 
		{
			elf_program_header_t *program = &programHeader[i];

			if(program->p_type == PT_LOAD)
			{
				if(program->p_paddr < minAddress)
					minAddress = program->p_paddr;

				if(program->p_paddr + program->p_memsz > maxAddress)
					maxAddress = program->p_paddr + program->p_memsz;

				ptload[segments ++] = program;
			}

			if(program->p_type == PT_DYNAMIC)
				library->dynamic = (elf_dyn_t *)program->p_vaddr;
		}

		// Reserve enough memory and copy the .text section
		library->pages = pageCount(maxAddress - minAddress);

		library->pmemory = pm_alloc(library->pages);
		if(!library->pmemory)
		{
			io_libraryRelease(library);
			return NULL;
		}

		library->vmemory = vm_alloc(vm_getKernelDirectory(), (uintptr_t)library->pmemory, library->pages, VM_FLAGS_KERNEL);
		if(!library->vmemory)
		{
			io_libraryRelease(library);
			return NULL;
		}

		uint8_t *target = (uint8_t *)library->vmemory;
		uint8_t *source = buffer;

		memset(target, 0, library->pages * VM_PAGE_SIZE);
		for(size_t i=0; i<segments; i++)
		{
			elf_program_header_t *program = ptload[i];
			memcpy(&target[program->p_vaddr - minAddress], &source[program->p_offset], program->p_filesz);
		}

		library->relocBase = library->vmemory - minAddress;

		// Verify
		if(library->dynamic)
		{
			library->dynamic = (elf_dyn_t *)(library->relocBase + ((uintptr_t)library->dynamic));
			io_libraryDigestDynamic(library);
		}
	}

	return library;
}
Пример #5
0
ld_exectuable_t *ld_exectuableCreate(vm_page_directory_t pdirectory, uint8_t *begin, size_t UNUSED(size))
{
	elf_header_t *header = (elf_header_t *)begin;

	if(strncmp((const char *)header->e_ident, ELF_MAGIC, strlen(ELF_MAGIC)) != 0)
		return NULL;

	ld_exectuable_t *executable = halloc(NULL, sizeof(ld_exectuable_t));
	if(executable)
	{
		// Initialize the executable
		executable->useCount   = 1;
		executable->entry      = header->e_entry;
		executable->pdirectory = pdirectory;


		elf_program_header_t *programHeader = (elf_program_header_t *)(begin + header->e_phoff);
		vm_address_t minAddress = -1;
		vm_address_t maxAddress = 0;

		size_t pages = 0;

		// Calculate the needed size
		for(int i=0; i<header->e_phnum; i++) 
		{
			elf_program_header_t *program = &programHeader[i];

			if(program->p_type == PT_LOAD)
			{
				if(program->p_paddr < minAddress)
					minAddress = program->p_paddr;

				if(program->p_paddr + program->p_memsz > maxAddress)
					maxAddress = program->p_paddr + program->p_memsz;
			}
		}

		// Calculate the starting address and the number of pages we need to allocate
		minAddress = round4kDown(minAddress);
		pages = pageCount(maxAddress - minAddress);

		// Memory allocation
		uint8_t *memory = (uint8_t *)pm_alloc(pages);
		uint8_t *target = (uint8_t *)vm_alloc(vm_getKernelDirectory(), (uintptr_t)memory, pages, VM_FLAGS_KERNEL);
		uint8_t *source = begin;

		memset(target, 0, pages * VM_PAGE_SIZE);

		// Copy the data from the image
		for(int i=0; i<header->e_phnum; i++) 
		{
			elf_program_header_t *program = &programHeader[i];

			if(program->p_type == PT_LOAD)
			{
				memcpy(&target[program->p_vaddr - minAddress], &source[program->p_offset], program->p_filesz);
			}
		}

		vm_free(vm_getKernelDirectory(), (vm_address_t)target, pages);
		vm_mapPageRange(pdirectory, (uintptr_t)memory, minAddress, pages, VM_FLAGS_USERLAND_R);

		executable->pimage = (uintptr_t)memory;
		executable->vimage = (vm_address_t)minAddress;
		executable->imagePages = pages;
	}

	return executable;
}