tazlito rev 497

Use startup.nsh for uefi boot
author Pascal Bellard <pascal.bellard@slitaz.org>
date Mon May 14 15:57:23 2018 +0200 (2018-05-14)
parents 3832db9191ef
children 5d84fadfd928
files tazlito
line diff
     1.1 --- a/tazlito	Tue May 08 08:15:56 2018 +0200
     1.2 +++ b/tazlito	Mon May 14 15:57:23 2018 +0200
     1.3 @@ -7,7 +7,7 @@
     1.4  # and/or a new ISO. Most commands must be run by root, except the stats
     1.5  # and the configuration file manipulation.
     1.6  #
     1.7 -# (C) 2007-2017 SliTaz - GNU General Public License.
     1.8 +# (C) 2007-2018 SliTaz - GNU General Public License.
     1.9  #
    1.10  # Authors: see the AUTHORS file
    1.11  #
    1.12 @@ -250,8 +250,10 @@
    1.13  	[ -d "$ROOTCD/boot" ] || die 'Unable to find the rootcd boot directory...'
    1.14  }
    1.15  
    1.16 -get() {
    1.17 -	od -v -j $1 -N ${3:-4} -t u${3:-4} -w${3:-4} -An "$2" 2>/dev/null | sed 's/ *//'
    1.18 +set32() {
    1.19 +	for i in $(seq 0 8 $((${4:-32}-8))); do
    1.20 +		printf '\\\\x%02X' $((($2 >> $i) & 255))
    1.21 +	done | xargs echo -en | dd bs=1 conv=notrunc of=$3 seek=$1 2>/dev/null
    1.22  }
    1.23  
    1.24  set64() {
    1.25 @@ -270,18 +272,10 @@
    1.26  # Force size and location in the 2nd eltorito boot file (/boot/isolinux/efi.img)
    1.27  
    1.28  fix_efi_boot_img_size() {
    1.29 -	i=$((2048*$(first_block $2/boot/isolinux/boot.cat)+102))
    1.30 -	set -- $1 $i $3 $i $2
    1.31 -	for i in $(seq 0 8 24); do
    1.32 -		printf '\\\\x%02X' $((($3 >> $i) & 255))
    1.33 -	done | xargs echo -en | dd bs=1 conv=notrunc of=$1 seek=$2 2>/dev/null
    1.34 -	set -- $1 $((2+$4)) $(first_block $5/boot/isolinux/efi.img)
    1.35 -	for i in $(seq 0 8 24); do
    1.36 -		printf '\\\\x%02X' $((($3 >> $i) & 255))
    1.37 -	done | xargs echo -en | dd bs=1 conv=notrunc of=$1 seek=$2 2>/dev/null
    1.38 -	for i in $(seq 0 8 24); do
    1.39 -		printf '\\\\x%02X' $(((($3*4) >> $i) & 255))
    1.40 -	done | xargs echo -en | dd bs=1 conv=notrunc of=$1 seek=$((0x1C+2048*$3)) 2>/dev/null
    1.41 +	local n=$3
    1.42 +	[ $n -gt 65535 ] && n=65535
    1.43 +	set32 $((0x66+2048*$(first_block $2/boot/isolinux/boot.cat))) $n $1 16
    1.44 +	set32 $((0x1C+2048*$4)) $(($4*4)) $1
    1.45  }
    1.46  
    1.47  
    1.48 @@ -290,10 +284,10 @@
    1.49  fix_efi_img_size() {
    1.50  	local e=$((0x809C))
    1.51  	for i in BOOT ISOLINUX EFI.IMG ; do
    1.52 -		local sz=$(get $(($e+10)) "$2")
    1.53 -		e=$(($(get $(($e+2)) "$2") * 2048))
    1.54 +		local sz=$(get $(($e+10)) "$2" 4)
    1.55 +		e=$(($(get $(($e+2)) "$2" 4) * 2048))
    1.56  		while [ $sz -gt 0 ]; do
    1.57 -			local len=$(get $e "$2" 2)
    1.58 +			local len=$(get $e "$2")
    1.59  			[ "$(dd if="$2" bs=1 skip=$(($e+33)) count=${#i} \
    1.60  				2>/dev/null)" == "$i" ] && continue 2
    1.61  			[ $len -eq 0 ] && break
    1.62 @@ -309,132 +303,196 @@
    1.63  # create /boot/isolinux/efi.img to share EFI files with the iso image
    1.64  
    1.65  fixup_uefi_part() {
    1.66 -	local n
    1.67  	[ -s $2/boot/isolinux/efi.img ] || return
    1.68 -
    1.69 +	local n=$(get 19 "$2/boot/isolinux/efi.img")
    1.70 +	[ $n -eq 0 ] && n=$(get 32 "$2/boot/isolinux/efi.img" 4)
    1.71 +	efiblock=$(first_block "$2/boot/isolinux/efi.img")
    1.72 +	fix_efi_img_size $(($n*512)) $1
    1.73 +	fix_efi_boot_img_size $1 $2 $n $efiblock
    1.74 +	
    1.75  	# Build file list tree
    1.76 -
    1.77 -	( cd $2 ; find efi -type f -exec echo \
    1.78 -	  'stat -c "$(busybox stat -m {} | sed q) %s f %n" {}' \; | sh | sort -n ) \
    1.79 -		>/tmp/fatfiles$$
    1.80 -	n=$(sed 's/ .*//;q' /tmp/fatfiles$$)
    1.81 -	( cd $2; find efi ) | awk -v n=$n 'BEGIN { FS="/" }
    1.82 +	fatsz=$(get 22 "$2/boot/isolinux/efi.img")
    1.83 +	resv=$(get 14 "$2/boot/isolinux/efi.img")
    1.84 +	basecluster=$((($resv+2*$fatsz)/4+$efiblock-1))
    1.85 +	hd "$2/boot/isolinux/efi.img" | awk 'BEGIN { skiphead=4 }
    1.86 +{
    1.87 +  if (skiphead!=0) {
    1.88 +    if ($1=="*") skiphead--
    1.89 +    next
    1.90 +  }
    1.91 +  if (skipdot!=0) {
    1.92 +    if (skipdot==2) up[cur]=$13 $12
    1.93 +    else cur=$13 $12
    1.94 +    skipdot=0
    1.95 +    next
    1.96 +  }
    1.97 +  if (($2=="2e" && $3=="20") || ($2=="2e" && $3=="2e" && $4=="20")) {
    1.98 +    if ($3=="2e") skipdot=2
    1.99 +    else skipdot=1
   1.100 +    next
   1.101 +  }
   1.102 +  if (gotname!=0) {
   1.103 +    path=""
   1.104 +    for (i=cur;i!="" && i!="0000";i=up[i]) path=dir[i] path
   1.105 +    if (gotname==2) dir[$13 $12]=name
   1.106 +    else print $1 " " $13 $12 " " path name
   1.107 +    gotname=0
   1.108 +    name=""
   1.109 +    next
   1.110 +  }
   1.111 +  if (s!="") {
   1.112 +    if (eos==0)
   1.113 +    for (i=2;i<18;i+=2) {
   1.114 +      if (i==12) i+=2
   1.115 +      if ($i=="00") break
   1.116 +      s=s substr($0,i+60,1)
   1.117 +    }
   1.118 +    name=s name
   1.119 +    s=""
   1.120 +    eos=0
   1.121 +    next
   1.122 +  }
   1.123 +  if ($13=="0f") {
   1.124 +    s=""
   1.125 +    for (i=3;i<16;i+=2) {
   1.126 +      if (i==13) i+=3
   1.127 +      if ($i=="00") { eos=1; break }
   1.128 +      s=s substr($0,i+60,1)
   1.129 +    }
   1.130 +    next
   1.131 +  }
   1.132 +  if ($13=="10") {
   1.133 +    name=name "/"
   1.134 +    gotname=2
   1.135 +    next
   1.136 +  }
   1.137 +  if ($13=="20") {
   1.138 +    gotname=1
   1.139 +    next
   1.140 +  }
   1.141 +}
   1.142 +' | (	while read offset cluster file; do
   1.143 +		cluster=$(($(first_block "$2/$file")-$basecluster))
   1.144 +		set32 $(($efiblock*2048+0x$offset+10)) $cluster "$1" 16
   1.145 +		echo "$cluster $((($(stat -c %s "$2/$file")+2047)/2048)) $file"
   1.146 +	done
   1.147 +
   1.148 +	# Update fat12 or fat16
   1.149 +	get 57 "$2/boot/isolinux/efi.img"
   1.150 +	dd if="$2/boot/isolinux/efi.img" bs=512 count=$fatsz skip=$resv 2> /dev/null | \
   1.151 +	od -An -t u1 -w1 -v
   1.152 +    ) | awk '
   1.153 +{
   1.154 +  if (state==0) {
   1.155 +    if ($2=="") {
   1.156 +      if ($1==12849) fat=12
   1.157 +      else fat=16
   1.158 +      state++
   1.159 +    }
   1.160 +    else {
   1.161 +      for (i=1;i<$2;i++) c[$1+i]=$1+i
   1.162 +      c[$1+$2]=65535
   1.163 +    }
   1.164 +    next
   1.165 +  }
   1.166 +  if (state==1) {
   1.167 +    prev=$1
   1.168 +    state++
   1.169 +    next
   1.170 +  }
   1.171 +  if (state==2) {
   1.172 +    if (fat==12) {
   1.173 +      n=($1%16)*256+prev
   1.174 +      if (n!=0) c[pos+1]=n
   1.175 +      pos++
   1.176 +      prev=$1/16
   1.177 +      state++
   1.178 +      next
   1.179 +    }
   1.180 +    n=$1*256+prev
   1.181 +  }
   1.182 +  else if (state==3) {
   1.183 +    n=$1*16+prev
   1.184 +  }
   1.185 +  if (n!=0) c[pos+1]=n
   1.186 +  pos++
   1.187 +  state=1
   1.188 +}
   1.189 +END {
   1.190 +  for (i=1;i<=pos;i+=2) {
   1.191 +    if (c[i]=="") c[i]=0
   1.192 +    if (c[i+1]=="") c[i+1]=0
   1.193 +    if (fat==12) printf "0  %02X %02X %02X |\n",c[i]%256,(c[i+1]%16)*16+(c[i]/256)%256,(c[i+1]/16)%256
   1.194 +    else printf "0  %02X %02X %02X %02X |\n",c[i]%256,(c[i]/256)%256,c[i+1]%256,(c[i+1]/256)%256
   1.195 +  }
   1.196 +}' | hexdump -R | dd of="$1" seek=$((4*$efiblock+$fatsz+$resv)) \
   1.197 +		conv=notrunc bs=512 > /dev/null 2>&1
   1.198 +	dd if="$1" of="$1" conv=notrunc bs=512 skip=$((4*$efiblock+$fatsz+$resv)) \
   1.199 +		count=$fatsz seek=$((4*$efiblock+$resv)) > /dev/null 2>&1
   1.200 +
   1.201 +	# Cleanup cache
   1.202 +	umount $2
   1.203 +	mount -o loop,ro $1 $2
   1.204 +}
   1.205 +
   1.206 +
   1.207 +# allocate efi.img stub to share EFI files in the EFI boot partition
   1.208 +
   1.209 +alloc_uefi_part() {
   1.210 +	local basedir=$(dirname "$1")/..
   1.211 +	local fclust=$({
   1.212 +	[ -d $basedir/efi ] &&
   1.213 +		find $basedir/efi -type f -exec stat -c "%s %n" {} \;
   1.214 +	while [ -s "$1" ]; do
   1.215 +		local efifile
   1.216 +		case "$1" in
   1.217 +		*taz)	efifile=bootia32.efi ;;
   1.218 +		*taz64) efifile=bootx64.efi ;;
   1.219 +		esac
   1.220 +		if [ ! -s $basedir/efi/boot/$efifile ] &&
   1.221 +		   [ $(get $((0x82)) "$1") == $((0x4550)) ]; then
   1.222 +			mkdir -p $basedir/efi/boot 2> /dev/null
   1.223 +			for i in "$1" $basedir/boot/rootfs* ; do
   1.224 +				ln "$i" $basedir/efi/boot/
   1.225 +				stat -c "%s %n" "$i"
   1.226 +			done 2> /dev/null
   1.227 +			cat >> $basedir/efi/boot/startup.nsh <<EOT
   1.228 +FS0:\\EFI\\BOOT\\$(basename $1) rw root=0x100$( ( cd $basedir/efi/boot ; \
   1.229 +ls -r rootfs*gz ) | while read f ; do [ "$efifile" == "bootx64.efi" -a \
   1.230 +-s $basedir/efi/boot/${f}64 ] && f=${f}64; echo -n " initrd=/EFI/BOOT/$f";done)
   1.231 +EOT
   1.232 +		fi
   1.233 +		shift
   1.234 +	done; } | awk '{ n+=int(($1+2047)/2048) } END { print n+1 }')
   1.235 +	[ ${fclust:-0} -eq 0 ] && return
   1.236 +	local dclust=$( (cd $basedir; find efi -type d 2>/dev/null) | awk '
   1.237 +		BEGIN {
   1.238 +			FS="/"
   1.239 +		}
   1.240  		NF > 1 {
   1.241  			d[NF $NF]+=2
   1.242 -			p[NF $NF]=$0
   1.243 -			b[a++]=NF $NF
   1.244 -			if (NF>2) d[NF-1 $(NF-1)]++
   1.245 +			d[NF-1 $(NF-1)]+=($NF+25)/13
   1.246  		}
   1.247  		END {
   1.248 -			while (a-- > 0) if (d[i=b[a]] > 2) {
   1.249 -				n-= j =int((d[i]+63)/64)
   1.250 -				print n " " j*2048 " d " p[i]
   1.251 -			}
   1.252 -			print n-1 " 2048 d efi"
   1.253 -		}' >>/tmp/fatfiles$$
   1.254 -	sort -n /tmp/fatfiles$$ | awk '{ if (s == 0) s=$1;
   1.255 -		print ($1-s)+2 " " $2 " " $3 " " $4 }' > /tmp/fatfiles$$.tmp
   1.256 -	mv -f /tmp/fatfiles$$.tmp /tmp/fatfiles$$
   1.257 -
   1.258 -	# Build fat12 or fat16
   1.259 -
   1.260 -	if [ $(awk '{n+=int(($2+2047)/2048)}END{print n}' /tmp/fatfiles$$) \
   1.261 -			-lt 4000 ]; then
   1.262 -		sed '1s/.*/4087 2049 x\n1 1 x/' /tmp/fatfiles$$ | while read c s x; do
   1.263 -			seq $(($c+1)) $((($s-1)/2048+$c)) 
   1.264 -			echo 4095
   1.265 -		done | awk 'BEGIN { printf "0  "}
   1.266 -		{
   1.267 -			if (n == 0) n=$1
   1.268 -			else {
   1.269 -				printf "%02X %02X %02X ",n%256,
   1.270 -					($1%16)*16+(n/256),$1/16
   1.271 -				n=0
   1.272 -			}
   1.273 -		}
   1.274 -		END {
   1.275 -			if (n != 0) printf "FF 0F 00 "
   1.276 -			print "  |"
   1.277 -		}' | hexdump -R > /tmp/fatbin-12-$$
   1.278 +			for (i in d)
   1.279 +				n+=int((d[i]+63)/64)
   1.280 +			print n
   1.281 +		}')
   1.282 +	local clusters=$(($fclust+$dclust))
   1.283 +	if [ $clusters -lt 4085 ]; then
   1.284 +		fsect=$(((($clusters+2)*3+1023)/1024))
   1.285 +		ftype="31 32"
   1.286 +		fhead="F8 FF FF"
   1.287  	else
   1.288 -		sed '1s/.*/65527 2049 x\n1 1 x/' /tmp/fatfiles$$ | while read c s x; do
   1.289 -			seq $(($c+1)) $((($s-1)/2048+$c)) 
   1.290 -			echo 65535
   1.291 -		done | awk 'BEGIN { printf "0  "}
   1.292 -		{
   1.293 -			printf "%02X %02X ",$1%256,$1/256
   1.294 -		}
   1.295 -		END {
   1.296 -			print "  |"
   1.297 -		}' | hexdump -R > /tmp/fatbin-16-$$
   1.298 +		fsect=$((($clusters+2+255)/256))
   1.299 +		ftype="31 36"
   1.300 +		fhead="F8 FF FF FF"
   1.301  	fi
   1.302 -
   1.303 -	# align fat to 512 bytes
   1.304 -	dd of=$(ls /tmp/fatbin-*-$$) count=0 bs=512 \
   1.305 -		seek=$((($(stat -c %s /tmp/fatbin-*-$$)-1)/512+1)) 2>/dev/null
   1.306 -
   1.307 -	# build directory records
   1.308 -
   1.309 -	awk '
   1.310 -	BEGIN {
   1.311 -		c=2
   1.312 -		b16="/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0"
   1.313 -		b14="/0/0/0/0/0/0/0/0/0/0/0/0/0/0"
   1.314 -		print "EFI        /x10" b14 "/x0" c "/0/0/0/0/0"
   1.315 -		for (n=i=0; i<63; i++) print b16 b16
   1.316 -	}
   1.317 -	{
   1.318 -		clu[n]=$1
   1.319 -		size[n]=$2
   1.320 -		type[n]=$3
   1.321 -		name[n]=$4
   1.322 -		n++
   1.323 -	}
   1.324 -	END {
   1.325 -		path="efi"
   1.326 -		d21="/x10" b14 "/x%02X/x%02X/0/0/0/0\n"
   1.327 -		up[0]=0
   1.328 -		s=1
   1.329 -		do {
   1.330 -			l=split(path,x,"/")
   1.331 -			up[l]=c
   1.332 -			printf ".          " d21,c%256,c/256
   1.333 -			printf "..         " d21,up[l-1]%256,up[l-1]/256
   1.334 -			for (i=s,e=2; i<n; i++) {
   1.335 -				if (substr(name[i],1,length(path)) != path ||
   1.336 -				    split(substr(name[i],length(path)+2),x,"/") > 1)
   1.337 -					continue
   1.338 -				split(toupper(x[1]),x,".")
   1.339 -				if (length(x[1]) >= 8) printf substr(x[1],1,8)
   1.340 -				else printf x[1] substr("       ",1,8-length(x[1]))
   1.341 -				if (length(x[2]) >= 3) printf substr(x[2],1,3)
   1.342 -				else printf x[2] substr("   ",1,3-length(x[2]))
   1.343 -				if (type[i] != "d") printf "/0"
   1.344 -				else { printf "/x10"; size[i]=0 }
   1.345 -				printf b14 "/x%02X/x%02X",clu[i]%256,clu[i]/256
   1.346 -				printf "/x%02X/x%02X/x%02X/x%02X\n",size[i]%256,
   1.347 -					(size[i]/256)%256,(size[i]/256/256)%256,
   1.348 -					size[i]/256/256/256
   1.349 -				e++
   1.350 -			}
   1.351 -			while (e++ < 64) print b16 b16
   1.352 -			path=name[s]
   1.353 -			c=clu[s]
   1.354 -		} while (type[s++] == "d")
   1.355 -	}' < /tmp/fatfiles$$ | while read line; do
   1.356 -		echo "$line" | sed 's| |/x20|g;s|/|\\\\|g' | xargs echo -en
   1.357 -	done > /tmp/fatdir$$
   1.358 -
   1.359 -	# build boot record
   1.360 -
   1.361 -	fat=$(($(stat -c %s /tmp/fatbin-*-$$)/512))
   1.362 -	r=$((4-($fat+$fat+$(stat -c %s /tmp/fatdir$$)/512)%4))
   1.363 -	dd if=/dev/zero bs=512 count=$r of=/tmp/fatbr$$ 2> /dev/null
   1.364 -	echo -en '\x55\xAA' | \
   1.365 -		dd of=/tmp/fatbr$$ seek=510 bs=1 conv=notrunc 2> /dev/null
   1.366 -	n=$(first_block $2/boot/isolinux/efi.img)
   1.367 -	fat="$(printf "%02X %02X" $(($fat%256)) $((($fat>>8)%256)))"
   1.368 -	s=$((($(first_block "$(ls -r $2/boot/rootfs* | sed q)") - $n)*4))
   1.369 +	rsect=$(( 1+ ((2*$fsect)-1)%4 ))
   1.370 +	fsz="$(printf "%02X %02X" $(($fsect%256)) $((($fsect>>8)%256)))"
   1.371 +	#       reserved +   fat*2   + root dir  +   dirs
   1.372 +	count=$((($rsect + $fsect*2)/4 +  2  + $dclust ))
   1.373 +	s=$((($count+$fclust)*4))
   1.374  	if [ $s -gt 65535 ]; then
   1.375  		size="00 00"
   1.376  		size32="$(printf "%02X %02X %02X %02X" $(($s%256)) \
   1.377 @@ -443,74 +501,44 @@
   1.378  		size="$(printf "%02X %02X" $(($s%256)) $((($s>>8)%256)) )"
   1.379  		size32="00 00 00 00"
   1.380  	fi
   1.381 -	t=32; [ -s /tmp/fatbin-16-$$ ] && t=36
   1.382 -	hexdump -R <<EOT | dd conv=notrunc of=/tmp/fatbr$$ 2> /dev/null
   1.383 -0  eb 3c 90 53 6c 69 54 61  7a 00 00 00 02 04 $r 00  |
   1.384 -0  02 40 00 $size f8 $fat   20 00 40 00 00 00 00 00  |
   1.385 +	dd if=/dev/zero bs=512 of=$basedir/boot/isolinux/efi.img \
   1.386 +		count=$s 2> /dev/null
   1.387 +
   1.388 +	# Create boot sector
   1.389 +	echo -en '\x55\xAA' | dd of=$basedir/boot/isolinux/efi.img \
   1.390 +		seek=510 bs=1 conv=notrunc 2> /dev/null
   1.391 +	hexdump -R <<EOT | dd of=$basedir/boot/isolinux/efi.img \
   1.392 +		conv=notrunc 2> /dev/null
   1.393 +0  eb 3c 90 53 6c 69 54 61  7a 00 00 00 02 04 $rsect 00  |
   1.394 +0  02 40 00 $size f8 $fsz   20 00 40 00 00 00 00 00  |
   1.395  0  $size32     80 00 29 00  00 00 00 4e 4f 20 4e 41  |
   1.396 -0  4d 45 20 20 20 20 46 41  54 31 $t 20 20 20 cd 18  |
   1.397 +0  4d 45 20 20 20 20 46 41  54 $ftype 20 20 20 cd 18  |
   1.398  0  cd 19 eb fa  |
   1.399  EOT
   1.400  
   1.401 -	# patch efi.img stub
   1.402 -
   1.403 -	cat /tmp/fatbr$$ /tmp/fatbin-*-$$ /tmp/fatbin-*-$$ /tmp/fatdir$$ | \
   1.404 -	dd of=$1 conv=notrunc bs=2k seek=$n 2>/dev/null
   1.405 -	fix_efi_img_size $(($s*512)) $1
   1.406 -	fix_efi_boot_img_size $1 $2 $s
   1.407 -	rm -f /tmp/fat*$$
   1.408 -
   1.409 -	# Cleanup cache
   1.410 -	umount $2
   1.411 -	mount -o loop,ro $1 $2
   1.412 -}
   1.413 -
   1.414 -
   1.415 -# allocate efi.img stub to share EFI files in the EFI boot partition
   1.416 -
   1.417 -alloc_uefi_part() {
   1.418 -	local basedir=$(dirname "$1")/..
   1.419 -	local clusters=$({
   1.420 -	[ -d $basedir/efi ] &&
   1.421 -		find $basedir/efi -type f -exec stat -c "%s" {} \;
   1.422 -	while [ -s "$1" ]; do
   1.423 -		local efifile
   1.424 -		case "$1" in
   1.425 -		*taz)	efifile=bootia32.efi ;;
   1.426 -		*taz64) efifile=bootx64.efi ;;
   1.427 -		esac
   1.428 -		if [ ! -s $basedir/efi/boot/$efifile ] &&
   1.429 -		   [ $(get $((0x82)) "$1") == $((0x4550)) ]; then
   1.430 -			stat -c "%s" "$1"
   1.431 -			mkdir -p $basedir/efi/boot 2> /dev/null
   1.432 -			ln "$1" $basedir/efi/boot/$efifile
   1.433 -		fi
   1.434 -		shift
   1.435 -	done; } | awk '{ n+=int(($1+2047)/2048) } END { print n }')
   1.436 -	[ ${clusters:-0} -eq 0 ] && return
   1.437 -	local dclust=$( (cd $basedir; find efi -type d 2>/dev/null) | awk '
   1.438 -		BEGIN {
   1.439 -			FS="/"
   1.440 -		}
   1.441 -		NF > 1 {
   1.442 -			d[NF $NF]+=2
   1.443 -			d[NF-1 $(NF-1)]++
   1.444 -		}
   1.445 -		END {
   1.446 -			for (i in d)
   1.447 -				n+=int((d[i]+63)/64)
   1.448 -			print n
   1.449 -		}')
   1.450 -	clusters=$(($clusters+$dclust))
   1.451 -	if [ $clusters -lt 4000 ]; then
   1.452 -		#     reserved   +    fat*2      +      root dir  +   dirs
   1.453 -		count=$(((1 + (($clusters*3+1023)/1024)*2+3)/4+1  +  $dclust ))
   1.454 -	else
   1.455 -		#     reserved   +    fat*2      +      root dir  +   dirs
   1.456 -		count=$(((1 + (($clusters+255)/256)*2+3)/4 +  1  + $dclust ))
   1.457 -	fi
   1.458 -	dd if=/dev/zero bs=2k of=$basedir/boot/isolinux/efi.img \
   1.459 -		count=$count 2> /dev/null
   1.460 +	# Create fats
   1.461 +	echo "0  $fhead |" | hexdump -R | dd of=$basedir/boot/isolinux/efi.img \
   1.462 +		seek=$(($rsect)) bs=512 conv=notrunc 2> /dev/null
   1.463 +	echo "0  $fhead |" | hexdump -R | dd of=$basedir/boot/isolinux/efi.img \
   1.464 +		seek=$(($rsect+$fsect)) bs=512 conv=notrunc 2> /dev/null
   1.465 +
   1.466 +	mkdir -p /tmp/mnt$$
   1.467 +	mount -o loop $basedir/boot/isolinux/efi.img /tmp/mnt$$
   1.468 +	( cd $basedir; find efi -type d | cpio -o -H newc ) | \
   1.469 +		( cd /tmp/mnt$$ ; cpio -idmu )
   1.470 +	sync
   1.471 +	dd if=$basedir/boot/isolinux/efi.img of=/tmp/fat$$ \
   1.472 +		skip=$rsect bs=512 count=$fsect 2> /dev/null
   1.473 +	( cd $basedir; find efi -type f | cpio -o -H newc ) | \
   1.474 +		( cd /tmp/mnt$$ ; cpio -idmu )
   1.475 +	umount /tmp/mnt$$
   1.476 +	cat /tmp/fat$$ /tmp/fat$$ | dd of=$basedir/boot/isolinux/efi.img \
   1.477 +		seek=$rsect bs=512 conv=notrunc 2> /dev/null
   1.478 +	rm /tmp/fat$$
   1.479 +	rmdir /tmp/mnt$$
   1.480 +
   1.481 +	dd count=0 bs=2k of=$basedir/boot/isolinux/efi.img \
   1.482 +		seek=$count 2> /dev/null
   1.483  }
   1.484  
   1.485  
   1.486 @@ -542,7 +570,7 @@
   1.487  $PWD/boot/isolinux 100
   1.488  $(ls -r $PWD/boot/rootfs* | awk 'BEGIN{n=149} { print $1 " " n-- }')
   1.489  $(ls $PWD/boot/bzImage* | awk 'BEGIN{n=200} { print $1 " " n-- }')
   1.490 -$(find $PWD/efi -type f 2>/dev/null | awk 'BEGIN{n=299} { print $1 " " n-- }')
   1.491 +$(find $PWD/efi -type f 2>/dev/null | sort -r | awk 'BEGIN{n=299} { print $1 " " n-- }')
   1.492  $PWD/boot/isolinux/efi.img 300
   1.493  $PWD/boot/isolinux/isolinux.bin 399
   1.494  $PWD/boot/isolinux/boot.cat 400
   1.495 @@ -1618,7 +1646,7 @@
   1.496  # Get byte(s) from a binary file
   1.497  
   1.498  get() {
   1.499 -	od -v -j $1 -N ${3:-2} -t u${3:-2} -w${3:-2} -An $2 2>/dev/null
   1.500 +	od -v -j $1 -N ${3:-2} -t u${3:-2} -w${3:-2} -An $2 2>/dev/null | sed 's/ *//'
   1.501  }
   1.502  
   1.503