diff --git a/contrib/bochs/.cvsignore b/contrib/bochs/.cvsignore index baadb8c9..a5a930a3 100644 --- a/contrib/bochs/.cvsignore +++ b/contrib/bochs/.cvsignore @@ -2,4 +2,4 @@ bochsout.txt parport.out ne2k-tx.log ne2k-txdump.txt - +tunctl diff --git a/contrib/bochs/Makefile b/contrib/bochs/Makefile index 3c0e645a..4a5b14ce 100644 --- a/contrib/bochs/Makefile +++ b/contrib/bochs/Makefile @@ -1,7 +1,10 @@ -all : serial-console.1 +all : tunctl serial-console.1 %.1 : % pod2man $< > $@ +tunctl : tunctl.c + $(CC) -o $@ $< + clean : - rm -f serial-console.1 + rm -f serial-console.1 tunctl diff --git a/contrib/bochs/README b/contrib/bochs/README index 8495e3ca..fd4b821d 100644 --- a/contrib/bochs/README +++ b/contrib/bochs/README @@ -14,25 +14,28 @@ but it doesn't seem to quite work.) To get bochs running is fairly simple: -1. Get the bochs source code: +1. Build the utilities in this directory + make + +2. Get the bochs source code: cvs -d:pserver:anonymous@cvs.sourceforge.net:/cvsroot/bochs login cvs -d:pserver:anonymous@cvs.sourceforge.net:/cvsroot/bochs co bochs -2. Configure bochs with +3. Configure bochs with pushd bochs ./configure --enable-all-optimisations --enable-pci --enable-pnic --enable-debugger --enable-magic-breakpoints --enable-disasm popd -3. Build bochs: +4. Build bochs: make -C bochs -4. Set up a TAP virtual network device: +5. Set up a TAP virtual network device: modprobe tun - tunctl -u -t tap0 + ./tunctl -u -t tap0 ifconfig tap0 up 10.254.254.2 netmask 255.255.255.0 -5. Add the following fragment to /etc/dhcpd.conf: +6. Add the following fragment to /etc/dhcpd.conf: subnet 10.254.254.0 netmask 255.255.255.252 { range dynamic-bootp 10.254.254.1 10.254.254.1; } @@ -42,15 +45,15 @@ To get bochs running is fairly simple: machine you are using for running Bochs. If not, then you're on your own. -6. Restart dhcpd +7. Restart dhcpd /etc/init.d/dhcpd restart -7. Build Etherboot images +8. Build Etherboot images pushd ../../src make bin/pnic.dsk popd -8. Start Bochs +9. Start Bochs ./bochs/bochs -q You should get to the debugger prompt "". Type "c" to start running Bochs. diff --git a/contrib/bochs/tunctl.c b/contrib/bochs/tunctl.c new file mode 100644 index 00000000..6e439060 --- /dev/null +++ b/contrib/bochs/tunctl.c @@ -0,0 +1,113 @@ +/* Copyright 2002 Jeff Dike + * Licensed under the GPL + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static void Usage(char *name) +{ + fprintf(stderr, "Create: %s [-b] [-u owner] [-t device-name] " + "[-f tun-clone-device]\n", name); + fprintf(stderr, "Delete: %s -d device-name [-f tun-clone-device]\n\n", + name); + fprintf(stderr, "The default tun clone device is /dev/net/tun - some systems" + " use\n/dev/misc/net/tun instead\n\n"); + fprintf(stderr, "-b will result in brief output (just the device name)\n"); + exit(1); +} + +int main(int argc, char **argv) +{ + struct ifreq ifr; + struct passwd *pw; + long owner = geteuid(); + int tap_fd, opt, delete = 0, brief = 0; + char *tun = "", *file = "/dev/net/tun", *name = argv[0], *end; + + while((opt = getopt(argc, argv, "bd:f:t:u:")) > 0){ + switch(opt) { + case 'b': + brief = 1; + break; + case 'd': + delete = 1; + tun = optarg; + break; + case 'f': + file = optarg; + break; + case 'u': + pw = getpwnam(optarg); + if(pw != NULL){ + owner = pw->pw_uid; + break; + } + owner = strtol(optarg, &end, 0); + if(*end != '\0'){ + fprintf(stderr, "'%s' is neither a username nor a numeric uid.\n", + optarg); + Usage(name); + } + break; + case 't': + tun = optarg; + break; + case 'h': + default: + Usage(name); + } + } + + argv += optind; + argc -= optind; + + if(argc > 0) + Usage(name); + + if((tap_fd = open(file, O_RDWR)) < 0){ + fprintf(stderr, "Failed to open '%s' : ", file); + perror(""); + exit(1); + } + + memset(&ifr, 0, sizeof(ifr)); + + ifr.ifr_flags = IFF_TAP | IFF_NO_PI; + strncpy(ifr.ifr_name, tun, sizeof(ifr.ifr_name) - 1); + if(ioctl(tap_fd, TUNSETIFF, (void *) &ifr) < 0){ + perror("TUNSETIFF"); + exit(1); + } + + if(delete){ + if(ioctl(tap_fd, TUNSETPERSIST, 0) < 0){ + perror("TUNSETPERSIST"); + exit(1); + } + printf("Set '%s' nonpersistent\n", ifr.ifr_name); + } + else { + if(ioctl(tap_fd, TUNSETPERSIST, 1) < 0){ + perror("TUNSETPERSIST"); + exit(1); + } + if(ioctl(tap_fd, TUNSETOWNER, owner) < 0){ + perror("TUNSETPERSIST"); + exit(1); + } + if(brief) + printf("%s\n", ifr.ifr_name); + else printf("Set '%s' persistent and owned by uid %ld\n", ifr.ifr_name, + owner); + } + return(0); +}