OSDev http://osdev.su/ |
|
JamesM и fork() http://osdev.su/viewtopic.php?f=6&t=840 |
Страница 1 из 1 |
Автор: | Lincor [ 09 дек 2013, 15:35 ] |
Заголовок сообщения: | JamesM и fork() |
знаю, боян, но все же, почему не работает функция fork() в руководстве по разработке ядра James Molloy? на английском osdev есть несколько таких вопросов, но лично мне ни один из предложенных вариантов не помог функции fork() и clone_directory (видимо, виновата именно она): Код: int fork() { // We are modifying kernel structures, and so cannot be interrupted. asm volatile("cli"); // Take a pointer to this process' task struct for later reference. task_t *parent_task = (task_t*)current_task; // Clone the address space. page_directory_t *directory = clone_directory(current_directory); // Create a new process. task_t *new_task = (task_t*)kmalloc(sizeof(task_t)); new_task->id = next_pid++; new_task->esp = new_task->ebp = 0; new_task->eip = 0; new_task->page_directory = directory; current_task->kernel_stack = kmalloc_a(KERNEL_STACK_SIZE); new_task->next = 0; // Add it to the end of the ready queue. // Find the end of the ready queue... task_t *tmp_task = (task_t*)ready_queue; while (tmp_task->next) tmp_task = tmp_task->next; // ...And extend it. tmp_task->next = new_task; // This will be the entry point for the new process. u32int eip = read_eip(); // We could be the parent or the child here - check. if (current_task == parent_task) { // We are the parent, so set up the esp/ebp/eip for our child. u32int esp; asm volatile("mov %%esp, %0" : "=r"(esp)); u32int ebp; asm volatile("mov %%ebp, %0" : "=r"(ebp)); new_task->esp = esp; new_task->ebp = ebp; new_task->eip = eip; // All finished: Reenable interrupts. asm volatile("sti"); // And by convention return the PID of the child. return new_task->id; } else { // We are the child - by convention return 0. return 0; } } Код: page_directory_t *clone_directory(page_directory_t *src)
{ u32int phys; // Make a new page directory and obtain its physical address. page_directory_t *dir = (page_directory_t*)kmalloc_ap(sizeof(page_directory_t), &phys); // Ensure that it is blank. memset(dir, 0, sizeof(page_directory_t)); // Get the offset of tablesPhysical from the start of the page_directory_t structure. u32int offset = (u32int)dir->tablesPhysical - (u32int)dir; // Then the physical address of dir->tablesPhysical is: dir->physicalAddr = phys + offset; // Go through each page table. If the page table is in the kernel directory, do not make a new copy. int i; for (i = 0; i < 1024; i++) { if (!src->tables[i]) continue; if (kernel_directory->tables[i] == src->tables[i]) { // It's in the kernel, so just use the same pointer. dir->tables[i] = src->tables[i]; dir->tablesPhysical[i] = src->tablesPhysical[i]; } else { // Copy the table. u32int phys; dir->tables[i] = clone_table(src->tables[i], &phys); dir->tablesPhysical[i] = phys | 0x07; } } return dir; } |
Автор: | Nable [ 10 дек 2013, 00:32 ] |
Заголовок сообщения: | Re: JamesM и fork() |
Так задумано - там есть некоторые косяки, которые нужно самостоятельно отладчиком найти. |
Страница 1 из 1 | Часовой пояс: UTC + 3 часа |
Powered by phpBB® Forum Software © phpBB Group http://www.phpbb.com/ |