1 #!/bin/bash 2 # 3 # This file is subject to the terms and condit 4 # License. See the file "COPYING" in the main 5 # for more details. 6 # 7 # Copyright (C) 2017 by Changbin Du <changbin.d 8 # 9 # Adapted from code in arch/x86/boot/Makefile 10 # 11 # "make fdimage/fdimage144/fdimage288/hdimage/ 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 comman 29 # 30 31 # Use "make V=1" to debug this script 32 case "${KBUILD_VERBOSE}" in 33 *1*) 34 set -x 35 ;; 36 esac 37 38 # Exit the top-level shell with an error 39 topshell=$$ 40 trap 'exit 1' USR1 41 die() { 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 fi 49 verify() { 50 if [ ! -f "$1" -o ! -r "$1" ]; then 51 die "Missing file: $1" 52 fi 53 } 54 55 diskfmt="$1" 56 FIMAGE="$2" 57 FBZIMAGE="$3" 58 MTOOLSRC="$4" 59 KCMDLINE="$5" 60 shift 5 # Remaining ar 61 62 export MTOOLSRC 63 64 # common options for dd 65 dd='dd iflag=fullblock' 66 67 # Make sure the files actually exist 68 verify "$FBZIMAGE" 69 70 declare -a FDINITRDS 71 irdpfx=' initrd=' 72 initrdopts_syslinux='' 73 initrdopts_efi='' 74 for f in "$@"; do 75 if [ -f "$f" -a -r "$f" ]; then 76 FDINITRDS=("${FDINITRDS[@]}" "$f") 77 fname="$(basename "$f")" 78 initrdopts_syslinux="${initrdopts_ 79 irdpfx=, 80 initrdopts_efi="${initrdopts_efi} 81 fi 82 done 83 84 # Read a $3-byte littleendian unsigned value a 85 le() { 86 local n=0 87 local m=1 88 for b in $(od -A n -v -j $2 -N $3 -t u 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 96 # boot file name. Returns false with no output 97 # EFI image or otherwise unknown. 98 efiarch() { 99 [ -f "$1" ] || return 100 [ $(le "$1" 0 2) -eq 23117 ] || return 101 peoffs=$(le "$1" 60 4) 102 [ $peoffs -ge 64 ] || return 103 [ $(le "$1" $peoffs 4) -eq 17744 ] || 104 case $(le "$1" $((peoffs+4+20)) 2) in 105 267) ;; 106 523) ;; 107 *) return 1 ;; 108 esac 109 [ $(le "$1" $((peoffs+4+20+68)) 2) -eq 110 case $(le "$1" $((peoffs+4)) 2) in 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 123 # files as full length, and padding each file 124 cluster=16384 125 filesizes() { 126 local t=0 127 local s 128 for s in $(ls -lnL "$@" 2>/dev/null | 129 t=$((t + ((s+cluster-1)/cluste 130 done 131 echo $t 132 } 133 134 # Expand directory names which should be in /u 135 # of possible alternatives 136 sharedirs() { 137 local dir file 138 for dir in /usr/share /usr/lib64 /usr/ 139 for file; do 140 echo "$dir/$file" 141 echo "$dir/${file^^}" 142 done 143 done 144 } 145 efidirs() { 146 local dir file 147 for dir in /usr/share /boot /usr/lib64 148 for file; do 149 echo "$dir/$file" 150 echo "$dir/${file^^}" 151 done 152 done 153 } 154 155 findsyslinux() { 156 local f="$(find -L $(sharedirs syslinu 157 -name "$1" -readable -type 158 if [ ! -f "$f" ]; then 159 die "Need a $1 file, please in 160 fi 161 echo "$f" 162 return 0 163 } 164 165 findovmf() { 166 local arch="$1" 167 shift 168 local -a names=(-false) 169 local name f 170 for name; do 171 names=("${names[@]}" -or -inam 172 done 173 for f in $(find -L $(efidirs edk2 ovmf 174 \( "${names[@]}" \) -r 175 -print 2>/dev/null); d 176 if [ "$(efiarch "$f")" = "$arc 177 echo "$f" 178 return 0 179 fi 180 done 181 die "Need a $1 file for $arch, please 182 } 183 184 do_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 191 fi 192 if [ -n "$kefiarch" ]; then 193 echo linux "$KCMDLINE$initrdop 194 mcopy - "$1"startup.ns 195 fi 196 echo default linux "$KCMDLINE$initrdop 197 mcopy - "$1"syslinux.cfg 198 mcopy "$FBZIMAGE" "$1"linux 199 } 200 201 genbzdisk() { 202 verify "$MTOOLSRC" 203 mformat -v 'LINUX_BOOT' a: 204 syslinux "$FIMAGE" 205 do_mcopy a: 206 } 207 208 genfdimage144() { 209 verify "$MTOOLSRC" 210 $dd if=/dev/zero of="$FIMAGE" bs=1024 211 mformat -v 'LINUX_BOOT' v: 212 syslinux "$FIMAGE" 213 do_mcopy v: 214 } 215 216 genfdimage288() { 217 verify "$MTOOLSRC" 218 $dd if=/dev/zero of="$FIMAGE" bs=1024 219 mformat -v 'LINUX_BOOT' w: 220 syslinux "$FIMAGE" 221 do_mcopy w: 222 } 223 224 genhdimage() { 225 verify "$MTOOLSRC" 226 mbr="$(findsyslinux mbr.bin)" 227 kefiarch="$(efiarch "$FBZIMAGE")" 228 if [ -n "$kefiarch" ]; then 229 # The efishell provides comman 230 efishell="$(findovmf $kefiarch 231 ptype='-T 0xef' # EFI system p 232 fi 233 sizes=$(filesizes "$FBZIMAGE" "${FDINI 234 # Allow 1% + 2 MiB for filesystem and 235 # syslinux, and config files; this is 236 megs=$(((sizes + sizes/100 + 2*1024*10 237 $dd if=/dev/zero of="$FIMAGE" bs=$((10 238 mpartition -I -c -s 32 -h 64 $ptype -b 239 $dd if="$mbr" of="$FIMAGE" bs=440 coun 240 mformat -v 'LINUX_BOOT' -s 32 -h 64 -c 241 syslinux --offset $((64*512)) "$FIMAGE 242 do_mcopy h: 243 } 244 245 geniso() { 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 254 cp "${FDINITRDS[@]}" "$tmp_dir"/ 255 genisoimage -J -r -appid 'LINUX_BOOT' 256 -quiet -o "$FIMAGE" -b iso 257 -c boot.cat -no-emul-boot 258 -boot-info-table "$tmp_dir 259 isohybrid "$FIMAGE" 2>/dev/null || tru 260 rm -rf "$tmp_dir" 261 } 262 263 rm -f "$FIMAGE" 264 265 case "$diskfmt" in 266 bzdisk) genbzdisk;; 267 fdimage144) genfdimage144;; 268 fdimage288) genfdimage288;; 269 hdimage) genhdimage;; 270 isoimage) geniso;; 271 *) die "Unknown image format: 272 esac
Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.