Example #1
0
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;
}
Example #2
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(&regs);
  } else {
    screen_write("unhandled interrupt: ");
    screen_write_dec(int_no);
    screen_put('\n');
    for(;;);
  }
}
Example #3
0
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
}