1#!/bin/sh -e 2# 3# Copyright (c) 2012, Intel Corporation. 4# All rights reserved. 5# 6# install.sh [device_name] [rootfs_name] 7# 8 9PATH=/sbin:/bin:/usr/sbin:/usr/bin 10 11# figure out how big of a boot partition we need 12boot_size=$(du -ms /run/media/$1/ | awk '{print $1}') 13# remove rootfs.img ($2) from the size if it exists, as its not installed to /boot 14if [ -e /run/media/$1/$2 ]; then 15 boot_size=$(( boot_size - $( du -ms /run/media/$1/$2 | awk '{print $1}') )) 16fi 17# remove initrd from size since its not currently installed 18if [ -e /run/media/$1/initrd ]; then 19 boot_size=$(( boot_size - $( du -ms /run/media/$1/initrd | awk '{print $1}') )) 20fi 21# add 10M to provide some extra space for users and account 22# for rounding in the above subtractions 23boot_size=$(( boot_size + 10 )) 24 25# 5% for swap 26swap_ratio=5 27 28# Get a list of hard drives 29hdnamelist="" 30live_dev_name=`cat /proc/mounts | grep ${1%/} | awk '{print $1}'` 31live_dev_name=${live_dev_name#\/dev/} 32# Only strip the digit identifier if the device is not an mmc 33case $live_dev_name in 34 mmcblk*) 35 ;; 36 nvme*) 37 ;; 38 *) 39 live_dev_name=${live_dev_name%%[0-9]*} 40 ;; 41esac 42 43echo "Searching for hard drives ..." 44 45# Some eMMC devices have special sub devices such as mmcblk0boot0 etc 46# we're currently only interested in the root device so pick them wisely 47devices=`ls /sys/block/ | grep -v mmcblk` || true 48mmc_devices=`ls /sys/block/ | grep "mmcblk[0-9]\{1,\}$"` || true 49devices="$devices $mmc_devices" 50 51for device in $devices; do 52 case $device in 53 loop*) 54 # skip loop device 55 ;; 56 sr*) 57 # skip CDROM device 58 ;; 59 ram*) 60 # skip ram device 61 ;; 62 *) 63 # skip the device LiveOS is on 64 # Add valid hard drive name to the list 65 case $device in 66 $live_dev_name*) 67 # skip the device we are running from 68 ;; 69 *) 70 hdnamelist="$hdnamelist $device" 71 ;; 72 esac 73 ;; 74 esac 75done 76 77if [ -z "${hdnamelist}" ]; then 78 echo "You need another device (besides the live device /dev/${live_dev_name}) to install the image. Installation aborted." 79 exit 1 80fi 81 82TARGET_DEVICE_NAME="" 83for hdname in $hdnamelist; do 84 # Display found hard drives and their basic info 85 echo "-------------------------------" 86 echo /dev/$hdname 87 if [ -r /sys/block/$hdname/device/vendor ]; then 88 echo -n "VENDOR=" 89 cat /sys/block/$hdname/device/vendor 90 fi 91 if [ -r /sys/block/$hdname/device/model ]; then 92 echo -n "MODEL=" 93 cat /sys/block/$hdname/device/model 94 fi 95 if [ -r /sys/block/$hdname/device/uevent ]; then 96 echo -n "UEVENT=" 97 cat /sys/block/$hdname/device/uevent 98 fi 99 echo 100done 101 102# Get user choice 103while true; do 104 echo "Please select an install target or press n to exit ($hdnamelist ): " 105 read answer 106 if [ "$answer" = "n" ]; then 107 echo "Installation manually aborted." 108 exit 1 109 fi 110 for hdname in $hdnamelist; do 111 if [ "$answer" = "$hdname" ]; then 112 TARGET_DEVICE_NAME=$answer 113 break 114 fi 115 done 116 if [ -n "$TARGET_DEVICE_NAME" ]; then 117 break 118 fi 119done 120 121if [ -n "$TARGET_DEVICE_NAME" ]; then 122 echo "Installing image on /dev/$TARGET_DEVICE_NAME ..." 123else 124 echo "No hard drive selected. Installation aborted." 125 exit 1 126fi 127 128device=/dev/$TARGET_DEVICE_NAME 129 130# 131# The udev automounter can cause pain here, kill it 132# 133rm -f /etc/udev/rules.d/automount.rules 134rm -f /etc/udev/scripts/mount* 135 136# 137# Unmount anything the automounter had mounted 138# 139umount ${device}* 2> /dev/null || /bin/true 140 141mkdir -p /tmp 142 143# Create /etc/mtab if not present 144if [ ! -e /etc/mtab ] && [ -e /proc/mounts ]; then 145 ln -sf /proc/mounts /etc/mtab 146fi 147 148disk_size=$(parted ${device} unit mb print | grep '^Disk .*: .*MB' | cut -d" " -f 3 | sed -e "s/MB//") 149 150swap_size=$((disk_size*swap_ratio/100)) 151rootfs_size=$((disk_size-boot_size-swap_size)) 152 153rootfs_start=$((boot_size)) 154rootfs_end=$((rootfs_start+rootfs_size)) 155swap_start=$((rootfs_end)) 156 157# MMC devices are special in a couple of ways 158# 1) they use a partition prefix character 'p' 159# 2) they are detected asynchronously (need rootwait) 160rootwait="" 161part_prefix="" 162if [ ! "${device#/dev/mmcblk}" = "${device}" ] || \ 163 [ ! "${device#/dev/nvme}" = "${device}" ]; then 164 part_prefix="p" 165 rootwait="rootwait" 166fi 167 168# USB devices also require rootwait 169if [ -n `readlink /dev/disk/by-id/usb* | grep $TARGET_DEVICE_NAME` ]; then 170 rootwait="rootwait" 171fi 172 173bootfs=${device}${part_prefix}1 174rootfs=${device}${part_prefix}2 175swap=${device}${part_prefix}3 176 177echo "*****************" 178echo "Boot partition size: $boot_size MB ($bootfs)" 179echo "Rootfs partition size: $rootfs_size MB ($rootfs)" 180echo "Swap partition size: $swap_size MB ($swap)" 181echo "*****************" 182echo "Deleting partition table on ${device} ..." 183dd if=/dev/zero of=${device} bs=512 count=35 184 185echo "Creating new partition table on ${device} ..." 186parted ${device} mklabel gpt 187 188echo "Creating boot partition on $bootfs" 189parted ${device} mkpart boot fat32 0% $boot_size 190parted ${device} set 1 boot on 191 192echo "Creating rootfs partition on $rootfs" 193parted ${device} mkpart root ext4 $rootfs_start $rootfs_end 194 195echo "Creating swap partition on $swap" 196parted ${device} mkpart swap linux-swap $swap_start 100% 197 198parted ${device} print 199 200echo "Waiting for device nodes..." 201C=0 202while [ $C -ne 3 ] && [ ! -e $bootfs -o ! -e $rootfs -o ! -e $swap ]; do 203 C=$(( C + 1 )) 204 sleep 1 205done 206 207echo "Formatting $bootfs to vfat..." 208mkfs.vfat $bootfs 209 210echo "Formatting $rootfs to ext4..." 211mkfs.ext4 $rootfs 212 213echo "Formatting swap partition...($swap)" 214mkswap $swap 215 216mkdir /tgt_root 217mkdir /src_root 218mkdir -p /boot 219 220# Handling of the target root partition 221mount $rootfs /tgt_root 222mount -o rw,loop,noatime,nodiratime /run/media/$1/$2 /src_root 223echo "Copying rootfs files..." 224cp -a /src_root/* /tgt_root 225if [ -d /tgt_root/etc/ ] ; then 226 boot_uuid=$(blkid -o value -s UUID ${bootfs}) 227 swap_part_uuid=$(blkid -o value -s PARTUUID ${swap}) 228 echo "/dev/disk/by-partuuid/$swap_part_uuid swap swap defaults 0 0" >> /tgt_root/etc/fstab 229 echo "UUID=$boot_uuid /boot vfat defaults 1 2" >> /tgt_root/etc/fstab 230 # We dont want udev to mount our root device while we're booting... 231 if [ -d /tgt_root/etc/udev/ ] ; then 232 echo "${device}" >> /tgt_root/etc/udev/mount.ignorelist 233 fi 234fi 235 236umount /src_root 237 238# Handling of the target boot partition 239mount $bootfs /boot 240echo "Preparing boot partition..." 241 242EFIDIR="/boot/EFI/BOOT" 243mkdir -p $EFIDIR 244# Copy the efi loader 245cp /run/media/$1/EFI/BOOT/*.efi $EFIDIR 246 247if [ -f /run/media/$1/EFI/BOOT/grub.cfg ]; then 248 root_part_uuid=$(blkid -o value -s PARTUUID ${rootfs}) 249 GRUBCFG="$EFIDIR/grub.cfg" 250 cp /run/media/$1/EFI/BOOT/grub.cfg $GRUBCFG 251 # Update grub config for the installed image 252 # Delete the install entry 253 sed -i "/menuentry 'install'/,/^}/d" $GRUBCFG 254 # Delete the initrd lines 255 sed -i "/initrd /d" $GRUBCFG 256 # Delete any LABEL= strings 257 sed -i "s/ LABEL=[^ ]*/ /" $GRUBCFG 258 # Replace root= and add additional standard boot options 259 # We use root as a sentinel value, as vmlinuz is no longer guaranteed 260 sed -i "s/ root=[^ ]*/ root=PARTUUID=$root_part_uuid rw $rootwait quiet /g" $GRUBCFG 261fi 262 263if [ -d /run/media/$1/loader ]; then 264 rootuuid=$(blkid -o value -s PARTUUID ${rootfs}) 265 SYSTEMDBOOT_CFGS="/boot/loader/entries/*.conf" 266 # copy config files for systemd-boot 267 cp -dr /run/media/$1/loader /boot 268 # delete the install entry 269 rm -f /boot/loader/entries/install.conf 270 # delete the initrd lines 271 sed -i "/initrd /d" $SYSTEMDBOOT_CFGS 272 # delete any LABEL= strings 273 sed -i "s/ LABEL=[^ ]*/ /" $SYSTEMDBOOT_CFGS 274 # delete any root= strings 275 sed -i "s/ root=[^ ]*/ /" $SYSTEMDBOOT_CFGS 276 # add the root= and other standard boot options 277 sed -i "s@options *@options root=PARTUUID=$rootuuid rw $rootwait quiet @" $SYSTEMDBOOT_CFGS 278fi 279 280umount /tgt_root 281 282# copy any extra files needed for ESP 283if [ -d /run/media/$1/esp ]; then 284 cp -r /run/media/$1/esp/* /boot 285fi 286 287# Copy kernel artifacts. To add more artifacts just add to types 288# For now just support kernel types already being used by something in OE-core 289for types in bzImage zImage vmlinux vmlinuz fitImage; do 290 for kernel in `find /run/media/$1/ -name $types*`; do 291 cp $kernel /boot 292 done 293done 294 295umount /boot 296 297sync 298 299echo "Installation successful. Remove your installation media and press ENTER to reboot." 300 301read enter 302 303echo "Rebooting..." 304reboot -f 305