bool game_initialise (void) { char buffer[FILENAME_MAX]; if (SDL_Init (SDL_INIT_JOYSTICK | SDL_INIT_VIDEO | SDL_INIT_NOPARACHUTE) != 0) { fprintf (stderr, "SDL_Init(): %s\n", SDL_GetError ()); return false; } #ifdef __unix__ /* clean up after SDL messing around where it shouldn't */ unix_restore_signal_handlers (); #endif keyboard_initialise (); mouse_initialise (); display_initialise (); sound_initialise (); if (sys_get_data_path (buffer, sizeof (buffer))) game_data_path = xstrdup (buffer); else game_data_path = xstrdup ("."); create_user_directory (); return true; }
// Allocates a new env and loads the named user program into it. struct Env* env_create(char* user_program_name, unsigned int page_WS_size) { //[1] get pointer to the start of the "user_program_name" program in memory // Hint: use "get_user_program_info" function, // you should set the following "ptr_program_start" by the start address of the user program uint8* ptr_program_start = 0; struct UserProgramInfo* ptr_user_program_info = get_user_program_info(user_program_name); if(ptr_user_program_info == 0) return NULL; ptr_program_start = ptr_user_program_info->ptr_start ; // if(ptr_user_program_info->environment != NULL) // { // cprintf("env_create: an old environment already exist for [%s]!! \nfreeing the old one by calling start_env_free....\n", ptr_user_program_info->environment->prog_name); // start_env_free(ptr_user_program_info->environment); // // //return ptr_user_program_info; // } //[2] allocate new environment, (from the free environment list) //if there's no one, return NULL // Hint: use "allocate_environment" function struct Env* e = NULL; if(allocate_environment(&e) < 0) { return 0; } //[2.5 - 2012] Set program name inside the environment e->prog_name = ptr_user_program_info->name ; //[3] allocate a frame for the page directory, Don't forget to set the references of the allocated frame. //REMEMBER: "allocate_frame" should always return a free frame uint32* ptr_user_page_directory; unsigned int phys_user_page_directory; if(USE_KHEAP) { ptr_user_page_directory = create_user_directory(); phys_user_page_directory = kheap_physical_address((uint32)ptr_user_page_directory); } else { int r; struct Frame_Info *p = NULL; allocate_frame(&p) ; p->references = 1; ptr_user_page_directory = STATIC_KERNEL_VIRTUAL_ADDRESS(to_physical_address(p)); phys_user_page_directory = to_physical_address(p); } //[4] initialize the new environment by the virtual address of the page directory // Hint: use "initialize_environment" function //2016 e->page_WS_max_size = page_WS_size; initialize_environment(e, ptr_user_page_directory, phys_user_page_directory); // We want to load the program into the user virtual space // each program is constructed from one or more segments, // each segment has the following information grouped in "struct ProgramSegment" // 1- uint8 *ptr_start: start address of this segment in memory // 2- uint32 size_in_file: size occupied by this segment inside the program file, // 3- uint32 size_in_memory: actual size required by this segment in memory // usually size_in_file < or = size_in_memory // 4- uint8 *virtual_address: start virtual address that this segment should be copied to it //[6] switch to user page directory // Hint: use rcr3() and lcr3() uint32 kern_phys_pgdir = rcr3() ; lcr3(e->env_cr3) ; //[7] load each program segment into user virtual space struct ProgramSegment* seg = NULL; //use inside PROGRAM_SEGMENT_FOREACH as current segment information int segment_counter=0; uint32 remaining_ws_pages = (e->page_WS_max_size)-1; // we are reserving 1 page of WS for the stack that will be allocated just before the end of this function uint32 lastTableNumber=0xffffffff; PROGRAM_SEGMENT_FOREACH(seg, ptr_program_start) { segment_counter++; //allocate space for current program segment and map it at seg->virtual_address then copy its content // from seg->ptr_start to seg->virtual_address //Hint: use program_segment_alloc_map_copy_workingset() //cprintf("SEGMENT #%d, dest start va = %x, dest end va = %x\n",segment_counter, seg->virtual_address, (seg->virtual_address + seg->size_in_memory)); LOG_STRING("==============================================================================="); LOG_STATMENT(cprintf("SEGMENT #%d, size_in_file = %d, size_in_memory= %d, dest va = %x",segment_counter,seg->size_in_file, seg->size_in_memory, seg->virtual_address)); LOG_STRING("==============================================================================="); uint32 allocated_pages=0; program_segment_alloc_map_copy_workingset(e, seg, &allocated_pages, remaining_ws_pages, &lastTableNumber); remaining_ws_pages -= allocated_pages; LOG_STATMENT(cprintf("SEGMENT: allocated pages in WS = %d",allocated_pages)); LOG_STATMENT(cprintf("SEGMENT: remaining WS pages after allocation = %d",remaining_ws_pages)); ///[1] temporary initialize 1st page in memory then writing it on page file uint32 dataSrc_va = (uint32) seg->ptr_start; uint32 seg_va = (uint32) seg->virtual_address ; uint32 start_first_page = ROUNDDOWN(seg_va , PAGE_SIZE); uint32 end_first_page = ROUNDUP(seg_va , PAGE_SIZE); uint32 offset_first_page = seg_va - start_first_page ; memset(ptr_temp_page , 0, PAGE_SIZE); uint8 *src_ptr = (uint8*) dataSrc_va; uint8 *dst_ptr = (uint8*) (ptr_temp_page + offset_first_page); int i; for (i = seg_va ; i < end_first_page ; i++, src_ptr++,dst_ptr++ ) { *dst_ptr = *src_ptr ; } if (pf_add_env_page(e, start_first_page, ptr_temp_page) == E_NO_PAGE_FILE_SPACE) panic("ERROR: Page File OUT OF SPACE. can't load the program in Page file!!"); //LOG_STRING(" -------------------- PAGE FILE: 1st page is written"); ///[2] Start writing the segment ,from 2nd page until before last page, to page file ... uint32 start_last_page = ROUNDDOWN(seg_va + seg->size_in_file, PAGE_SIZE) ; uint32 end_last_page = seg_va + seg->size_in_file; for (i = end_first_page ; i < start_last_page ; i+= PAGE_SIZE, src_ptr+= PAGE_SIZE) { if (pf_add_env_page(e, i, src_ptr) == E_NO_PAGE_FILE_SPACE) panic("ERROR: Page File OUT OF SPACE. can't load the program in Page file!!"); } //LOG_STRING(" -------------------- PAGE FILE: 2nd page --> before last page are written"); ///[3] temporary initialize last page in memory then writing it on page file dst_ptr = (uint8*) ptr_temp_page; memset(dst_ptr, 0, PAGE_SIZE); for (i = start_last_page ; i < end_last_page ; i++, src_ptr++,dst_ptr++ ) { *dst_ptr = *src_ptr; } if (pf_add_env_page(e, start_last_page, ptr_temp_page) == E_NO_PAGE_FILE_SPACE) panic("ERROR: Page File OUT OF SPACE. can't load the program in Page file!!"); //LOG_STRING(" -------------------- PAGE FILE: last page is written"); ///[4] writing the remaining seg->size_in_memory pages to disk uint32 start_remaining_area = ROUNDUP(seg_va + seg->size_in_file,PAGE_SIZE) ; uint32 remainingLength = (seg_va + seg->size_in_memory) - start_remaining_area ; for (i=0 ; i < ROUNDUP(remainingLength,PAGE_SIZE) ;i+= PAGE_SIZE, start_remaining_area += PAGE_SIZE) { if (pf_add_empty_env_page(e, start_remaining_area, 1) == E_NO_PAGE_FILE_SPACE) panic("ERROR: Page File OUT OF SPACE. can't load the program in Page file!!"); } //LOG_STRING(" -------------------- PAGE FILE: segment remaining area is written (the zeros) "); }