aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sparc/boot
diff options
context:
space:
mode:
Diffstat (limited to 'arch/sparc/boot')
-rw-r--r--arch/sparc/boot/piggyback_32.c142
1 files changed, 102 insertions, 40 deletions
diff --git a/arch/sparc/boot/piggyback_32.c b/arch/sparc/boot/piggyback_32.c
index ac944aec7301..cfd95ec01f18 100644
--- a/arch/sparc/boot/piggyback_32.c
+++ b/arch/sparc/boot/piggyback_32.c
@@ -9,7 +9,7 @@
9 it under the terms of the GNU General Public License as published by 9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or 10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version. 11 (at your option) any later version.
12 12
13 This program is distributed in the hope that it will be useful, 13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of 14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
@@ -18,15 +18,16 @@
18 You should have received a copy of the GNU General Public License 18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software 19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ 20 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
21 21
22#include <stdio.h> 22#include <dirent.h>
23#include <stdlib.h>
23#include <string.h> 24#include <string.h>
25#include <unistd.h>
24#include <ctype.h> 26#include <ctype.h>
25#include <errno.h> 27#include <errno.h>
26#include <fcntl.h> 28#include <fcntl.h>
27#include <dirent.h> 29#include <stdio.h>
28#include <unistd.h> 30
29#include <stdlib.h>
30#include <sys/types.h> 31#include <sys/types.h>
31#include <sys/stat.h> 32#include <sys/stat.h>
32 33
@@ -35,16 +36,19 @@
35 * as PROM looks for a.out image only. 36 * as PROM looks for a.out image only.
36 */ 37 */
37 38
39/* read two bytes as big endian */
38static unsigned short ld2(char *p) 40static unsigned short ld2(char *p)
39{ 41{
40 return (p[0] << 8) | p[1]; 42 return (p[0] << 8) | p[1];
41} 43}
42 44
45/* read 4 bytes as big endian */
43static unsigned int ld4(char *p) 46static unsigned int ld4(char *p)
44{ 47{
45 return (p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3]; 48 return (p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3];
46} 49}
47 50
51/* save 4 bytes as big endian */
48static void st4(char *p, unsigned int x) 52static void st4(char *p, unsigned int x)
49{ 53{
50 p[0] = x >> 24; 54 p[0] = x >> 24;
@@ -53,6 +57,12 @@ static void st4(char *p, unsigned int x)
53 p[3] = x; 57 p[3] = x;
54} 58}
55 59
60static void die(const char *str)
61{
62 perror(str);
63 exit(1);
64}
65
56static void usage(void) 66static void usage(void)
57{ 67{
58 /* fs_img.gz is an image of initial ramdisk. */ 68 /* fs_img.gz is an image of initial ramdisk. */
@@ -61,10 +71,57 @@ static void usage(void)
61 exit(1); 71 exit(1);
62} 72}
63 73
64static void die(char *str) 74static int start_line(const char *line)
65{ 75{
66 perror (str); 76 if (strcmp(line + 8, " T start\n") == 0)
67 exit(1); 77 return 1;
78 else if (strcmp(line + 16, " T start\n") == 0)
79 return 1;
80 return 0;
81}
82
83static int end_line(const char *line)
84{
85 if (strcmp(line + 8, " A _end\n") == 0)
86 return 1;
87 else if (strcmp (line + 16, " A _end\n") == 0)
88 return 1;
89 return 0;
90}
91
92/*
93 * Find address for start and end in System.map.
94 * The file looks like this:
95 * f0004000 T start
96 * f0379f79 A _end
97 * 1234567890123456
98 * ^coloumn 1
99 * There is support for 64 bit addresses too.
100 *
101 * Return 0 if either start or end is not found
102 */
103static int get_start_end(const char *filename, unsigned int *start, unsigned int *end)
104{
105 FILE *map;
106 char buffer[1024];
107
108 *start = 0;
109 *end = 0;
110 map = fopen(filename, "r");
111 if (!map)
112 die(filename);
113 while (fgets(buffer, 1024, map)) {
114 if (start_line(buffer))
115 *start = strtoul(buffer, NULL, 16);
116 else if (end_line(buffer))
117 *end = strtoul(buffer, NULL, 16);
118 }
119 fclose (map);
120
121 if (*start == 0 || *end == 0)
122 return 0;
123
124 return 1;
68} 125}
69 126
70int main(int argc,char **argv) 127int main(int argc,char **argv)
@@ -72,33 +129,29 @@ int main(int argc,char **argv)
72 static char aout_magic[] = { 0x01, 0x03, 0x01, 0x07 }; 129 static char aout_magic[] = { 0x01, 0x03, 0x01, 0x07 };
73 char buffer[1024], *q, *r; 130 char buffer[1024], *q, *r;
74 unsigned int i, j, k, start, end, offset; 131 unsigned int i, j, k, start, end, offset;
75 FILE *map;
76 struct stat s; 132 struct stat s;
77 int image, tail; 133 int image, tail;
78 134
79 if (argc != 4) usage(); 135 if (argc != 4)
80 start = end = 0; 136 usage();
81 if (stat (argv[3], &s) < 0) die (argv[3]); 137 if (stat (argv[3], &s) < 0)
82 map = fopen (argv[2], "r"); 138 die(argv[3]);
83 if (!map) die(argv[2]); 139
84 while (fgets (buffer, 1024, map)) { 140 if (!get_start_end(argv[2], &start, &end)) {
85 if (!strcmp (buffer + 8, " T start\n") || !strcmp (buffer + 16, " T start\n")) 141 fprintf (stderr, "Could not determine start and end from %s\n", argv[2]);
86 start = strtoul (buffer, NULL, 16);
87 else if (!strcmp (buffer + 8, " A _end\n") || !strcmp (buffer + 16, " A _end\n"))
88 end = strtoul (buffer, NULL, 16);
89 }
90 fclose (map);
91 if (!start || !end) {
92 fprintf (stderr, "Could not determine start and end from System.map\n");
93 exit(1); 142 exit(1);
94 } 143 }
95 if ((image = open(argv[1],O_RDWR)) < 0) die(argv[1]); 144 if ((image = open(argv[1], O_RDWR)) < 0)
96 if (read(image,buffer,512) != 512) die(argv[1]); 145 die(argv[1]);
146 if (read(image, buffer, 512) != 512)
147 die(argv[1]);
97 if (memcmp (buffer, "\177ELF", 4) == 0) { 148 if (memcmp (buffer, "\177ELF", 4) == 0) {
98 q = buffer + ld4(buffer + 28); 149 q = buffer + ld4(buffer + 28);
99 i = ld4(q + 4) + ld4(buffer + 24) - ld4(q + 8); 150 i = ld4(q + 4) + ld4(buffer + 24) - ld4(q + 8);
100 if (lseek(image,i,0) < 0) die("lseek"); 151 if (lseek(image, i, 0) < 0)
101 if (read(image,buffer,512) != 512) die(argv[1]); 152 die("lseek");
153 if (read(image, buffer, 512) != 512)
154 die(argv[1]);
102 j = 0; 155 j = 0;
103 } else if (memcmp(buffer, aout_magic, 4) == 0) { 156 } else if (memcmp(buffer, aout_magic, 4) == 0) {
104 i = j = 32; 157 i = j = 32;
@@ -107,9 +160,11 @@ int main(int argc,char **argv)
107 exit(1); 160 exit(1);
108 } 161 }
109 k = i; 162 k = i;
110 i += (ld2(buffer + j + 2)<<2) - 512; 163 i += (ld2(buffer + j + 2) << 2) - 512;
111 if (lseek(image,i,0) < 0) die("lseek"); 164 if (lseek(image, i, 0) < 0)
112 if (read(image,buffer,1024) != 1024) die(argv[1]); 165 die("lseek");
166 if (read(image, buffer, 1024) != 1024)
167 die(argv[1]);
113 for (q = buffer, r = q + 512; q < r; q += 4) { 168 for (q = buffer, r = q + 512; q < r; q += 4) {
114 if (*q == 'H' && q[1] == 'd' && q[2] == 'r' && q[3] == 'S') 169 if (*q == 'H' && q[1] == 'd' && q[2] == 'r' && q[3] == 'S')
115 break; 170 break;
@@ -119,19 +174,26 @@ int main(int argc,char **argv)
119 exit(1); 174 exit(1);
120 } 175 }
121 offset = i + (q - buffer) + 10; 176 offset = i + (q - buffer) + 10;
122 if (lseek(image, offset, 0) < 0) die ("lseek"); 177 if (lseek(image, offset, 0) < 0)
178 die("lseek");
123 179
124 st4(buffer, 0); 180 st4(buffer, 0);
125 st4(buffer + 4, 0x01000000); 181 st4(buffer + 4, 0x01000000);
126 st4(buffer + 8, (end + 32 + 4095) & ~4095); 182 st4(buffer + 8, (end + 32 + 4095) & ~4095);
127 st4(buffer + 12, s.st_size); 183 st4(buffer + 12, s.st_size);
128 184
129 if (write(image,buffer+2,14) != 14) die (argv[1]); 185 if (write(image, buffer + 2, 14) != 14)
130 if (lseek(image, k - start + ((end + 32 + 4095) & ~4095), 0) < 0) die ("lseek"); 186 die(argv[1]);
131 if ((tail = open(argv[3],O_RDONLY)) < 0) die(argv[3]); 187 if (lseek(image, k - start + ((end + 32 + 4095) & ~4095), 0) < 0)
132 while ((i = read (tail,buffer,1024)) > 0) 188 die("lseek");
133 if (write(image,buffer,i) != i) die (argv[1]); 189 if ((tail = open(argv[3],O_RDONLY)) < 0)
134 if (close(image) < 0) die("close"); 190 die(argv[3]);
135 if (close(tail) < 0) die("close"); 191 while ((i = read (tail, buffer, 1024)) > 0)
136 return 0; 192 if (write(image, buffer, i) != i)
193 die(argv[1]);
194 if (close(image) < 0)
195 die("close");
196 if (close(tail) < 0)
197 die("close");
198 return 0;
137} 199}