void init() { /* Call sys_setup. This sets up the root nodes, and filedesc's 0, 1 and 2. */ sys_setup(); kprintf("Something stirs and something tries, and starts to climb towards the light.\n"); /* Set some basic environment variables. These allow simple root execution, * basic terminal access, and a shell to run from */ add_init_env("PATH=/bin/:/usr/bin/:/usr/sbin:"); add_init_env("TERM=seaos"); add_init_env("HOME=/"); add_init_env("SHELL=/bin/sh"); int ret=0; int pid; init_pid = current_task->pid+1; set_cpu_interrupt_flag(1); switch_to_user_mode(); /* We have to be careful now. If we try to call any kernel functions * without doing a system call, the processor will generate a GPF (or * a page fault) because you can't execute kernel code in ring 3! * So we write simple wrapper functions for common functions that * we will need */ ret = u_execve("/sh", (char **)stuff_to_pass, (char **)init_env); unset_ksf(KSF_HAVEEXECED); ret = u_execve("/bin/sh", (char **)stuff_to_pass, (char **)init_env); unset_ksf(KSF_HAVEEXECED); ret = u_execve("/usr/bin/sh", (char **)stuff_to_pass, (char **)init_env); unset_ksf(KSF_HAVEEXECED); printf("Failed to start the init process. Halting.\n"); u_exit(0); }
int main(int argc, const char *argv[]) { __builtin_nyuzi_write_control_reg(1, fault_handler); switch_to_user_mode(); // This will fault asm("eret"); // CHECK: FAULT 10 current flags 04 prev flags 00 }
uint64_t exec(char* filename) { // find file dir_entry* file = find_file(filename); // not found? exit if (!file) return 0; clean_user_space(); // let's load it! void* entry = load_executable(file->filename); // can't load but already cleaned everything :( //if (!entry) exit(); // jump switch_to_user_mode(entry); }
// Tests a usermode iteration. void umode_disp(fs_node_t *fs_root) { // Initialize the system calls initialise_syscalls(); // user mode switch_to_user_mode(); // begin cli ucl_interface(fs_root); // begin user cli /*while (true) { char buffer[256]; syscall_monitor_write("$ "); scanf(buffer); cl_handler(buffer, fs_root); }*/ }
int main(void) { unsigned int va; int asid; unsigned int stack_addr = (unsigned int) &va & ~(PAGE_SIZE - 1); // Map code & data for (va = 0; va < 0x10000; va += PAGE_SIZE) { add_itlb_mapping(va, va); add_dtlb_mapping(va, va | TLB_WRITABLE | TLB_GLOBAL); } add_dtlb_mapping(stack_addr, stack_addr | TLB_WRITABLE); add_dtlb_mapping(IO_REGION_BASE, IO_REGION_BASE | TLB_SUPERVISOR | TLB_WRITABLE); // Alias mapping that we will use for test (the normal mapped region is used // to halt the test). add_dtlb_mapping(0x100000, IO_REGION_BASE | TLB_SUPERVISOR | TLB_WRITABLE); __builtin_nyuzi_write_control_reg(CR_FAULT_HANDLER, fault_handler); __builtin_nyuzi_write_control_reg(CR_FLAGS, FLAG_MMU_EN | FLAG_SUPERVISOR_EN); // Can write to page in supervisor mode globaltmp = *((volatile unsigned int*) 0x100000); printf("check1\n"); // CHECK: check1 // Switch to user mode, but leave MMU active switch_to_user_mode(); *((volatile unsigned int*) 0x100000) = 0x12; // CHECK: FAULT 8 00100000 current flags 06 prev flags 02 // XXX no way to verify that the write wasn't sent to external bus }