summaryrefslogtreecommitdiff
path: root/package/aboot/src/netabootwrap.c
diff options
context:
space:
mode:
Diffstat (limited to 'package/aboot/src/netabootwrap.c')
-rw-r--r--package/aboot/src/netabootwrap.c185
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;
+}
+
+
+