1 /* $Id: piggyback.c,v 1.4 2000/12/05 00:48:57 anton Exp $
2 Simple utility to make a single-image install kernel with initial ramdisk
3 for Sparc tftpbooting without need to set up nfs.
5 Copyright (C) 1996 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
6 Pete Zaitcev <zaitcev@yahoo.com> endian fixes for cross-compiles, 2000.
8 This program is free software; you can redistribute it and/or modify
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
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
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
20 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
30 #include <sys/types.h>
34 * Note: run this on an a.out kernel (use elftoaout for it),
35 * as PROM looks for a.out image only.
38 unsigned short ld2(char *p
)
40 return (p
[0] << 8) | p
[1];
43 unsigned int ld4(char *p
)
45 return (p
[0] << 24) | (p
[1] << 16) | (p
[2] << 8) | p
[3];
48 void st4(char *p
, unsigned int x
)
58 /* fs_img.gz is an image of initial ramdisk. */
59 fprintf(stderr
, "Usage: piggyback vmlinux.aout System.map fs_img.gz\n");
60 fprintf(stderr
, "\tKernel image will be modified in place.\n");
70 int main(int argc
,char **argv
)
72 static char aout_magic
[] = { 0x01, 0x03, 0x01, 0x07 };
73 unsigned char buffer
[1024], *q
, *r
;
74 unsigned int i
, j
, k
, start
, end
, offset
;
79 if (argc
!= 4) usage();
81 if (stat (argv
[3], &s
) < 0) die (argv
[3]);
82 map
= fopen (argv
[2], "r");
83 if (!map
) die(argv
[2]);
84 while (fgets (buffer
, 1024, map
)) {
85 if (!strcmp (buffer
+ 8, " T start\n") || !strcmp (buffer
+ 16, " T start\n"))
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);
92 fprintf (stderr
, "Could not determine start and end from System.map\n");
95 if ((image
= open(argv
[1],O_RDWR
)) < 0) die(argv
[1]);
96 if (read(image
,buffer
,512) != 512) die(argv
[1]);
97 if (memcmp (buffer
, "\177ELF", 4) == 0) {
98 q
= buffer
+ ld4(buffer
+ 28);
99 i
= ld4(q
+ 4) + ld4(buffer
+ 24) - ld4(q
+ 8);
100 if (lseek(image
,i
,0) < 0) die("lseek");
101 if (read(image
,buffer
,512) != 512) die(argv
[1]);
103 } else if (memcmp(buffer
, aout_magic
, 4) == 0) {
106 fprintf (stderr
, "Not ELF nor a.out. Don't blame me.\n");
110 i
+= (ld2(buffer
+ j
+ 2)<<2) - 512;
111 if (lseek(image
,i
,0) < 0) die("lseek");
112 if (read(image
,buffer
,1024) != 1024) die(argv
[1]);
113 for (q
= buffer
, r
= q
+ 512; q
< r
; q
+= 4) {
114 if (*q
== 'H' && q
[1] == 'd' && q
[2] == 'r' && q
[3] == 'S')
118 fprintf (stderr
, "Couldn't find headers signature in the kernel.\n");
121 offset
= i
+ (q
- buffer
) + 10;
122 if (lseek(image
, offset
, 0) < 0) die ("lseek");
125 st4(buffer
+ 4, 0x01000000);
126 st4(buffer
+ 8, (end
+ 32 + 4095) & ~4095);
127 st4(buffer
+ 12, s
.st_size
);
129 if (write(image
,buffer
+2,14) != 14) die (argv
[1]);
130 if (lseek(image
, k
- start
+ ((end
+ 32 + 4095) & ~4095), 0) < 0) die ("lseek");
131 if ((tail
= open(argv
[3],O_RDONLY
)) < 0) die(argv
[3]);
132 while ((i
= read (tail
,buffer
,1024)) > 0)
133 if (write(image
,buffer
,i
) != i
) die (argv
[1]);
134 if (close(image
) < 0) die("close");
135 if (close(tail
) < 0) die("close");