patch-2.4.19 linux-2.4.19/arch/ppc/boot/utils/mkevimg
Next file: linux-2.4.19/arch/ppc/boot/utils/mkimage.wrapper
Previous file: linux-2.4.19/arch/ppc/boot/utils/Makefile
Back to the patch index
Back to the overall index
- Lines: 489
- Date:
Wed Dec 31 16:00:00 1969
- Orig file:
linux-2.4.18/arch/ppc/boot/utils/mkevimg
- Orig date:
Mon Jul 2 14:34:57 2001
diff -urN linux-2.4.18/arch/ppc/boot/utils/mkevimg linux-2.4.19/arch/ppc/boot/utils/mkevimg
@@ -1,488 +0,0 @@
-#!/usr/bin/perl
-
-#
-# Copyright (c) 1998-1999 TiVo, Inc.
-# All rights reserved.
-#
-# Copyright (c) 1999 Grant Erickson <grant@lcse.umn.edu>
-# Major syntactic and usability rework.
-#
-# Module name: mkevimg
-#
-# Description:
-# Converts an ELF output file from the linker into the format used by
-# the IBM evaluation board ROM Monitor to load programs from a host
-# onto the evaluation board. The ELF file must be an otherwise execut-
-# able file (with the text and data addresses bound at link time) and
-# have space reserved after the entry point for the load information
-# block:
-#
-# typedef struct boot_block {
-# unsigned long magic; 0x0052504F
-# unsigned long dest; Target address of the image
-# unsigned long num_512blocks; Size, rounded-up, in 512 byte blocks
-# unsigned long debug_flag; Run the debugger or image after load
-# unsigned long entry_point; The image address to jump to after load
-# unsigned long checksum; 32 bit checksum including header
-# unsigned long reserved[2];
-# } boot_block_t;
-#
-#
-
-use File::Basename;
-use Getopt::Std;
-
-#
-# usage()
-#
-# Description:
-# This routine prints out the proper command line usage for this program
-#
-# Input(s):
-# status - Flag determining what usage information will be printed and what
-# the exit status of the program will be after the information is
-# printed.
-#
-# Output(s):
-# N/A
-#
-# Returns:
-# This subroutine does not return.
-#
-
-sub usage {
- my($status);
- $status = $_[0];
-
- printf("Usage: %s [-hlvV] <ELF input file> <Evaluation board output file>\n",
- $program);
-
- if ($status != 0) {
- printf("Try `%s -h' for more information.\n", $program);
- }
-
- if ($status != 1) {
- print(" -c Put checksum in load information block.\n");
- print(" -h Print out this message and exit.\n");
- print(" -l Linux mode; if present, copy 'image' and 'initrd' sections.\n");
- print(" -v Verbose. Print out lots of ELF information.\n");
- print(" -V Print out version information and exit.\n");
- }
-
- exit($status);
-}
-
-#
-# version()
-#
-# Description:
-# This routine prints out program version information
-#
-# Input(s):
-# N/A
-#
-# Output(s):
-# N/A
-#
-# Returns:
-# This subroutine does not return.
-#
-
-sub version {
- print("mkevimg Version 1.1.0\n");
- print("Copyright (c) 1998-1999 TiVo, Inc.\n");
- print("Copyright (c) 1999 Grant Erickson <grant\@lcse.umn.edu>\n");
-
- exit (0);
-}
-
-#
-# file_check()
-#
-# Description:
-# This routine checks an input file to ensure that it exists, is a
-# regular file, and is readable.
-#
-# Input(s):
-# file - Input file to be checked.
-#
-# Output(s):
-# N/A
-#
-# Returns:
-# 0 if the file exists, is a regular file, and is readable, otherwise -1.
-#
-
-sub file_check {
- my($file);
- $file = $_[0];
-
- if (!(-e $file)) {
- printf("The file \"%s\" does not exist.\n", $file);
- return (-1);
- } elsif (!(-f $file)) {
- printf("The file \"%s\" is not a regular file.\n", $file);
- return (-1);
- } elsif (!(-r $file)) {
- printf("The file \"%s\" is not readable.\n", $file);
- return (-1);
- }
-
- return (0);
-}
-
-#
-# decode_options()
-#
-# Description:
-# This routine steps through the command-line arguments, parsing out
-# recognzied options.
-#
-# Input(s):
-# N/A
-#
-# Output(s):
-# N/A
-#
-# Returns:
-# N/A
-#
-
-sub decode_options {
-
- if (!getopts("chlvV")) {
- usage(1);
- }
-
- if ($opt_c) {
- $do_checksum = 1;
- }
-
- if ($opt_h) {
- usage(0);
- }
-
- if ($opt_l) {
- $linux = 1;
- }
-
- if ($opt_V) {
- version();
- exit (0);
- }
-
- if ($opt_v) {
- $verbose = 1;
- }
-
- if (!($ifile = shift(@ARGV))) {
- usage(1);
- }
-
- if (!($ofile = shift(@ARGV))) {
- usage (1);
- }
-
- if (file_check($ifile)) {
- exit(1);
- }
-
-}
-
-#
-# ELF file and section header field numbers
-#
-
-require '../utils/elf.pl';
-
-#
-# Main program body
-#
-
-{
- $program = basename($0);
-
- decode_options();
-
- open(ELF, "<$ifile") || die "Cannot open input file";
-
- $ifilesize = (-s $ifile);
-
- if ($verbose) {
- print("Output file: $ofile\n");
- print("Input file: $ifile, $ifilesize bytes.\n");
- }
-
- if (read(ELF, $ibuf, $ifilesize) != $ifilesize) {
- print("Failed to read input file!\n");
- exit(1);
- }
-
- #
- # Parse ELF header
- #
-
- @eh = unpack("a16n2N5n6", $ibuf);
-
- #
- # Make sure this is actually a PowerPC ELF file.
- #
-
- if (substr($eh[$e_ident], 0, 4) ne "\177ELF") {
- printf("The file \"%s\" is not an ELF file.\n", $ifile);
- exit (1);
- } elsif ($eh[$e_machine] != 20) {
- printf("The file \"%s\" is not a PowerPC ELF file.\n", $ifile);
- exit (1);
- }
-
- if ($verbose) {
- print("File header:\n");
- printf(" Identifier: %s\n", $eh[$e_ident]);
- printf(" Type: %d\n", $eh[$e_type]);
- printf(" Machine: %d\n", $eh[$e_machine]);
- printf(" Version: %d\n", $eh[$e_version]);
- printf(" Entry point: 0x%08x\n", $eh[$e_entry]);
- printf(" Program header offset: 0x%x\n", $eh[$e_phoff]);
- printf(" Section header offset: 0x%x\n", $eh[$e_shoff]);
- printf(" Flags: 0x%08x\n", $eh[$e_flags]);
- printf(" Header size: %d\n", $eh[$e_ehsize]);
- printf(" Program entry size: %d\n", $eh[$e_phentsize]);
- printf(" Program table entries: %d\n", $eh[$e_phnum]);
- printf(" Section header size: %d\n", $eh[$e_shentsize]);
- printf(" Section table entries: %d\n", $eh[$e_shnum]);
- printf(" String table section: %d\n", $eh[$e_shstrndx]);
- }
-
- #
- # Find the section header for the string table.
- #
-
- $strtable_section_offset = $eh[$e_shoff] +
- $eh[$e_shstrndx] * $eh[$e_shentsize];
-
- if ($verbose) {
- printf("String table section header offset: 0x%x\n",
- $strtable_section_offset);
- }
-
- #
- # Find the start of the string table.
- #
-
- @strh = unpack("N10", substr($ibuf, $strtable_section_offset,
- $eh[$e_shentsize]));
-
- if ($verbose) {
- printf("Section name strings start at: 0x%x, %d bytes.\n",
- $strh[$sh_offset], $strh[$sh_size]);
- }
-
- $names = substr($ibuf, $strh[$sh_offset], $strh[$sh_size]);
-
- # Grab each section header and find '.text' and '.bss' sections in
- # particular.
-
- if ($verbose) {
- print("Section headers:\n");
- print("Idx Name Size Address File off Algn\n");
- print("--- ------------------------ -------- -------- -------- ----\n");
- }
-
- $off = $eh[$e_shoff];
-
- for($i = 0; $i < $eh[$e_shnum]; $i++, $off += $eh[$e_shentsize]) {
- @sh = unpack("N10", substr($ibuf, $off, $eh[$e_shentsize]));
-
- # Take the first section name from the array returned by split.
-
- ($name) = split(/\000/, substr($names, $sh[$sh_name]));
-
- if ($verbose) {
- printf("%3d %-24s %8x %08x %08x %4d\n",
- $i, $name, $sh[$sh_size], $sh[$sh_addr],
- $sh[$sh_offset], $sh[$sh_addralign]);
- }
-
- # Attempt to find the .text and .bss sections
-
- if ($name =~ /^\.bss$/) {
- ($bss_addr, $bss_offset, $bss_size) =
- ($sh[$sh_addr], $sh[$sh_offset], $sh[$sh_size]);
-
- } elsif ($name =~ /^\.text$/) {
- ($text_addr, $text_offset, $text_size) =
- ($sh[$sh_addr], $sh[$sh_offset], $sh[$sh_size]);
-
- } elsif ($linux && ($name =~ /^\image$/)) {
- $image_found = 1;
-
- ($image_addr, $image_offset, $image_size) =
- ($sh[$sh_addr], $sh[$sh_offset], $sh[$sh_size]);
-
- } elsif ($linux && ($name =~ /^\initrd$/)) {
- $initrd_found = 1;
-
- ($initrd_addr, $initrd_offset, $initrd_size) =
- ($sh[$sh_addr], $sh[$sh_offset], $sh[$sh_size]);
-
- }
- }
-
- printf("Text section - Address: 0x%08x, Size: 0x%08x\n",
- $text_addr, $text_size);
- printf("Bss section - Address: 0x%08x, Size: 0x%08x\n",
- $bss_addr, $bss_size);
-
- if ($linux) {
- if ($image_found) {
- printf("Image section - Address: 0x%08x, Size: 0x%08x\n",
- $image_addr, $image_size);
- }
-
- if ($initrd_found) {
- printf("Initrd section - Address: 0x%08x, Size: 0x%08x\n",
- $initrd_addr, $initrd_size);
- }
- }
-
- #
- # Open output file
- #
-
- open(BOOT, ">$ofile") || die "Cannot open output file";
-
- #
- # Compute image size
- #
-
- $output_size = $bss_offset - $text_offset + $bss_size;
-
- if ($linux && $image_found) {
- $output_size += $image_size;
- }
-
- if ($linux && $initrd_found) {
- $output_size += $initrd_size;
- }
-
- #
- # Compute size with header
- #
-
- $header = pack("H8N7", "0052504f", 0, 0, 0, 0, 0, 0, 0);
- $num_blocks = ($output_size + length($header) + 511) / 512;
-
- #
- # Write IBM PowerPC evaluation board boot_block_t header
- #
-
- $header = pack("H8N7", "0052504f", $text_addr, $num_blocks, 0,
- $text_addr, 0, 0, 0);
-
-
- $bytes = length($header);
-
- if (($resid = syswrite(BOOT, $header, $bytes)) != $bytes) {
- die("Could not write boot image header to output file.");
- }
-
- printf("Entry point = 0x%08x\n", $text_addr);
- printf("Image size = 0x%08x (%d bytes) (%d blocks).\n",
- $output_size, $output_size, $num_blocks);
-
- #
- # Write image starting after ELF and program headers and
- # continuing to beginning of bss
- #
-
- $bytes = $bss_offset - $text_offset + $bss_size;
-
- if (($resid = syswrite(BOOT, $ibuf, $bytes, $text_offset)) != $bytes) {
- die("Could not write boot image to output file.\n");
- }
-
- #
- # If configured, write out the image and initrd sections as well
- #
-
- if ($linux) {
- if ($image_found) {
- $bytes = $image_size;
- if (($resid = syswrite(BOOT, $ibuf, $bytes, $image_offset)) != $bytes) {
- die("Could not write boot image to output file.\n");
- }
- }
-
- if ($initrd_found) {
- $bytes = $initrd_size;
- if (($resid = syswrite(BOOT, $ibuf, $bytes, $initrd_offset)) != $bytes) {
- die("Could not write boot image to output file.\n");
- }
- }
- }
-
- #
- # Pad to a multiple of 512 bytes
- # If the (size of the boot image mod 512) is between 509 and 511 bytes
- # then the tftp to the Walnut fails. This may be fixed in more recent
- # Walnut bootrom.
- #
-
- $pad_size = 512 - ((length($header) + $output_size) % 512);
- if ($pad_size == 512) {
- $pad_size = 0;
- }
-
- if ($pad_size != 0) {
-
- if ($verbose) {
- print("Padding boot image by an additional $pad_size bytes.\n");
- }
-
- $pad_string = pack("H8","deadbeef") x 128;
-
- syswrite(BOOT, $pad_string, $pad_size) or
- die "Could not pad boot image in output file.\n";
-
- }
-
- #
- # Compute 32 bit checksum over entire file.
- #
-
- if ($do_checksum) {
-
- close(BOOT);
- open(BOOT, "+<$ofile") || die "Cannot open output file";
- undef $/;
- $temp = unpack("%32N*", <BOOT>);
- # Solaris and PPC Linux return 0x80000000 for "-$temp" when $temp
- # is negative. "~($temp - 1)" negates $temp properly.
- $csum = ~($temp - 1);
- printf("Checksum = 0x%08x\r\n", $csum);
-
- #
- # Rewrite IBM PowerPC evaluation board boot_block_t header,
- # this time with the checksum included
- #
-
- $header = pack("H8N7", "0052504f", $text_addr, $num_blocks, 0,
- $text_addr, $csum, 0, 0);
-
- seek(BOOT, 0, 0);
- syswrite(BOOT, $header, length($header)) or
- die("Could not write boot image header to output file.");
-
- }
-
- #
- # Clean-up and leave
- #
-
- close(BOOT);
-
- print("\nBoot image file \"$ofile\" built successfully.\n\n");
-
- exit(0);
-}
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)