#!/bin/sh
#
# Construct a PPC64 zImage file from the vmlinuz, System.map, config, initrd
# and zImage.stub files included in a kernel RPM
#
# Copyright (C) 2004 Red Hat, Inc. All Rights Reserved.
# Written by David Howells (dhowells@redhat.com)
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version
# 2 of the License, or (at your option) any later version.


if [ $# != 6 ]
    then
    echo "Usage: $0 <vmlinuz>|no <config>|no <sysmap>|no <initrd>|no <zImage.stub> <output>" >&2
    exit 2
fi

vmlinux="$1"
config="$2"
sysmap="$3"
initrd="$4"
zimagestub="$5"
output="$6"

if [ ! -f "$zimagestub" ]; then
    echo "zImage.stub $zimagestub does not exist"
    exit 1
fi

if  ! touch $output; then
    echo "unable to write to $output"
    exit 1
fi


for file in zImage.lds /usr/share/ppc64-utils/zImage.lds; do
    if [ -f $file ]; then
        LDS=$file
    fi
done

if [ -z "$LDS" ]; then
    echo "unable to find linker script"
    exit 1
fi

#
# delete temporary files at end
#
cleanup=

do_cleanup () {
    if [ -n "$cleanup" ]
	then
	echo CLEANING UP
	rm -fv $cleanup
    fi
}
trap do_cleanup 0

#
# decide what sections we want to add, and compress the contents-to-be
#
sections=

if [ "$vmlinux" != "no" ]
    then
    [ -f "$vmlinux" ] || { echo "vmlinux $vmlinux doesn't exist" ; exit 1; }
    type=`file $vmlinux`
    if expr "$type" : ".*gzip compressed data.*" >&/dev/null
	then
	file=$vmlinux
    else
	file=`mktemp /tmp/vmlinuz.gz.XXXXXX` || { echo $"could not make temp file"; exit 1; }
	cleanup="$cleanup $file"
	gzip -9 <$vmlinux >$file || exit
    fi
    sections="$sections\
	--add-section .kernel:vmlinux.strip=$file \
	--set-section-flags .kernel:vmlinux.strip=contents,alloc,load,readonly,data \
	"
fi

if [ "$config" != "no" ]
    then
    [ -f "$config" ] || { echo "config $config doesn't exist" ; exit 1; }
    type=`file $config`
    if expr "$type" : ".*gzip compressed data.*" >&/dev/null
	then
	file=$config
    else
	file=`mktemp /tmp/config.gz.XXXXXX` || { echo $"could not make temp file"; exit 1; }
	cleanup="$cleanup $file"
	gzip -9 <$config >$file || exit
    fi
    sections="$sections\
	--add-section .kernel:.config=$file \
	--set-section-flags .kernel:.config=contents,alloc,load,readonly,data \
	"
fi

if [ "$sysmap" != "no" ]
    then
    [ -f "$sysmap" ] || { echo "system map $sysmap doesn't exist" ; exit 1; }
    type=`file $sysmap`
    if expr "$type" : ".*gzip compressed data.*" >&/dev/null
	then
	file=$sysmap
    else
	file=`mktemp /tmp/sysmap.gz.XXXXXX` || { echo $"could not make temp file"; exit 1; }
	cleanup="$cleanup $file"
	gzip -9 <$sysmap >$file || exit
    fi
    sections="$sections\
	--add-section .kernel:System.map=$file \
	--set-section-flags .kernel:System.map=contents,alloc,load,readonly,data \
	"
fi

if [ "$initrd" != "no" ]
    then
    [ -f "$initrd" ] || { echo "initrd $initrd doesn't exist" ; exit 1; }
    type=`file $initrd`
    if expr "$type" : ".*gzip compressed data.*" >&/dev/null
	then
	file=$initrd
    else
	file=`mktemp /tmp/initrd.gz.XXXXXX` || { echo $"could not make temp file"; exit 1; }
	cleanup="$cleanup $file"
	gzip -9 <$initrd >$file || exit
    fi
    sections="$sections\
	--add-section .kernel:initrd=$file \
	--set-section-flags .kernel:initrd=contents,alloc,load,readonly,data \
	"
fi

#
# insert the requisite items into the object
#
bits=`mktemp /tmp/zImage.bits.XXXXXX` || { echo $"could not make temp file"; exit 1; }
cleanup="$cleanup $bits"
objcopy -F elf32-powerpc $zimagestub $bits $sections || exit

#
# link the whole thing together
#
cleanup2="$cleanup"
cleanup="$cleanup $output"
ld -m elf32ppclinux \
	-T $LDS \
	-o $output \
	$bits || exit
cleanup="$cleanup2"
