This source file includes following definitions.
- intel_long
- intel_short
- die
- usage
- main
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23 #include <stdio.h>
24 #include <string.h>
25 #include <stdlib.h>
26 #include <sys/types.h>
27 #include <sys/stat.h>
28 #include <sys/sysmacros.h>
29 #include <unistd.h>
30 #include <fcntl.h>
31 #include <linux/a.out.h>
32 #include <linux/config.h>
33 #include <errno.h>
34
35 #define MINIX_HEADER 32
36
37 #define N_MAGIC_OFFSET 1024
38 #ifndef __BFD__
39 static int GCC_HEADER = sizeof(struct exec);
40 #endif
41
42 #define SYS_SIZE DEF_SYSSIZE
43
44 #define DEFAULT_MAJOR_ROOT 0
45 #define DEFAULT_MINOR_ROOT 0
46
47
48
49 #define SETUP_SECTS 4
50
51 #define STRINGIFY(x) #x
52
53 typedef union {
54 long l;
55 short s[2];
56 char b[4];
57 } conv;
58
59 long intel_long(long l)
60 {
61 conv t;
62
63 t.b[0] = l & 0xff; l >>= 8;
64 t.b[1] = l & 0xff; l >>= 8;
65 t.b[2] = l & 0xff; l >>= 8;
66 t.b[3] = l & 0xff; l >>= 8;
67 return t.l;
68 }
69
70 short intel_short(short l)
71 {
72 conv t;
73
74 t.b[0] = l & 0xff; l >>= 8;
75 t.b[1] = l & 0xff; l >>= 8;
76 return t.s[0];
77 }
78
79 void die(const char * str)
80 {
81 fprintf(stderr,"%s\n",str);
82 exit(1);
83 }
84
85 void usage(void)
86 {
87 die("Usage: build bootsect setup system [rootdev] [> image]");
88 }
89
90 int main(int argc, char ** argv)
91 {
92 int i,c,id, sz;
93 unsigned long sys_size;
94 char buf[1024];
95 #ifndef __BFD__
96 struct exec *ex = (struct exec *)buf;
97 #endif
98 char major_root, minor_root;
99 struct stat sb;
100 unsigned char setup_sectors;
101
102 if ((argc < 4) || (argc > 5))
103 usage();
104 if (argc > 4) {
105 if (!strcmp(argv[4], "CURRENT")) {
106 if (stat("/", &sb)) {
107 perror("/");
108 die("Couldn't stat /");
109 }
110 major_root = major(sb.st_dev);
111 minor_root = minor(sb.st_dev);
112 } else if (strcmp(argv[4], "FLOPPY")) {
113 if (stat(argv[4], &sb)) {
114 perror(argv[4]);
115 die("Couldn't stat root device.");
116 }
117 major_root = major(sb.st_rdev);
118 minor_root = minor(sb.st_rdev);
119 } else {
120 major_root = 0;
121 minor_root = 0;
122 }
123 } else {
124 major_root = DEFAULT_MAJOR_ROOT;
125 minor_root = DEFAULT_MINOR_ROOT;
126 }
127 fprintf(stderr, "Root device is (%d, %d)\n", major_root, minor_root);
128 for (i=0;i<sizeof buf; i++) buf[i]=0;
129 if ((id=open(argv[1],O_RDONLY,0))<0)
130 die("Unable to open 'boot'");
131 if (read(id,buf,MINIX_HEADER) != MINIX_HEADER)
132 die("Unable to read header of 'boot'");
133 if (((long *) buf)[0]!=intel_long(0x04100301))
134 die("Non-Minix header of 'boot'");
135 if (((long *) buf)[1]!=intel_long(MINIX_HEADER))
136 die("Non-Minix header of 'boot'");
137 if (((long *) buf)[3] != 0)
138 die("Illegal data segment in 'boot'");
139 if (((long *) buf)[4] != 0)
140 die("Illegal bss in 'boot'");
141 if (((long *) buf)[5] != 0)
142 die("Non-Minix header of 'boot'");
143 if (((long *) buf)[7] != 0)
144 die("Illegal symbol table in 'boot'");
145 i=read(id,buf,sizeof buf);
146 fprintf(stderr,"Boot sector %d bytes.\n",i);
147 if (i != 512)
148 die("Boot block must be exactly 512 bytes");
149 if ((*(unsigned short *)(buf+510)) != (unsigned short)intel_short(0xAA55))
150 die("Boot block hasn't got boot flag (0xAA55)");
151 buf[508] = (char) minor_root;
152 buf[509] = (char) major_root;
153 i=write(1,buf,512);
154 if (i!=512)
155 die("Write call failed");
156 close (id);
157
158 if ((id=open(argv[2],O_RDONLY,0))<0)
159 die("Unable to open 'setup'");
160 if (read(id,buf,MINIX_HEADER) != MINIX_HEADER)
161 die("Unable to read header of 'setup'");
162 if (((long *) buf)[0]!=intel_long(0x04100301))
163 die("Non-Minix header of 'setup'");
164 if (((long *) buf)[1]!=intel_long(MINIX_HEADER))
165 die("Non-Minix header of 'setup'");
166 if (((long *) buf)[3] != 0)
167 die("Illegal data segment in 'setup'");
168 if (((long *) buf)[4] != 0)
169 die("Illegal bss in 'setup'");
170 if (((long *) buf)[5] != 0)
171 die("Non-Minix header of 'setup'");
172 if (((long *) buf)[7] != 0)
173 die("Illegal symbol table in 'setup'");
174 for (i=0 ; (c=read(id,buf,sizeof buf))>0 ; i+=c )
175 if (write(1,buf,c)!=c)
176 die("Write call failed");
177 if (c != 0)
178 die("read-error on 'setup'");
179 close (id);
180 setup_sectors = (unsigned char)((i + 511) / 512);
181
182 if (setup_sectors < SETUP_SECTS)
183 setup_sectors = SETUP_SECTS;
184 fprintf(stderr,"Setup is %d bytes.\n",i);
185 for (c=0 ; c<sizeof(buf) ; c++)
186 buf[c] = '\0';
187 while (i < setup_sectors * 512) {
188 c = setup_sectors * 512 - i;
189 if (c > sizeof(buf))
190 c = sizeof(buf);
191 if (write(1,buf,c) != c)
192 die("Write call failed");
193 i += c;
194 }
195
196 if ((id=open(argv[3],O_RDONLY,0))<0)
197 die("Unable to open 'system'");
198 #ifndef __BFD__
199 if (read(id,buf,GCC_HEADER) != GCC_HEADER)
200 die("Unable to read header of 'system'");
201 if (N_MAGIC(*ex) == ZMAGIC) {
202 GCC_HEADER = N_MAGIC_OFFSET;
203 lseek(id, GCC_HEADER, SEEK_SET);
204 } else if (N_MAGIC(*ex) != QMAGIC)
205 die("Non-GCC header of 'system'");
206 fprintf(stderr,"System is %d kB (%d kB code, %d kB data and %d kB bss)\n",
207 (ex->a_text+ex->a_data+ex->a_bss)/1024,
208 ex->a_text /1024,
209 ex->a_data /1024,
210 ex->a_bss /1024);
211 sz = N_SYMOFF(*ex) - GCC_HEADER + 4;
212 #else
213 if (fstat (id, &sb)) {
214 perror ("fstat");
215 die ("Unable to stat 'system'");
216 }
217 sz = sb.st_size;
218 fprintf (stderr, "System is %d kB\n", sz/1024);
219 #endif
220 sys_size = (sz + 15) / 16;
221 if (sys_size > SYS_SIZE)
222 die("System is too big");
223 while (sz > 0) {
224 int l, n;
225
226 l = sz;
227 if (l > sizeof(buf))
228 l = sizeof(buf);
229 if ((n=read(id, buf, l)) != l) {
230 if (n == -1)
231 perror(argv[1]);
232 else
233 fprintf(stderr, "Unexpected EOF\n");
234 die("Can't read 'system'");
235 }
236 if (write(1, buf, l) != l)
237 die("Write failed");
238 sz -= l;
239 }
240 close(id);
241 if (lseek(1, 497, 0) == 497) {
242 if (write(1, &setup_sectors, 1) != 1)
243 die("Write of setup sectors failed");
244 }
245 if (lseek(1,500,0) == 500) {
246 buf[0] = (sys_size & 0xff);
247 buf[1] = ((sys_size >> 8) & 0xff);
248 if (write(1, buf, 2) != 2)
249 die("Write failed");
250 }
251 return(0);
252 }