summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Makefile21
-rw-r--r--paxf.c129
2 files changed, 150 insertions, 0 deletions
diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000..0ed0c94
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,21 @@
+#
+# patch a binary .axf file with a new set of kernel parameters
+#
+
+CC ?= gcc
+CFLAGS ?= -g
+
+OBJ = paxf.o
+
+
+all: paxf
+
+paxf: paxf.o
+ $(CC) $(CFLAGS) -o paxf $(OBJ)
+
+clean:
+ rm -f paxf $(OBJ)
+
+.c.o:
+ $(CC) $(CFLAGS) -c $<
+
diff --git a/paxf.c b/paxf.c
new file mode 100644
index 0000000..3e167e6
--- /dev/null
+++ b/paxf.c
@@ -0,0 +1,129 @@
+/**********************************************************************
+ * Given a linux-system.axf file built in a certain way, replace
+ * the kernel parameters used with whatever I'd like to put in
+ * there instead.
+ *
+ * This is a quick and dirty hack; if it works for *anything* other
+ * than this, I think I'll laugh hysterically.
+ *
+ *
+ * Copyright (c) 2012, Al Stone <ahs3@ahs3.net>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of version 2 (only) of the GNU General
+ * Public License as published by the Free Software Foundation.
+ *
+ **********************************************************************/
+
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/mman.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+
+#define ARG_OFFSET 0x4000e4
+#define AXF_FILE "./linux-system-useless.axf"
+#define BUFFER_LENGTH 400
+
+void
+usage() {
+ fprintf(stderr, "usage: paxf <output-axf> <kernel-parameters>\n\n");
+ fprintf(stderr, "where:\n");
+ fprintf(stderr,
+ " <output-axf> => name to use for patched axf file\n");
+ fprintf(stderr,
+ " <kernel-parameters> => the kernel parameters wanted as a\n");
+ fprintf(stderr,
+ " single string (assume there are NO\n");
+ fprintf(stderr,
+ " parameters provided by default)\n");
+}
+
+int
+main(int argv, char *argc[]) {
+
+ int infd, outfd;
+ char *fname;
+ char *kargs;
+
+ /* crude argument handling */
+ if (argv < 3) {
+ usage();
+ exit(1);
+ }
+ fname = argc[1];
+ kargs = argc[2];
+
+ outfd = open(fname, O_RDWR | O_CREAT | O_TRUNC,
+ S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH);
+ if (! (outfd > 0)) {
+ fprintf(stderr, "? cannot open %s as output\n", fname);
+ exit(1);
+ }
+
+ if (strlen(kargs) > BUFFER_LENGTH) {
+ fprintf(stderr, "? not enough space for the kernel args (%d)\n",
+ strlen(kargs));
+ exit(1);
+ }
+
+ /*
+ * map in the entire axf file to use as a template, then copy
+ * it all to the new location, except for the bits we need to
+ * change
+ */
+ unsigned char *axf = NULL;
+ struct stat stat_buf;
+ off_t axf_size;
+ int count;
+ unsigned char *buf;
+
+ if (stat(AXF_FILE, &stat_buf) == 0) {
+ axf_size = stat_buf.st_size;
+ }
+ else {
+ fprintf(stderr, "? cannot stat %s (%d)\n", AXF_FILE, errno);
+ exit(1);
+ }
+
+ infd = open(AXF_FILE, O_RDONLY);
+ if (infd) {
+ axf = mmap(NULL, axf_size, PROT_READ, MAP_PRIVATE, infd, 0);
+ if (axf <= 0) {
+ fprintf(stderr, "? memory map failed (%d)\n", errno);
+ exit(1);
+ }
+
+ /* copy everything before the kernel args */
+ lseek(infd, 0, SEEK_SET);
+ lseek(outfd, 0, SEEK_SET);
+ write(outfd, axf, ARG_OFFSET);
+
+ /*
+ * replace the BUFFER_LENGTH space in the input axf file
+ * with the arguments we really want
+ */
+ buf = malloc(BUFFER_LENGTH + 1);
+ memset(buf, ' ', BUFFER_LENGTH);
+ memcpy(buf, kargs, strlen(kargs));
+ write(outfd, buf, BUFFER_LENGTH);
+
+ /* copy everything after the kernel args */
+ write(outfd, axf + ARG_OFFSET + BUFFER_LENGTH,
+ axf_size - (ARG_OFFSET + BUFFER_LENGTH));
+
+ close(outfd);
+ free(buf);
+ munmap(axf, axf_size);
+ close(infd);
+ }
+ else {
+ fprintf(stderr, "? cannot open %s as input\n", AXF_FILE);
+ exit(1);
+ }
+}
+