diff options
author | Al Stone <ahs3@redhat.com> | 2012-11-30 16:08:01 -0700 |
---|---|---|
committer | Al Stone <ahs3@redhat.com> | 2012-11-30 16:08:01 -0700 |
commit | 7cfa935df23105fec704e7311ebdba410798c3d5 (patch) | |
tree | 63cae11b48c6f6eee4b5d2c7421f1c8bb8a3f7d0 | |
parent | 450a29d7bdee7e348754982541dbfd6f5be6072f (diff) | |
download | patch-axf-7cfa935df23105fec704e7311ebdba410798c3d5.tar.gz patch-axf-7cfa935df23105fec704e7311ebdba410798c3d5.tar.xz patch-axf-7cfa935df23105fec704e7311ebdba410798c3d5.zip |
first commit of the patch tool
Signed-off-by: Al Stone <ahs3@redhat.com>
-rw-r--r-- | Makefile | 21 | ||||
-rw-r--r-- | paxf.c | 129 |
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 $< + @@ -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); + } +} + |