bunch of work in progress on getting x86_64 bootstrap working.
[newos.git] / boot / x86_64 / makeflop.c
blob8cffaadcb52017af8243b5962d4a96afb1599eb7
1 /*
2 ** Copyright 2001, Travis Geiselbrecht. All rights reserved.
3 ** Distributed under the terms of the NewOS License.
4 */
5 #include <stdio.h>
6 #include <stdlib.h>
7 #include <sys/stat.h>
8 #include <unistd.h>
9 #include <fcntl.h>
11 #ifndef O_BINARY
12 #define O_BINARY 0
13 #endif
15 void usage(char const *progname)
17 printf("usage: %s [-p #padding] bootblock payload outfile\n", progname);
20 int main(int argc, char *argv[])
22 struct stat st;
23 int err;
24 unsigned int blocks;
25 unsigned char bootsector[1024];
26 unsigned char buf[512];
27 size_t read_size;
28 size_t written_bytes;
29 int padding;
30 int infd;
31 int outfd;
32 signed char opt;
33 char const *progname;
35 padding = 0;
36 progname = argv[0];
38 while( (opt = getopt(argc, argv, "p:")) != -1)
39 switch (opt) {
40 case 'p':
41 padding= atoi(optarg);
42 if (padding < 0) {
43 usage(progname);
44 return -1;
46 break;
47 case '?':
48 default:
49 usage(progname);
50 return -1;
52 argc -= optind - 1;
53 argv += optind - 1;
55 if(argc < 4) {
56 printf("insufficient args\n");
57 usage(progname);
58 return -1;
61 err = stat(argv[2], &st);
62 if(err < 0) {
63 printf("error stating file '%s'\n", argv[2]);
64 return -1;
67 outfd = open(argv[3], O_BINARY|O_WRONLY|O_CREAT|O_TRUNC, 0666);
68 if(outfd < 0) {
69 printf("error: cannot open output file '%s'\n", argv[3]);
70 return -1;
73 // first read the bootblock
74 infd = open(argv[1], O_BINARY|O_RDONLY);
75 if(infd < 0) {
76 printf("error: cannot open bootblock file '%s'\n", argv[1]);
77 return -1;
79 if(read(infd, bootsector, sizeof(bootsector)) < sizeof(bootsector)
80 || lseek(infd, 0, SEEK_END) != sizeof(bootsector)) {
81 printf ("error: size of bootblock file '%s' must match %d bytes.\n", argv[1], sizeof(bootsector));
82 return -1;
84 close(infd);
86 // patch the size of the output into bytes 3 & 4 of the bootblock
87 blocks = st.st_size / 512;
88 if((st.st_size % 512) != 0)
89 blocks++;
90 printf("size %d, blocks %d (size %d)\n", (unsigned long)st.st_size, blocks, blocks * 512);
91 bootsector[2] = (blocks & 0x00ff);
92 bootsector[3] = (blocks & 0xff00) >> 8;
94 write(outfd, bootsector, sizeof(bootsector));
95 written_bytes = sizeof(bootsector);
97 infd = open(argv[2], O_BINARY|O_RDONLY);
98 if(infd < 0) {
99 printf("error: cannot open input file '%s'\n", argv[1]);
100 return -1;
103 while((read_size = read(infd, buf, sizeof(buf))) > 0) {
104 write(outfd, buf, read_size);
105 written_bytes += read_size;
108 if (padding) {
109 if (written_bytes % padding) {
110 size_t towrite = padding - written_bytes % padding;
111 unsigned char *buf = malloc(towrite);
113 memset(buf, 0, towrite);
114 write(outfd, buf, towrite);
115 written_bytes+= towrite;
117 printf("output file padded to %ld\n", (unsigned long)written_bytes);
121 close(outfd);
122 close(infd);
124 return 0;