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

📄 mkboot.c

📁 Linux内核源代码 为压缩文件 是<<Linux内核>>一书中的源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
	while(size != 0) {		written = write(fd, buf, size);		if (written == -1) {			perror("Can't write to boot image");			exit(1);		}		size -= written;	}}static intusage(program_name)	char *program_name;{	fprintf(stderr, "Usage: %s infile outfile\n", program_name);	exit(0);}intmain(argc, argv)	int argc;	char *argv[];{	char *infile, *outfile;	struct stat ifstat;	off_t ifsize;	char *image;	int ifd, ofd, i, symtabix, strtabix;	Elf32_Ehdr eh;	Elf32_Phdr *ph;	Elf32_Shdr *sh;	unsigned long vaddr, entry, bss, kernel_entry, kernel_end;	unsigned char ahdr[32];	Elf32_Sym sym;	int	symnum;	char *symname;	/*	 * Verify some basic assuptions about type sizes made in this code	 */	if (sizeof(Elf32_Half) != 2) {		fprintf(stderr, "Fix mkboot: sizeof(Elf32_Half) != 2\n");		exit(1);	}	if (sizeof(Elf32_Word) != 4) {		fprintf(stderr, "Fix mkboot: sizeof(Elf32_Word) != 4\n");		exit(1);	}	if (sizeof(Elf32_Addr) != 4) {		fprintf(stderr, "Fix mkboot: sizeof(Elf32_Addr) != 4\n");		exit(1);	}	if (argc != 3)		usage(argv[0]);	infile = argv[1];	outfile = argv[2];	if (stat(infile, &ifstat) < 0) {		perror("Can't stat kernel image.");		exit(1);	}	if (!S_ISREG(ifstat.st_mode)) {		fprintf(stderr, "Input file isn't a regular file.\n");		exit(1);	}	ifsize = ifstat.st_size;	image = malloc((size_t)ifsize);	if (image == NULL) {		fprintf(stderr, "Can't allocate memory to read file\n");		exit(1);	}	/*	 * Read the entire input file in.	 */	ifd = open(infile, O_RDONLY);	if(ifd == 0) {		fprintf(stderr, "Can't open input file\n");		exit(1);	}	do_read(ifd, image, ifsize);	close(ifd);	/*	 * Now swap the ELF header in.  This is ugly but we the file	 * we're reading might have different type sizes, byteorder	 * or alignment than the host.	 */	memcpy(eh.e_ident, (void *)image, sizeof(eh.e_ident));	if(memcmp(eh.e_ident, ELFMAG, SELFMAG)) {		fprintf(stderr, "Input file isn't a ELF file\n");		exit(1);	}	if(eh.e_ident[EI_CLASS] != ELFCLASS32) {		fprintf(stderr, "Input file isn't a 32 bit ELF file\n");		exit(1);	}	if(eh.e_ident[EI_DATA] != ELFDATA2LSB) {		fprintf(stderr, "Input file isn't a little endian ELF file\n");		exit(1);	}	if(eh.e_ident[EI_VERSION] != EV_CURRENT) {		fprintf(stderr, "Input file isn't a version %d ELF file\n",		        EV_CURRENT);		exit(1);	}	/*	 * Ok, so far the file looks ok.  Now swap the rest of the header in	 * and do some more paranoia checks.	 */	eh.e_type      = get_Elf32_Half(image + 16);	eh.e_machine   = get_Elf32_Half(image + 18);	eh.e_version   = get_Elf32_Word(image + 20);	eh.e_entry     = get_Elf32_Addr(image + 24);	eh.e_phoff     = get_Elf32_Off(image + 28);	eh.e_shoff     = get_Elf32_Off(image + 32);	eh.e_flags     = get_Elf32_Word(image + 36);	eh.e_ehsize    = get_Elf32_Half(image + 40);	eh.e_phentsize = get_Elf32_Half(image + 42);	eh.e_phnum     = get_Elf32_Half(image + 44);	eh.e_shentsize = get_Elf32_Half(image + 46);	eh.e_shnum     = get_Elf32_Half(image + 48);	eh.e_shstrndx  = get_Elf32_Half(image + 50);	if(eh.e_type != ET_EXEC) {		fprintf(stderr, "Input file isn't a executable.\n");		exit(1);	}	if(eh.e_machine != EM_MIPS && eh.e_machine != EM_MIPS_RS4_BE) {		fprintf(stderr, "Input file isn't a MIPS executable.\n");		exit(1);	}	/*	 * Now read the program headers ...	 */	ph = malloc(sizeof(Elf32_Phdr) * eh.e_phnum);	if (ph == NULL) {		fprintf(stderr, "No memory for program header table.\n");		exit(1);	}	for(i = 0;i < eh.e_phnum; i++)		get_elfph((void *)(image + eh.e_phoff + i * 32), ph + i);	/*	 * ... and then the section headers.	 */	sh = malloc(sizeof(Elf32_Shdr) * eh.e_shnum);	if (sh == NULL) {		fprintf(stderr, "No memory for section header table.\n");		exit(1);	}	for(i = 0;i < eh.e_shnum; i++)		get_elfsh((void *)(image + eh.e_shoff + (i * 40)), sh + i);	/*	 * Find the symboltable and the stringtable in the file.	 */	for(i = 0;i < eh.e_shnum; i++) {		if (!strcmp (image + sh [eh.e_shstrndx].sh_offset + sh[i].sh_name,		             ".symtab")) {			symtabix = i;			continue;		}		if (!strcmp (image + sh [eh.e_shstrndx].sh_offset + sh[i].sh_name,		             ".strtab")) {			strtabix = i;			continue;		}	}	if (symtabix == -1) {		fprintf(stderr, "The executable doesn't have a symbol table\n");		exit(1);	}	if (strtabix == -1) {		fprintf(stderr, "The executable doesn't have a string table\n");		exit(1);	}	/*	 * Dig for the two required symbols in the symbol table.	 */	symnum = sh[symtabix].sh_size / 16;	for(i = 0;i < symnum;i++) {		get_elfsym(image + sh[symtabix].sh_offset + (i * 16), &sym);		symname = image + sh[strtabix].sh_offset + sym.st_name;		if (ELF32_ST_BIND(sym.st_info) != STB_GLOBAL)			continue;		if (ELF32_ST_TYPE(sym.st_info) != STT_NOTYPE &&		    ELF32_ST_TYPE(sym.st_info) != STT_OBJECT &&		    ELF32_ST_TYPE(sym.st_info) != STT_FUNC)			continue;		if (strcmp("kernel_entry", symname) == 0) {			kernel_entry = sym.st_value;			continue;		}		if (strcmp("_end", symname) == 0) {			kernel_end = sym.st_value;			continue;		}	}#ifdef VERBOSE	/*	 * And print what we will be loaded into memory.	 */	for(i = 0;i < eh.e_phnum; i++) {		if (ph[i].p_type != PT_LOAD) {			continue;		}		printf("  Offset: %08lx\n", ph[i].p_offset);		printf("  file size: %08lx\n", ph[i].p_filesz);		printf("  mem size: %08lx\n", ph[i].p_memsz);		printf("    Loading: %08lx - %08lx\n",		       ph[i].p_vaddr, ph[i].p_vaddr + ph[i].p_filesz);		printf("    Zero mapping: %08lx - %08lx\n",		       ph[i].p_vaddr + ph[i].p_filesz,		       ph[i].p_vaddr + ph[i].p_memsz);	}#endif	/*	 * Time to open the outputfile.	 */	ofd = open(outfile, O_WRONLY|O_CREAT|O_TRUNC, 0666);	if (ofd == -1) {		perror("Can't open boot image for output.");		exit(1);	}	/*	 * First compute the layout of the file.  We need to do this	 * first because we can't seek back to the beginning due to the	 * broken Seek() call in the Magnum firmware.	 */	entry = vaddr = 0xffffffff;	bss = 0;	for(i = 0;i < eh.e_phnum; i++) {		if (ph[i].p_type != PT_LOAD)			continue;		if (vaddr == 0xffffffff)			entry = vaddr = ph[i].p_vaddr;		vaddr = ph[i].p_vaddr + ph[i].p_filesz;		bss = ph[i].p_memsz - ph[i].p_filesz;	}	/*	 * In the next step we construct the boot image.  The boot file	 * looks essentially like a dump of the loaded kernel with a	 * minimal header.  Because Milo supports already a.out image	 * we simply dump the image in an a.out image ...  First let's	 * write the header.	 */	/*	 * Create and write the a.out header.	 */	put_word(ahdr, AOUT_INFO(OMAGIC, M_MIPS1, 0));	put_word(ahdr + 4, vaddr - entry);	/* text size */	put_word(ahdr + 8, 0);			/* data size */	put_word(ahdr + 12, bss);		/* bss size */	put_word(ahdr + 16, 2 * 12);		/* size of symbol table */	put_word(ahdr + 20, entry);		/* base address */	put_word(ahdr + 24, 0);			/* size of text relocations */	put_word(ahdr + 28, 0);			/* size of data relocations */	do_write(ofd, ahdr, 32);	/*	 * Write text and data segment combined into the a.out text segment	 * and a zero length data segment into the file.	 */	vaddr = 0xffffffff;	bss = 0;	for(i = 0;i < eh.e_phnum; i++) {		if (ph[i].p_type != PT_LOAD)			continue;		if (vaddr == 0xffffffff)			vaddr = ph[i].p_vaddr;		writepad(ofd, ph[i].p_vaddr - vaddr);	/* Write zero pad */		do_write(ofd, image + ph[i].p_offset, ph[i].p_filesz);		vaddr = ph[i].p_vaddr + ph[i].p_filesz;		bss = ph[i].p_memsz - ph[i].p_filesz;	}	/*	 * Now write the symbol table.  It has only two symbols,	 * kernel_entry and _end which we need for booting.	 */	put_word(ahdr    , 4);			/* n_un.n_strx */	put_byte(ahdr + 4, N_TEXT | N_EXT);	/* n_type */	put_byte(ahdr + 5, 0);			/* n_other */	put_half(ahdr + 6, 0);			/* n_desc */	put_word(ahdr + 8, kernel_entry);	/* n_value */	do_write(ofd, ahdr, 12);	put_word(ahdr    , 4 + 13);		/* n_un.n_strx */	put_byte(ahdr + 4, N_ABS | N_EXT);	/* n_type */	put_byte(ahdr + 5, 0);			/* n_other */	put_half(ahdr + 6, 0);			/* n_desc */	put_word(ahdr + 8, kernel_end);		/* n_value */	do_write(ofd, ahdr, 12);	/*	 * Now write stringtable size and the strings.	 */	put_word(ahdr, 4 + 20);	do_write(ofd, ahdr, 4);	do_write(ofd, "kernel_entry\0_end\0\0", 20);	/*	 * That's is all ...	 */	close(ofd);#ifdef VERBOSE	printf("Entry: %08lx\n", entry);	printf("Dumped image %08lx - %08lx\n", 0x80000000, vaddr);	printf("Extra bss at end: %08lx\n", bss);#endif	return 0;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -