📄 romimage.cpp
字号:
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//
// This source code is licensed under Microsoft Shared Source License
// Version 1.0 for Windows CE.
// For a copy of the license visit http://go.microsoft.com/fwlink/?LinkId=3223.
//
#include "headers.h"
#include "parse.h"
#include "bin.h"
#include "compcat.h"
#include "sre.h"
#include "rom.h"
#include "pbtimebomb.h"
bool last_pass = true;
bool process_args(char *argv[], int argc, string &bib_file, string &output_file, bool &launch);
bool pass_state(Config &config, ModuleList &module_list, FileList &file_list, MemoryList &memory_list, MemoryList &reserve_list, ModuleList::iterator &kernel);
bool get_kernel(ModuleList::iterator &kernel, const ModuleList &module_list);
bool init_kernel(ModuleList::iterator &kernel, ModuleList &module_list, const MemoryList &memory_list, const Config &config);
bool compute_load_locataions(ModuleList &module_list, const MemoryList &reserve_list, Config &config);
bool compact_image(AddressList &hole_list,
CopyList ©_list,
ModuleList &module_list,
MemoryList &memory_list,
FileList &file_list,
const MemoryList &reserve_list,
const Config &config,
const MemoryList::iterator &xip_mem);
#define FATAL(x) do{ if(!(x)){ fprintf(stderr, "Fatal error hit, exiting...\n"); exit(1); } } while(0)
/*****************************************************************************/
int main(int argc, char *argv[]){
if(getenv("d_break"))
DebugBreak();
#ifdef PBTIMEBOMB
cout << "\nWindows CE ROM Image Builder v4.0." << PBTIMEBOMB << " Copyright (c) Microsoft Corporation\n";
cout << "Built: " __DATE__ " " __TIME__ << "\n\n";
// check PB PID Timebomb
if(!IsRomImageEnabled()){
fprintf(stderr, "Error: failed PB timebomb check\n");
exit(1);
}
#else
cout << "\nWindows CE ROM Image Builder v4.0.000 Copyright (c) Microsoft Corporation\n";
cout << "Built: " __DATE__ " " __TIME__ << "\n\n";
#endif
Config config;
// prereserve 100 memory spots because if someone adds a memory section after the modules are set STL
// may realoc and invalidate all the memory_iterators in the files and modules.
MemoryList memory_list;
MemoryList reserve_list;
ModuleList module_list;
FileList file_list;
MemoryList::iterator mem_itr;
ModuleList::iterator mod_itr;
FileList::iterator file_itr;
string bib_file;
bool launch = false;
bool bad_fixups = false;
bool bad_fixups_fatal = false;
// do command line arguments
FATAL(process_args(argv, argc, bib_file, config.output_file, launch));
// parse the bib file
FATAL(ParseBIBFile(bib_file, memory_list, reserve_list, module_list, file_list, config));
if(module_list.empty())
{
cerr << "Error: No modules defined in bib file, aborting...\n";
FATAL(false);
}
// this only needs to be done once
for(mod_itr = module_list.begin(); mod_itr != module_list.end(); mod_itr++) FATAL(mod_itr->sync_names(config.profile, config.copy_files));
for(mod_itr = module_list.begin(); mod_itr != module_list.end(); mod_itr++) FATAL(mod_itr->add_sig_files(file_list));
// determine if we have any .rel files at all
WIN32_FIND_DATA FindFileData;
HANDLE hFind;
string reloc_file = module_list[0].full_path();
reloc_file.erase(reloc_file.rfind('\\') + 1);
reloc_file += "*.rel";
hFind = FindFirstFile(reloc_file.c_str(), &FindFileData);
if(hFind == INVALID_HANDLE_VALUE){
cerr << "Warning: No .rel files found, using old fixup style for all modules\n";
for(mod_itr = module_list.begin(); mod_itr != module_list.end(); mod_itr++) mod_itr->set_code_split(false);
bad_fixups_fatal = true;
}
else
FindClose(hFind);
// find the kernel and make sure it's first.
ModuleList::iterator kernel;
for(kernel = module_list.begin(); kernel != module_list.end(); kernel++)
if(kernel->name() == "nk.exe"){
Module temp = *kernel;
module_list.erase(kernel);
module_list.insert(module_list.begin(), temp);
break;
}
kernel = module_list.begin();
// sort by exe and by split code sections
// stable_partition(kernel + 1, module_list.end(), mem_fun_ref(Module::not_is_file_compressed));
stable_partition(kernel + 1, module_list.end(), mem_fun_ref(Module::is_exe));
stable_partition(kernel + 1, module_list.end(), mem_fun_ref(Module::is_code_split));
stable_partition(kernel + 1, module_list.end(), mem_fun_ref(Module::fixup_like_kernel));
reserve_list.sort();
Config config_backup(config);
ModuleList module_list_backup(module_list);
if(config.xipchain){
Memory memory;
StringList token_list;
char buffer[10];
int count = 1; // for the chain file itself
for(mem_itr = memory_list.begin(); mem_itr != memory_list.end(); mem_itr++)
if(mem_itr->type() == RAMIMAGE_TYPE ||
mem_itr->type() == NANDIMAGE_TYPE ||
mem_itr->type() == ROM8_TYPE ||
mem_itr->type() == ROMx8_TYPE ||
mem_itr->type() == ROM16_TYPE)
count++;
token_list.push_back(CHAIN_INFORMATION);
sprintf(buffer, "%08x", config.xipchain);
token_list.push_back(buffer);
sprintf(buffer, "%08x", count * sizeof(XIPCHAIN_SUMMARY));
token_list.push_back(buffer);
token_list.push_back(EXTENSION_TYPE);
token_list.push_back(kernel->memory_iterator()->name());
memory.set(token_list);
memory_list.push_back(memory);
}
do{
FATAL(pass_state(config, module_list, file_list, memory_list, reserve_list, kernel));
fixup_start:
ModuleList::iterator modbak_itr = module_list_backup.begin();
for(mod_itr = module_list.begin(); mod_itr != module_list.end(); mod_itr++) modbak_itr++->set_code_split(mod_itr->is_code_split());
stable_partition(module_list_backup.begin() + 1, module_list_backup.end(), mem_fun_ref(Module::is_code_split));
// if we autosized and are now on the last pass restore the modules and config
if(!config.autosize && config_backup.autosize){
module_list = module_list_backup;
DWORD tempxip = config.xipchain;
config = config_backup;
config.xipchain = tempxip;
config.autosize = false;
}
else if(bad_fixups){
module_list = module_list_backup;
DWORD tempxip = config.xipchain;
config = config_backup;
config.xipchain = tempxip;
bad_fixups_fatal = true;
}
FATAL(init_kernel(kernel, module_list, memory_list, config));
// process the modules
for(mod_itr = module_list.begin(); mod_itr != module_list.end(); mod_itr++) FATAL(mod_itr->load());
for(mod_itr = module_list.begin(); mod_itr != module_list.end(); mod_itr++) FATAL(mod_itr->verify_cpu());
// reset dll ranges
for(mem_itr = memory_list.begin(); mem_itr != memory_list.end(); mem_itr++){
mem_itr->dll_code_start = mem_itr->dll_code_orig;
mem_itr->dll_data_start = mem_itr->dll_data_orig;
mem_itr->dll_data_split = 0;
mem_itr->code_space_full = false;
}
FATAL(compute_load_locataions(module_list, reserve_list, config));
// get symbols
for(mod_itr = module_list.begin(); mod_itr != module_list.end(); mod_itr++)
if(config.profile || mod_itr->is_kernel())
FATAL(mod_itr->get_symbols(config.profile_all, memory_list));
// relocate image
for(mod_itr = module_list.begin(); mod_itr != module_list.end(); mod_itr++) FATAL(mod_itr->relocate_image());
// do fixups
for(mod_itr = module_list.begin(); mod_itr != module_list.end(); mod_itr++)
if(!mod_itr->fixup()){
if(bad_fixups_fatal){
cerr << "Error: fatal fixup error, aborting....\n";
exit(1);
}
static bool first = true;
if(first){
cerr << "Rel files are required to load the code section of modules into slot 1 and therefore freeing up more virtual memory space in slot 0.\n";
first = false;
}
cerr << "Warning: No .rel file found for module " << mod_itr->name() << ", using old fixup style." << endl;
mod_itr->set_code_split(false);
bad_fixups = 1;
}
if(bad_fixups && !bad_fixups_fatal)
goto fixup_start;
// remove discardables
for(mod_itr = module_list.begin(); mod_itr != module_list.end(); mod_itr++) FATAL(mod_itr->remove_discardable_sections());
// imports
for(mod_itr = module_list.begin(); mod_itr != module_list.end(); mod_itr++) mod_itr->resolve_imports(module_list, config.error_late_bind);
// Check import results afterwards so that they can check all missing functions at one time
FATAL(Module::import_success());
for(mod_itr = module_list.begin(); mod_itr != module_list.end(); mod_itr++) FATAL(mod_itr->compress(config.compress));
for(mod_itr = module_list.begin(); mod_itr != module_list.end(); mod_itr++) FATAL(mod_itr->sig_adjust());
// process the files
for(file_itr = file_list.begin(); file_itr != file_list.end(); file_itr++) FATAL(file_itr->load());
for(file_itr = file_list.begin(); file_itr != file_list.end(); file_itr++) FATAL(file_itr->compress(config.compress));
CopyList copy_list;
AddressList hole_list;
// per region processing
for(mem_itr = memory_list.begin(); mem_itr != memory_list.end(); mem_itr++){
if(mem_itr->type() == RAMIMAGE_TYPE || mem_itr->type() == NANDIMAGE_TYPE || mem_itr->type() == ROM8_TYPE || mem_itr->type() == ROMx8_TYPE || mem_itr->type() == ROM16_TYPE){
LAST_PASS_PRINT cout << "Processing " << mem_itr->name() << endl;
FATAL(compact_image(hole_list, copy_list, module_list, memory_list, file_list, reserve_list, config, mem_itr));
for(MemoryList::iterator mem_itr2 = memory_list.begin(); mem_itr2 != memory_list.end(); mem_itr2++){
// fixup kernel variables
if(mem_itr->is_kernel()){
if(mem_itr2->type() == FIXUPVAR_TYPE){
if(mem_itr2->address())
kernel->fixupvar(mem_itr2->fixupvar_section, mem_itr2->address(), mem_itr2->length());
else
cerr << "Warning: FixupVar " << mem_itr2->name() << " not found in kernel. Variable not fixed up.\n";
}
}
// set extension address
if(mem_itr2->type() == EXTENSION_TYPE && mem_itr2->extension_location == mem_itr->name()){
if(mem_itr->is_kernel() && kernel->is_kernel() && kernel->rom_extensions())
kernel->fixupvar(0,
kernel->rom_extensions() - kernel->memory_iterator()->address() + sizeof(EXTENSION) - sizeof(DWORD) - kernel->page_size(),
mem_itr2->extension_offset);
else if(mem_itr->is_kernel() && kernel->is_kernel())
kernel->set_rom_extensions(mem_itr2->extension_offset);
else
Module::s_romhdr.pExtensions = (void*)mem_itr2->extension_offset;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -