[icestorm] 35/75: Created a tool for building multiboot images

Ruben Undheim rubund-guest at moszumanska.debian.org
Wed Oct 7 15:52:07 UTC 2015


This is an automated email from the git hooks/post-receive script.

rubund-guest pushed a commit to branch master
in repository icestorm.

commit d1893e1116fee67db54962dba7417508b3128b9e
Author: Marcus Comstedt <marcus at mc.pp.se>
Date:   Fri Aug 7 19:40:34 2015 +0200

    Created a tool for building multiboot images
---
 Makefile             |   4 +
 icemulti/.gitignore  |   3 +
 icemulti/Makefile    |  24 +++++
 icemulti/icemulti.cc | 263 +++++++++++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 294 insertions(+)

diff --git a/Makefile b/Makefile
index be631e7..8704427 100644
--- a/Makefile
+++ b/Makefile
@@ -3,21 +3,25 @@ all:
 	$(MAKE) -C icebox
 	$(MAKE) -C icepack
 	$(MAKE) -C iceprog
+	$(MAKE) -C icemulti
 
 clean:
 	$(MAKE) -C icebox clean
 	$(MAKE) -C icepack clean
 	$(MAKE) -C iceprog clean
+	$(MAKE) -C icemulti clean
 
 install:
 	$(MAKE) -C icebox install
 	$(MAKE) -C icepack install
 	$(MAKE) -C iceprog install
+	$(MAKE) -C icemulti install
 
 uninstall:
 	$(MAKE) -C icebox uninstall
 	$(MAKE) -C icepack uninstall
 	$(MAKE) -C iceprog uninstall
+	$(MAKE) -C icemulti uninstall
 
 .PHONY: all clean install uninstall
 
diff --git a/icemulti/.gitignore b/icemulti/.gitignore
new file mode 100644
index 0000000..51ac8f9
--- /dev/null
+++ b/icemulti/.gitignore
@@ -0,0 +1,3 @@
+icemulti
+icemulti.o
+icemulti.d
diff --git a/icemulti/Makefile b/icemulti/Makefile
new file mode 100644
index 0000000..0b4e0aa
--- /dev/null
+++ b/icemulti/Makefile
@@ -0,0 +1,24 @@
+# CXX = clang
+LDLIBS = -lm -lstdc++
+CXXFLAGS = -MD -O0 -ggdb -Wall -std=c++11
+CC = $(CXX)
+DESTDIR = /usr/local
+
+all: icemulti
+
+icemulti: icemulti.o
+
+install: all
+	cp icemulti $(DESTDIR)/bin/icemulti
+
+uninstall:
+	rm -f $(DESTDIR)/bin/icemulti
+
+clean:
+	rm -f icemulti
+	rm -f *.o *.d
+
+-include *.d
+
+.PHONY: all install uninstall clean
+
diff --git a/icemulti/icemulti.cc b/icemulti/icemulti.cc
new file mode 100644
index 0000000..5911550
--- /dev/null
+++ b/icemulti/icemulti.cc
@@ -0,0 +1,263 @@
+//
+//  Copyright (C) 2015  Marcus Comstedt <marcus at mc.pp.se>
+//
+//  Permission to use, copy, modify, and/or distribute this software for any
+//  purpose with or without fee is hereby granted, provided that the above
+//  copyright notice and this permission notice appear in all copies.
+//
+//  THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+//  WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+//  MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+//  ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+//  WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+//  ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+//  OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+//
+
+#include <fstream>
+#include <iostream>
+#include <cstdint>
+#include <memory>
+
+#include <stdio.h>
+
+#define log(...) fprintf(stderr, __VA_ARGS__);
+#define info(...) do { if (log_level > 0) fprintf(stderr, __VA_ARGS__); } while (0)
+#define error(...) do { fprintf(stderr, "Error: " __VA_ARGS__); exit(1); } while (0)
+
+int log_level = 0;
+
+static const int NUM_IMAGES = 4;
+static const int NUM_HEADERS = NUM_IMAGES + 1;
+static const int HEADER_SIZE = 32;
+static const int HEADERS_SIZE = NUM_HEADERS * HEADER_SIZE;
+
+static void write_byte(std::ostream &ofs, uint32_t &file_offset, uint8_t byte)
+{
+    ofs << byte;
+    file_offset++;
+}
+
+static void write_bytes(std::ostream &ofs, uint32_t &file_offset,
+                        const uint8_t *buf, size_t n)
+{
+    if (n > 0) {
+        ofs.write(reinterpret_cast<const char*>(buf), n);
+        file_offset += n;
+    }
+}
+
+static void write_file(std::ostream &ofs, uint32_t &file_offset,
+                       std::istream &ifs)
+{
+    const size_t bufsize = 8192;
+    uint8_t *buffer = new uint8_t[bufsize];
+
+    while(!ifs.eof()) {
+        ifs.read(reinterpret_cast<char *>(buffer), bufsize);
+        if (ifs.bad())
+            error("Read error on input image");
+        write_bytes(ofs, file_offset, buffer, ifs.gcount());
+    }
+
+    delete[] buffer;
+}
+
+static void pad_to(std::ostream &ofs, uint32_t &file_offset, uint32_t target)
+{
+    if (target < file_offset)
+        error("Trying to pad backwards!\n");
+    while(file_offset < target)
+        write_byte(ofs, file_offset, 0xff);
+}
+
+class Image {
+    std::ifstream ifs;
+    uint32_t offs;
+
+public:
+    Image(const char *filename) : ifs(filename, std::ifstream::binary) {}
+
+    size_t size();
+    void write(std::ostream &ofs, uint32_t &file_offset);
+    void place(uint32_t o) { offs = o; }
+    uint32_t offset() const { return offs; }
+};
+
+size_t Image::size()
+{
+    ifs.seekg (0, ifs.end);
+    size_t length = ifs.tellg();
+    ifs.seekg (0, ifs.beg);
+    return length;
+}
+
+void Image::write(std::ostream &ofs, uint32_t &file_offset)
+{
+    write_file(ofs, file_offset, ifs);
+}
+
+class Header {
+    uint32_t image_offs;
+    bool coldboot_flag;
+    bool empty;
+public:
+    Header() : empty(true) {}
+    Header(const Image &i) :
+        image_offs(i.offset()), coldboot_flag(false), empty(false) {}
+    void set_coldboot_flag() { coldboot_flag = true; }
+    void write(std::ostream &ofs, uint32_t &file_offset);
+};
+
+void Header::write(std::ostream &ofs, uint32_t &file_offset)
+{
+    if (empty)
+        return;
+
+    // Preamble
+    write_byte(ofs, file_offset, 0x7e);
+    write_byte(ofs, file_offset, 0xaa);
+    write_byte(ofs, file_offset, 0x99);
+    write_byte(ofs, file_offset, 0x7e);
+
+    // Boot mode
+    write_byte(ofs, file_offset, 0x92);
+    write_byte(ofs, file_offset, 0x00);
+    write_byte(ofs, file_offset, (coldboot_flag? 0x10: 0x00));
+
+    // Boot address
+    write_byte(ofs, file_offset, 0x44);
+    write_byte(ofs, file_offset, 0x03);
+    write_byte(ofs, file_offset, (image_offs >> 16) & 0xff);
+    write_byte(ofs, file_offset, (image_offs >> 8) & 0xff);
+    write_byte(ofs, file_offset, image_offs & 0xff);
+
+    // Bank offset
+    write_byte(ofs, file_offset, 0x82);
+    write_byte(ofs, file_offset, 0x00);
+    write_byte(ofs, file_offset, 0x00);
+
+    // Reboot
+    write_byte(ofs, file_offset, 0x01);
+    write_byte(ofs, file_offset, 0x08);
+
+    // Zero out any unused bytes
+    while (file_offset & (HEADER_SIZE - 1))
+        write_byte(ofs, file_offset, 0x00);
+}
+
+void usage()
+{
+    log("\n");
+    log("Usage: icemulti [options] input-files\n");
+    log("\n");
+    log(" -c\n");
+    log(" coldboot mode, power on reset image is selected by CBSEL0/CBSEL1\n");
+    log("\n");
+    log(" -p0, -p1, -p2, -p3\n");
+    log(" select power on reset image when not using coldboot mode\n");
+    log("\n");
+    log(" -o filename\n");
+    log(" write output image to file instead of stdout\n");
+    log("\n");
+    log(" -v\n");
+    log(" verbose (repeat to increase verbosity)\n");
+    log("\n");
+    exit(1);
+}
+
+int main(int argc, char **argv)
+{
+    bool coldboot = false;
+    int por_image = 0;
+    int image_count = 0;
+    Header headers[NUM_HEADERS];
+    std::unique_ptr<Image> images[NUM_IMAGES];
+    const char *outfile_name = NULL;
+
+    for (int i = 1; i < argc; i++)
+    {
+	if (argv[i][0] == '-' && argv[i][1]) {
+            for (int j = 1; argv[i][j]; j++)
+                if (argv[i][j] == 'c') {
+                    coldboot = true;
+                } else if (argv[i][j] == 'p' && argv[i][j+1]) {
+                    por_image = argv[i][++j] - '0';
+                } else if (argv[i][j] == 'o') {
+                    if (argv[i][j+1])
+                        outfile_name = &argv[i][j+1];
+                    else if(i+1 < argc)
+                        outfile_name = argv[++i];
+                    else
+                        usage();
+                    break;
+                } else if (argv[i][j] == 'v') {
+                    log_level++;
+                } else
+                    usage();
+            continue;
+        }
+
+        if (image_count >= NUM_IMAGES)
+            error("Too many images supplied\n");
+        images[image_count++].reset(new Image(argv[i]));
+    }
+
+    if (!image_count)
+        usage();
+
+    if (coldboot && por_image != 0)
+        error("Can't select power on reset boot image in cold boot mode\n");
+
+    if (por_image >= image_count)
+        error("Specified non-existing image for power on reset\n");
+
+    // Place images
+    uint32_t offs = 0x100;
+    for (int i=0; i<image_count; i++) {
+        images[i]->place(offs);
+        offs += images[i]->size();
+
+        // Align to 4K
+        if (offs & 0xfff) {
+            offs |= 0xfff;
+            offs++;
+        }
+    }
+
+    // Populate headers
+    for (int i=0; i<image_count; i++)
+        headers[i + 1] = Header(*images[i]);
+    headers[0] = headers[por_image + 1];
+    for (int i=image_count; i < NUM_IMAGES; i++)
+        headers[i + 1] = headers[0];
+    if (coldboot)
+        headers[0].set_coldboot_flag();
+
+    std::ofstream ofs;
+    std::ostream *osp;
+
+    if (outfile_name != NULL) {
+        ofs.open(outfile_name, std::ofstream::binary);
+        if (!ofs.is_open())
+            error("Failed to open output file.\n");
+        osp = &ofs;
+    } else {
+        osp = &std::cout;
+    }
+
+    uint32_t file_offset = 0;
+    for (int i=0; i<NUM_HEADERS; i++)
+    {
+        pad_to(*osp, file_offset, i * HEADER_SIZE);
+        headers[i].write(*osp, file_offset);
+    }
+    for (int i=0; i<image_count; i++)
+    {
+        pad_to(*osp, file_offset, images[i]->offset());
+        images[i]->write(*osp, file_offset);
+    }
+
+    info("Done.\n");
+    return 0;
+}

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/debian-science/packages/icestorm.git



More information about the debian-science-commits mailing list