This source file includes following definitions.
- die
- comp
- main
1
2
3
4
5
6 #include <string.h>
7 #include <stdio.h>
8 #include <unistd.h>
9 #include <fcntl.h>
10
11 #include <a.out.h>
12
13 #include <asm/system.h>
14
15 #define MAXSECT 10
16 #define MAXBUF 8192
17
18 int verbose = 0;
19 int pad = 0;
20 char * program = "tools/build";
21 char buffer[MAXBUF];
22 unsigned long bootblock[64];
23 struct filehdr fhdr;
24 struct aouthdr ahdr;
25 struct scnhdr shdr[MAXSECT];
26
27 char * usage = "'build [-b] system > secondary' or 'build > primary'";
28
29 static void die(char * str)
30 {
31 fprintf(stderr,"%s: %s\n", program, str);
32 exit(1);
33 }
34
35 static int comp(struct scnhdr * a, struct scnhdr * b)
36 {
37 return a->s_vaddr - b->s_vaddr;
38 }
39
40 int main(int argc, char ** argv)
41 {
42 int fd, i;
43 unsigned long tmp, start;
44 unsigned long system_start, system_size;
45 char * infile = NULL;
46
47 system_start = START_ADDR;
48 system_size = START_SIZE;
49 if (argc) {
50 program = *(argv++);
51 argc--;
52 }
53 while (argc > 0) {
54 if (**argv == '-') {
55 while (*++*argv) {
56 switch (**argv) {
57 case 'b':
58 system_start = BOOT_ADDR;
59 system_size = BOOT_SIZE;
60 pad = 1;
61 break;
62 case 'v':
63 verbose++;
64 break;
65 default:
66 die(usage);
67 }
68 }
69 } else if (infile)
70 die(usage);
71 else
72 infile = *argv;
73 argv++;
74 argc--;
75 }
76 if (!infile) {
77 memcpy(bootblock, "Linux Test", 10);
78 bootblock[60] = BOOT_SIZE / 512;
79 bootblock[61] = 1;
80 bootblock[62] = 0;
81 tmp = 0;
82 for (i = 0 ; i < 63 ; i++)
83 tmp += bootblock[i];
84 bootblock[63] = tmp;
85 if (write(1, (char *) bootblock, 512) != 512) {
86 perror("bbwrite");
87 exit(1);
88 }
89 return 0;
90 }
91 fd = open(infile, O_RDONLY);
92 if (fd < 0) {
93 perror(infile);
94 exit(1);
95 }
96 if (read(fd, &fhdr, sizeof(struct filehdr)) != sizeof(struct filehdr))
97 die("unable to read file header");
98 if (fhdr.f_nscns > MAXSECT)
99 die("Too many sections");
100 if (fhdr.f_opthdr != AOUTHSZ)
101 die("optional header doesn't look like a.out");
102 if (read(fd, &ahdr, sizeof(struct aouthdr)) != sizeof(struct aouthdr))
103 die("unable to read a.out header");
104 for (i = 0 ; i < fhdr.f_nscns ; i++) {
105 if (read(fd, i+shdr, sizeof(struct scnhdr)) != sizeof(struct scnhdr))
106 die("unable to read section header");
107 if (shdr[i].s_paddr != shdr[i].s_vaddr)
108 die("unable to handle different phys/virt addresses");
109 if (shdr[i].s_relptr)
110 die("Unable to handle relocation info");
111 if (verbose) {
112 fprintf(stderr, "section %d (%.8s):\t%lx - %lx (at %x)\n",
113 i, shdr[i].s_name,
114 shdr[i].s_vaddr,
115 shdr[i].s_vaddr + shdr[i].s_size,
116 shdr[i].s_scnptr);
117 }
118 }
119 qsort(shdr, fhdr.f_nscns, sizeof(shdr[1]), comp);
120 start = system_start;
121 for (i = 0 ; i < fhdr.f_nscns ; i++) {
122 unsigned long size, offset;
123 memset(buffer, 0, MAXBUF);
124 if (!strcmp(shdr[i].s_name, ".comment"))
125 continue;
126 if (shdr[i].s_vaddr != start)
127 die("Unordered or badly placed segments");
128 size = shdr[i].s_size;
129 start += size;
130 offset = shdr[i].s_scnptr;
131 if (lseek(fd, offset, SEEK_SET) != offset)
132 die("Unable to seek in in-file");
133 while (size > 0) {
134 unsigned long num = size;
135 if (num > MAXBUF)
136 num = MAXBUF;
137 if (offset)
138 if (read(fd, buffer, num) != num)
139 die("partial read");
140 if (write(1, buffer, num) != num)
141 die("partial write");
142 size -= num;
143 }
144 if (verbose) {
145 fprintf(stderr, "section %d (%.8s):\t%lx - %lx (at %x)\n",
146 i, shdr[i].s_name,
147 shdr[i].s_vaddr,
148 shdr[i].s_vaddr + shdr[i].s_size,
149 shdr[i].s_scnptr);
150 }
151 }
152 if (start > system_start + system_size) {
153 fprintf(stderr, "Boot image too large\n");
154 exit(1);
155 }
156 if (pad) {
157 unsigned long count = (system_start + system_size) - start;
158 memset(buffer, 0, MAXBUF);
159 while (count > 0) {
160 int i = MAXBUF;
161 if (i > count)
162 i = count;
163 i = write(1, buffer, i);
164 if (i <= 0) {
165 perror("pad write");
166 exit(1);
167 }
168 count -= i;
169 }
170 }
171
172 return 0;
173 }