#include #include #include "system.h" #include #include #include #include #include #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; }