diff options
Diffstat (limited to 'package/aboot/src/netabootwrap.c')
-rw-r--r-- | package/aboot/src/netabootwrap.c | 185 |
1 files changed, 185 insertions, 0 deletions
diff --git a/package/aboot/src/netabootwrap.c b/package/aboot/src/netabootwrap.c new file mode 100644 index 000000000..aa49b43fd --- /dev/null +++ b/package/aboot/src/netabootwrap.c @@ -0,0 +1,185 @@ +#include <sys/types.h> +#include <asm/console.h> +#include "system.h" +#include <stdio.h> +#include <fcntl.h> +#include <string.h> +#include <sys/stat.h> +#include <unistd.h> +#include "netwrap.h" +#include "bootloader.h" + + +char *tfn="netboot.img", *kfn="vmlinux.gz", *ifn=NULL, *barg=NULL; +char *progname; + +void print_usage(void ) +{ + printf("Following shows options and default values or example value\n"); + printf("%s -t netboot.img -k vmlinux.gz -i initrd.gz -a \"root=/dev/hda1 single\"\n", progname); + exit(1); +} + +void open_file(char *fn, int *fd, int *sz) +{ + struct stat buf; + + *fd = open(fn, O_RDONLY); + if (fd < 0) { + fprintf(stderr, "%s: Cannot open %s\n", progname, fn); + print_usage(); + exit(1); + } + + fstat(*fd, &buf); + + if (buf.st_size <= 10*1024) { + fprintf(stderr, "%s:Is this a right file %s, size = %d\n", progname, fn, (int)buf.st_size); + print_usage(); + exit(1); + } + + *sz = buf.st_size; +} + +void append_file(int tfd, int sfd) +{ + char buf[4096]; + int red; + + while ((red=read(sfd, buf, 4096))) + write(tfd, buf, red); +} + +int main(int argc, char **argv) +{ + int tfd=0, kfd=0, ifd=0, ksz=0, isz=0; + struct header hdr; + char *stmp; + + progname=argv[0]; + + /* + * Read switches. + */ + for (argc--, argv++; argc > 0; argc--, argv++) { + if (argv[0][0] != '-') + break; + switch (argv[0][1]) { + + case 't': /* override target file name */ + if (argv[0][2]) { + stmp = &(argv[0][2]); + } else { + argc--; + argv++; + stmp = argv[0]; + } + if (!stmp) { + fprintf(stderr, + "%s: missing file name for target\n",progname); + break; + } + tfn = stmp; + break; + case 'k': /* override kernel name */ + if (argv[0][2]) { + stmp = &(argv[0][2]); + } else { + argc--; + argv++; + stmp = argv[0]; + } + if (!stmp) { + fprintf(stderr, + "%s: missing file name for kernel\n",progname); + break; + } + kfn = stmp; + break; + case 'i': /* override file name for initrd */ + if (argv[0][2]) { + stmp = &(argv[0][2]); + } else { + argc--; + argv++; + stmp = argv[0]; + } + if (!stmp) { + fprintf(stderr, + "%s: missing file name for initial RAM-disk\n",progname); + break; + } + ifn = stmp; + break; + case 'a': /* add kernel parameters */ + if (argv[0][2]) { + stmp = &(argv[0][2]); + } else { + argc--; + argv++; + stmp = argv[0]; + } + if (!stmp) { + fprintf(stderr, + "%s: No kernel parameters specified\n",progname); + break; + } + barg = stmp; + break; + default: + fprintf(stderr, "%s: unknown switch: -%c\n", + progname, argv[0][1]); + print_usage(); + break; + + } /* switch */ + } /* for args */ + + open_file(kfn, &kfd, &ksz); + + if (ifn) + open_file(ifn, &ifd, &isz); + + printf("Target file name is %s\n", tfn); + unlink(tfn); + tfd = open(tfn, O_RDWR|O_CREAT, 0644); + + write(tfd, bootloader, sizeof(bootloader)); + + hdr.header_size = sizeof(int)*3; + hdr.kern_size = ksz; + hdr.ird_size = isz; + + if (barg) printf("With kernel arguments : %s \n", barg); + else printf("Without kernel argument\n"); + + if (barg) { + if (strlen(barg) >= 200) { + printf("Kernel argument-list is too long\n"); + exit(1); + } + strncpy(hdr.boot_arg, barg, strlen(barg)+1); + hdr.header_size += strlen(barg)+1; + } + + lseek(tfd, align_512(sizeof(bootloader)), SEEK_SET); + write(tfd, &hdr, hdr.header_size); + + printf("Binding kernel %s\n", kfn); + lseek(tfd, align_512((unsigned long)lseek(tfd, 0, SEEK_CUR)), SEEK_SET); + append_file(tfd, kfd); + + if (ifn) { + printf("Binding initrd %s\n", ifn); + lseek(tfd, align_512((unsigned long)lseek(tfd, 0, SEEK_CUR)), SEEK_SET); + append_file(tfd, ifd); + } + + close(tfd); + printf("Done.\n"); + return 0; +} + + + |