#include #include #include #include #include #include "zlib.h" gzFile ZEXPORT gzopen (char*, char*); #define PAGE_SHIFT 12 #define PAGE_SIZE (1UL << PAGE_SHIFT) int main(int argc, char **argv) { gzFile in; Elf32_Ehdr elf_header; Elf32_Phdr *program_header; unsigned long min_addr, max_addr, kernel_size; int i; char * base; in = gzopen("vmlinux.gz", "rb"); gzread(in, &elf_header, sizeof(Elf32_Ehdr)); if (elf_header.e_machine != EM_68K) { fprintf(stderr, "Not MC680x0 architecture\n"); return 1; } if (elf_header.e_type != ET_EXEC) { fprintf(stderr, "Not an executable file\n"); return 2; } program_header = (Elf32_Phdr *)malloc(elf_header.e_phnum * sizeof (Elf32_Phdr)); if (program_header == NULL) { fprintf(stderr, "Cannot allocate memory\n"); return 3; } gzseek(in, elf_header.e_phoff, SEEK_SET); gzread(in, program_header, elf_header.e_phnum * sizeof(Elf32_Phdr)); min_addr = 0xffffffff; max_addr = 0; for (i = 0; i < elf_header.e_phnum; i++) { min_addr = (min_addr > program_header[i].p_vaddr) ? program_header[i].p_vaddr : min_addr; max_addr = (max_addr < program_header[i].p_vaddr + program_header[i].p_memsz) ? program_header[i].p_vaddr + program_header[i].p_memsz: max_addr; } if (min_addr == 0) { min_addr = PAGE_SIZE; program_header[0].p_vaddr += PAGE_SIZE; program_header[0].p_offset += PAGE_SIZE; program_header[0].p_filesz -= PAGE_SIZE; program_header[0].p_memsz -= PAGE_SIZE; } kernel_size = max_addr - min_addr; fprintf(stderr, "Kernel memory footprint: %ld\n", kernel_size); fprintf(stderr, "Base address: 0x%lx\n", min_addr); fprintf(stderr, "Entry point: 0x%lx\n", (long)elf_header.e_entry); base = (char*)malloc(kernel_size); memset(base, 0, kernel_size); for (i = 0; i < elf_header.e_phnum; i++) { fprintf(stderr, "Reading Program Section #%d, " "offset 0x%lx, (0x%lx,%lx)\n", i, (long)program_header[i].p_offset, program_header[i].p_vaddr - PAGE_SIZE, (long)program_header[i].p_filesz); gzseek(in, program_header[i].p_offset, SEEK_SET); gzread(in, base + program_header[i].p_vaddr - PAGE_SIZE, program_header[i].p_filesz); } write(STDOUT_FILENO, base, kernel_size); gzclose(in); return 0; }