⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mkprep.c

📁 linux内核源码
💻 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 + -