예제 #1
0
파일: dump.c 프로젝트: DavidFeng/ci
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;
}
예제 #2
0
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 */
	}

}
예제 #3
0
//-------- 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;
}
예제 #4
0
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;
}
예제 #5
0
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;
}
예제 #6
0
파일: ogfile.cpp 프로젝트: 112212/7k2
//-------- 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;
}
예제 #7
0
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 */
	}

}