📄 mkprep.c
字号:
/* * Makes a prep bootable image which can be dd'd onto * a disk device to make a bootdisk. Will take * as input a elf executable, strip off the header * and write out a boot image as: * 1) default - strips elf header * suitable as a network boot image * 2) -pbp - strips elf header and writes out prep boot partition image * cat or dd onto disk for booting * 3) -asm - strips elf header and writes out as asm data * useful for generating data for a compressed image * -- Cort * * Modified for x86 hosted builds by Matt Porter <porter@neta.com> * Modified for Sparc hosted builds by Peter Wahl <PeterWahl@web.de> */#include <stdio.h>#include <string.h>#include <stdlib.h>/* size of read buffer */#define SIZE 0x1000/* * Partition table entry * - from the PReP spec */typedef struct partition_entry { unsigned char boot_indicator; unsigned char starting_head; unsigned char starting_sector; unsigned char starting_cylinder; unsigned char system_indicator; unsigned char ending_head; unsigned char ending_sector; unsigned char ending_cylinder; unsigned char beginning_sector[4]; unsigned char number_of_sectors[4];} partition_entry_t;#define BootActive 0x80#define SystemPrep 0x41void copy_image(FILE *, FILE *);void write_prep_partition(FILE *, FILE *);void write_asm_data(FILE *, FILE *);unsigned int elfhdr_size = 65536;int main(int argc, char *argv[]){ FILE *in, *out; int argptr = 1; int prep = 0; int asmoutput = 0; if (argc < 3 || argc > 4) { fprintf(stderr, "usage: %s [-pbp] [-asm] <boot-file> <image>\n", argv[0]); exit(-1); }/* needs to handle args more elegantly -- but this is a small/simple program */ /* check for -pbp */ if (!strcmp(argv[argptr], "-pbp")) { prep = 1; argptr++; } /* check for -asm */ if (!strcmp(argv[argptr], "-asm")) { asmoutput = 1; argptr++; } /* input file */ if (!strcmp(argv[argptr], "-")) in = stdin; else if (!(in = fopen(argv[argptr], "r"))) exit(-1); argptr++; /* output file */ if (!strcmp(argv[argptr], "-")) out = stdout; else if (!(out = fopen(argv[argptr], "w"))) exit(-1); argptr++; /* skip elf header in input file */ /*if ( !prep )*/ fseek(in, elfhdr_size, SEEK_SET); /* write prep partition if necessary */ if (prep) write_prep_partition(in, out); /* write input image to bootimage */ if (asmoutput) write_asm_data(in, out); else copy_image(in, out); return 0;}void store_le32(unsigned int v, unsigned char *p){ p[0] = v; p[1] = v >>= 8; p[2] = v >>= 8; p[3] = v >> 8;}void write_prep_partition(FILE *in, FILE *out){ unsigned char block[512]; partition_entry_t pe; unsigned char *entry = block; unsigned char *length = block + 4; long pos = ftell(in), size; if (fseek(in, 0, SEEK_END) < 0) { fprintf(stderr,"info failed\n"); exit(-1); } size = ftell(in); if (fseek(in, pos, SEEK_SET) < 0) { fprintf(stderr,"info failed\n"); exit(-1); } memset(block, '\0', sizeof(block)); /* set entry point and boot image size skipping over elf header */ store_le32(0x400/*+65536*/, entry); store_le32(size-elfhdr_size+0x400, length); /* sets magic number for msdos partition (used by linux) */ block[510] = 0x55; block[511] = 0xAA; /* * Build a "PReP" partition table entry in the boot record * - "PReP" may only look at the system_indicator */ pe.boot_indicator = BootActive; pe.system_indicator = SystemPrep; /* * The first block of the diskette is used by this "boot record" which * actually contains the partition table. (The first block of the * partition contains the boot image, but I digress...) We'll set up * one partition on the diskette and it shall contain the rest of the * diskette. */ pe.starting_head = 0; /* zero-based */ pe.starting_sector = 2; /* one-based */ pe.starting_cylinder = 0; /* zero-based */ pe.ending_head = 1; /* assumes two heads */ pe.ending_sector = 18; /* assumes 18 sectors/track */ pe.ending_cylinder = 79; /* assumes 80 cylinders/diskette */ /* * The "PReP" software ignores the above fields and just looks at * the next two. * - size of the diskette is (assumed to be) * (2 tracks/cylinder)(18 sectors/tracks)(80 cylinders/diskette) * - unlike the above sector numbers, the beginning sector is zero-based! */#if 0 store_le32(1, pe.beginning_sector);#else /* This has to be 0 on the PowerStack? */ store_le32(0, pe.beginning_sector);#endif store_le32(2*18*80-1, pe.number_of_sectors); memcpy(&block[0x1BE], &pe, sizeof(pe)); fwrite(block, sizeof(block), 1, out); fwrite(entry, 4, 1, out); fwrite(length, 4, 1, out); /* set file position to 2nd sector where image will be written */ fseek( out, 0x400, SEEK_SET );}void copy_image(FILE *in, FILE *out){ char buf[SIZE]; int n; while ( (n = fread(buf, 1, SIZE, in)) > 0 ) fwrite(buf, 1, n, out);}voidwrite_asm_data(FILE *in, FILE *out){ int i, cnt, pos = 0; unsigned int cksum = 0, val; unsigned char *lp; unsigned char buf[SIZE]; size_t len; fputs("\t.data\n\t.globl input_data\ninput_data:\n", out); while ((len = fread(buf, 1, sizeof(buf), in)) > 0) { cnt = 0; lp = buf; /* Round up to longwords */ while (len & 3) buf[len++] = '\0'; for (i = 0; i < len; i += 4) { if (cnt == 0) fputs("\t.long\t", out); fprintf(out, "0x%02X%02X%02X%02X", lp[0], lp[1], lp[2], lp[3]); val = *(unsigned long *)lp; cksum ^= val; lp += 4; if (++cnt == 4) { cnt = 0; fprintf(out, " # %x \n", pos+i-12); } else { fputs(",", out); } } if (cnt) fputs("0\n", out); pos += len; } fprintf(out, "\t.globl input_len\ninput_len:\t.long\t0x%x\n", pos); fprintf(stderr, "cksum = %x\n", cksum);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -