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
7 # Copyright (C) 2017 by Changbin Du <changbin.du@intel.com>
9 # Adapted from code in arch/x86/boot/Makefile by H. Peter Anvin and others
11 # "make fdimage/fdimage144/fdimage288/hdimage/isoimage"
12 # script for x86 architecture
16 # $2 - target image file
17 # $3 - kernel bzImage file
18 # $4 - mtools configuration file
20 # $6+ - initrd image file(s)
22 # This script requires:
25 # mtools (for fdimage* and hdimage)
26 # edk2/OVMF (for hdimage)
28 # Otherwise try to stick to POSIX shell commands...
31 # Use "make V=1" to debug this script
32 case "${KBUILD_VERBOSE}" in
38 # Exit the top-level shell with an error
48 # Verify the existence and readability of a file
50 if [ ! -f "$1" -o ! -r "$1" ]; then
51 die "Missing file: $1"
60 shift 5 # Remaining arguments = initrd files
64 # common options for dd
65 dd='dd iflag=fullblock'
67 # Make sure the files actually exist
72 initrdopts_syslinux=''
75 if [ -f "$f" -a -r "$f" ]; then
76 FDINITRDS=("${FDINITRDS[@]}" "$f")
77 fname="$(basename "$f")"
78 initrdopts_syslinux="${initrdopts_syslinux}${irdpfx}${fname}"
80 initrdopts_efi="${initrdopts_efi} initrd=${fname}"
84 # Read a $3-byte littleendian unsigned value at offset $2 from file $1
88 for b in $(od -A n -v -j $2 -N $3 -t u1 "$1"); do
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.
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
107 *) return 1 ;; # Invalid
109 [ $(le "$1" $((peoffs+4+20+68)) 2) -eq 10 ] || return # EFI app
110 case $(le "$1" $((peoffs+4)) 2) in # Machine type
114 20530) echo riscv32 ;;
115 20580) echo riscv64 ;;
116 20776) echo riscv128 ;;
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
128 for s in $(ls -lnL "$@" 2>/dev/null | awk '/^-/{ print $5; }'); do
129 t=$((t + ((s+cluster-1)/cluster)*cluster))
134 # Expand directory names which should be in /usr/share into a list
135 # of possible alternatives
138 for dir in /usr/share /usr/lib64 /usr/lib; do
141 echo "$dir/${file^^}"
147 for dir in /usr/share /boot /usr/lib64 /usr/lib; do
150 echo "$dir/${file^^}"
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."
168 local -a names=(-false)
171 names=("${names[@]}" -or -iname "$name")
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
181 die "Need a $1 file for $arch, please install EDK2/OVMF."
185 if [ ${#FDINITRDS[@]} -gt 0 ]; then
186 mcopy "${FDINITRDS[@]}" "$1"
188 if [ -n "$efishell" ]; then
189 mmd "$1"EFI "$1"EFI/Boot
190 mcopy "$efishell" "$1"EFI/Boot/boot${kefiarch}.efi
192 if [ -n "$kefiarch" ]; then
193 echo linux "$KCMDLINE$initrdopts_efi" | \
194 mcopy - "$1"startup.nsh
196 echo default linux "$KCMDLINE$initrdopts_syslinux" | \
197 mcopy - "$1"syslinux.cfg
198 mcopy "$FBZIMAGE" "$1"linux
203 mformat -v 'LINUX_BOOT' a:
210 $dd if=/dev/zero of="$FIMAGE" bs=1024 count=1440 2>/dev/null
211 mformat -v 'LINUX_BOOT' v:
218 $dd if=/dev/zero of="$FIMAGE" bs=1024 count=2880 2>/dev/null
219 mformat -v 'LINUX_BOOT' w:
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
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"
246 tmp_dir="$(dirname "$FIMAGE")/isoimage"
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
267 fdimage144) genfdimage144;;
268 fdimage288) genfdimage288;;
269 hdimage) genhdimage;;
271 *) die "Unknown image format: $diskfmt";;