0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032 case "${KBUILD_VERBOSE}" in
0033 *1*)
0034 set -x
0035 ;;
0036 esac
0037
0038
0039 topshell=$$
0040 trap 'exit 1' USR1
0041 die() {
0042 echo "" 1>&2
0043 echo " *** $*" 1>&2
0044 echo "" 1>&2
0045 kill -USR1 $topshell
0046 }
0047
0048
0049 verify() {
0050 if [ ! -f "$1" -o ! -r "$1" ]; then
0051 die "Missing file: $1"
0052 fi
0053 }
0054
0055 diskfmt="$1"
0056 FIMAGE="$2"
0057 FBZIMAGE="$3"
0058 MTOOLSRC="$4"
0059 KCMDLINE="$5"
0060 shift 5
0061
0062 export MTOOLSRC
0063
0064
0065 dd='dd iflag=fullblock'
0066
0067
0068 verify "$FBZIMAGE"
0069
0070 declare -a FDINITRDS
0071 irdpfx=' initrd='
0072 initrdopts_syslinux=''
0073 initrdopts_efi=''
0074 for f in "$@"; do
0075 if [ -f "$f" -a -r "$f" ]; then
0076 FDINITRDS=("${FDINITRDS[@]}" "$f")
0077 fname="$(basename "$f")"
0078 initrdopts_syslinux="${initrdopts_syslinux}${irdpfx}${fname}"
0079 irdpfx=,
0080 initrdopts_efi="${initrdopts_efi} initrd=${fname}"
0081 fi
0082 done
0083
0084
0085 le() {
0086 local n=0
0087 local m=1
0088 for b in $(od -A n -v -j $2 -N $3 -t u1 "$1"); do
0089 n=$((n + b*m))
0090 m=$((m * 256))
0091 done
0092 echo $n
0093 }
0094
0095
0096
0097
0098 efiarch() {
0099 [ -f "$1" ] || return
0100 [ $(le "$1" 0 2) -eq 23117 ] || return
0101 peoffs=$(le "$1" 60 4)
0102 [ $peoffs -ge 64 ] || return
0103 [ $(le "$1" $peoffs 4) -eq 17744 ] || return
0104 case $(le "$1" $((peoffs+4+20)) 2) in
0105 267) ;;
0106 523) ;;
0107 *) return 1 ;;
0108 esac
0109 [ $(le "$1" $((peoffs+4+20+68)) 2) -eq 10 ] || return
0110 case $(le "$1" $((peoffs+4)) 2) in
0111 332) echo i386 ;;
0112 450) echo arm ;;
0113 512) echo ia64 ;;
0114 20530) echo riscv32 ;;
0115 20580) echo riscv64 ;;
0116 20776) echo riscv128 ;;
0117 34404) echo x64 ;;
0118 43620) echo aa64 ;;
0119 esac
0120 }
0121
0122
0123
0124 cluster=16384
0125 filesizes() {
0126 local t=0
0127 local s
0128 for s in $(ls -lnL "$@" 2>/dev/null | awk '/^-/{ print $5; }'); do
0129 t=$((t + ((s+cluster-1)/cluster)*cluster))
0130 done
0131 echo $t
0132 }
0133
0134
0135
0136 sharedirs() {
0137 local dir file
0138 for dir in /usr/share /usr/lib64 /usr/lib; do
0139 for file; do
0140 echo "$dir/$file"
0141 echo "$dir/${file^^}"
0142 done
0143 done
0144 }
0145 efidirs() {
0146 local dir file
0147 for dir in /usr/share /boot /usr/lib64 /usr/lib; do
0148 for file; do
0149 echo "$dir/$file"
0150 echo "$dir/${file^^}"
0151 done
0152 done
0153 }
0154
0155 findsyslinux() {
0156 local f="$(find -L $(sharedirs syslinux isolinux) \
0157 -name "$1" -readable -type f -print -quit 2>/dev/null)"
0158 if [ ! -f "$f" ]; then
0159 die "Need a $1 file, please install syslinux/isolinux."
0160 fi
0161 echo "$f"
0162 return 0
0163 }
0164
0165 findovmf() {
0166 local arch="$1"
0167 shift
0168 local -a names=(-false)
0169 local name f
0170 for name; do
0171 names=("${names[@]}" -or -iname "$name")
0172 done
0173 for f in $(find -L $(efidirs edk2 ovmf) \
0174 \( "${names[@]}" \) -readable -type f \
0175 -print 2>/dev/null); do
0176 if [ "$(efiarch "$f")" = "$arch" ]; then
0177 echo "$f"
0178 return 0
0179 fi
0180 done
0181 die "Need a $1 file for $arch, please install EDK2/OVMF."
0182 }
0183
0184 do_mcopy() {
0185 if [ ${
0186 mcopy "${FDINITRDS[@]}" "$1"
0187 fi
0188 if [ -n "$efishell" ]; then
0189 mmd "$1"EFI "$1"EFI/Boot
0190 mcopy "$efishell" "$1"EFI/Boot/boot${kefiarch}.efi
0191 fi
0192 if [ -n "$kefiarch" ]; then
0193 echo linux "$KCMDLINE$initrdopts_efi" | \
0194 mcopy - "$1"startup.nsh
0195 fi
0196 echo default linux "$KCMDLINE$initrdopts_syslinux" | \
0197 mcopy - "$1"syslinux.cfg
0198 mcopy "$FBZIMAGE" "$1"linux
0199 }
0200
0201 genbzdisk() {
0202 verify "$MTOOLSRC"
0203 mformat -v 'LINUX_BOOT' a:
0204 syslinux "$FIMAGE"
0205 do_mcopy a:
0206 }
0207
0208 genfdimage144() {
0209 verify "$MTOOLSRC"
0210 $dd if=/dev/zero of="$FIMAGE" bs=1024 count=1440 2>/dev/null
0211 mformat -v 'LINUX_BOOT' v:
0212 syslinux "$FIMAGE"
0213 do_mcopy v:
0214 }
0215
0216 genfdimage288() {
0217 verify "$MTOOLSRC"
0218 $dd if=/dev/zero of="$FIMAGE" bs=1024 count=2880 2>/dev/null
0219 mformat -v 'LINUX_BOOT' w:
0220 syslinux "$FIMAGE"
0221 do_mcopy w:
0222 }
0223
0224 genhdimage() {
0225 verify "$MTOOLSRC"
0226 mbr="$(findsyslinux mbr.bin)"
0227 kefiarch="$(efiarch "$FBZIMAGE")"
0228 if [ -n "$kefiarch" ]; then
0229
0230 efishell="$(findovmf $kefiarch shell.efi shell${kefiarch}.efi)"
0231 ptype='-T 0xef'
0232 fi
0233 sizes=$(filesizes "$FBZIMAGE" "${FDINITRDS[@]}" "$efishell")
0234
0235
0236 megs=$(((sizes + sizes/100 + 2*1024*1024 - 1)/(1024*1024)))
0237 $dd if=/dev/zero of="$FIMAGE" bs=$((1024*1024)) count=$megs 2>/dev/null
0238 mpartition -I -c -s 32 -h 64 $ptype -b 64 -a p:
0239 $dd if="$mbr" of="$FIMAGE" bs=440 count=1 conv=notrunc 2>/dev/null
0240 mformat -v 'LINUX_BOOT' -s 32 -h 64 -c $((cluster/512)) -t $megs h:
0241 syslinux --offset $((64*512)) "$FIMAGE"
0242 do_mcopy h:
0243 }
0244
0245 geniso() {
0246 tmp_dir="$(dirname "$FIMAGE")/isoimage"
0247 rm -rf "$tmp_dir"
0248 mkdir "$tmp_dir"
0249 isolinux=$(findsyslinux isolinux.bin)
0250 ldlinux=$(findsyslinux ldlinux.c32)
0251 cp "$isolinux" "$ldlinux" "$tmp_dir"
0252 cp "$FBZIMAGE" "$tmp_dir"/linux
0253 echo default linux "$KCMDLINE" > "$tmp_dir"/isolinux.cfg
0254 cp "${FDINITRDS[@]}" "$tmp_dir"/
0255 genisoimage -J -r -appid 'LINUX_BOOT' -input-charset=utf-8 \
0256 -quiet -o "$FIMAGE" -b isolinux.bin \
0257 -c boot.cat -no-emul-boot -boot-load-size 4 \
0258 -boot-info-table "$tmp_dir"
0259 isohybrid "$FIMAGE" 2>/dev/null || true
0260 rm -rf "$tmp_dir"
0261 }
0262
0263 rm -f "$FIMAGE"
0264
0265 case "$diskfmt" in
0266 bzdisk) genbzdisk;;
0267 fdimage144) genfdimage144;;
0268 fdimage288) genfdimage288;;
0269 hdimage) genhdimage;;
0270 isoimage) geniso;;
0271 *) die "Unknown image format: $diskfmt";;
0272 esac