tazlito rev 476

uefi support aventually...
author Pascal Bellard <pascal.bellard@slitaz.org>
date Fri Jan 19 21:06:16 2018 +0100 (2018-01-19)
parents fb83501c662e
children 7959015b775d
files tazlito
line diff
     1.1 --- a/tazlito	Mon Dec 25 21:13:19 2017 +0100
     1.2 +++ b/tazlito	Fri Jan 19 21:06:16 2018 +0100
     1.3 @@ -248,17 +248,249 @@
     1.4  	[ -d "$ROOTCD/boot" ] || die 'Unable to find the rootcd boot directory...'
     1.5  }
     1.6  
     1.7 +get() {
     1.8 +	od -v -j $1 -N ${3:-4} -t u${3:-4} -w${3:-4} -An "$2" 2>/dev/null | sed 's/ *//'
     1.9 +}
    1.10 +
    1.11 +set64() {
    1.12 +	for i in $(seq 0 8 24 ; seq 24 -8 0); do
    1.13 +		printf '\\\\x%02X' $((($2 >> $i) & 255))
    1.14 +	done | xargs echo -en | dd bs=1 conv=notrunc of=$3 seek=$1 2>/dev/null
    1.15 +}
    1.16 +
    1.17 +
    1.18 +# Force the size for the /boot/isolinux/efi.img file
    1.19 +
    1.20 +fix_efi_img_size() {
    1.21 +	local e=$((0x809C))
    1.22 +	for i in BOOT ISOLINUX EFI.IMG ; do
    1.23 +		local sz=$(get $(($e+10)) "$2")
    1.24 +		e=$(($(get $(($e+2)) "$2") * 2048))
    1.25 +		while [ $sz -gt 0 ]; do
    1.26 +			local len=$(get $e "$2" 2)
    1.27 +			[ "$(dd if="$2" bs=1 skip=$(($e+33)) count=${#i} \
    1.28 +				2>/dev/null)" == "$i" ] && continue 2
    1.29 +			[ $len -eq 0 ] && break
    1.30 +			sz=$(($sz-$len))
    1.31 +			e=$(($e+$len))
    1.32 +		done
    1.33 +		return	# not found
    1.34 +	done
    1.35 +	set64 $(($e+10)) $1 "$2"
    1.36 +}
    1.37 +
    1.38 +
    1.39 +# create /boot/isolinux/efi.img to share EFI files with the iso image
    1.40 +
    1.41 +fixup_uefi_part() {
    1.42 +	local n
    1.43 +	[ -s $2/boot/isolinux/efi.img ] || return
    1.44 +
    1.45 +	# Build file list tree
    1.46 +
    1.47 +	( cd $2 ; find efi -type f -exec echo \
    1.48 +	  'stat -c "$(stat -m {} | sed q) %s f %n" {}' \; | sh | sort -n ) \
    1.49 +		>/tmp/fatfiles$$
    1.50 +	n=$(sed 's/ .*//;q' /tmp/fatfiles$$)
    1.51 +	( cd $2; find efi ) | awk -v n=$n 'BEGIN { FS="/" }
    1.52 +		NF > 1 {
    1.53 +			d[NF $NF]+=2
    1.54 +			p[NF $NF]=$0
    1.55 +			b[a++]=NF $NF
    1.56 +			if (NF>2) d[NF-1 $(NF-1)]++
    1.57 +		}
    1.58 +		END {
    1.59 +			while (a-- > 0) if (d[i=b[a]] > 2) {
    1.60 +				n-= j =int((d[i]+63)/64)
    1.61 +				print n " " j*2048 " d " p[i]
    1.62 +			}
    1.63 +			print n-1 " 2048 d efi"
    1.64 +		}' >>/tmp/fatfiles$$
    1.65 +	sort -n /tmp/fatfiles$$ | awk '{ if (s == 0) s=$1;
    1.66 +		print ($1-s)+2 " " $2 " " $3 " " $4 }' > /tmp/fatfiles$$.tmp
    1.67 +	mv -f /tmp/fatfiles$$.tmp /tmp/fatfiles$$
    1.68 +
    1.69 +	# Build fat12 or fat16
    1.70 +
    1.71 +	if [ $(awk '{n+=int(($2+2047)/2048)}END{print n}' /tmp/fatfiles$$) \
    1.72 +			-lt 4000 ]; then
    1.73 +		sed '1s/.*/4087 2049 x\n1 1 x/' /tmp/fatfiles$$ | while read c s x; do
    1.74 +			seq $(($c+1)) $((($s-1)/2048+$c)) 
    1.75 +			echo 4095
    1.76 +		done | awk 'BEGIN { printf "0  "}
    1.77 +		{
    1.78 +			if (n == 0) n=$1
    1.79 +			else {
    1.80 +				printf "%02X %02X %02X ",n%256,
    1.81 +					($1%16)*16+(n/256),$1/16
    1.82 +				n=0
    1.83 +			}
    1.84 +		}
    1.85 +		END {
    1.86 +			if (n != 0) printf "FF 0F 00 "
    1.87 +			print "  |"
    1.88 +		}' | hexdump -R > /tmp/fatbin-12-$$
    1.89 +	else
    1.90 +		sed '1s/.*/65527 2049 x\n1 1 x/' /tmp/fatfiles$$ | while read c s x; do
    1.91 +			seq $(($c+1)) $((($s-1)/2048+$c)) 
    1.92 +			echo 65535
    1.93 +		done | awk 'BEGIN { printf "0  "}
    1.94 +		{
    1.95 +			printf "%02X %02X ",$1%256,$1/256
    1.96 +		}
    1.97 +		END {
    1.98 +			print "  |"
    1.99 +		}' | hexdump -R > /tmp/fatbin-16-$$
   1.100 +	fi
   1.101 +
   1.102 +	# align fat to 2k
   1.103 +	dd of=$(ls /tmp/fatbin-*-$$) count=0 bs=2048 \
   1.104 +		seek=$((($(stat -c %s /tmp/fatbin-*-$$)-1)/2048+1)) 2>/dev/null
   1.105 +
   1.106 +	# build directory records
   1.107 +
   1.108 +	awk '
   1.109 +	BEGIN {
   1.110 +		c=2
   1.111 +		b16="/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0"
   1.112 +		b14="/0/0/0/0/0/0/0/0/0/0/0/0/0/0"
   1.113 +		print "EFI        /x10" b14 "/x0" c "/0/0/x08/0/0"
   1.114 +		for (n=i=0; i<63; i++) print b16 b16
   1.115 +	}
   1.116 +	{
   1.117 +		clu[n]=$1
   1.118 +		size[n]=$2
   1.119 +		type[n]=$3
   1.120 +		name[n]=$4
   1.121 +		n++
   1.122 +	}
   1.123 +	END {
   1.124 +		path="efi"
   1.125 +		d21="/x10" b14 "/x%02X/x%02X/0/x08/0/0\n"
   1.126 +		up[0]=0
   1.127 +		s=1
   1.128 +		do {
   1.129 +			l=split(path,x,"/")
   1.130 +			up[l]=c
   1.131 +			printf ".          " d21,c%256,c/256
   1.132 +			printf "..         " d21,up[l-1]%256,up[l-1]/256
   1.133 +			for (i=s,e=2; i<n; i++) {
   1.134 +				if (substr(name[i],1,length(path)) != path ||
   1.135 +				    split(substr(name[i],length(path)+2),x,"/") > 1)
   1.136 +					continue
   1.137 +				split(toupper(x[1]),x,".")
   1.138 +				if (length(x[1]) >= 8) printf substr(x[1],1,8)
   1.139 +				else printf x[1] substr("       ",1,8-length(x[1]))
   1.140 +				if (length(x[2]) >= 3) printf substr(x[2],1,3)
   1.141 +				else printf x[2] substr("   ",1,3-length(x[2]))
   1.142 +				if (type[i] == "d") printf "/x10"; else printf "/0"
   1.143 +				printf b14 "/x%02X/x%02X",clu[i]%256,clu[i]/256
   1.144 +				printf "/x%02X/x%02X/x%02X/x%02X\n",size[i]%256,
   1.145 +					(size[i]/256)%256,(size[i]/256/256)%256,
   1.146 +					size[i]/256/256/256
   1.147 +				e++
   1.148 +			}
   1.149 +			while (e++ < 64) print b16 b16
   1.150 +			path=name[s]
   1.151 +			c=clu[s]
   1.152 +		} while (type[s++] == "d")
   1.153 +	}' < /tmp/fatfiles$$ | while read line; do
   1.154 +		echo "$line" | sed 's| |/x20|g;s|/|\\\\|g' | xargs echo -en
   1.155 +	done > /tmp/fatdir$$
   1.156 +
   1.157 +	# build boot record
   1.158 +
   1.159 +	fat=$(($(stat -c %s /tmp/fatbin-*-$$)/512))
   1.160 +	r=$((4-($fat+$fat+$(stat -c %s /tmp/fatdir$$)/512)%4))
   1.161 +	dd if=/dev/zero bs=512 count=$r of=/tmp/fatbr$$ 2> /dev/null
   1.162 +	echo -en '\x55\xAA' | \
   1.163 +		dd of=/tmp/fatbr$$ seek=510 bs=1 conv=notrunc 2> /dev/null
   1.164 +	n=$(stat -m $2/boot/isolinux/efi.img | sed q)
   1.165 +	fat="$(printf "%02X %02X" $(($fat%256)) $((($fat>>8)%256)))"
   1.166 +	s=$((($(stat -m $(ls -r $2/boot/rootfs* | sed q) | sed q) - $n)*4))
   1.167 +	if [ $s -gt 65535 ]; then
   1.168 +		size="00 00"
   1.169 +		size32="$(printf "%02X %02X %02X %02X" $(($s%256)) \
   1.170 +			$((($s>>8)%256)) $((($s>>16)%256)) $((($s>>24)%256)) )"
   1.171 +	else
   1.172 +		size="$(printf "%02X %02X" $(($s%256)) $((($s>>8)%256)) )"
   1.173 +		size32="00 00 00 00"
   1.174 +	fi
   1.175 +	t=32; [ -s /tmp/fatbin-16-$$ ] && t=36
   1.176 +	hexdump -R <<EOT | dd conv=notrunc of=/tmp/fatbr$$ 2> /dev/null
   1.177 +0  eb 3c 90 53 6c 69 54 61  7a 00 00 00 02 04 $r 00  |
   1.178 +0  02 40 00 $size f8 $fat   20 00 40 00 00 00 00 00  |
   1.179 +0  $size32     80 00 29 00  00 00 00 4e 4f 20 4e 41  |
   1.180 +0  4d 45 20 20 20 20 46 41  54 31 $t 20 20 20 cd 18  |
   1.181 +0  cd 19 eb fa  |
   1.182 +EOT
   1.183 +
   1.184 +	# patch efi.img stub
   1.185 +
   1.186 +	cat /tmp/fatbr$$ /tmp/fatbin-*-$$ /tmp/fatbin-*-$$ /tmp/fatdir$$ | \
   1.187 +	dd of=$1 conv=notrunc bs=2k seek=$n 2>/dev/null
   1.188 +	fix_efi_img_size $(($s*512)) $1
   1.189 +	rm -f /tmp/fat*$$
   1.190 +}
   1.191 +
   1.192 +
   1.193 +# allocate efi.img stub to share EFI files in the EFI boot partition
   1.194 +
   1.195 +alloc_uefi_part() {
   1.196 +	local basedir=$(dirname "$1")/..
   1.197 +	local clusters=$({
   1.198 +	[ -d $basedir/efi ] &&
   1.199 +		find $basedir/efi -type f -exec stat -c "%s" {} \;
   1.200 +	while [ -s "$1" ]; do
   1.201 +		local efifile
   1.202 +		case "$1" in
   1.203 +		*taz)	efifile=bootia32.efi ;;
   1.204 +		*taz64) efifile=bootx64.efi ;;
   1.205 +		esac
   1.206 +		if [ ! -s $basedir/efi/boot/$efifile ] &&
   1.207 +		   [ $(get $((0x82)) "$1") == $((0x4550)) ]; then
   1.208 +			stat -c "%s" "$1"
   1.209 +			mkdir -p $basedir/efi/boot 2> /dev/null
   1.210 +			ln "$1" $basedir/efi/boot/$efifile
   1.211 +		fi
   1.212 +		shift
   1.213 +	done; } | awk '{ n+=int(($1+2047)/2048) } END { print n }')
   1.214 +	[ $clusters -eq 0 ] && return
   1.215 +	local dclust=$( (cd $basedir; find efi -type d 2>/dev/null) | awk '
   1.216 +		BEGIN {
   1.217 +			FS="/"
   1.218 +		}
   1.219 +		NF > 1 {
   1.220 +			d[NF $NF]+=2
   1.221 +			d[NF-1 $(NF-1)]++
   1.222 +		}
   1.223 +		END {
   1.224 +			for (i in d)
   1.225 +				n+=int((d[i]+63)/64)
   1.226 +			print n
   1.227 +		}')
   1.228 +	clusters=$(($clusters+$dclust))
   1.229 +	if [ $clusters -lt 4000 ]; then
   1.230 +		#     reserved   +    fat*2      +      root dir  +   dirs
   1.231 +		count=$(( 1 + (($clusters*3+4095)/4096)*2 + 1     + $dclust ))
   1.232 +	else
   1.233 +		#     reserved   +    fat*2      +      root dir  +   dirs
   1.234 +		count=$(( 1 + (($clusters+1023)/1024)*2  +  1     + $dclust ))
   1.235 +	fi
   1.236 +	dd if=/dev/zero bs=2k of=$basedir/boot/isolinux/efi.img count=$count
   1.237 +}
   1.238 +
   1.239  
   1.240  # isolinux.conf doesn't know the kernel version.
   1.241  # We name the kernel image 'bzImage'.
   1.242  # isolinux/syslinux first tries the '64' suffix with a 64bits cpu.
   1.243  
   1.244  make_bzImage_hardlink() {
   1.245 -	if [   -s ${1:-.}/vmlinuz*slitaz ]; then
   1.246 +	if [   -e ${1:-.}/vmlinuz*slitaz ]; then
   1.247  		rm -f ${1:-.}/bzImage 2>/dev/null
   1.248  		ln    ${1:-.}/vmlinuz*slitaz ${1:-.}/bzImage
   1.249  	fi
   1.250 -	if [   -s ${1:-.}/vmlinuz*slitaz64 ]; then
   1.251 +	if [   -e ${1:-.}/vmlinuz*slitaz64 ]; then
   1.252  		rm -f ${1:-.}/bzImage64 2> /dev/null
   1.253  		ln    ${1:-.}/vmlinuz*slitaz64 ${1:-.}/bzImage64
   1.254  	fi
   1.255 @@ -269,13 +501,17 @@
   1.256  	cd $2
   1.257  	deduplicate
   1.258  
   1.259 +	make_bzImage_hardlink $2/boot
   1.260 +	alloc_uefi_part $(ls -r $2/boot/vmlinuz*slitaz*)
   1.261 +
   1.262  	cat > /tmp/cdsort$$ <<EOT
   1.263 -$PWD/boot 100
   1.264 -$PWD/boot/bzImage 200
   1.265 -$(n=199; ls -r $PWD/boot/rootfs* | while read f; do echo "$f $((n--))"; done)
   1.266 -$PWD/boot/isolinux 300
   1.267 +$PWD/boot/isolinux 100
   1.268 +$(ls -r $PWD/boot/rootfs* | awk 'BEGIN{n=149} { print $1 " " n-- }')
   1.269 +$(ls $PWD/boot/bzImage* | awk 'BEGIN{n=200} { print $1 " " n-- }')
   1.270 +$(find $PWD/efi -type f 2>/dev/null | awk 'BEGIN{n=299} { print $1 " " n-- }')
   1.271 +$PWD/boot/isolinux/efi.img 300
   1.272 +$PWD/boot/isolinux/isolinux.bin 399
   1.273  $PWD/boot/isolinux/boot.cat 400
   1.274 -$PWD/boot/isolinux/isolinux.bin 399
   1.275  EOT
   1.276  
   1.277  	action 'Computing md5...'
   1.278 @@ -287,8 +523,7 @@
   1.279  	title 'Generating ISO image'
   1.280  
   1.281  	_ 'Generating %s' "$1"
   1.282 -	make_bzImage_hardlink $2/boot
   1.283 -	uefi="$(cd $2 ; ls boot/isolinux/*efi*img 2> /dev/null)"
   1.284 +	uefi="$(cd $2 ; ls boot/isolinux/efi.img 2> /dev/null)"
   1.285  	genisoimage -R  -o $1  -hide-rr-moved -sort /tmp/cdsort$$ \
   1.286  		-b boot/isolinux/isolinux.bin -c boot/isolinux/boot.cat \
   1.287  		-no-emul-boot   -boot-load-size 4   -boot-info-table \
   1.288 @@ -302,7 +537,9 @@
   1.289  
   1.290  	mkdir /tmp/mnt$$
   1.291  	mount -o loop,ro $1 /tmp/mnt$$
   1.292 -	for i in boot/isolinux/isolinux.bin boot/isolinux/boot.cat ; do
   1.293 +	fixup_uefi_part $1 /tmp/mnt$$
   1.294 +	for i in boot/isolinux/isolinux.bin boot/isolinux/boot.cat \
   1.295 +		 ${uefi:+boot/isolinux/efi.img} ; do
   1.296  		sed -i "s|.* $i|$( cd /tmp/mnt$$ ; md5sum $i)|" $2/md5sum
   1.297  	done
   1.298  	dd if=$2/md5sum of=$1 conv=notrunc bs=2k \
   1.299 @@ -320,7 +557,7 @@
   1.300  
   1.301  	if [ -x '/usr/bin/isohybrid' ]; then
   1.302  		action 'Creating hybrid ISO...'
   1.303 -		/usr/bin/isohybrid $1 -entry 2 2>/dev/null
   1.304 +		isohybrid $1 $([ -n "$uefi" ] || echo -entry 2) 2>/dev/null
   1.305  		status
   1.306  	fi
   1.307  
   1.308 @@ -1014,7 +1251,7 @@
   1.309  	grep -q '/sys/block/./dev' $TMP_DIR/initfs/init ||
   1.310  	for i in /dev/fd0 /dev/[hs]d[a-f]* /dev/loop* ; do
   1.311  		cp -a $i $TMP_DIR/initfs/dev
   1.312 -	done
   1.313 +	done 2>/dev/null
   1.314  	$need_lib && for i in /lib/ld-* /lib/lib[cm][-\.]* ; do
   1.315  		cp -a $i $TMP_DIR/initfs/lib
   1.316  	done
   1.317 @@ -1778,7 +2015,7 @@
   1.318  		done
   1.319  
   1.320  		action 'Copying the rootfs...'
   1.321 -		cp $TMP_DIR/boot/rootfs.?z "$TARGET/rootcd/boot"
   1.322 +		cp $TMP_DIR/boot/rootfs*.?z "$TARGET/rootcd/boot"
   1.323  		status
   1.324  
   1.325  		# Extract initramfs.
   1.326 @@ -2187,6 +2424,7 @@
   1.327  				INITRAMFS_SIZE=$(du -chs $TMP_DIR/rootcd/boot/rootfs*.gz | awk 'END { print $1 }')
   1.328  				rm -f $TMP_DIR/rootcd/boot/rootfs.gz $TMP_DIR/rootcd/md5sum
   1.329  				mv $TMP_DIR/rootcd/boot $TMP_DIR/rootfs
   1.330 +				[ -d $TMP_DIR/rootcd/efi ] && mv $TMP_DIR/rootcd/efi $TMP_DIR/rootfs
   1.331  				sed 's/.*  \(.*\).tazpkg*/\1/' > $TMP_DIR/$FLAVOR.pkglist \
   1.332  					< $TMP_DIR/rootfs$INSTALLED.md5
   1.333  				PKGCNT=$(grep -v ^# $TMP_DIR/$FLAVOR.pkglist | wc -l | awk '{ print $1 }')
   1.334 @@ -2202,6 +2440,7 @@
   1.335  				else
   1.336  					find_flavor_rootfs $TMP_DIR/rootfs
   1.337  					[ -d $TMP_DIR/rootfs/boot ] && mv $TMP_DIR/rootfs/boot $TMP_DIR/rootcd
   1.338 +					[ -d $TMP_DIR/rootfs/efi ] && mv $TMP_DIR/rootfs/efi $TMP_DIR/rootcd
   1.339  					for i in rootfs rootcd ; do
   1.340  						[ "$(ls $TMP_DIR/$i)" ] &&
   1.341  						( cd "$TMP_DIR/$i"; find * | cpio -o -H newc ) | dogzip "$TMP_DIR/$FLAVOR.$i"
   1.342 @@ -2369,7 +2608,12 @@
   1.343  		status
   1.344  
   1.345  		# Move the boot dir with the Linux kernel from rootfs.
   1.346 -		# The boot dir goes directly on the CD.
   1.347 +		# The efi & boot dirs go directly on the CD.
   1.348 +		if [ -d "$ROOTFS/efi" ] ; then
   1.349 +			action 'Moving the efi directory...'
   1.350 +			mv $ROOTFS/efi $ROOTCD
   1.351 +			status
   1.352 +		fi
   1.353  		if [ -d "$ROOTFS/boot" ] ; then
   1.354  			action 'Moving the boot directory...'
   1.355  			mv $ROOTFS/boot $ROOTCD