Commit Diff


commit - 6b6a9b6f372bb83e8dee9a0b688c5f545ea4c0f1
commit + 2dc7cc54f72e53f42c087edac8010a2c7b707132
blob - 04dcfb59d3e51abca2c53625c1d617cc6796a1e1
blob + ffe40d5c20744cefd274edf24aad08d884d1f49f
--- .gitignore
+++ .gitignore
@@ -3,3 +3,4 @@
 squat.elf
 squat.img
 config.mk
+tools/img_eGON.BT0/img_eGON.BT0
blob - b18eaf83bcdaaff2cec1409888c81b226761be3b
blob + 925065f43c11f5f65d867b2ce1ec7d40606f3246
--- Makefile
+++ Makefile
@@ -21,7 +21,7 @@ OBJS		= ${ASFILES:.S=.o} ${CXXFILES:.cc=.o}
 
 -include	config.mk
 
-.PHONY:	clean qemu gdb-remote
+.PHONY:	clean qemu gdb-remote tools
 
 all: squat.img
 
@@ -36,6 +36,7 @@ squat.elf: linker.ld ${OBJS}
 
 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 \
@@ -43,3 +44,6 @@ qemu: squat.img
 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
@@ -0,0 +1,9 @@
+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
@@ -0,0 +1,209 @@
+#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;
+}