#!/usr/bin/perl
######################################################################
# 
# File: makepxfile
# 
# Description: Combine all the bits together for .px kernel binary
#              format.
# 
# Copyright (c) 2004 TiVo Inc.
# 
######################################################################

if ($#ARGV != 3) {
    die "usage: makepxfile <kernel info file> <kernel data file> <signature file> <px output file>";
}

$ifile = $ARGV[1];
if (-f $ifile){
    $ifilesize=(-s $ifile);
}
open ifile or die "couldn't open input file: $ifile\n";
read (ifile,$ibuf,$ifilesize) == $ifilesize or die("couldnt allocate\n");

$infofile = $ARGV[0];

open infofile or die "Couldn't open info file: $infofile\n";

$kerneloffset = <infofile>;
$kernelsize = <infofile>;
$kernelentry = <infofile>;
close infofile;

$haveSigfile = 1;
$sigsize = 0;

$sigfile = $ARGV[2];

if (-f $ifile){
    $sigsize=(-s $sigfile);
}

if ($sigsize > 0) {
    open sigfile or die "couldn't open signature file: $sigfile";
    read (sigfile,$sigbuf,$sigsize) == $sigsize
	or die "couldn't allocate sig\n";
    close sigfile;
}

$kerneloffset -= 32;
$kernelsize += 32;

#
# Compute image size
#

$extra_size = $ifilesize - $kernelsize;
$image_size = $ifilesize;
$total_size = $ifilesize + 32;   # account for the boot table
$total_size += $sigsize;         # and for the signature if present
$total_blocks = int(($total_size + 511) / 512);
$total_bytes = $total_blocks * 512;
$padding_bytes = $total_bytes - $total_size;


printf "Kernel   load address is 0x%08X\n", $kerneloffset;
printf "Kernel   image length is 0x%08X\n", $kernelsize;
printf "Checked-data   length is 0x%08X\n", $extra_size;
printf "Boot     image length is 0x%08X\n", $image_size;
printf "Signature      length is 0x%08X\n", $sigsize;
printf "Unpadded image length is 0x%08X\n", $total_size;
printf "Padding        length is 0x%08X\n", $padding_bytes;
printf "Padded   image length is 0x%08X\n", $total_bytes;


#
# Open output file
#
open ofile, "> $ARGV[3]" or die "no output file\n";

#
# Write px header
#
$header = pack "H8NNNNNNN", "0052504f", $kerneloffset, $total_blocks - 1,
    0, $kernelentry, $kernelsize, $ifilesize, 0;
    
syswrite ofile, $header, length($header) or die "couldnt write header to output file";


#
# Write image - everything originally extracted, plus signature
#

syswrite ofile, $ibuf, $image_size   or
    die "couldnt write image to output file\n";

if ($sigsize > 0) {
    syswrite ofile, $sigbuf, $sigsize   or
	die "couldnt write signature to output file\n";
}

#
# Pad to a multiple of 512 bytes if necessary
#
if  ($padding_bytes > 0) {
    $nullstring = pack ("H8","deadbeef") x 128;
    syswrite ofile, $nullstring, $padding_bytes;
}

close ofile;




