uintptr_t process_load_elf(struct process *p, uintptr_t elf) { int need_kernel = 0; Elf32_Ehdr *hdr = (void *)elf; Elf32_Phdr *phdr = (void *)((char *)hdr + hdr->e_phoff); struct thread *t = thread_current(); /* * If the process address space is not the current one we need extra * mapping in the kernel to write on the pages */ if (!t || t->parent->as != p->as) need_kernel = 1; for (uint32_t i = 0; i < hdr->e_phnum; ++i) { if (phdr[i].p_type != PT_LOAD) continue; vaddr_t vaddr; paddr_t paddr; size_t page_size = align(phdr[i].p_memsz, PAGE_SIZE) / PAGE_SIZE; /* TODO: Error handling */ vaddr = region_reserve(p->as, phdr[i].p_vaddr, page_size); /* TODO: Error handling */ paddr = segment_alloc_address(page_size); /* TODO: Error handling */ vaddr = as_map(p->as, vaddr, paddr, phdr[i].p_memsz, AS_MAP_USER | AS_MAP_WRITE); /* TODO: Error handling */ if (need_kernel) vaddr = as_map(&kernel_as, 0, paddr, phdr[i].p_memsz, AS_MAP_WRITE); memcpy((void *)vaddr, (void *)(elf + phdr[i].p_offset), phdr[i].p_filesz); memset((char *)vaddr + phdr[i].p_filesz, 0, phdr[i].p_memsz - phdr[i].p_filesz); if (need_kernel) as_unmap(&kernel_as, vaddr, AS_UNMAP_NORELEASE); } return hdr->e_entry; }
int cons_init(void) { i_region reg; t_uint16 line; t_uint16 c; int br; if (region_reserve(__as_id, 0x1000, CONS_ADDR - 0x1000, REGION_OPT_NONE, 0, PAGESZ, ®) != ERROR_NONE) return (-1); cons.attr = CONS_FRONT(CONS_WHITE) | CONS_BACK(CONS_BLACK) | CONS_INT; cons.vga = (char*)(t_vaddr)reg; cons.line = 0; cons.column = 0; /* XXX[needless with the serial kernel redirection since we've got the whole screen for ourselves] for (br = 1, line = CONS_LINES - 1; br && line > 0; line--) { for (c = 0; c < CONS_COLUMNS * CONS_BPC; c += CONS_BPC) if (cons.vga[line * CONS_COLUMNS * CONS_BPC + c * CONS_BPC]) { br = 0; break; } } if (line == CONS_LINES - 1) { cons_scroll(1); cons.line = line; } else cons.line = line + 1; */ cons_clear(); return (0); }
t_status interface_region_reserve(o_syscall* message) { t_status error; i_region result1; error = region_reserve(message->u.request.u.region_reserve.arg1, message->u.request.u.region_reserve.arg2, message->u.request.u.region_reserve.arg3, message->u.request.u.region_reserve.arg4, message->u.request.u.region_reserve.arg5, message->u.request.u.region_reserve.arg6, &result1); message->u.reply.error = error; message->u.reply.u.region_reserve.result1 = result1; return (STATUS_OK); }
t_status architecture_environment_server(i_as id) { i_segment segment; i_region region; o_as* as; at_pd pd; o_region* r; o_segment* s; /* * 1) */ if (as_get(id, &as) != STATUS_OK) MACHINE_ESCAPE("unable to retrieve the address space object"); /* * 2) */ if (segment_reserve(as->id, ___kaneton$pagesz, PERMISSION_READ | PERMISSION_WRITE, SEGMENT_OPTION_SYSTEM, &segment) != STATUS_OK) MACHINE_ESCAPE("unable to reserve a segment"); if (segment_get(segment, &s) != STATUS_OK) MACHINE_ESCAPE("unable to retrieve the segment object"); /* * 3) */ as->machine.pd = s->address; /* * 4) */ if (architecture_pd_map(as->machine.pd, &pd) != STATUS_OK) MACHINE_ESCAPE("unable to map the page directory"); if (architecture_pd_build(pd) != STATUS_OK) MACHINE_ESCAPE("unable to build the page directory"); if (architecture_pd_unmap(pd) != STATUS_OK) MACHINE_ESCAPE("unable to unmap the page directory"); /* * 5) */ if (region_locate(_kernel.as, _thread.machine.tss, ®ion) == FALSE) MACHINE_ESCAPE("unable to locate the region in which the TSS lies"); if (region_get(_kernel.as, region, &r) != STATUS_OK) MACHINE_ESCAPE("unable to retrieve the region object"); if (region_reserve(as->id, r->segment, 0x0, REGION_OPTION_FORCE | REGION_OPTION_NONE, _thread.machine.tss, r->size, ®ion) != STATUS_OK) MACHINE_ESCAPE("unable to reserve the region mapping the TSS"); /* * 6) */ if (region_locate(_kernel.as, (t_vaddr)_segment.machine.gdt.table, ®ion) == FALSE) MACHINE_ESCAPE("unable to locate the region in which the GDT lies"); if (region_get(_kernel.as, region, &r) != STATUS_OK) MACHINE_ESCAPE("unable to retrieve the region object"); if (region_reserve(as->id, r->segment, 0x0, REGION_OPTION_FORCE | REGION_OPTION_NONE, (t_vaddr)_segment.machine.gdt.table, ___kaneton$pagesz, ®ion) != STATUS_OK) MACHINE_ESCAPE("unable to reserve the region mapping the GDT"); /* * 7) */ if (region_locate(_kernel.as, (t_vaddr)_event.machine.idt.table, ®ion) == FALSE) MACHINE_ESCAPE("unable to locate the region in which the IDT lies"); if (region_get(_kernel.as, region, &r) != STATUS_OK) MACHINE_ESCAPE("unable to retrieve the region object"); if (region_reserve(as->id, r->segment, 0x0, REGION_OPTION_FORCE | REGION_OPTION_NONE, (t_vaddr)_event.machine.idt.table, ___kaneton$pagesz, ®ion) != STATUS_OK) MACHINE_ESCAPE("unable to reserve the region mapping the IDT"); /* * 8) */ if (region_reserve(as->id, _init->kcode, ARCHITECTURE_LINKER_SYMBOL(_handler_code_begin) - _init->kcode, REGION_OPTION_FORCE, ARCHITECTURE_LINKER_SYMBOL(_handler_code_begin), ARCHITECTURE_LINKER_SYMBOL(_handler_code_end) - ARCHITECTURE_LINKER_SYMBOL(_handler_code_begin), ®ion) != STATUS_OK) MACHINE_ESCAPE("unable to map the handler code section"); /* * 9) */ if (region_reserve(as->id, _init->kcode, ARCHITECTURE_LINKER_SYMBOL(_handler_data_begin) - _init->kcode, REGION_OPTION_FORCE, ARCHITECTURE_LINKER_SYMBOL(_handler_data_begin), ARCHITECTURE_LINKER_SYMBOL(_handler_data_end) - ARCHITECTURE_LINKER_SYMBOL(_handler_data_begin), ®ion) != STATUS_OK) MACHINE_ESCAPE("unable to map the handler data section"); MACHINE_LEAVE(); }
void test_core_as_copy_01(void) { i_task task1; i_task task2; i_as as1; i_as as2; i_segment seg1; i_segment seg2; i_segment seg3; i_segment seg4; i_segment seg5; i_segment seg6; i_segment useless; i_region reg; t_uint32 i; t_uint8 buff[4 * ___kaneton$pagesz]; TEST_ENTER(); /* * first address space */ if (task_reserve(TASK_CLASS_GUEST, TASK_BEHAVIOUR_INTERACTIVE, TASK_PRIORITY_INTERACTIVE, &task1) != STATUS_OK) TEST_ERROR("[task_reserve] error"); if (as_reserve(task1, &as1) != STATUS_OK) TEST_ERROR("[as_reserve] error"); if (segment_reserve(as1, 2 * ___kaneton$pagesz, PERMISSION_READ | PERMISSION_WRITE, SEGMENT_OPTION_NONE, &seg1) != STATUS_OK) TEST_ERROR("[segment_reserve] error"); if (segment_reserve(as1, ___kaneton$pagesz, PERMISSION_READ | PERMISSION_WRITE, SEGMENT_OPTION_NONE, &useless) != STATUS_OK) TEST_ERROR("[segment_reserve] error"); if (segment_reserve(as1, 4 * ___kaneton$pagesz, PERMISSION_READ | PERMISSION_WRITE, SEGMENT_OPTION_NONE, &seg2) != STATUS_OK) TEST_ERROR("[segment_reserve] error"); if (segment_reserve(as1, ___kaneton$pagesz, PERMISSION_READ | PERMISSION_WRITE, SEGMENT_OPTION_NONE, &useless) != STATUS_OK) TEST_ERROR("[segment_reserve] error"); if (segment_reserve(as1, 2 * ___kaneton$pagesz, PERMISSION_READ | PERMISSION_WRITE, SEGMENT_OPTION_NONE, &seg3) != STATUS_OK) TEST_ERROR("[segment_reserve] error"); if (region_reserve(as1, seg1, ___kaneton$pagesz, REGION_OPTION_FORCE, 0x20000000, ___kaneton$pagesz, ®) != STATUS_OK) TEST_ERROR("[region_reserve] error"); if (region_reserve(as1, seg2, ___kaneton$pagesz, REGION_OPTION_FORCE, 0x20001000, 2 * ___kaneton$pagesz, ®) != STATUS_OK) TEST_ERROR("[region_reserve] error"); if (region_reserve(as1, seg3, 0, REGION_OPTION_FORCE, 0x20003000, ___kaneton$pagesz, ®) != STATUS_OK) TEST_ERROR("[region_reserve] error"); /* * second address space */ if (task_reserve(TASK_CLASS_GUEST, TASK_BEHAVIOUR_INTERACTIVE, TASK_PRIORITY_INTERACTIVE, &task2) != STATUS_OK) TEST_ERROR("[task_reserve] error"); if (as_reserve(task2, &as2) != STATUS_OK) TEST_ERROR("[as_reserve] error"); if (segment_reserve(as2, 2 * ___kaneton$pagesz, PERMISSION_READ | PERMISSION_WRITE, SEGMENT_OPTION_NONE, &seg4) != STATUS_OK) TEST_ERROR("[segment_reserve] error"); if (segment_reserve(as2, ___kaneton$pagesz, PERMISSION_READ | PERMISSION_WRITE, SEGMENT_OPTION_NONE, &useless) != STATUS_OK) TEST_ERROR("[segment_reserve] error"); if (segment_reserve(as2, 4 * ___kaneton$pagesz, PERMISSION_READ | PERMISSION_WRITE, SEGMENT_OPTION_NONE, &seg5) != STATUS_OK) TEST_ERROR("[segment_reserve] error"); if (segment_reserve(as2, ___kaneton$pagesz, PERMISSION_READ | PERMISSION_WRITE, SEGMENT_OPTION_NONE, &useless) != STATUS_OK) TEST_ERROR("[segment_reserve] error"); if (segment_reserve(as2, 2 * ___kaneton$pagesz, PERMISSION_READ | PERMISSION_WRITE, SEGMENT_OPTION_NONE, &seg6) != STATUS_OK) TEST_ERROR("[segment_reserve] error"); if (region_reserve(as2, seg4, 0, REGION_OPTION_FORCE, 0x40000000, ___kaneton$pagesz, ®) != STATUS_OK) TEST_ERROR("[region_reserve] error"); if (region_reserve(as2, seg5, 2 * ___kaneton$pagesz, REGION_OPTION_FORCE, 0x40001000, ___kaneton$pagesz, ®) != STATUS_OK) TEST_ERROR("[region_reserve] error"); if (region_reserve(as2, seg6, 0, REGION_OPTION_FORCE, 0x40002000, 2 * ___kaneton$pagesz, ®) != STATUS_OK) TEST_ERROR("[region_reserve] error"); /* * operations */ for (i = 0; i < 4 * ___kaneton$pagesz; i++) buff[i] = (i * 2 + 4) % 256; if (as_write(as1, buff, 4 * ___kaneton$pagesz, 0x20000000) != STATUS_OK) TEST_ERROR("[as_write] error"); for (i = 0; i < 4 * ___kaneton$pagesz; i++) buff[i] = 0; if (as_copy(as1, 0x20000000, as2, 0x40000000, 4 * ___kaneton$pagesz) != STATUS_OK) TEST_ERROR("[as_copy] error"); if (as_read(as2, 0x40000000, 4 * ___kaneton$pagesz, buff) != STATUS_OK) TEST_ERROR("[as_read] error"); for (i = 0; i < 4 * ___kaneton$pagesz; i++) if (buff[i] != (i * 2 + 4) % 256) TEST_ERROR("the data appears invalid once read from the " "address space\n"); TEST_SIGNATURE(rr3fiw3w20aafi9gre9g); TEST_LEAVE(); }
t_status architecture_handler_setup(void) { t_uint16 selector; i_segment segment; i_region region; as_idt idt; o_region* o; t_uint32 i; /* * 1) */ if (segment_reserve(_kernel.as, ___kaneton$pagesz, PERMISSION_READ | PERMISSION_WRITE, SEGMENT_OPTION_SYSTEM, &segment) != STATUS_OK) MACHINE_ESCAPE("unable to reserve a segment"); if (region_reserve(_kernel.as, segment, 0x0, REGION_OPTION_NONE, 0x0, ___kaneton$pagesz, ®ion) != STATUS_OK) MACHINE_ESCAPE("unable to reserve a region for the segment"); if (region_get(_kernel.as, region, &o) != STATUS_OK) MACHINE_ESCAPE("unable to retrieve the region object"); /* * 2) */ if (architecture_idt_build(o->address, ARCHITECTURE_IDT_SIZE, &idt) != STATUS_OK) MACHINE_ESCAPE("unable to build the IDT at the given address"); if (architecture_idt_import(&idt) != STATUS_OK) MACHINE_ESCAPE("unable to import the built IDT"); /* * 3) */ if (architecture_gdt_selector(ARCHITECTURE_GDT_INDEX_KERNEL_CODE, ARCHITECTURE_PRIVILEGE_KERNEL, &selector) != STATUS_OK) MACHINE_ESCAPE("unable to build the kernel code segment selector"); /* * 4) */ for (i = ARCHITECTURE_IDT_EXCEPTION_BASE; i < ARCHITECTURE_IDT_EXCEPTION_BASE + ARCHITECTURE_IDT_EXCEPTION_SIZE; i++) { if (architecture_idt_insert(i, (t_vaddr)_architecture_handler_shells[i], selector, ARCHITECTURE_IDTE_DPL_SET( ARCHITECTURE_PRIVILEGE_RING0) | ARCHITECTURE_IDTE_32BIT | ARCHITECTURE_IDTE_INTERRUPT) != STATUS_OK) MACHINE_ESCAPE("unable to register the exception handler '%u'", i); } /* * 5) */ for (i = ARCHITECTURE_IDT_IRQ_BASE; i < ARCHITECTURE_IDT_IRQ_BASE + ARCHITECTURE_IDT_IRQ_SIZE; i++) { if (architecture_idt_insert(i, (t_vaddr)_architecture_handler_shells[i], selector, ARCHITECTURE_IDTE_DPL_SET( ARCHITECTURE_PRIVILEGE_RING0) | ARCHITECTURE_IDTE_32BIT | ARCHITECTURE_IDTE_INTERRUPT) != STATUS_OK) MACHINE_ESCAPE("unable to register the exception handler '%u'", i); } /* * 6) */ for (i = ARCHITECTURE_IDT_SYSCALL_BASE; i < ARCHITECTURE_IDT_SYSCALL_BASE + ARCHITECTURE_IDT_SYSCALL_SIZE; i++) { if (architecture_idt_insert(i, (t_vaddr)_architecture_handler_shells[i], selector, ARCHITECTURE_IDTE_DPL_SET( ARCHITECTURE_PRIVILEGE_RING3) | ARCHITECTURE_IDTE_32BIT | ARCHITECTURE_IDTE_INTERRUPT) != STATUS_OK) MACHINE_ESCAPE("unable to register the exception handler '%u'", i); } MACHINE_LEAVE(); }