aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile5
-rw-r--r--pipe_image.c55
2 files changed, 59 insertions, 1 deletions
diff --git a/Makefile b/Makefile
index da43892..6ced357 100644
--- a/Makefile
+++ b/Makefile
@@ -47,7 +47,10 @@ qemu-bin : kernel7.img
qemu-loader : loader.img
qemu-system-arm -m 256 -M raspi2 -serial stdio -kernel $^
+pipe_image : pipe_image.c
+ gcc -Wall -std=gnu99 -O3 $^ -o $@
+
clean :
- -rm *.img *.elf *.o
+ -rm *.img *.elf *.o pipe_image
.PHONY: all qemu-elf qemu-bin clean
diff --git a/pipe_image.c b/pipe_image.c
new file mode 100644
index 0000000..7e24ea7
--- /dev/null
+++ b/pipe_image.c
@@ -0,0 +1,55 @@
+#include <stdio.h>
+#include <err.h>
+#include <endian.h>
+#include <stdint.h>
+#include <sys/types.h>
+
+#define ANSI_FG_RED "\033[0;31m"
+
+/* This program pipes it's argument file to stdout prepending it */
+/* with it's size (4 bytes, little endian). It is intended to be used */
+/* with our bootloader (i.e. by piping kernel image to UART). */
+
+int main(int argc, char **argv) {
+ char *image_file_name = argc > 1 ? argv[1] : "kernel7.img";
+
+ FILE *image_file_handle = fopen(image_file_name, "r");
+
+ if (!image_file_handle)
+ err(-1, "couldn't open" ANSI_FG_RED "%s", image_file_name);
+
+ if (fseek(image_file_handle, 0, SEEK_END))
+ err(-1, "error navigating through file");
+
+ ssize_t image_size = ftell(image_file_handle);
+ if (image_size < 0)
+ err(-1, "couldn't get image file size");
+
+ if (image_size >> 32)
+ err(-1, "file to big (should be smaller than 4G)");
+
+ if (fseek(image_file_handle, 0, SEEK_SET))
+ err(-1, "error navigating through file");
+
+ uint32_t image_size_le = htole32(image_size);
+
+ if (fwrite(&image_size_le, 4, 1, stdout) != 1)
+ err(-1, "couldn't write to stdout");
+
+ ssize_t bytes_left = image_size;
+
+ char buf[1024];
+
+ while (bytes_left)
+ {
+ size_t bytes_read;
+ if ((bytes_read = fread(buf, 1, sizeof(buf), image_file_handle))
+ < 1)
+ err(-1, "error reading the file");
+
+ if (fwrite(buf, bytes_read, 1, stdout) != 1)
+ err(-1, "error writing to stdout");
+
+ bytes_left -= bytes_read;
+ }
+}