Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v2.6.22-rc3 241 lines 5.8 kB view raw
1/* 2 * Makes a prep bootable image which can be dd'd onto 3 * a disk device to make a bootdisk. Will take 4 * as input a elf executable, strip off the header 5 * and write out a boot image as: 6 * 1) default - strips elf header 7 * suitable as a network boot image 8 * 2) -pbp - strips elf header and writes out prep boot partition image 9 * cat or dd onto disk for booting 10 * 3) -asm - strips elf header and writes out as asm data 11 * useful for generating data for a compressed image 12 * -- Cort 13 * 14 * Modified for x86 hosted builds by Matt Porter <porter@neta.com> 15 * Modified for Sparc hosted builds by Peter Wahl <PeterWahl@web.de> 16 */ 17 18#include <stdio.h> 19#include <string.h> 20#include <stdlib.h> 21 22/* size of read buffer */ 23#define SIZE 0x1000 24 25/* 26 * Partition table entry 27 * - from the PReP spec 28 */ 29typedef struct partition_entry { 30 unsigned char boot_indicator; 31 unsigned char starting_head; 32 unsigned char starting_sector; 33 unsigned char starting_cylinder; 34 35 unsigned char system_indicator; 36 unsigned char ending_head; 37 unsigned char ending_sector; 38 unsigned char ending_cylinder; 39 40 unsigned char beginning_sector[4]; 41 unsigned char number_of_sectors[4]; 42} partition_entry_t; 43 44#define BootActive 0x80 45#define SystemPrep 0x41 46 47void copy_image(FILE *, FILE *); 48void write_prep_partition(FILE *, FILE *); 49void write_asm_data(FILE *, FILE *); 50 51unsigned int elfhdr_size = 65536; 52 53int main(int argc, char *argv[]) 54{ 55 FILE *in, *out; 56 int argptr = 1; 57 int prep = 0; 58 int asmoutput = 0; 59 60 if (argc < 3 || argc > 4) { 61 fprintf(stderr, "usage: %s [-pbp] [-asm] <boot-file> <image>\n", 62 argv[0]); 63 exit(-1); 64 } 65 66/* needs to handle args more elegantly -- but this is a small/simple program */ 67 68 /* check for -pbp */ 69 if (!strcmp(argv[argptr], "-pbp")) { 70 prep = 1; 71 argptr++; 72 } 73 74 /* check for -asm */ 75 if (!strcmp(argv[argptr], "-asm")) { 76 asmoutput = 1; 77 argptr++; 78 } 79 80 /* input file */ 81 if (!strcmp(argv[argptr], "-")) 82 in = stdin; 83 else if (!(in = fopen(argv[argptr], "r"))) 84 exit(-1); 85 argptr++; 86 87 /* output file */ 88 if (!strcmp(argv[argptr], "-")) 89 out = stdout; 90 else if (!(out = fopen(argv[argptr], "w"))) 91 exit(-1); 92 argptr++; 93 94 /* skip elf header in input file */ 95 /*if ( !prep )*/ 96 fseek(in, elfhdr_size, SEEK_SET); 97 98 /* write prep partition if necessary */ 99 if (prep) 100 write_prep_partition(in, out); 101 102 /* write input image to bootimage */ 103 if (asmoutput) 104 write_asm_data(in, out); 105 else 106 copy_image(in, out); 107 108 return 0; 109} 110 111void store_le32(unsigned int v, unsigned char *p) 112{ 113 p[0] = v; 114 p[1] = v >>= 8; 115 p[2] = v >>= 8; 116 p[3] = v >> 8; 117} 118 119void write_prep_partition(FILE *in, FILE *out) 120{ 121 unsigned char block[512]; 122 partition_entry_t pe; 123 unsigned char *entry = block; 124 unsigned char *length = block + 4; 125 long pos = ftell(in), size; 126 127 if (fseek(in, 0, SEEK_END) < 0) { 128 fprintf(stderr,"info failed\n"); 129 exit(-1); 130 } 131 size = ftell(in); 132 if (fseek(in, pos, SEEK_SET) < 0) { 133 fprintf(stderr,"info failed\n"); 134 exit(-1); 135 } 136 137 memset(block, '\0', sizeof(block)); 138 139 /* set entry point and boot image size skipping over elf header */ 140 store_le32(0x400/*+65536*/, entry); 141 store_le32(size-elfhdr_size+0x400, length); 142 143 /* sets magic number for msdos partition (used by linux) */ 144 block[510] = 0x55; 145 block[511] = 0xAA; 146 147 /* 148 * Build a "PReP" partition table entry in the boot record 149 * - "PReP" may only look at the system_indicator 150 */ 151 pe.boot_indicator = BootActive; 152 pe.system_indicator = SystemPrep; 153 /* 154 * The first block of the diskette is used by this "boot record" which 155 * actually contains the partition table. (The first block of the 156 * partition contains the boot image, but I digress...) We'll set up 157 * one partition on the diskette and it shall contain the rest of the 158 * diskette. 159 */ 160 pe.starting_head = 0; /* zero-based */ 161 pe.starting_sector = 2; /* one-based */ 162 pe.starting_cylinder = 0; /* zero-based */ 163 pe.ending_head = 1; /* assumes two heads */ 164 pe.ending_sector = 18; /* assumes 18 sectors/track */ 165 pe.ending_cylinder = 79; /* assumes 80 cylinders/diskette */ 166 167 /* 168 * The "PReP" software ignores the above fields and just looks at 169 * the next two. 170 * - size of the diskette is (assumed to be) 171 * (2 tracks/cylinder)(18 sectors/tracks)(80 cylinders/diskette) 172 * - unlike the above sector numbers, the beginning sector is zero-based! 173 */ 174#if 0 175 store_le32(1, pe.beginning_sector); 176#else 177 /* This has to be 0 on the PowerStack? */ 178 store_le32(0, pe.beginning_sector); 179#endif 180 181 store_le32(2*18*80-1, pe.number_of_sectors); 182 183 memcpy(&block[0x1BE], &pe, sizeof(pe)); 184 185 fwrite(block, sizeof(block), 1, out); 186 fwrite(entry, 4, 1, out); 187 fwrite(length, 4, 1, out); 188 /* set file position to 2nd sector where image will be written */ 189 fseek( out, 0x400, SEEK_SET ); 190} 191 192 193 194void copy_image(FILE *in, FILE *out) 195{ 196 char buf[SIZE]; 197 int n; 198 199 while ( (n = fread(buf, 1, SIZE, in)) > 0 ) 200 fwrite(buf, 1, n, out); 201} 202 203 204void 205write_asm_data(FILE *in, FILE *out) 206{ 207 int i, cnt, pos = 0; 208 unsigned int cksum = 0, val; 209 unsigned char *lp; 210 unsigned char buf[SIZE]; 211 size_t len; 212 213 fputs("\t.data\n\t.globl input_data\ninput_data:\n", out); 214 while ((len = fread(buf, 1, sizeof(buf), in)) > 0) { 215 cnt = 0; 216 lp = buf; 217 /* Round up to longwords */ 218 while (len & 3) 219 buf[len++] = '\0'; 220 for (i = 0; i < len; i += 4) { 221 if (cnt == 0) 222 fputs("\t.long\t", out); 223 fprintf(out, "0x%02X%02X%02X%02X", 224 lp[0], lp[1], lp[2], lp[3]); 225 val = *(unsigned long *)lp; 226 cksum ^= val; 227 lp += 4; 228 if (++cnt == 4) { 229 cnt = 0; 230 fprintf(out, " # %x \n", pos+i-12); 231 } else { 232 fputs(",", out); 233 } 234 } 235 if (cnt) 236 fputs("0\n", out); 237 pos += len; 238 } 239 fprintf(out, "\t.globl input_len\ninput_len:\t.long\t0x%x\n", pos); 240 fprintf(stderr, "cksum = %x\n", cksum); 241}