Skip to content

Instantly share code, notes, and snippets.

@quexy
Last active August 29, 2015 14:06
Show Gist options
  • Save quexy/19c504b8ead8d2520a6e to your computer and use it in GitHub Desktop.
Save quexy/19c504b8ead8d2520a6e to your computer and use it in GitHub Desktop.
QEMU for architecture-switching chroot (eg: initial RPi setup)
// based on: https://www.gentoo.org/proj/en/base/embedded/handbook/?part=1&chap=5
// build as: gcc -static qemu-arch-cpu.c -O3 -s -o /usr/bin/qemu-arch-cpu
// use like: ln -s /usr/bin/qemu-arch-cpu /usr/bin/qemu-arm-arm1176
#include <malloc.h>
#include <string.h>
#include <unistd.h>
char** parse_tuple(char* tuple) {
int pos = 0;
char** result = malloc(2 * sizeof(char*));
while (tuple[pos] != '-' && tuple[pos] != '\0') ++pos;
if (tuple[pos] == '\0') return NULL; else pos += 1;
result[0] = tuple + pos;
while (tuple[pos] != '-' && tuple[pos] != '\0') ++pos;
if (tuple[pos] == '\0') return NULL; else tuple[pos] = '\0';
result[1] = tuple + pos + 1;
return result;
}
char* create_name(char* arch) {
const char* qemu = "/usr/bin/qemu-";
int len = strlen(qemu) + strlen(arch) + 1;
char* result = (char*)malloc(len * sizeof(char));
if (result == NULL) return result;
sprintf(result, "%s%s", qemu, arch);
return result;
}
int main(int argc, char** argv, char** envp) {
char** newargv = NULL;
char** tuple = NULL;
newargv = malloc((argc + 3) * sizeof(char*));
if (newargv == NULL) return -1;
tuple = parse_tuple(argv[0]);
if (tuple == NULL) return -2;
newargv[0] = create_name(tuple[0]);
if (newargv[0] == NULL) return -1;
newargv[1] = "-cpu";
newargv[2] = tuple[1];
for (i = 0; i < argc - 1; ++i)
newargv[i + 3] = argv[i + 1];
newargv[argc + 2] = NULL;
return execve(newargv[0], newargv, envp);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment