extern "C" int syscall_main(int command, int arg1, int arg2, int arg3, IRETState iret) { (void)arg3; switch(command) { case SYSCALL_COMMAND_FORK: { auto task = Task::Create("one.elf"); task->next = _kernel_state.task->next; _kernel_state.task->next = task; return 0; return -1; break; } case SYSCALL_COMMAND_OPEN: return 5; break; case SYSCALL_COMMAND_GET: if(arg1 == STDIN_FILENO) { __asm__ ("sti"); while(!stdin_available) { __asm__ ("hlt"); } __asm__ ("cli"); stdin_available = false; // POSIX -> 11. General Terminal Interface -> Canonical Mode Input Processing screen_put(stdin_char, SCREEN_COLOR_USER); return stdin_char; } else { if(pos > sizeof(buffer)) { return EOF; } return buffer[pos++]; } case SYSCALL_COMMAND_PUT: switch(arg2) { case STDOUT_FILENO: screen_put(arg1, SCREEN_COLOR_USER); break; case STDERR_FILENO: //screen_put(arg1, SCREEN_COLOR_ERROR); // XXX: too messy for now screen_put(arg1, SCREEN_COLOR_USER); break; default: screen_print("SYSCALL_COMMAND_PUT: unsupported fileno\n"); break; } break; default: screen_print("unrecognized syscall command\n"); break; } return 0; }
// This gets called from interrupt.s void isr_handler(registers_t regs) { // This line is important. When the processor extends the 8-bit interrupt number // to a 32bit value, it sign-extends, not zero extends. So if the most significant // bit (0x80) is set, regs.int_no will be very large (about 0xffffff80). u8 int_no = regs.int_no & 0xFF; if (interrupt_handlers[int_no] != 0) { isr_t handler = interrupt_handlers[int_no]; handler(®s); } else { screen_write("unhandled interrupt: "); screen_write_dec(int_no); screen_put('\n'); for(;;); } }
void task_entry(const char *exe_name) { __asm__ ("sti"); screen_print("spawned new task\n"); screen_print("loading "); screen_print(exe_name); screen_put('\n'); const char *paths[] = {"bin", exe_name}; auto mData = _kernel_state.fs.GetInode(2, paths); if(mData.IsNothing()) { kernel_panic("failed to get inode"); } auto data = mData.FromJust(); _kernel_state.pager->Enable(_kernel_state.task->context); ELF elf(data); user_enter(elf.entry(), &_kernel_state.task->stack[PAGE_ALLOCATOR_PAGE_SIZE * Task::STACK_PAGES]); for(;;) { __asm__ ("hlt"); } // unreachable }