⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 bin.cpp

📁 WinCE5.0部分核心源码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
    xip_mem->dll_data_split = xip_mem->dll_data_start;

  Module::s_romhdr.usMiscFlags = 0;
  
  if(kernel->is_kernel_debugger_enabled())
    Module::s_romhdr.usMiscFlags |= ROM_KERNEL_DEBUGGER_ENABLED;

  if(xip_mem->is_kernel()){
    Module::s_romhdr.pExtensions = (void *)kernel->rom_extensions();
    Module::s_romhdr.usMiscFlags |= ROM_CONTAINS_KERNEL;
  }
  
  Memory::write_extensions(image_file, memory_list, reserve_list, config.xipchain, *xip_mem);
 
  Module::s_romhdr.dllfirst  = (HIWORD(xip_mem->dll_data_start) << 16) | HIWORD(xip_mem->dll_data_split);
  Module::s_romhdr.dlllast   = xip_mem->dll_data_orig;

  if(HIWORD(Module::s_romhdr.dllfirst) == LOWORD(Module::s_romhdr.dllfirst) && 
     HIWORD(Module::s_romhdr.dllfirst) == HIWORD(Module::s_romhdr.dlllast))
    Module::s_romhdr.dllfirst  &= 0xffff0000;

  Module::s_romhdr.physfirst = xip_mem->address();
  Module::s_romhdr.physlast  = max(Module::physlast(), romhdr_offset + sizeof(ROMHDR));

  /***** only the ROMHDR record can be written after here *****/
  /*****                   NO OTHER RECORDS               *****/

  Module::s_romhdr.ulKernelFlags  = config.rom_info.flags;
  Module::s_romhdr.ulFSRamPercent = config.fsram_percent;
  Module::s_romhdr.usCPUType      = (USHORT)kernel->cpu_id();

  Module::s_romhdr.ulRAMFree = kernel->align_page(Module::s_romhdr.ulRAMFree);

  LAST_PASS_PRINT printf("ROM Header                %08x  %08x  (%10u)\n", romhdr_offset, sizeof(Module::s_romhdr), sizeof(Module::s_romhdr));
  Module::dump_toc(xip_mem);
  memcpy(&xip_mem->m_romhdr, &Module::s_romhdr, sizeof(Module::s_romhdr));

  // check for overlapped image/ram condition
  if(!config.autosize && xip_mem->type() != NANDIMAGE_TYPE){
    Address temp(Module::s_romhdr.ulRAMFree, Module::s_romhdr.ulRAMEnd - Module::s_romhdr.ulRAMFree);

    if(temp.intersects(Module::s_romhdr.physfirst, Module::s_romhdr.physlast - Module::s_romhdr.physfirst)){
      fprintf(stderr, "Error: Ram start overlaps rom binary\n");
      fprintf(stderr, "Rom end  : 0x%08x\n", Module::s_romhdr.physlast);
      fprintf(stderr, "Ram start: 0x%08x\n", Module::s_romhdr.ulRAMFree);

      for(MemoryList::iterator mem_itr = memory_list.begin(); mem_itr != memory_list.end(); mem_itr++){
        if(mem_itr->m_romhdr.physfirst && mem_itr->m_romhdr.physlast && mem_itr->m_romhdr.ulRAMFree){
          fprintf(stderr, "%s\n", mem_itr->name().c_str());
          fprintf(stderr, "physfirst %08x\n", mem_itr->m_romhdr.physfirst);
          fprintf(stderr, "physlast  %08x\n", mem_itr->m_romhdr.physlast);
          fprintf(stderr, "ulRAMFree %08x\n", mem_itr->m_romhdr.ulRAMFree);
        }
      }

      return false;      
    }
  }

  // write romhdr
  Module::write_bin(image_file, romhdr_offset, &Module::s_romhdr, sizeof(Module::s_romhdr));

  // write config.lst autosize helper file
  if(!config.autosize && config.xipchain){
    static bool first = true;
    string config_list = config.output_file;
    
    if(config_list.rfind("\\") != string::npos)
      config_list = config_list.substr(0, config_list.rfind("\\"));
  
    config_list += "\\config.lst";

    ofstream list_file(config_list.c_str(), first ? ios::trunc : ios::app);
      
    if(list_file.bad()){
      cerr << "Error: Could not open '" << config_list << "' for writing\n";
      return false;
    }

    list_file << "\nMEMORY\n";

    if(first) 
      list_file << "RAM" << "\t"
                << hex << Module::s_romhdr.ulRAMStart << "\t"
                << hex << Module::s_romhdr.ulRAMEnd - Module::s_romhdr.ulRAMStart << "\t"
                << "RAM" 
                << endl;

    list_file << xip_mem->name() << "\t" 
              << hex << Module::s_romhdr.physfirst << "\t" 
              << hex << Module::s_romhdr.physlast - Module::s_romhdr.physfirst << "\t" 
              << xip_mem->type() 
              << endl;
    
    list_file << "\nCONFIG\n";
    list_file << "DLLHIGHCODEADDR " << xip_mem->name() << "\t " << hex << (xip_mem->dll_code_orig  & 0xffff0000) << endl;
    list_file << "DLLLOWCODEADDR  " << xip_mem->name() << "\t " << hex << (xip_mem->dll_code_start & 0xffff0000) << endl;
    list_file << "DLLHIGHADDR     " << xip_mem->name() << "\t " << hex << (xip_mem->dll_data_orig  & 0xffff0000) << endl;
    list_file << "DLLLOWADDR      " << xip_mem->name() << "\t " << hex << (xip_mem->dll_data_start & 0xffff0000) << endl;
    
    first = false;
  }

  // write some other misc stuff
  DWORD start_ip = xip_mem->address() + kernel->entry_rva();
    
  if(xip_mem->is_kernel() && kernel->is_kernel()){
    if(config.bootjump)
      kernel->write_prolog(image_file, start_ip, config.bootjump_addr, config.user_reset_vector);

    if(config.x86boot && start_ip){
      unsigned short jump_offset;
  
      if(config.x86boot_addr)
        jump_offset = LOWORD(config.x86boot_addr) - LOWORD(0xfff3);
      else{
        jump_offset = LOWORD(start_ip) - LOWORD(0xfff3);
    
        if(HIWORD(start_ip) != 0xffff)
          cerr << "Error: Address of startup not in last 64k of x86 image." << endl;
      }
      
      unsigned char x86_boot_record[] = { 0xe9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
                                          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0xaa };

      memcpy(x86_boot_record + 1, &jump_offset, sizeof(jump_offset));

#if 0
      if(kernel->memory_iterator()->address() + kernel->memory_iterator()->length() > Module::s_romhdr.physlast){        
        fprintf(stderr, 
                "Error: bootjump (%08x) record was outside of rom region (%08x-%08x)",
                kernel->memory_iterator()->address() + kernel->memory_iterator()->length() - 16,
                Module::s_romhdr.physfirst,
                Module::s_romhdr.physlast);
        return false;
      }
#endif

      Module::write_bin(image_file, 
                        kernel->memory_iterator()->address() + kernel->memory_iterator()->length() - 16,
                        x86_boot_record, 
                        sizeof(x86_boot_record), false);
    }
  }
  
  // write out image start info
  DWORD zero = 0;

  LAST_PASS_PRINT printf("Starting ip:             %08x\n", start_ip);

  start_ip += config.rom_info.offset;

  DWORD size = 0;
  for(FileList::iterator fitr = file_list.begin(); fitr != file_list.end(); fitr++) size += fitr->size();
  LAST_PASS_PRINT printf("Raw files size:          %08x\n", size);

  size = 0;
  for(fitr = file_list.begin(); fitr != file_list.end(); fitr++) size += fitr->compressed_size();
  LAST_PASS_PRINT printf("Compressed files size:   %08x\n", size);

  if(!config.autosize){
    if(0 && config.rom_autosize && config.rom_info.size){
      if(Module::s_romhdr.physlast > config.rom_info.offset + config.rom_info.size + config.rom_info.start){
        fprintf(stderr, "Error: Image exceeds specified memory size by %u bytes and may not run.\n",
                Module::s_romhdr.physlast - (config.rom_info.offset + config.rom_info.size));
        return false;
      }  
    }
    else{
      for(MemoryList::iterator mem_itr = memory_list.begin(); mem_itr != memory_list.end(); mem_itr++){
        if(Module::s_romhdr.physfirst < mem_itr->address() && mem_itr->address() < Module::s_romhdr.physlast ||
           Module::s_romhdr.physfirst < mem_itr->address_end() && mem_itr->address_end() < Module::s_romhdr.physlast){
          if(mem_itr->type() == RAM_TYPE && config.error_too_big){
            fprintf(stderr, "Error: Image exceeds specified memory size by %u bytes and may not run.\n",
                    Module::s_romhdr.physlast - mem_itr->address_end());
            return false;
          }
          else if(mem_itr->type() == RAMIMAGE_TYPE){
            fprintf(stderr, "Warning: Image exceeds specified memory size by %u bytes and may not run.\n",
                    Module::s_romhdr.physlast - mem_itr->address_end());
          }
        }
      }
    }
  }

  if(!config.autosize){
    if(xip_mem->is_kernel()){
      image_file.write((char *)&zero, sizeof(DWORD));
      image_file.write((char *)&start_ip, sizeof(DWORD));
      image_file.write((char *)&zero, sizeof(DWORD));
    }
    else{
      image_file.write((char *)&zero, sizeof(DWORD));
      image_file.write((char *)&zero, sizeof(DWORD));
      image_file.write((char *)&zero, sizeof(DWORD));
    }
  }

  // fixup length
  image_length = Module::s_romhdr.physlast - Module::s_romhdr.physfirst;
  if(!config.autosize){
    image_file.seekp(11);
    image_file.write((char *)&image_length, sizeof(DWORD));
  }

  return true;
}

/*****************************************************************************/
bool write_chain(const Config &config, const MemoryList &memory_list){
  string chain_file_name = config.output_file;
  
  ofstream image_file(chain_file_name.c_str(), ios::trunc | ios::binary);
  if(image_file.bad()){
    cerr << "Error: Could not open '" << chain_file_name << "' for writing\n";
    return false;
  }
  
  if(chain_file_name.rfind("\\") != string::npos)
    chain_file_name = chain_file_name.substr(0, chain_file_name.rfind("\\"));

  chain_file_name += "\\chain.lst";

  ofstream list_file(chain_file_name.c_str(), ios::trunc);
  if(list_file.bad()){
    cerr << "Error: Could not open '" << chain_file_name << "' for writing\n";
    return false;
  }
  
  const DWORD zero = 0;
  
  image_file.write("B000FF\n", 7);

  DWORD chain_start = config.xipchain + config.rom_info.offset;
  image_file.write((char *)&chain_start, sizeof(DWORD));
  image_file.write((char *)&zero, sizeof(DWORD));  // temporary size holder

  DWORD crc = 0;
  DWORD order = 0;

  Data xip_data(&zero, sizeof(DWORD));  // reserve room for count at the head

  for(MemoryList::const_iterator mem_itr = memory_list.begin(); mem_itr != memory_list.end(); mem_itr++){
    if(mem_itr->type() != RAMIMAGE_TYPE && mem_itr->type() != NANDIMAGE_TYPE)
      continue;

    XIPCHAIN_ENTRY xip_entry = {0};
    xip_entry.pvAddr      = (LPVOID)mem_itr->address();
    xip_entry.dwLength    = mem_itr->m_romhdr.physlast - mem_itr->m_romhdr.physfirst;
    xip_entry.dwMaxLength = mem_itr->length();
    xip_entry.usFlags     = ROMXIP_OK_TO_LOAD;
    xip_entry.usOrder     = (USHORT)++order;

    strncpy(xip_entry.szName, mem_itr->name().c_str(), mem_itr->name().size() + 1);

    xip_data.append(&xip_entry, sizeof(xip_entry));
    (*(DWORD*)xip_data.ptr())++; // increment region count at start of buffer

    if(mem_itr->is_kernel())
      list_file << "+";
      
    list_file << mem_itr->name() << ".bin" << endl;
  }

  // zero to end the chain
  xip_data.append(&zero, sizeof(DWORD));

  list_file << "chain.bin\n";

  File::write_bin(image_file, config.xipchain + ROM_CHAIN_OFFSET, xip_data.ptr(), xip_data.size());

  // three more dwords to close out the image
  image_file.write((char *)&zero, sizeof(DWORD));
  image_file.write((char *)&zero, sizeof(DWORD));
  image_file.write((char *)&zero, sizeof(DWORD));

  // and one more for good luck
  image_file.write((char *)&zero, sizeof(DWORD));

  // fixup length
  DWORD image_length = xip_data.size();
  image_file.seekp(11);
  image_file.write((char *)&image_length, sizeof(DWORD));

  // call bin2xip
  string privkey = config.output_file;
  
  if(privkey.rfind("\\") != string::npos)
    privkey = privkey.substr(0, privkey.rfind("\\"));

  privkey += "\\privkey.dat";

  char cmd_line[MAX_PATH] = {0};
  
  if(INVALID_FILE_ATTRIBUTES != GetFileAttributes(privkey.c_str()))
  {
    sprintf(cmd_line, "bin2xip.exe %s %s", config.output_file.c_str(), privkey.c_str());

    STARTUPINFO suDummy;
    memset(&suDummy, 0, sizeof(suDummy));
    PROCESS_INFORMATION piDummy;

    if(!CreateProcess(0, cmd_line, NULL, NULL, TRUE, 0, NULL, "\\", &suDummy, &piDummy)){
      fprintf(stderr, "Failed calling %s: %d\n", cmd_line, GetLastError());
      // return false;
    }
    else{
      WaitForSingleObject(piDummy.hProcess, INFINITE);
    }
  }
  
  return true;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -