📄 bin.cpp
字号:
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 + -