commit - 621f0e86e870df27570c60b2d36a870213fa06e3
commit + 29b6aefcc50d941aa40b4884b28a3ecc95f2752b
blob - fa81d1fc96717d9898057354443c6ea1450fcc7b
blob + 718b1ffbaef1959e058b15834d9403eea4b414d1
--- tools/img_eGON.BT0/img_eGON.BT0.cc
+++ tools/img_eGON.BT0/img_eGON.BT0.cc
#include <string.h>
#include <fcntl.h>
#include <errno.h>
+#include <sys/stat.h>
+#include <cstddef>
#include <iostream>
#include <iomanip>
#include <memory>
#include <array>
#include <algorithm>
#include <vector>
+#include <string>
namespace
struct CommandLineArguments
{
const char *m_image_file_path{nullptr};
+ const char *m_bin_file_path{nullptr};
};
std::cerr << "Usage: " << file_name << " [OPTS]" << std::endl << std::endl;
std::cerr << "OPTS may be: " << std::endl;
- std::cerr << "\t-f FILE : image file path" << std::endl;
+ std::cerr << "\t-f IMG_FILE : image file header (required)" << std::endl;
+ std::cerr << "\t-c BIN_FILE : create IMG_FILE from BIN_FILE"<< std::endl;
+ std::cerr << "\t if not specified: check and dump IMG_FILE" << std::endl;
}
)
{
int ch;
- while ((ch = getopt(argc, argv, "f:")) != -1) {
+ while ((ch = getopt(argc, argv, "f:c:")) != -1) {
switch (ch) {
case 'f':
args.m_image_file_path = optarg;
break;
+ case 'c':
+ args.m_bin_file_path = optarg;
+ break;
default:
std::cerr << "Invalid command line" << std::endl;
return false;
uint8_t m_spl_signature[SPL_SIGNATURE_LENGTH];
uint8_t m_spl_version;
uint32_t m_zero18;
- uint32_t m_zero1C;
+ uint32_t m_zero1c;
uint32_t m_name_offset;
uint32_t m_zero24;
uint32_t m_zero28;
constexpr uint32_t JUMP_INSTRUCTION{0xea000000 | ((sizeof(Header) / 4) - 2)};
+const std::string NAME = "sun50i-a64-pinephone-1.2";
+
bool validate_and_dump(const char *image_file_path)
{
const UniqueFd image_file{open(image_file_path, O_RDONLY)};
}
Header header{};
- const auto readed{read(image_file.get(), &header, sizeof(header))};
- if (readed != sizeof(header))
+ const auto read_res{read(image_file.get(), &header, sizeof(header))};
+ if (read_res != sizeof(header))
{
const auto error{errno};
std::cerr << "Read file \"" << image_file_path << "\" failed. ";
- if (readed == -1)
+ if (read_res == -1)
std::cerr << "Error code (" << std::dec << error << "): "
<< strerror(error) << std::endl;
else
std::cout << "+0x1c : 0x"
<< std::hex << std::setw(8) << std::setfill('0')
- << header.m_zero1C << std::endl;
+ << header.m_zero1c << std::endl;
std::cout << "+0x20 Name offset : 0x"
<< std::hex << std::setw(8) << std::setfill('0') << header.m_name_offset
<< ", " << std::dec << header.m_name_offset;
std::cout << std::endl;
+ if (header.m_name_offset >= offsetof(Header, m_name_offset) &&
+ header.m_name_offset < (offsetof(Header, m_name_offset) + sizeof(header.m_strings)))
+ {
+ std::cout << " (v) OK" << std::endl;
+ }
+ else
+ {
+ std::cout << " (x) Unexpected" << std::endl;
+ ret_value = false;
+ }
std::cout << "+0x24 : 0x"
<< std::hex << std::setw(8) << std::setfill('0')
}
+bool
+create(
+ const char *from_bin_file_path,
+ const char *to_image_file_path
+)
+{
+ struct stat bin_file_sb{};
+ if (stat(from_bin_file_path, &bin_file_sb) == -1)
+ {
+ const auto error{errno};
+ std::cerr << "Stat file \"" << from_bin_file_path << "\" failed. "
+ << "Error code (" << std::dec << error << "): " << strerror(error) << std::endl;
+ return false;
+ }
+ // round up 512
+ const uint32_t rounded_size = (uint32_t(bin_file_sb.st_size) + 511) & ~511;
+ if (bin_file_sb.st_size > rounded_size)
+ {
+ std::cerr << "Input binary file \"" << from_bin_file_path << "\" is too large." << std::endl;
+ return false;
+ }
+
+ const uint32_t binary_size{uint32_t(sizeof(Header)) + rounded_size};
+ std::vector<uint8_t> binary;
+ binary.resize(binary_size);
+
+ const UniqueFd bin_file{open(from_bin_file_path, O_RDONLY)};
+ if (!bin_file)
+ {
+ const auto error{errno};
+ std::cerr << "Open file \"" << from_bin_file_path << "\" failed. "
+ << "Error code (" << std::dec << error << "): " << strerror(error) << std::endl;
+ return false;
+ }
+
+ const auto read_res{read(bin_file.get(), &binary[sizeof(Header)], bin_file_sb.st_size)};
+ if (read_res != bin_file_sb.st_size)
+ {
+ const auto error{errno};
+ std::cerr << "Read file \"" << from_bin_file_path << "\" failed.";
+ if (read_res == -1)
+ std::cerr << " Error code (" << std::dec << error << "): " << strerror(error);
+ std::cerr << std::endl;
+ return false;
+ }
+
+ Header &header = *reinterpret_cast<Header *>(&binary[0]);
+ header.m_jump_instruction = JUMP_INSTRUCTION;
+ std::copy(MAGIC.cbegin(), MAGIC.cend(), &header.m_magic[0]);
+ header.m_checksum = CHECKSUM_INITIAL;
+ header.m_length = rounded_size;
+ std::copy(SPL_SIGNATURE.cbegin(), SPL_SIGNATURE.cend(), &header.m_spl_signature[0]);
+ header.m_spl_version = SPL_VERSION_0_2;
+ header.m_name_offset = offsetof(Header, m_strings);
+ std::copy(NAME.cbegin(), NAME.cend(), &header.m_strings[0]);
+
+ uint32_t checksum = 0;
+ for (uint32_t i = 0; i < binary_size / sizeof(uint32_t); ++i)
+ checksum += reinterpret_cast<const uint32_t *>(&binary[0])[i];
+ header.m_checksum = checksum;
+
+ const UniqueFd image_file{open(to_image_file_path, O_WRONLY | O_CREAT | O_TRUNC, S_IRWXU | S_IRWXG | S_IROTH)};
+ if (!image_file)
+ {
+ const auto error{errno};
+ std::cerr << "Create file \"" << to_image_file_path << "\" failed. "
+ << "Error code (" << std::dec << error << "): " << strerror(error) << std::endl;
+ return false;
+ }
+ const auto write_res{write(image_file.get(), &binary[0], binary_size)};
+ if (write_res != binary_size)
+ {
+ const auto error{errno};
+ std::cerr << "Write file \"" << to_image_file_path << "\" failed.";
+ if (read_res == -1)
+ std::cerr << " Error code (" << std::dec << error << "): " << strerror(error);
+ std::cerr << std::endl;
+ return false;
+ }
+ return true;
+}
+
} // namespace header
bool run(const CommandLineArguments &args)
{
+ if (args.m_bin_file_path)
+ return header::create(args.m_bin_file_path, args.m_image_file_path);
return header::validate_and_dump(args.m_image_file_path);
}