cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

genimage.sh (6655B)


      1#!/bin/bash
      2#
      3# This file is subject to the terms and conditions of the GNU General Public
      4# License.  See the file "COPYING" in the main directory of this archive
      5# for more details.
      6#
      7# Copyright (C) 2017 by Changbin Du <changbin.du@intel.com>
      8#
      9# Adapted from code in arch/x86/boot/Makefile by H. Peter Anvin and others
     10#
     11# "make fdimage/fdimage144/fdimage288/hdimage/isoimage"
     12# script for x86 architecture
     13#
     14# Arguments:
     15#   $1  - fdimage format
     16#   $2  - target image file
     17#   $3  - kernel bzImage file
     18#   $4  - mtools configuration file
     19#   $5  - kernel cmdline
     20#   $6+ - initrd image file(s)
     21#
     22# This script requires:
     23#   bash
     24#   syslinux
     25#   mtools (for fdimage* and hdimage)
     26#   edk2/OVMF (for hdimage)
     27#
     28# Otherwise try to stick to POSIX shell commands...
     29#
     30
     31# Use "make V=1" to debug this script
     32case "${KBUILD_VERBOSE}" in
     33*1*)
     34        set -x
     35        ;;
     36esac
     37
     38# Exit the top-level shell with an error
     39topshell=$$
     40trap 'exit 1' USR1
     41die() {
     42	echo ""        1>&2
     43	echo " *** $*" 1>&2
     44	echo ""        1>&2
     45	kill -USR1 $topshell
     46}
     47
     48# Verify the existence and readability of a file
     49verify() {
     50	if [ ! -f "$1" -o ! -r "$1" ]; then
     51		die "Missing file: $1"
     52	fi
     53}
     54
     55diskfmt="$1"
     56FIMAGE="$2"
     57FBZIMAGE="$3"
     58MTOOLSRC="$4"
     59KCMDLINE="$5"
     60shift 5				# Remaining arguments = initrd files
     61
     62export MTOOLSRC
     63
     64# common options for dd
     65dd='dd iflag=fullblock'
     66
     67# Make sure the files actually exist
     68verify "$FBZIMAGE"
     69
     70declare -a FDINITRDS
     71irdpfx=' initrd='
     72initrdopts_syslinux=''
     73initrdopts_efi=''
     74for f in "$@"; do
     75	if [ -f "$f" -a -r "$f" ]; then
     76	    FDINITRDS=("${FDINITRDS[@]}" "$f")
     77	    fname="$(basename "$f")"
     78	    initrdopts_syslinux="${initrdopts_syslinux}${irdpfx}${fname}"
     79	    irdpfx=,
     80	    initrdopts_efi="${initrdopts_efi} initrd=${fname}"
     81	fi
     82done
     83
     84# Read a $3-byte littleendian unsigned value at offset $2 from file $1
     85le() {
     86	local n=0
     87	local m=1
     88	for b in $(od -A n -v -j $2 -N $3 -t u1 "$1"); do
     89		n=$((n + b*m))
     90		m=$((m * 256))
     91	done
     92	echo $n
     93}
     94
     95# Get the EFI architecture name such that boot{name}.efi is the default
     96# boot file name. Returns false with no output if the file is not an
     97# EFI image or otherwise unknown.
     98efiarch() {
     99	[ -f "$1" ] || return
    100	[ $(le "$1" 0 2) -eq 23117 ] || return		# MZ magic
    101	peoffs=$(le "$1" 60 4)				# PE header offset
    102	[ $peoffs -ge 64 ] || return
    103	[ $(le "$1" $peoffs 4) -eq 17744 ] || return	# PE magic
    104	case $(le "$1" $((peoffs+4+20)) 2) in		# PE type
    105		267)	;;				# PE32
    106		523)	;;				# PE32+
    107		*) return 1 ;;				# Invalid
    108	esac
    109	[ $(le "$1" $((peoffs+4+20+68)) 2) -eq 10 ] || return # EFI app
    110	case $(le "$1" $((peoffs+4)) 2) in		# Machine type
    111		 332)	echo i386	;;
    112		 450)	echo arm	;;
    113		 512)	echo ia64	;;
    114		20530)	echo riscv32	;;
    115		20580)	echo riscv64	;;
    116		20776)	echo riscv128	;;
    117		34404)	echo x64	;;
    118		43620)	echo aa64	;;
    119	esac
    120}
    121
    122# Get the combined sizes in bytes of the files given, counting sparse
    123# files as full length, and padding each file to cluster size
    124cluster=16384
    125filesizes() {
    126	local t=0
    127	local s
    128	for s in $(ls -lnL "$@" 2>/dev/null | awk '/^-/{ print $5; }'); do
    129		t=$((t + ((s+cluster-1)/cluster)*cluster))
    130	done
    131	echo $t
    132}
    133
    134# Expand directory names which should be in /usr/share into a list
    135# of possible alternatives
    136sharedirs() {
    137	local dir file
    138	for dir in /usr/share /usr/lib64 /usr/lib; do
    139		for file; do
    140			echo "$dir/$file"
    141			echo "$dir/${file^^}"
    142		done
    143	done
    144}
    145efidirs() {
    146	local dir file
    147	for dir in /usr/share /boot /usr/lib64 /usr/lib; do
    148		for file; do
    149			echo "$dir/$file"
    150			echo "$dir/${file^^}"
    151		done
    152	done
    153}
    154
    155findsyslinux() {
    156	local f="$(find -L $(sharedirs syslinux isolinux) \
    157		    -name "$1" -readable -type f -print -quit 2>/dev/null)"
    158	if [ ! -f "$f" ]; then
    159		die "Need a $1 file, please install syslinux/isolinux."
    160	fi
    161	echo "$f"
    162	return 0
    163}
    164
    165findovmf() {
    166	local arch="$1"
    167	shift
    168	local -a names=(-false)
    169	local name f
    170	for name; do
    171		names=("${names[@]}" -or -iname "$name")
    172	done
    173	for f in $(find -L $(efidirs edk2 ovmf) \
    174			\( "${names[@]}" \) -readable -type f \
    175			-print 2>/dev/null); do
    176		if [ "$(efiarch "$f")" = "$arch" ]; then
    177			echo "$f"
    178			return 0
    179		fi
    180	done
    181	die "Need a $1 file for $arch, please install EDK2/OVMF."
    182}
    183
    184do_mcopy() {
    185	if [ ${#FDINITRDS[@]} -gt 0 ]; then
    186		mcopy "${FDINITRDS[@]}" "$1"
    187	fi
    188	if [ -n "$efishell" ]; then
    189		mmd "$1"EFI "$1"EFI/Boot
    190		mcopy "$efishell" "$1"EFI/Boot/boot${kefiarch}.efi
    191	fi
    192	if [ -n "$kefiarch" ]; then
    193		echo linux "$KCMDLINE$initrdopts_efi" | \
    194			mcopy - "$1"startup.nsh
    195	fi
    196	echo default linux "$KCMDLINE$initrdopts_syslinux" | \
    197		mcopy - "$1"syslinux.cfg
    198	mcopy "$FBZIMAGE" "$1"linux
    199}
    200
    201genbzdisk() {
    202	verify "$MTOOLSRC"
    203	mformat -v 'LINUX_BOOT' a:
    204	syslinux "$FIMAGE"
    205	do_mcopy a:
    206}
    207
    208genfdimage144() {
    209	verify "$MTOOLSRC"
    210	$dd if=/dev/zero of="$FIMAGE" bs=1024 count=1440 2>/dev/null
    211	mformat -v 'LINUX_BOOT' v:
    212	syslinux "$FIMAGE"
    213	do_mcopy v:
    214}
    215
    216genfdimage288() {
    217	verify "$MTOOLSRC"
    218	$dd if=/dev/zero of="$FIMAGE" bs=1024 count=2880 2>/dev/null
    219	mformat -v 'LINUX_BOOT' w:
    220	syslinux "$FIMAGE"
    221	do_mcopy w:
    222}
    223
    224genhdimage() {
    225	verify "$MTOOLSRC"
    226	mbr="$(findsyslinux mbr.bin)"
    227	kefiarch="$(efiarch "$FBZIMAGE")"
    228	if [ -n "$kefiarch" ]; then
    229		# The efishell provides command line handling
    230		efishell="$(findovmf $kefiarch shell.efi shell${kefiarch}.efi)"
    231		ptype='-T 0xef'	# EFI system partition, no GPT
    232	fi
    233	sizes=$(filesizes "$FBZIMAGE" "${FDINITRDS[@]}" "$efishell")
    234	# Allow 1% + 2 MiB for filesystem and partition table overhead,
    235	# syslinux, and config files; this is probably excessive...
    236	megs=$(((sizes + sizes/100 + 2*1024*1024 - 1)/(1024*1024)))
    237	$dd if=/dev/zero of="$FIMAGE" bs=$((1024*1024)) count=$megs 2>/dev/null
    238	mpartition -I -c -s 32 -h 64 $ptype -b 64 -a p:
    239	$dd if="$mbr" of="$FIMAGE" bs=440 count=1 conv=notrunc 2>/dev/null
    240	mformat -v 'LINUX_BOOT' -s 32 -h 64 -c $((cluster/512)) -t $megs h:
    241	syslinux --offset $((64*512)) "$FIMAGE"
    242	do_mcopy h:
    243}
    244
    245geniso() {
    246	tmp_dir="$(dirname "$FIMAGE")/isoimage"
    247	rm -rf "$tmp_dir"
    248	mkdir "$tmp_dir"
    249	isolinux=$(findsyslinux isolinux.bin)
    250	ldlinux=$(findsyslinux  ldlinux.c32)
    251	cp "$isolinux" "$ldlinux" "$tmp_dir"
    252	cp "$FBZIMAGE" "$tmp_dir"/linux
    253	echo default linux "$KCMDLINE" > "$tmp_dir"/isolinux.cfg
    254	cp "${FDINITRDS[@]}" "$tmp_dir"/
    255	genisoimage -J -r -appid 'LINUX_BOOT' -input-charset=utf-8 \
    256		    -quiet -o "$FIMAGE" -b isolinux.bin \
    257		    -c boot.cat -no-emul-boot -boot-load-size 4 \
    258		    -boot-info-table "$tmp_dir"
    259	isohybrid "$FIMAGE" 2>/dev/null || true
    260	rm -rf "$tmp_dir"
    261}
    262
    263rm -f "$FIMAGE"
    264
    265case "$diskfmt" in
    266	bzdisk)     genbzdisk;;
    267	fdimage144) genfdimage144;;
    268	fdimage288) genfdimage288;;
    269	hdimage)    genhdimage;;
    270	isoimage)   geniso;;
    271	*)          die "Unknown image format: $diskfmt";;
    272esac