📄 mkboot.c
字号:
/* * Make a bootable image from a Linux/MIPS kernel. * * This file is subject to the terms and conditions of the GNU General Public * License. See the file "COPYING" in the main directory of this archive * for more details. * * Copyright (C) 1996 by Ralf Baechle * * This file is written in plain Kernighan & Ritchie C as it has to run * on all crosscompile hosts no matter how braindead. This code might * also become part of Milo. It's therefore important that we don't use * seek because the Seek() call of the Magnum 4000 ARC BIOS is broken. */#include <stdio.h>#include <stdlib.h>#include <string.h>#include <errno.h>#include <sys/stat.h>#include <unistd.h>#include <fcntl.h>/* * Define this for verbose debugging output. */#undef VERBOSE/* * Don't use the host's elf.h - it might be using incompatible defines */#define EI_NIDENT 16/* * Basic ELF types. */typedef unsigned short Elf32_Half;typedef unsigned short Elf32_Section;typedef unsigned int Elf32_Word;typedef unsigned int Elf32_Addr;typedef unsigned int Elf32_Off;typedef struct{ unsigned char e_ident[EI_NIDENT]; /* Magic number and other info */ Elf32_Half e_type; /* Object file type */ Elf32_Half e_machine; /* Architecture */ Elf32_Word e_version; /* Object file version */ Elf32_Addr e_entry; /* Entry point virtual address */ Elf32_Off e_phoff; /* Program header table file offset */ Elf32_Off e_shoff; /* Section header table file offset */ Elf32_Word e_flags; /* Processor-specific flags */ Elf32_Half e_ehsize; /* ELF header size in bytes */ Elf32_Half e_phentsize; /* Program header table entry size */ Elf32_Half e_phnum; /* Program header table entry count */ Elf32_Half e_shentsize; /* Section header table entry size */ Elf32_Half e_shnum; /* Section header table entry count */ Elf32_Half e_shstrndx; /* Section header string table index */} Elf32_Ehdr;/* * ELF magic number */#define ELFMAG "\177ELF"#define SELFMAG 4#define EI_CLASS 4 /* File class byte index */#define ELFCLASSNONE 0 /* Invalid class */#define ELFCLASS32 1 /* 32-bit objects */#define ELFCLASS64 2 /* 64-bit objects */#define EI_DATA 5 /* Data encoding byte index */#define ELFDATA2LSB 1 /* 2's complement, little endian */#define ELFDATA2MSB 2 /* 2's complement, big endian */#define EI_VERSION 6 /* File version byte index */#define EV_CURRENT 1 /* Current version *//* * Acceptable machine type in e_machine. */#define EM_MIPS 8 /* MIPS R3000 big-endian */#define EM_MIPS_RS4_BE 10 /* MIPS R4000 big-endian *//* * The type of ELF file we accept. */#define ET_EXEC 2 /* Executable file *//* * Definition of a single program header structure */typedef struct{ Elf32_Word p_type; /* Segment type */ Elf32_Off p_offset; /* Segment file offset */ Elf32_Addr p_vaddr; /* Segment virtual address */ Elf32_Addr p_paddr; /* Segment physical address */ Elf32_Word p_filesz; /* Segment size in file */ Elf32_Word p_memsz; /* Segment size in memory */ Elf32_Word p_flags; /* Segment flags */ Elf32_Word p_align; /* Segment alignment */} Elf32_Phdr;/* * Legal values for p_type */#define PT_NULL 0 /* Program header table entry unused */#define PT_LOAD 1 /* Loadable program segment */#define PT_DYNAMIC 2 /* Dynamic linking information */#define PT_INTERP 3 /* Program interpreter */#define PT_NOTE 4 /* Auxiliary information */#define PT_SHLIB 5 /* Reserved */#define PT_PHDR 6 /* Entry for header table itself */#define PT_NUM 7 /* Number of defined types. */#define PT_LOPROC 0x70000000 /* Start of processor-specific */#define PT_HIPROC 0x7fffffff /* End of processor-specific */typedef struct{ Elf32_Word sh_name; /* Section name (string tbl index) */ Elf32_Word sh_type; /* Section type */ Elf32_Word sh_flags; /* Section flags */ Elf32_Addr sh_addr; /* Section virtual addr at execution */ Elf32_Off sh_offset; /* Section file offset */ Elf32_Word sh_size; /* Section size in bytes */ Elf32_Word sh_link; /* Link to another section */ Elf32_Word sh_info; /* Additional section information */ Elf32_Word sh_addralign; /* Section alignment */ Elf32_Word sh_entsize; /* Entry size if section holds table */} Elf32_Shdr;typedef struct{ Elf32_Word st_name; /* Symbol name (string tbl index) */ Elf32_Addr st_value; /* Symbol value */ Elf32_Word st_size; /* Symbol size */ unsigned char st_info; /* Symbol type and binding */ unsigned char st_other; /* No defined meaning, 0 */ Elf32_Section st_shndx; /* Section index */} Elf32_Sym;/* How to extract and insert information held in the st_info field. */#define ELF32_ST_BIND(val) (((unsigned char) (val)) >> 4)#define ELF32_ST_TYPE(val) ((val) & 0xf)/* Legal values for ST_BIND subfield of st_info (symbol binding). */#define STB_GLOBAL 1 /* Global symbol *//* Legal values for ST_TYPE subfield of st_info (symbol type). */#define STT_NOTYPE 0 /* Symbol type is unspecified */#define STT_OBJECT 1 /* Symbol is a data object */#define STT_FUNC 2 /* Symbol is a code object */static unsigned intget_Elf32_Half(unsigned char *p){ return p[0] | (p[1] << 8);}#define get_Elf32_Section(p) get_Elf32_Half(p)static unsigned intget_Elf32_Word(unsigned char *p){ return p[0] | (p[1] << 8) | (p[2] << 16) | (p[3] << 24);}#define get_Elf32_Addr(p) get_Elf32_Word(p)#define get_Elf32_Off(p) get_Elf32_Word(p)static voidput_byte(p, x) unsigned char *p; unsigned char x;{ p[0] = x;}static voidput_half(p, x) unsigned char *p; unsigned short x;{ p[0] = x & 0xff; p[1] = (x >> 8) & 0xff;}static voidput_word(p, x) unsigned char *p; unsigned long x;{ p[0] = x & 0xff; p[1] = (x >> 8) & 0xff; p[2] = (x >> 16) & 0xff; p[3] = (x >> 24) & 0xff;}/* * Swap a program header in. */static voidget_elfph(p, ph) unsigned char *p; Elf32_Phdr *ph;{ ph->p_type = get_Elf32_Word(p); ph->p_offset = get_Elf32_Off(p + 4); ph->p_vaddr = get_Elf32_Addr(p + 8); ph->p_paddr = get_Elf32_Addr(p + 12); ph->p_filesz = get_Elf32_Word(p + 16); ph->p_memsz = get_Elf32_Word(p + 20); ph->p_flags = get_Elf32_Word(p + 24); ph->p_align = get_Elf32_Word(p + 28);}/* * Swap a section header in. */static voidget_elfsh(p, sh) unsigned char *p; Elf32_Shdr *sh;{ sh->sh_name = get_Elf32_Word(p); sh->sh_type = get_Elf32_Word(p + 4); sh->sh_flags = get_Elf32_Word(p + 8); sh->sh_addr = get_Elf32_Addr(p + 12); sh->sh_offset = get_Elf32_Off(p + 16); sh->sh_size = get_Elf32_Word(p + 20); sh->sh_link = get_Elf32_Word(p + 24); sh->sh_info = get_Elf32_Word(p + 28); sh->sh_addralign = get_Elf32_Word(p + 32); sh->sh_entsize = get_Elf32_Word(p + 36);}/* * Swap a section header in. */static voidget_elfsym(p, sym) unsigned char *p; Elf32_Sym *sym;{ sym->st_name = get_Elf32_Word(p); sym->st_value = get_Elf32_Addr(p + 4); sym->st_size = get_Elf32_Word(p + 8); sym->st_info = *(p + 12); sym->st_other = *(p + 13); sym->st_shndx = get_Elf32_Section(p + 14);}/* * The a.out magic number */#define OMAGIC 0407 /* Code indicating object file or impure executable. */#define M_MIPS1 151 /* MIPS R3000/R3000 binary */#define M_MIPS2 152 /* MIPS R6000/R4000 binary *//* * Compute and return an a.out magic number. */#define AOUT_INFO(magic, type, flags) \ (((magic) & 0xffff) | \ (((int)(type) & 0xff) << 16) | \ (((flags) & 0xff) << 24))/* * a.out symbols */#define N_UNDF 0#define N_ABS 2#define N_TEXT 4#define N_DATA 6#define N_BSS 8#define N_FN 15#define N_EXT 1#define min(x,y) (((x)<(y))?(x):(y))static voiddo_read(fd, buf, size) int fd; char *buf; ssize_t size;{ ssize_t rd; while(size != 0) { rd = read(fd, buf, size); if (rd == -1) { perror("Can't read from file."); exit(1); } size -= rd; }}static voidwritepad(fd, size) int fd; size_t size;{ static void *zeropage = NULL; ssize_t written; if (zeropage == NULL) { zeropage = malloc(4096); if (zeropage == NULL) { fprintf(stderr, "Couldn't allocate zero buffer.\n"); exit(1); } memset(zeropage, '\0', 4096); } while(size != 0) { written = write(fd, zeropage, min(4096, size)); if (written == -1) { perror("Can't write to boot image"); exit(1); } size -= written; }}static voiddo_write(fd, buf, size) int fd; char *buf; ssize_t size;{ ssize_t written;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -