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