commit - 6b6a9b6f372bb83e8dee9a0b688c5f545ea4c0f1
commit + 2dc7cc54f72e53f42c087edac8010a2c7b707132
blob - 04dcfb59d3e51abca2c53625c1d617cc6796a1e1
blob + ffe40d5c20744cefd274edf24aad08d884d1f49f
--- .gitignore
+++ .gitignore
squat.elf
squat.img
config.mk
+tools/img_eGON.BT0/img_eGON.BT0
blob - b18eaf83bcdaaff2cec1409888c81b226761be3b
blob + 925065f43c11f5f65d867b2ce1ec7d40606f3246
--- Makefile
+++ Makefile
-include config.mk
-.PHONY: clean qemu gdb-remote
+.PHONY: clean qemu gdb-remote tools
all: squat.img
clean:
rm -rf *.o squat.elf squat.img
+ ${MAKE} -C tools/img_eGON.BT0 clean
qemu: squat.img
qemu-system-${ARCH} -M ${BOARD} -cpu cortex-a53 \
gdb-remote: squat.img
qemu-system-${ARCH} -s -S -M ${BOARD} -cpu cortex-a53 \
-kernel squat.img -nographic -monitor none -serial stdio
+
+tools:
+ ${MAKE} -C tools/img_eGON.BT0 img_eGON.BT0
blob - /dev/null
blob + 544268e60dc99f8a7137783858123c5a1dabfdae (mode 644)
--- /dev/null
+++ tools/img_eGON.BT0/Makefile
+CXXFLAGS += -Wall -Wextra -std=c++11
+
+.PHONY: clean
+
+img_eGON.BT0: img_eGON.BT0.cc
+ ${CXX} ${CXXFLAGS} img_eGON.BT0.cc -o img_eGON.BT0
+
+clean:
+ rm -f img_eGON.BT0
blob - /dev/null
blob + 39d426c2ffa46120a2543ff12e82eb9ae0a80f21 (mode 644)
--- /dev/null
+++ tools/img_eGON.BT0/img_eGON.BT0.cc
+#include <unistd.h>
+#include <string.h>
+#include <fcntl.h>
+#include <errno.h>
+
+#include <iostream>
+#include <iomanip>
+#include <memory>
+
+namespace
+{
+
+ /** Non-copiable objects */
+struct NonCopiable
+{
+ NonCopiable() = default;
+ NonCopiable(const NonCopiable &) = delete;
+ NonCopiable &operator =(const NonCopiable &) = delete;
+};
+
+
+/** Smart pointer for file descriptor */
+class UniqueFd : public NonCopiable
+{
+public:
+ explicit UniqueFd(int fd) : m_fd(fd) {}
+ ~UniqueFd(){ if (*this) close(m_fd); }
+ operator bool() const {return m_fd != -1;}
+ int get() const { return m_fd; }
+
+private:
+ int m_fd;
+};
+
+
+struct CommandLineArguments
+{
+ const char *m_image_file_path{nullptr};
+};
+
+
+void usage(const char *program)
+{
+ const char *file_name = strrchr(program, '/');
+ if (!file_name)
+ file_name = program;
+ else
+ ++file_name;
+
+ 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;
+}
+
+
+bool
+parse_command_line(
+ /* in */ int argc,
+ /* in */ char *argv[],
+ /* out */ CommandLineArguments &args
+)
+{
+ int ch;
+ while ((ch = getopt(argc, argv, "f:")) != -1) {
+ switch (ch) {
+ case 'f':
+ args.m_image_file_path = optarg;
+ break;
+ default:
+ std::cerr << "Invalid command line" << std::endl;
+ return false;
+ }
+ }
+ if (!args.m_image_file_path)
+ {
+ std::cerr << "Invalid command line: -f option required" << std::endl;
+ return false;
+ }
+ return true;
+}
+
+
+char printable(char ch)
+{
+ return ch ? (std::isprint(ch) ? ch : '?') : ' ';
+}
+
+
+struct Header {
+ uint32_t m_jump_instruction;
+ uint8_t m_magic[8];
+ uint32_t m_checksum;
+ uint32_t m_length;
+ uint8_t m_spl_signature[4];
+ uint32_t m_zero18;
+ uint32_t m_zero1C;
+ uint32_t m_name_offset;
+ uint32_t m_zero24;
+ uint32_t m_zero28;
+ uint8_t m_strings[52];
+};
+
+
+bool run(int argc, char *argv[])
+{
+ CommandLineArguments args;
+ if (!parse_command_line(argc, argv, args))
+ {
+ usage(argv[0]);
+ return false;
+ }
+
+ const UniqueFd image_file{open(args.m_image_file_path, O_RDONLY)};
+ if (!image_file)
+ {
+ const auto error{errno};
+ std::cerr << "Open file \"" << args.m_image_file_path << "\" failed. "
+ << "Error code (" << std::dec << error << "): " << strerror(error) << std::endl;
+ return false;
+ }
+
+ Header header{};
+ if (read(image_file.get(), &header, sizeof(header)) == -1)
+ {
+ const auto error{errno};
+ std::cerr << "Read file \"" << args.m_image_file_path << "\" failed. "
+ << "Error code (" << std::dec << error << "): " << strerror(error) << std::endl;
+ return false;
+ }
+
+ std::cout << "+00 Jump instruction : 0x"
+ << std::hex << std::setw(8) << std::setfill('0')
+ << header.m_jump_instruction << std::endl;
+
+ std::cout << "+04 Magic :";
+ for (const auto ch : header.m_magic)
+ std::cout << " 0x" << std::hex << std::setw(2) << std::setfill('0')
+ << uint32_t(ch);
+ std::cout << std::endl;
+ std::cout << " ";
+ for (const auto ch : header.m_magic)
+ std::cout << printable(ch);
+ std::cout << std::endl;
+
+ std::cout << "+0C Checksum : 0x"
+ << std::hex << std::setw(8) << std::setfill('0')
+ << header.m_checksum << std::endl;
+
+ std::cout << "+10 Length : 0x"
+ << std::hex << std::setw(8) << std::setfill('0') << header.m_length
+ << ", " << std::dec << header.m_length << std::endl;
+
+ std::cout << "+14 SPL signature :";
+ for (const auto ch : header.m_spl_signature)
+ std::cout << " 0x" << std::hex << std::setw(2) << std::setfill('0')
+ << uint32_t(ch);
+ std::cout << std::endl;
+ std::cout << " ";
+ for (const auto ch : header.m_spl_signature)
+ std::cout << printable(ch);
+ std::cout << std::endl;
+
+ std::cout << "+18 : 0x"
+ << std::hex << std::setw(8) << std::setfill('0')
+ << header.m_zero18 << std::endl;
+
+ std::cout << "+1C : 0x"
+ << std::hex << std::setw(8) << std::setfill('0')
+ << header.m_zero1C << std::endl;
+
+ std::cout << "+20 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;
+
+ std::cout << "+24 : 0x"
+ << std::hex << std::setw(8) << std::setfill('0')
+ << header.m_zero24 << std::endl;
+
+ std::cout << "+28 : 0x"
+ << std::hex << std::setw(8) << std::setfill('0')
+ << header.m_zero28 << std::endl;
+
+ std::cout << "+2C Strings :";
+ for (const auto ch : header.m_strings)
+ std::cout << " 0x" << std::hex << std::setw(2) << std::setfill('0')
+ << uint32_t(ch);
+ std::cout << std::endl;
+ std::cout << " ";
+ for (const auto ch : header.m_strings)
+ std::cout << printable(ch);
+ std::cout << std::endl;
+
+ return true;
+}
+
+
+}
+
+
+extern "C"
+int
+main(
+ /* in */ int argc,
+ /* in */ char *argv[]
+)
+{
+ return run(argc, argv) ? 0 : 1;
+}