13 #include <lib/stdio.h>
15 #include "sys/scheduler.h"
17 elf_t* load_elf(
const char* name){
25 qemu_err(
"Failed to open ELF file: %s / %d", name, file_elf->err);
56 void unload_elf(
elf_t* elf) {
64 int32_t run_elf_file(
const char *name,
int argc,
char* eargv[]) {
65 elf_t* elf_file = load_elf(name);
68 uint32_t vmm_allocated[4096] = {0};
69 uint32_t vmm_mapped[4096] = {0};
70 uint32_t vmm_sizes[4096] = {0};
72 if (elf_file ==
nullptr) {
73 qemu_err(
"[DBG] Error opening file %s\n", name);
90 uint32_t vmm_allocated_count = 0;
95 if (phdr->
p_type != PT_LOAD)
98 qemu_log(
" - TYPE: %s OFFSET: %x VADDR: %x PADDR:%x FSIZE: %x MSIZE: %xx ",
99 (phdr->
p_type == PT_LOAD ?
"LOAD" :
"UNKNOWN"),
108 size_t pagecount = MAX((ALIGN(phdr->
p_memsz, PAGE_SIZE) / PAGE_SIZE), 1);
110 physical_addr_t addrto = phys_alloc_multi_pages(pagecount);
111 qemu_log(
"Page count allocated now: %d (memsz: %d; PAGE SIZE: %d)",
112 pagecount, phdr->
p_memsz, PAGE_SIZE);
115 get_kernel_page_directory(),
119 (PAGE_PRESENT | PAGE_USER | PAGE_WRITEABLE)
122 vmm_allocated[vmm_allocated_count] = addrto;
123 vmm_sizes[vmm_allocated_count] = pagecount;
124 vmm_mapped[vmm_allocated_count] = phdr->
p_vaddr;
125 vmm_allocated_count++;
128 qemu_log(
"Set %x - %x to zero.", (
int)((
void*)phdr->
p_vaddr), (
int)((
void*)phdr->
p_vaddr) + phdr->
p_memsz);
136 int(*entry_point)(
int argc,
char* eargv[]) = (
int(*)(int,
char**))elf_file->
elf_header.
e_entry;
139 qemu_log(
"Executing");
140 int _result = entry_point(argc, eargv);
142 qemu_log(
"Program returned: %d", _result);
143 qemu_log(
"Cleaning VMM:");
145 for (int32_t i = 0; i < vmm_allocated_count; i++){
146 qemu_log(
"\tCleaning %d: %x [%d]", i, vmm_allocated[i], vmm_sizes[i]);
147 for(
int j = 0; j < vmm_sizes[i]; j++) {
148 unmap_single_page(get_kernel_page_directory(), vmm_mapped[i] + (j * PAGE_SIZE));
150 phys_free_single_page(vmm_allocated[i]);
153 qemu_log(
"Cleaned %d pages", vmm_allocated_count);
157 unload_elf(elf_file);
162 int32_t spawn(
const char *name,
int argc,
char* eargv[]) {
163 __asm__
volatile(
"cli");
165 elf_t* elf_file = load_elf(name);
167 if (elf_file ==
nullptr) {
168 qemu_err(
"[DBG] Error opening file %s\n", name);
176 process_t* proc = (process_t*)kcalloc(1,
sizeof(process_t));
180 proc->list_item.list =
nullptr;
181 proc->threads_count = 0;
184 proc->suspend =
false;
186 for (int32_t i = 0; i < elf_file->elf_header.e_phnum; i++) {
189 if (phdr->
p_type != PT_LOAD)
192 size_t pagecount = MAX((ALIGN(phdr->
p_memsz, PAGE_SIZE) / PAGE_SIZE), 1);
194 physical_addr_t addrto = phys_alloc_multi_pages(pagecount);
197 get_kernel_page_directory(),
200 pagecount * PAGE_SIZE,
201 (PAGE_PRESENT | PAGE_USER | PAGE_WRITEABLE)
205 qemu_log(
"Set %x - %x to zero.", (
int)((
void*)phdr->
p_vaddr), (
int)((
void*)phdr->
p_vaddr) + phdr->
p_memsz);
213 int(*entry_point)(
int argc,
char* eargv[]) = (
int(*)(int,
char**))elf_file->elf_header.e_entry;
214 qemu_log(
"ELF entry point: %x", elf_file->elf_header.e_entry);
220 void* virt = clone_kernel_page_directory(proc->page_tables_virts);
221 uint32_t phys = virt2phys(get_kernel_page_directory(), (virtual_addr_t) virt);
223 proc->page_dir = phys;
227 qemu_log(
"PROCESS CREATED");
229 for (int32_t i = 0; i < elf_file->elf_header.e_phnum; i++) {
232 if(phdr->
p_type != PT_LOAD)
235 size_t pagecount = MAX((ALIGN(phdr->
p_memsz, PAGE_SIZE) / PAGE_SIZE), 1);
237 qemu_log(
"\t??? Cleaning %d: %x [%d]", i, phdr->
p_vaddr, pagecount * PAGE_SIZE);
239 for(
size_t x = 0; x < pagecount; x++) {
241 get_kernel_page_directory(),
242 phdr->
p_vaddr + (x * PAGE_SIZE)
247 qemu_log(
"CLEANED %d pages", elf_file->elf_header.e_phnum);
251 unload_elf(elf_file);
253 qemu_log(
"RESUMING...");
255 __asm__
volatile(
"sti");
void * memset(void *ptr, char value, size_t num)
Заполнение массива указанными символами
int strcpy(char *dest, const char *src)
Копирование строк
list_t process_list
Список процессов
list_t thread_list
Список потоков
thread_t * _thread_create_unwrapped(process_t *proc, void *entry_point, size_t stack_size, bool kernel, bool suspend)
Создание потока
uint32_t next_pid
Следующий ID задачи (PID)
ssize_t fseek(FILE *stream, ssize_t offset, uint8_t whence)
Установка позиции в потоке данных относительно текущей позиции
void fclose(FILE *stream)
Закончить работу с файлом
FILE * fopen(const char *filename, const char *_mode)
Открывает файл
int fread(FILE *stream, size_t count, size_t size, void *buffer)
Чтение файла
Elf32_Addr e_entry
Точка входа в процесс
Elf32_Half e_shnum
Количество записей в заголовке раздела
Elf32_Half e_phnum
Количество записей заголовка программы
Elf32_Half e_type
Тип объектного файла
Elf32_Half e_shentsize
Размер записи заголовка раздела
Elf32_Half e_mashine
Тип архитектуры
unsigned char e_ident[EI_NIDENT]
Идентификационные данные ELF.
Elf32_Half e_phentsize
Размер записи заголовка программы
Elf32_Off e_shoff
Смещение заголовка таблицы разделов
Elf32_Off e_phoff
Смещение заголовка программы
Elf32_Word e_version
Версия объектного файла
Elf32_Word e_flags
Флаги, специфичные для процессора
Elf32_Addr p_paddr
Физический адрес заголовка программы
Elf32_Word p_type
Тип заголовка программы
Elf32_Word p_filesz
Число байтов в сегменте файла
Elf32_Off p_offset
Смещение заголовка программы
Elf32_Addr p_vaddr
Виртуальный адрес заголовка программы
Структура файла. Требуется для работы с VFS.
FILE * file
Ссылка на файл
Elf32_Ehdr elf_header
ELF заголовок
Elf32_Phdr * p_header
Программный заголовок
Elf32_Shdr * section
Секции