int run_process(int argc, char **argv, int debug) { struct Process * pl = load_process(*argv); if (!pl) return -1; be = pl->be; bd = pl->bd; int r = run_c(argc, argv, debug, pl->main_addr); free_process(pl); return r; }
void kernel_main(uint32_t r0, uint32_t r1, uint32_t *atags, uint32_t memory_kernel) { unsigned int memory_total; int init_process,idle_process; struct atag_info_t atag_info; uint32_t framebuffer_width=800,framebuffer_height=600; (void) r0; /* Ignore boot method */ /* Initialize Software Structures */ processes_init(); /* Detect Hardware */ atags_detect(atags,&atag_info); hardware_type=atag_info.hardware_type; /* Initialize Hardware */ /* Serial console is most important so do that first */ uart_init(); /* Enable Interrupts */ enable_interrupts(); /************************/ /* Boot message! */ /************************/ printk("\r\nBooting VMWos...\r\n"); /**************************/ /* Device Drivers */ /**************************/ /* Set up ACT LED */ led_init(); /* Set up timer */ timer_init(); /* Set up keyboard */ ps2_keyboard_init(); /* Enable the Framebuffer */ if (atag_info.framebuffer_x!=0) { framebuffer_width=atag_info.framebuffer_x; } if (atag_info.framebuffer_y!=0) { framebuffer_height=atag_info.framebuffer_y; } framebuffer_init(framebuffer_width,framebuffer_height,24); framebuffer_console_init(); /* Delay to allow time for serial port to settle */ /* So we can actually see the output on the terminal */ delay(0x3f0000); printk("\r\nWaiting for serial port to be ready (press any key)\r\n"); uart_getc(); uart_enable_interrupts(); /* Clear screen */ printk("\n\r\033[2J\n\r\n\r"); /* Print boot message */ printk("\033[0;41m \033[42m \033[44m \033[42m \033[44m \033[0m VMW OS\r\n"); printk(" \033[0;41m \033[42m \033[44m \033[42m \033[44m \033[0m Version 0.%d\r\n\r\n",VERSION); /* Print hardware version */ printk("Hardware version: %x ",r1); if (r1==0xc42) printk("(Raspberry Pi)"); else printk("(Unknown Hardware)"); printk("\r\n"); printk("Detected Model "); switch(hardware_type) { case RPI_MODEL_A: printk("A"); break; case RPI_MODEL_APLUS: printk("A+"); break; case RPI_MODEL_B: printk("B"); break; case RPI_MODEL_BPLUS: printk("B+"); break; case RPI_MODEL_B2: printk("B2"); break; case RPI_COMPUTE_NODE: printk("Compute Node"); break; default: printk("Unknown %x",hardware_type); break; } printk("\r\n"); /* Print ATAGS */ atags_dump(atags); printk("\r\n"); /* Get amount of RAM from ATAGs */ memory_total=atag_info.ramsize; /* Init memory subsystem */ memory_init(memory_total,memory_kernel); /* Init the MMU */ printk("Initializing MMU and caches\r\n"); //enable_mmu(0, memory_total); //l1_data_cache_clear(); //l1_data_cache_enable(); l1_instruction_cache_enable(); /* Memory Benchmark */ #if 1 { int i; uint32_t before,after; before=ticks_since_boot(); for(i=0;i<16;i++) { memset(benchmark,0,BENCH_SIZE); } after=ticks_since_boot(); printk("MEMSPEED: %d MB took %d ticks %dkB/s\r\n", 16, (after-before), div32(16*1024,(((after-before)*1000)/64))); } #endif /* Load the idle thread */ idle_process=load_process("idle",PROCESS_FROM_RAM, (char *)&idle_task,8,4096); init_process=load_process("shell",PROCESS_FROM_DISK, NULL,0,8192); load_process("printa",PROCESS_FROM_DISK, NULL,0,8192); load_process("printb",PROCESS_FROM_DISK, NULL,0,8192); /* Enter our "init" process*/ printk("\r\nEntering userspace by starting process %d!\r\n", init_process); process[idle_process].ready=1; process[init_process].ready=1; userspace_started=1; /* run init and restore stack as we won't return */ run_process(init_process,0x8000); /* we should never get here */ while(1) { /* Loop Forever */ /* Should probably execute a wfi instruction */ } }
//-------- Begin of function GameFile::load_game --------// // // return : <int> 1 - loaded successfully. // 0 - not loaded. // -1 - error and partially loaded // int GameFile::load_game(const char *base_path, char* fileName) { char full_path[MAX_PATH+1]; File file; int rc=0; const char *errMsg = NULL; power.win_opened=1; // to disable power.mouse_handler() int oldCursor = mouse_cursor.get_icon(); mouse_cursor.set_icon( CURSOR_WAITING ); int powerEnableFlag = power.enable_flag; if( fileName ) strcpy( file_name, fileName ); rc = 1; if (!misc.path_cat(full_path, base_path, file_name, MAX_PATH)) { rc = 0; errMsg = _("Path too long to the saved game"); } if(rc && !file.file_open(full_path, 0, 1)) // 0=tell File don't handle error itself { rc = 0; errMsg = _("Cannot open save game file"); } //-------- read in the GameFile class --------// if( rc ) { char gameFileName[MAX_PATH+1]; strcpy( gameFileName, file_name ); // save the file name actually read, in case that the file names are different MSG(__FILE__":%d: file_read(this, ...);\n", __LINE__); if( !file.file_read(this, sizeof(GameFile)) ) // read the whole object from the saved game file { rc = 0; errMsg = _("Cannot read file header"); } if( rc ) { if( !validate_header() ) { rc = 0; errMsg = _("Save game incompatible"); } else strcpy( file_name, gameFileName ); } } //--------------------------------------------// // 1=allow the writing size and the read size to be different if( rc ) { config.terrain_set = terrain_set; game.deinit(1); // deinit last game first, 1-it is called during loading of a game game.init(1); // init game //-------- read in saved game ----------// // ###### patch begin Gilbert 20/1 #######// //if( !read_file(&file) ) //{ // rc = -1; // errMsg = "Load game error"; //} switch( read_file(&file) ) { case 1: rc = 1; break; case -1: rc = 0; // consider cancel load game errMsg = _("Incompatible save game"); break; case 0: default: rc = -1; errMsg = _("Load game error"); } if( rc > 0 ) { load_process(); // process game data after loading the game //------- create the town network --------// town_network_array.recreate_after_load(); } // ###### patch end Gilbert 20/1 #######// } file.file_close(); power.enable_flag = powerEnableFlag; mouse_cursor.restore_icon( oldCursor ); power.win_opened=0; //---------------------------------------// switch(rc) // don't display msg if loaded successfully (rc==1) { case 0: case -1: box.msg( errMsg ); break; } last_read_success_flag = rc; // for external functions to read. return rc; }
bool setup_config(atrt_config& config, const char* atrt_mysqld) { BaseString tmp(g_clusters); if (atrt_mysqld) { tmp.appfmt(",.atrt"); } Vector<BaseString> clusters; tmp.split(clusters, ","); bool fqpn = clusters.size() > 1 || g_fqpn; size_t j; for (unsigned i = 0; i<clusters.size(); i++) { struct atrt_cluster *cluster = new atrt_cluster; config.m_clusters.push_back(cluster); cluster->m_name = clusters[i]; cluster->m_options.m_features = 0; if (fqpn) { cluster->m_dir.assfmt("cluster%s/", cluster->m_name.c_str()); } else { cluster->m_dir = ""; } cluster->m_next_nodeid= 1; int argc = 1; const char * argv[] = { "atrt", 0, 0 }; BaseString buf; buf.assfmt("--defaults-group-suffix=%s", clusters[i].c_str()); argv[argc++] = buf.c_str(); char ** tmp = (char**)argv; const char *groups[] = { "cluster_config", 0 }; int ret = load_defaults(g_my_cnf, groups, &argc, &tmp); if (ret) { g_logger.error("Unable to load defaults for cluster: %s", clusters[i].c_str()); return false; } struct { atrt_process::Type type; const char * name; const char * value; } proc_args[] = { { atrt_process::AP_NDB_MGMD, "--ndb_mgmd=", 0 }, { atrt_process::AP_NDBD, "--ndbd=", 0 }, { atrt_process::AP_NDB_API, "--ndbapi=", 0 }, { atrt_process::AP_NDB_API, "--api=", 0 }, { atrt_process::AP_MYSQLD, "--mysqld=", 0 }, { atrt_process::AP_ALL, 0, 0} }; /** * Find all processes... */ for (j = 0; j<(size_t)argc; j++) { if (my_getopt_is_args_separator(tmp[j])) /* skip arguments separator */ continue; for (unsigned k = 0; proc_args[k].name; k++) { if (!strncmp(tmp[j], proc_args[k].name, strlen(proc_args[k].name))) { proc_args[k].value = tmp[j] + strlen(proc_args[k].name); break; } } } if (strcmp(clusters[i].c_str(), ".atrt") == 0) { /** * Only use a mysqld... */ proc_args[0].value = 0; proc_args[1].value = 0; proc_args[2].value = 0; proc_args[3].value = 0; proc_args[4].value = atrt_mysqld; } /** * Load each process */ for (j = 0; proc_args[j].name; j++) { if (proc_args[j].value) { BaseString tmp(proc_args[j].value); Vector<BaseString> list; tmp.split(list, ","); for (unsigned k = 0; k<list.size(); k++) if (!load_process(config, *cluster, proc_args[j].type, k + 1, list[k].c_str())) return false; } } { /** * Load cluster options */ int argc = 1; const char * argv[] = { "atrt", 0, 0 }; argv[argc++] = buf.c_str(); const char *groups[] = { "mysql_cluster", 0 }; char ** tmp = (char**)argv; ret = load_defaults(g_my_cnf, groups, &argc, &tmp); if (ret) { g_logger.error("Unable to load defaults for cluster: %s", clusters[i].c_str()); return false; } load_options(argc, tmp, atrt_process::AP_CLUSTER, cluster->m_options); } } return true; }
static bool load_process(atrt_config& config, atrt_cluster& cluster, atrt_process::Type type, unsigned idx, const char * hostname) { atrt_host * host_ptr = find(hostname, config.m_hosts); atrt_process *proc_ptr = new atrt_process; const unsigned proc_no = (unsigned)config.m_processes.size(); config.m_processes.push_back(proc_ptr); host_ptr->m_processes.push_back(proc_ptr); cluster.m_processes.push_back(proc_ptr); atrt_process& proc = *proc_ptr; proc.m_index = idx; proc.m_type = type; proc.m_host = host_ptr; proc.m_save.m_saved = false; proc.m_nodeid= -1; proc.m_cluster = &cluster; proc.m_options.m_features = 0; proc.m_rep_src = 0; proc.m_proc.m_id = -1; proc.m_proc.m_type = "temporary"; proc.m_proc.m_owner = "atrt"; proc.m_proc.m_group = cluster.m_name.c_str(); proc.m_proc.m_stdout = "log.out"; proc.m_proc.m_stderr = "2>&1"; proc.m_proc.m_runas = proc.m_host->m_user; proc.m_proc.m_ulimit = "c:unlimited"; proc.m_proc.m_env.assfmt("MYSQL_BASE_DIR=%s", g_prefix); proc.m_proc.m_env.appfmt(" MYSQL_HOME=%s", g_basedir); proc.m_proc.m_env.appfmt(" ATRT_PID=%u", (unsigned)proc_no); proc.m_proc.m_shutdown_options = ""; { /** * In 5.5...binaries aren't compiled with rpath * So we need an explicit LD_LIBRARY_PATH * * Use path from libmysqlclient.so */ char * dir = dirname(g_libmysqlclient_so_path); #if defined(__MACH__) proc.m_proc.m_env.appfmt(" DYLD_LIBRARY_PATH=%s", dir); #else proc.m_proc.m_env.appfmt(" LD_LIBRARY_PATH=%s", dir); #endif free(dir); } int argc = 1; const char * argv[] = { "atrt", 0, 0 }; BaseString buf[10]; char ** tmp = (char**)argv; const char *groups[] = { 0, 0, 0, 0 }; switch(type){ case atrt_process::AP_NDB_MGMD: proc.m_nodeid= cluster.m_next_nodeid++; // always specify node-id groups[0] = "cluster_config"; buf[1].assfmt("cluster_config.ndb_mgmd.%u", idx); groups[1] = buf[1].c_str(); buf[0].assfmt("--defaults-group-suffix=%s", cluster.m_name.c_str()); argv[argc++] = buf[0].c_str(); break; case atrt_process::AP_NDBD: if (g_fix_nodeid) proc.m_nodeid= cluster.m_next_nodeid++; groups[0] = "cluster_config"; buf[1].assfmt("cluster_config.ndbd.%u", idx); groups[1] = buf[1].c_str(); buf[0].assfmt("--defaults-group-suffix=%s", cluster.m_name.c_str()); argv[argc++] = buf[0].c_str(); break; case atrt_process::AP_MYSQLD: if (g_fix_nodeid) proc.m_nodeid= cluster.m_next_nodeid++; groups[0] = "mysqld"; groups[1] = "mysql_cluster"; buf[0].assfmt("--defaults-group-suffix=.%u%s",idx,cluster.m_name.c_str()); argv[argc++] = buf[0].c_str(); break; case atrt_process::AP_CLIENT: buf[0].assfmt("client.%u%s", idx, cluster.m_name.c_str()); groups[0] = buf[0].c_str(); break; case atrt_process::AP_NDB_API: if (g_fix_nodeid) proc.m_nodeid= cluster.m_next_nodeid++; break; default: g_logger.critical("Unhandled process type: %d", type); return false; } int ret = load_defaults(g_my_cnf, groups, &argc, &tmp); if (ret) { g_logger.error("Unable to load defaults for cluster: %s", cluster.m_name.c_str()); return false; } load_options(argc, tmp, type, proc.m_options); BaseString dir; dir.assfmt("%s/%s", proc.m_host->m_basedir.c_str(), cluster.m_dir.c_str()); switch(type){ case atrt_process::AP_NDB_MGMD: { proc.m_proc.m_name.assfmt("%u-%s", proc_no, "ndb_mgmd"); proc.m_proc.m_path.assign(g_ndb_mgmd_bin_path); proc.m_proc.m_args.assfmt("--defaults-file=%s/my.cnf", proc.m_host->m_basedir.c_str()); proc.m_proc.m_args.appfmt(" --defaults-group-suffix=%s", cluster.m_name.c_str()); proc.m_proc.m_args.append(" --nodaemon --mycnf"); proc.m_proc.m_args.appfmt(" --ndb-nodeid=%u", proc.m_nodeid); proc.m_proc.m_cwd.assfmt("%sndb_mgmd.%u", dir.c_str(), proc.m_index); proc.m_proc.m_args.appfmt(" --configdir=%s", proc.m_proc.m_cwd.c_str()); proc.m_proc.m_env.appfmt(" MYSQL_GROUP_SUFFIX=%s", cluster.m_name.c_str()); break; } case atrt_process::AP_NDBD: { if (g_mt == 0 || (g_mt == 1 && ((g_mt_rr++) & 1) == 0) || g_ndbmtd_bin_path == 0) { proc.m_proc.m_path.assign(g_ndbd_bin_path); } else { proc.m_proc.m_path.assign(g_ndbmtd_bin_path); } proc.m_proc.m_name.assfmt("%u-%s", proc_no, "ndbd"); proc.m_proc.m_args.assfmt("--defaults-file=%s/my.cnf", proc.m_host->m_basedir.c_str()); proc.m_proc.m_args.appfmt(" --defaults-group-suffix=%s", cluster.m_name.c_str()); proc.m_proc.m_args.append(" --nodaemon -n"); if (!g_restart) proc.m_proc.m_args.append(" --initial"); if (g_fix_nodeid) proc.m_proc.m_args.appfmt(" --ndb-nodeid=%u", proc.m_nodeid); proc.m_proc.m_cwd.assfmt("%sndbd.%u", dir.c_str(), proc.m_index); proc.m_proc.m_env.appfmt(" MYSQL_GROUP_SUFFIX=%s", cluster.m_name.c_str()); break; } case atrt_process::AP_MYSQLD: { proc.m_proc.m_name.assfmt("%u-%s", proc_no, "mysqld"); proc.m_proc.m_path.assign(g_mysqld_bin_path); proc.m_proc.m_args.assfmt("--defaults-file=%s/my.cnf", proc.m_host->m_basedir.c_str()); proc.m_proc.m_args.appfmt(" --defaults-group-suffix=.%d%s", proc.m_index, cluster.m_name.c_str()); proc.m_proc.m_args.append(" --core-file"); if (g_fix_nodeid) proc.m_proc.m_args.appfmt(" --ndb-nodeid=%d", proc.m_nodeid); // Add ndb connect string const char * val; if (cluster.m_options.m_loaded.get(ndbcs, &val)) { proc.m_proc.m_args.appfmt(" %s=%s", ndbcs, val); } proc.m_proc.m_cwd.appfmt("%smysqld.%u", dir.c_str(), proc.m_index); proc.m_proc.m_shutdown_options = "SIGKILL"; // not nice proc.m_proc.m_env.appfmt(" MYSQL_GROUP_SUFFIX=.%u%s", proc.m_index, cluster.m_name.c_str()); break; } case atrt_process::AP_NDB_API: { proc.m_proc.m_name.assfmt("%u-%s", proc_no, "ndb_api"); proc.m_proc.m_path = ""; proc.m_proc.m_args = ""; proc.m_proc.m_cwd.appfmt("%sndb_api.%u", dir.c_str(), proc.m_index); proc.m_proc.m_env.appfmt(" MYSQL_GROUP_SUFFIX=%s", cluster.m_name.c_str()); break; } case atrt_process::AP_CLIENT: { proc.m_proc.m_name.assfmt("%u-%s", proc_no, "mysql"); proc.m_proc.m_path = ""; proc.m_proc.m_args = ""; proc.m_proc.m_cwd.appfmt("%s/client.%u", dir.c_str(), proc.m_index); proc.m_proc.m_env.appfmt(" MYSQL_GROUP_SUFFIX=.%d%s", proc.m_index, cluster.m_name.c_str()); break; } case atrt_process::AP_ALL: case atrt_process::AP_CLUSTER: g_logger.critical("Unhandled process type: %d", proc.m_type); return false; } if (type == atrt_process::AP_MYSQLD) { /** * Add a client for each mysqld */ if (!load_process(config, cluster, atrt_process::AP_CLIENT, idx, hostname)) { return false; } } if (type == atrt_process::AP_CLIENT) { proc.m_mysqld = cluster.m_processes[cluster.m_processes.size()-2]; } return true; }
//-------- Begin of function GameFile::load_game --------// // // <char *> pathName save game path, without '\' at the end // <char *> fileName save game filename, null for unchange, use file_name // // return : <int> 1 - loaded successfully. // 0 - not loaded. // -1 - error and partially loaded // int GameFile::load_game(const char *path, const char* fileName) { File file; int rc=0; char *errMsg = NULL; power.win_opened=1; // to disable power.mouse_handler() int oldCursor = mouse_cursor.get_icon(); mouse_cursor.set_icon( CURSOR_WAITING ); int powerEnableFlag = power.enable_flag; if( fileName ) { if( path && path[0] != '\0' ) // non empty string { strcpy(file_name, path); strcat(file_name, PATH_DELIM); strcat(file_name, fileName); } else { strcpy(file_name, fileName); } } rc = 1; if( !file.file_open( file_name, 0, 1 ) ) // 0=tell File don't handle error itself { rc = 0; errMsg = text_game_menu.str_load_error_open(); // "Cannot open save game file"; } //-------- read in the GameFile class --------// if( rc ) { if( !file.file_read(this, sizeof(GameFile)) ) // read the whole object from the saved game file { rc = 0; errMsg = text_game_menu.str_load_error_header(); // "Cannot read file header"; } if( rc ) { if( !validate_header() ) { rc = 0; errMsg = text_game_menu.str_load_error_old(); // "Save game incompatible"; } else strcpy( file_name, file.file_name ); // set the file_name to the actual file } } //--------------------------------------------// // 1=allow the writing size and the read size to be different if( rc ) { config.terrain_set = terrain_set; config.building_size = building_size; // config.display_mode_id = display_mode_id; game.deinit_all(); // deinit last game first, 1-it is called during loading of a game game.init(1); // init game //-------- read in saved game ----------// switch( read_file(&file) ) { case 1: rc = 1; break; case -1: rc = 0; // consider cancel load game // errMsg = "Incompatible save game"; errMsg = text_game_menu.str_load_error_old(); // "Save game incompatible"; break; case 0: default: rc = -1; errMsg = text_game_menu.str_load_error_general(); // "Load game error"; } if( rc > 0 ) load_process(); // process game data after loading the game } file.file_close(); power.enable_flag = powerEnableFlag; mouse_cursor.restore_icon( oldCursor ); power.win_opened=0; //---------------------------------------// switch(rc) // don't display msg if loaded successfully (rc==1) { case 0: case -1: box.msg( errMsg ); break; } last_read_success_flag = rc; // for external functions to read. sys.signal_exit_flag = 4; // 4-means loading the game successfully. set it to exit the parent loop return rc; }
void kernel_main(uint32_t r0, uint32_t r1, uint32_t *atags, uint32_t memory_kernel) { unsigned int memory_total; int init_process,idle_process; struct atag_info_t atag_info; uint32_t framebuffer_width=800,framebuffer_height=600; uint32_t temperature; (void) r0; /* Ignore boot method */ /* Initialize Software Structures */ processes_init(); /* Detect Hardware */ atags_detect(atags,&atag_info); hardware_type=atag_info.hardware_type; /* Initialize Hardware */ /* Serial console is most important so do that first */ uart_init(); /* Enable HW random number generator */ bcm2835_rng_init(); /* Enable Interrupts */ enable_interrupts(); /************************/ /* Boot message! */ /************************/ printk("\nBooting VMWos...\n"); /**************************/ /* Device Drivers */ /**************************/ /* Set up ACT LED */ led_init(); /* Set up timer */ timer_init(); /* Set up keyboard */ ps2_keyboard_init(); /* Enable the Framebuffer */ if (atag_info.framebuffer_x!=0) { framebuffer_width=atag_info.framebuffer_x; } if (atag_info.framebuffer_y!=0) { framebuffer_height=atag_info.framebuffer_y; } framebuffer_init(framebuffer_width,framebuffer_height,24); framebuffer_console_init(); /* Delay to allow time for serial port to settle */ /* So we can actually see the output on the terminal */ delay(0x3f0000); printk("\nWaiting for serial port to be ready (press any key)\n"); uart_getc(); uart_enable_interrupts(); /* Clear screen */ printk("\n\033[2J\n\n"); /* Print boot message */ printk("\033[0;41m \033[42m \033[44m \033[42m \033[44m \033[0m VMW OS\n"); printk(" \033[0;41m \033[42m \033[44m \033[42m \033[44m \033[0m Version 0.%d\n\n",VERSION); /* Print hardware version */ printk("Hardware version: %x ",r1); if (r1==0xc42) printk("(Raspberry Pi)"); else printk("(Unknown Hardware)"); printk("\n"); printk("Detected Model "); switch(hardware_type) { case RPI_MODEL_A: printk("A"); break; case RPI_MODEL_APLUS: printk("A+"); break; case RPI_MODEL_B: printk("B"); break; case RPI_MODEL_BPLUS: printk("B+"); break; case RPI_MODEL_B2: printk("B2"); break; case RPI_COMPUTE_NODE: printk("Compute Node"); break; default: printk("Unknown %x",hardware_type); break; } printk("\n"); /* Check temperature */ temperature=thermal_read(); printk("CPU Temperature: %dC, %dF\n", temperature/1000, ((temperature*9)/5000)+32); /* Print ATAGS */ atags_dump(atags); printk("\n"); /* Get amount of RAM from ATAGs */ memory_total=atag_info.ramsize; /* Init memory subsystem */ memory_init(memory_total,memory_kernel); /* Start HW Perf Counters */ arm1176_init_pmu(); #if 0 asm("nop"); asm("nop"); asm("nop"); asm("nop"); asm("nop"); asm("nop"); asm("nop"); asm("nop"); asm("nop"); asm("nop"); asm("nop"); asm("nop"); asm("nop"); // printk("Heisenbug!\n"); #endif /* Setup Memory Hierarchy */ #if 1 memset_benchmark(memory_total); #else /* Enable L1 i-cache */ printk("Enabling L1 icache\n"); enable_l1_dcache(); /* Enable branch predictor */ printk("Enabling branch predictor\n"); /* Enable L1 d-cache */ printk("Enabling MMU with 1:1 Virt/Phys page mapping\n"); enable_mmu(0,memory_total); printk("Enabling L1 dcache\n"); enable_l1_dcache(); #endif /* Init the file descriptor table */ fd_table_init(); /* Initialize the ramdisk */ ramdisk_init(initrd_image,sizeof(initrd_image)); /* Mount the ramdisk */ mount("/dev/ramdisk","/","romfs",0,NULL); /* Load the idle thread */ idle_process=load_process("idle",PROCESS_FROM_RAM, (char *)&idle_task,8,4096); init_process=load_process("shell",PROCESS_FROM_DISK, NULL,0,8192); load_process("printa",PROCESS_FROM_DISK, NULL,0,8192); load_process("printb",PROCESS_FROM_DISK, NULL,0,8192); /* Enter our "init" process*/ printk("\nEntering userspace by starting process %d!\n", init_process); process[idle_process].ready=1; process[init_process].ready=1; userspace_started=1; /* run init and restore stack as we won't return */ run_process(init_process,0x8000); /* we should never get here */ while(1) { /* Loop Forever */ /* Should probably execute a wfi instruction */ } }