aboutsummaryrefslogtreecommitdiff
path: root/src/host
diff options
context:
space:
mode:
Diffstat (limited to 'src/host')
-rw-r--r--src/host/makefs.c97
-rw-r--r--src/host/pipe_image.c112
2 files changed, 209 insertions, 0 deletions
diff --git a/src/host/makefs.c b/src/host/makefs.c
new file mode 100644
index 0000000..379e8c5
--- /dev/null
+++ b/src/host/makefs.c
@@ -0,0 +1,97 @@
+// Take files given on stdin and make them into a ramfs image of our
+// own, (stupid) simple format.
+// In the format: for each file comes the null-terminated string
+// with filename, then null-padding until a 4-aligned offset, then
+// 4-byte little-endian size of the file and then the contents
+// of the file and then another null-padding until a 4-aligned offset.
+// Files encoded this way go one after another (so it's easy to add
+// something at the beginning).
+// At the and comes one null-byte (as if a file with empty name
+// was there).
+
+#include <stdint.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <err.h>
+#include <sys/stat.h>
+#include <string.h>
+
+#define ANSI_FG_RED "\033[0;31m"
+#define ANSI_FG_DEFAULT "\033[0;39m"
+
+int main(int argc, char **argv)
+{
+ // process files in the order they are provided on the command line
+ for (int i = 1; i < argc; i++)
+ {
+ struct stat fileinfo;
+
+ if (stat(argv[i], &fileinfo))
+ err(-1, "couldn't stat " ANSI_FG_RED "%s" ANSI_FG_DEFAULT,
+ argv[i]);
+
+ if (!S_ISREG(fileinfo.st_mode))
+ errx(-1, ANSI_FG_RED "%s" ANSI_FG_DEFAULT
+ " is not a regular file.", argv[i]);
+
+ // don't allow files with size so big, that it can't be encoded
+ // in a 4-byte unsigned int... In practice even smaller files
+ // won't fit on the rpi.
+ if (fileinfo.st_size > UINT32_MAX)
+ errx(-1, ANSI_FG_RED "%s" ANSI_FG_DEFAULT
+ " is too big.", argv[i]);
+
+ uint32_t file_size = fileinfo.st_size;
+ uint32_t name_size = strlen(argv[i]) + 1; // 1 for null-byte
+
+ if (fwrite(argv[i], 1, name_size, stdout) != name_size)
+ errx(-1, "error writing to stdout");
+
+ // pad with null-bytes until a 4-aligned offset
+ for (uint32_t j = 0; (j + name_size) & 0b11; j++)
+ if (putchar('\0'))
+ errx(-1, "error writing to stdout");
+
+ // TODO convert file_size to little endian first (in case our
+ // host is be).
+ if (fwrite(&file_size, 4, 1, stdout) != 1)
+ errx(-1, "error writing to stdout");
+
+ // flush b4 running cat, so that stuff we've written comes
+ // b4 the actual file contents in the output
+ if (fflush(stdout))
+ err(-1, "couldn't flush stdout");
+
+ // we don't copy the actual file ourselves - we run cat for that
+ pid_t pid;
+ int wstatus;
+ switch (pid = fork())
+ {
+ case -1:
+ err(-1, "couldn't fork");
+ case 0:
+ if (execlp("cat", "cat", argv[i], NULL))
+ err(-1, "couldn't execute cat");
+ default:
+ if (wait(&wstatus) == -1)
+ err(-1, "error waiting for child");
+
+ if (!WIFEXITED(wstatus) || WEXITSTATUS(wstatus))
+ exit(-1);
+ }
+
+ // again, pad with null-bytes until a 4-aligned offset
+ for (uint32_t j = 0; (j + file_size) & 0b11; j++)
+ if (putchar('\0'))
+ errx(-1, "error writing to stdout");
+ }
+
+ if (putchar('\0'))
+ errx(-1, "error writing to stdout");
+
+ return 0;
+}
+
diff --git a/src/host/pipe_image.c b/src/host/pipe_image.c
new file mode 100644
index 0000000..105f9a1
--- /dev/null
+++ b/src/host/pipe_image.c
@@ -0,0 +1,112 @@
+#include <stdio.h>
+#include <err.h>
+#include <endian.h>
+#include <stdint.h>
+#include <sys/types.h>
+#include "rs232.h"
+
+#define ANSI_FG_RED "\033[0;31m"
+#define ANSI_FG_DEFAULT "\033[0;39m"
+
+/* This program pipes it's argument file to /dev/ttyUSB0 or stdout */
+/* prepending it with it's size (4 bytes, little endian). */
+/* It is intended to be used with our bootloader. */
+
+int main(int argc, const char **argv) {
+ const char *image_file_name = "kernel.img";
+ _Bool stdout_instead_of_uart = 0;
+
+ if (argc > 1)
+ if (!strcmp(argv[1], "--stdout"))
+ {
+ stdout_instead_of_uart = 1;
+ argc--;
+ argv++;
+ }
+
+ if (argc > 1)
+ image_file_name = argv[1];
+
+ FILE *image_file_handle = fopen(image_file_name, "r");
+
+ if (!image_file_handle)
+ err(-1, "couldn't open" ANSI_FG_RED "%s" ANSI_FG_DEFAULT,
+ 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");
+
+ //init comport
+ const int comport=16;
+
+ if (!stdout_instead_of_uart)
+ if (RS232_OpenComport(comport, 115200, "8N1", 1) == 1)
+ err(-1, "Error opening comport");
+
+ uint32_t image_size_le = htole32(image_size);
+
+ if (stdout_instead_of_uart)
+ {
+ if (fwrite((unsigned char*) &image_size_le, 4, 1, stdout) != 1)
+ err(-1, "error writing number to stdout");
+ }
+ else
+ {
+ if (RS232_SendBuf(comport, (unsigned char*) &image_size_le, 4)
+ == -1)
+ err(-1, "error writing number to serial");
+ }
+
+ ssize_t bytes_left = image_size;
+
+ unsigned 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 (stdout_instead_of_uart)
+ {
+ if (fwrite((unsigned char*) buf, bytes_read, 1, stdout) != 1)
+ err(-1, "error writing to stdout");
+ }
+ else
+ {
+ if (RS232_SendBuf(comport, buf, bytes_read) == -1)
+ err(-1, "error writing to serial");
+ }
+
+ bytes_left -= bytes_read;
+ }
+/*
+ while(1){
+ int bytes_read=read(0,buf,sizeof(buf));
+ if (stdout_instead_of_uart)
+ {
+ if (fwrite((unsigned char*) buf, bytes_read, 1, stdout) != 1)
+ err(-1, "error writing to stdout");
+ }
+ else
+ {
+ if (RS232_SendBuf(comport, buf, bytes_read) == 1)
+ err(-1, "error writing to serial");
+ }
+ }
+ */
+ if (!stdout_instead_of_uart)
+ RS232_CloseComport(comport);
+
+ return 0;
+}