#include "../include/exec_from_file.h" #include "../include/disk.h" #include "../include/kheap.h" #include "../include/liballoc.h" #include "../include/string.h" #include "../include/paging.h" #include "../include/task.h" #define DivRoundUp(number, divisor) ((number + divisor - 1) / divisor) #define USER_STACK_TOP 0xBFFFFFF0//0xC0000000 // Top of user space memory #define USER_STACK_SIZE 0x4000 // 16KB stack (4 pages) #define USER_STACK_BOTTOM (USER_STACK_TOP - USER_STACK_SIZE) disk_ops_t ops1 = { .read = ata_read, .write = ata_write, }; static fat_t g_fat; int read_file(const char* path, uint8_t** buffer) { file_t file; int err = fat_fopen(&file, path, "r"); if (err) return err; uint32_t file_size = fat_fsize(&file); debug_log("file_size: %X\n", file_size); uint8_t buf[512]; //memset(buf, 0, 512); debug_log("heh\n"); *buffer = (uint8_t*)malloc(file_size); //memset(*buffer, 0, file_size); uint8_t* current = *buffer; debug_log("eeee\n"); int cnt = fat_fread(&file, *buffer, file_size); /*for (;;) { int cnt = fat_fread(&file, buf, 512); if (cnt < 0) return cnt; //printf("%s\n", buf); memcpy(current, buf, 512); current += 512; if (cnt < 512) break; }*/ return fat_fclose(&file); } void exec_from_file(const char* filename) { asm volatile("cli"); int err, cnt; err = fat_mount(&ops1, 0, &g_fat, "ebalo"); uint8_t* file; int result = read_file("/ebalo/aaa", &file); debug_log("result: %X\n", result); debug_log("buffer: %s\n", file); Elf32_Ehdr *elf_ehdr = (Elf32_Ehdr*)file; int program_header_table_entry_count = elf_ehdr->e_phnum; int program_header_table_entry_size = elf_ehdr->e_phentsize; debug_log("magic: %X, type: %X, entry: 0x%X\n", elf_ehdr->e_ident, elf_ehdr->e_type, elf_ehdr->e_entry); debug_log("PHNUM: %X\n", program_header_table_entry_count); debug_log("PHENTSIZE: %X\n\n", program_header_table_entry_size); uint32_t* proc_pd = create_page_dir(); uint32_t proc_pd_phys = (uint32_t)get_physaddr((void*)proc_pd); debug_log("proc_pd_phys: 0x%X\n", proc_pd_phys); uint32_t* curr_pd_virt = get_page_dir(); // CR3 содержит физический адрес, но get_page_dir возвращает его как uint32_t* uint32_t curr_pd_phys = (uint32_t)curr_pd_virt; // Просто приводим к uint32_t, так как CR3 содержит физический адрес set_page_dir(proc_pd_phys); for(int i = 0; i < program_header_table_entry_count; i++) { Elf32_Phdr *elf_phdr = (Elf32_Phdr *)((uint32_t)file + elf_ehdr->e_phoff + i * elf_ehdr->e_phentsize); debug_log("HEADER %X, type: 0x%X, vaddr: 0x%X, paddr: 0x%X, memsz: 0x%X\n", i, elf_phdr->p_type, elf_phdr->p_vaddr, elf_phdr->p_paddr, elf_phdr->p_memsz); if(elf_phdr->p_type != PT_LOAD) { debug_log("not PT_LOAD, skipping...\n"); continue; } int pages_needed = DivRoundUp(elf_phdr->p_memsz, 0x1000);//(elf_phdr->p_memsz / 0x1000) + 1; debug_log("pages needed: %X\n", pages_needed); for(int j = 0; j < pages_needed; j++) { uint32_t vaddr = (elf_phdr->p_vaddr & ~0xFFF) + j * 0x1000; void* phys_addr = alloc_page(); debug_log("mapping 0x%X -> 0x%X\n", phys_addr, vaddr); map_page(phys_addr, (void*)vaddr, PAGE_PRESENT | PAGE_RW | PAGE_USER); } memcpy((void*)elf_phdr->p_vaddr, file+elf_phdr->p_offset, elf_phdr->p_filesz); if (elf_phdr->p_memsz > elf_phdr->p_filesz) { uint32_t bss_start = elf_phdr->p_vaddr + elf_phdr->p_filesz; uint32_t bss_end = elf_phdr->p_vaddr + elf_phdr->p_memsz; memset((void*)bss_start, 0, bss_end - bss_start); } debug_log("p_filesz: 0x%X (%X)\n", elf_phdr->p_filesz, elf_phdr->p_filesz); debug_log("================================\n\n\n\n"); } debug_log("setting up the user stack...\n"); //TODO: i think this thing allocates more pages than needed for (uint32_t vaddr = USER_STACK_BOTTOM; vaddr <= USER_STACK_TOP; vaddr += PAGE_SIZE) { void* phys_addr = alloc_page(); if(!phys_addr) { printf("error allocating user stack page, aborting...\n"); set_page_dir(curr_pd_phys); //TODO: free previously allocated pages return; } map_page(phys_addr, (void*)(vaddr & ~0xFFF), PAGE_PRESENT | PAGE_RW | PAGE_USER); debug_log("mapping stack 0x%X -> 0x%X (0x%X)\n", (uint32_t)phys_addr, vaddr, (vaddr & ~0xFFF)); memset((void*)(vaddr & ~0xFFF), 0, PAGE_SIZE); // Add this } /* uint32_t user_esp = USER_STACK_TOP; // envp (environment pointer array) = NULL terminator user_esp -= 4; *(uint32_t*)user_esp = 0; // argv (argument pointer array) = NULL terminator user_esp -= 4; *(uint32_t*)user_esp = 0; // argc (argument count) = 0 user_esp -= 4; *(uint32_t*)user_esp = 0; */ set_page_dir(curr_pd_phys); Process* p_task1 = task_create(elf_ehdr->e_entry, USER_STACK_TOP, 3, proc_pd); asm volatile("sti"); }