summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJianxun Zhang <jianxun.zhang@linux.intel.com>2016-08-03 11:04:15 -0700
committerTom Zanussi <tom.zanussi@linux.intel.com>2016-08-03 17:37:11 -0500
commitdaa587ed5c950cdcbc3a4b2561fb92209c0784ec (patch)
treeabb5681569ce93984f4112dc12559d70c6dbe2f0
parent7d3305235702a7c730ea9af9db6b00156e664194 (diff)
downloadmeta-intel-daa587ed5c950cdcbc3a4b2561fb92209c0784ec.tar.gz
EFI installer: Deploy board-specific data and kernel cmdline
Extend the existing init-install-efi.sh in OE to call RMC tool so that it can deploy file blobs and a global kernel cmdline fragment associated to the type of current running board. At first, it tries to retrieve a special configuration file INSTALLER.CONFIG associated to the board from RMC database file on ESP. If the config file is fetched successfully, installer parses configuration file to know which file blobs should be deployed from database to target, also with other necessary information like FS attributes of deployed file. If a rule in config file is to create a directory, installer creates it accordingly. Developer must direct installer to create new directory first if destination of a file is in that directory by adding a '/' at the end of a line. The below is an example of INSTALLER.CONFIG. It directs installer to deploy a boot entry boot.conf to EFI partition, create a directory /etc/mylib/ on target's rootfs, and deploy a config file mylib.conf in the created directory. The first several lines started with '#' are comment. efi_entry_dir:root:disk:770:/boot/loader/entries/ boot.conf:root:disk:770:/boot/loader/entries/rmcboot.conf mylibdir:root:root:770:/tgt_root/etc/mylib/ mylib.conf:root:root:660:/tgt_root/etc/mylib/mylib.conf When installer cannot get config file for the type of running board, it skips any board-specific deployment. If a command fails at any step, installer simply moves to the next. After all the boot entries are deployed, installer seeks a config file KBOOTPARAM from RMC database file. In success, it appends the content of KBOOTPARAM to the end of kernel command line of every deployed entry. KBOOTPARAM works as a global kernel command line fragment specific to the type of running board. The installer is copied and modified from OE: ./recipes-core/initrdscripts/files/init-install-efi.sh: (OE-Core rev: 031c2f6ced917a81b4f39dca371773d0275ddf73) Signed-off-by: Jianxun Zhang <jianxun.zhang@linux.intel.com> Reviewed-by: Saul Wold <sgw@linux.intel.com> Signed-off-by: Tom Zanussi <tom.zanussi@linux.intel.com>
-rw-r--r--common/recipes-core/initrdscripts/files/init-install-efi.sh326
-rw-r--r--common/recipes-core/initrdscripts/initramfs-live-install-efi_%.bbappend1
2 files changed, 327 insertions, 0 deletions
diff --git a/common/recipes-core/initrdscripts/files/init-install-efi.sh b/common/recipes-core/initrdscripts/files/init-install-efi.sh
new file mode 100644
index 00000000..e12a9d21
--- /dev/null
+++ b/common/recipes-core/initrdscripts/files/init-install-efi.sh
@@ -0,0 +1,326 @@
1#!/bin/sh -e
2#
3# Copyright (c) 2016, Intel Corporation.
4# All rights reserved.
5#
6# install.sh [device_name] [rootfs_name]
7#
8# This file is a copy of file with same name in OE:
9# meta/recipes-core/initrdscripts/files/. We modify
10# it for RMC feature to deploy file blobs from RMC
11# database file to target.
12
13PATH=/sbin:/bin:/usr/sbin:/usr/bin
14
15# We need 20 Mb for the boot partition
16boot_size=20
17
18# 5% for swap
19swap_ratio=5
20
21# Get a list of hard drives
22hdnamelist=""
23live_dev_name=`cat /proc/mounts | grep ${1%/} | awk '{print $1}'`
24live_dev_name=${live_dev_name#\/dev/}
25# Only strip the digit identifier if the device is not an mmc
26case $live_dev_name in
27 mmcblk*)
28 ;;
29 *)
30 live_dev_name=${live_dev_name%%[0-9]*}
31 ;;
32esac
33
34echo "Searching for hard drives ..."
35
36for device in `ls /sys/block/`; do
37 case $device in
38 loop*)
39 # skip loop device
40 ;;
41 sr*)
42 # skip CDROM device
43 ;;
44 ram*)
45 # skip ram device
46 ;;
47 *)
48 # skip the device LiveOS is on
49 # Add valid hard drive name to the list
50 case $device in
51 $live_dev_name*)
52 # skip the device we are running from
53 ;;
54 *)
55 hdnamelist="$hdnamelist $device"
56 ;;
57 esac
58 ;;
59 esac
60done
61
62if [ -z "${hdnamelist}" ]; then
63 echo "You need another device (besides the live device /dev/${live_dev_name}) to install the image. Installation aborted."
64 exit 1
65fi
66
67TARGET_DEVICE_NAME=""
68for hdname in $hdnamelist; do
69 # Display found hard drives and their basic info
70 echo "-------------------------------"
71 echo /dev/$hdname
72 if [ -r /sys/block/$hdname/device/vendor ]; then
73 echo -n "VENDOR="
74 cat /sys/block/$hdname/device/vendor
75 fi
76 if [ -r /sys/block/$hdname/device/model ]; then
77 echo -n "MODEL="
78 cat /sys/block/$hdname/device/model
79 fi
80 if [ -r /sys/block/$hdname/device/uevent ]; then
81 echo -n "UEVENT="
82 cat /sys/block/$hdname/device/uevent
83 fi
84 echo
85done
86
87# Get user choice
88while true; do
89 echo "Please select an install target or press n to exit ($hdnamelist ): "
90 read answer
91 if [ "$answer" = "n" ]; then
92 echo "Installation manually aborted."
93 exit 1
94 fi
95 for hdname in $hdnamelist; do
96 if [ "$answer" = "$hdname" ]; then
97 TARGET_DEVICE_NAME=$answer
98 break
99 fi
100 done
101 if [ -n "$TARGET_DEVICE_NAME" ]; then
102 break
103 fi
104done
105
106if [ -n "$TARGET_DEVICE_NAME" ]; then
107 echo "Installing image on /dev/$TARGET_DEVICE_NAME ..."
108else
109 echo "No hard drive selected. Installation aborted."
110 exit 1
111fi
112
113device=/dev/$TARGET_DEVICE_NAME
114
115#
116# The udev automounter can cause pain here, kill it
117#
118rm -f /etc/udev/rules.d/automount.rules
119rm -f /etc/udev/scripts/mount*
120
121#
122# Unmount anything the automounter had mounted
123#
124umount ${device}* 2> /dev/null || /bin/true
125
126mkdir -p /tmp
127
128# Create /etc/mtab if not present
129if [ ! -e /etc/mtab ]; then
130 cat /proc/mounts > /etc/mtab
131fi
132
133disk_size=$(parted ${device} unit mb print | grep '^Disk .*: .*MB' | cut -d" " -f 3 | sed -e "s/MB//")
134
135swap_size=$((disk_size*swap_ratio/100))
136rootfs_size=$((disk_size-boot_size-swap_size))
137
138rootfs_start=$((boot_size))
139rootfs_end=$((rootfs_start+rootfs_size))
140swap_start=$((rootfs_end))
141
142# MMC devices are special in a couple of ways
143# 1) they use a partition prefix character 'p'
144# 2) they are detected asynchronously (need rootwait)
145rootwait=""
146part_prefix=""
147if [ ! "${device#/dev/mmcblk}" = "${device}" ]; then
148 part_prefix="p"
149 rootwait="rootwait"
150fi
151bootfs=${device}${part_prefix}1
152rootfs=${device}${part_prefix}2
153swap=${device}${part_prefix}3
154
155echo "*****************"
156echo "Boot partition size: $boot_size MB ($bootfs)"
157echo "Rootfs partition size: $rootfs_size MB ($rootfs)"
158echo "Swap partition size: $swap_size MB ($swap)"
159echo "*****************"
160echo "Deleting partition table on ${device} ..."
161dd if=/dev/zero of=${device} bs=512 count=35
162
163echo "Creating new partition table on ${device} ..."
164parted ${device} mklabel gpt
165
166echo "Creating boot partition on $bootfs"
167parted ${device} mkpart boot fat32 0% $boot_size
168parted ${device} set 1 boot on
169
170echo "Creating rootfs partition on $rootfs"
171parted ${device} mkpart root ext3 $rootfs_start $rootfs_end
172
173echo "Creating swap partition on $swap"
174parted ${device} mkpart swap linux-swap $swap_start 100%
175
176parted ${device} print
177
178echo "Formatting $bootfs to vfat..."
179mkfs.vfat $bootfs
180
181echo "Formatting $rootfs to ext3..."
182mkfs.ext3 $rootfs
183
184echo "Formatting swap partition...($swap)"
185mkswap $swap
186
187mkdir /tgt_root
188mkdir /src_root
189mkdir -p /boot
190
191# Handling of the target root partition
192mount $rootfs /tgt_root
193mount -o rw,loop,noatime,nodiratime /run/media/$1/$2 /src_root
194echo "Copying rootfs files..."
195cp -a /src_root/* /tgt_root
196if [ -d /tgt_root/etc/ ] ; then
197 boot_uuid=$(blkid -o value -s UUID ${bootfs})
198 swap_part_uuid=$(blkid -o value -s PARTUUID ${swap})
199 echo "/dev/disk/by-partuuid/$swap_part_uuid swap swap defaults 0 0" >> /tgt_root/etc/fstab
200 echo "UUID=$boot_uuid /boot vfat defaults 1 2" >> /tgt_root/etc/fstab
201 # We dont want udev to mount our root device while we're booting...
202 if [ -d /tgt_root/etc/udev/ ] ; then
203 echo "${device}" >> /tgt_root/etc/udev/mount.blacklist
204 fi
205fi
206
207# Handling of the target boot partition
208mount $bootfs /boot
209echo "Preparing boot partition..."
210
211# RMC deployment
212RMC_CMD=/src_root/usr/bin/rmc
213RMC_DB=/run/media/$1/rmc.db
214
215EFIDIR="/boot/EFI/BOOT"
216mkdir -p $EFIDIR
217
218# Copy the efi loader
219cp /run/media/$1/EFI/BOOT/*.efi $EFIDIR
220
221# We only support gummiboot/systemd-boot. Leave grub-efi not changed.
222if [ -d /run/media/$1/loader ]; then
223 # copy config files for gummiboot
224 cp -dr /run/media/$1/loader /boot
225fi
226
227# We don't want to quit when a step failed. For example,
228# a file system could not support some operations.
229set +e
230
231if [ -f "${RMC_DB}" ] && [ -f "${RMC_CMD}" ]; then
232 echo "Found RMC database and tool, start RMC deployment"
233 # query INSTALLER.CONFIG from RMC DB
234 if ${RMC_CMD} -B INSTALLER.CONFIG -d "${RMC_DB}" -o /tmp/installer.config; then
235 while IFS=':' read -r NAME TGT_UID TGT_GID TGT_MODE TGT_PATH; do
236 # skip comment
237 # The regexp in grep works with busybox grep which doesn't
238 # seem to have a -P to recognize '\t'. But this expression could not
239 # work with gnu grep...
240 if echo "$NAME"|grep -q $'^[ \t]*#'; then
241 continue
242 fi
243 # check if we should create a directory (last char in target path is '/')
244 # or deploy a file
245 LAST_CHAR=$(echo "${TGT_PATH:$((${#TGT_PATH}-1)):1}")
246
247 # Do not bail out for failures but user should get stderr message
248 if [ ${LAST_CHAR} = "/" ]; then
249 # name field is skipped for directory
250 echo "DIR: ${TGT_UID}:${TGT_GID}:${TGT_MODE} => ${TGT_PATH}"
251 mkdir -p "$TGT_PATH"
252 chown "${TGT_UID}:${TGT_GID}" "$TGT_PATH"
253 chmod "${TGT_MODE}" "$TGT_PATH"
254 else
255 ${RMC_CMD} -B "${NAME}" -d "${RMC_DB}" -o "${TGT_PATH}"
256 echo "FILE: ${NAME}:${TGT_UID}:${TGT_GID}:${TGT_MODE} => ${TGT_PATH}"
257 chown "${TGT_UID}:${TGT_GID}" "$TGT_PATH"
258 chmod "${TGT_MODE}" "$TGT_PATH"
259 fi
260 done < /tmp/installer.config
261 rm -rf /tmp/installer.config
262
263 # remove rmc from target since we don't think it is a valid
264 # case to run rmc after installation.
265 rm -rf /tgt_root/usr/bin/rmc
266 echo "RMC deployment finished"
267 else
268 echo "INSTALLER.CONFIG is not found, skip RMC deployment"
269 fi
270fi
271set -e
272
273if [ -f /run/media/$1/EFI/BOOT/grub.cfg ]; then
274 root_part_uuid=$(blkid -o value -s PARTUUID ${rootfs})
275 GRUBCFG="$EFIDIR/grub.cfg"
276 cp /run/media/$1/EFI/BOOT/grub.cfg $GRUBCFG
277 # Update grub config for the installed image
278 # Delete the install entry
279 sed -i "/menuentry 'install'/,/^}/d" $GRUBCFG
280 # Delete the initrd lines
281 sed -i "/initrd /d" $GRUBCFG
282 # Delete any LABEL= strings
283 sed -i "s/ LABEL=[^ ]*/ /" $GRUBCFG
284 # Delete any root= strings
285 sed -i "s/ root=[^ ]*/ /g" $GRUBCFG
286 # Add the root= and other standard boot options
287 sed -i "s@linux /vmlinuz *@linux /vmlinuz root=PARTUUID=$root_part_uuid rw $rootwait quiet @" $GRUBCFG
288fi
289
290if [ -d /run/media/$1/loader ]; then
291 rootuuid=$(blkid -o value -s PARTUUID ${rootfs})
292 GUMMIBOOT_CFGS="/boot/loader/entries/*.conf"
293 # delete the install entry
294 # fixme: If RMC did deploy install.conf at previous steps, it is purged here...
295 rm -f /boot/loader/entries/install.conf
296 # delete the initrd lines
297 sed -i "/initrd /d" $GUMMIBOOT_CFGS
298 # delete any LABEL= strings
299 sed -i "s/ LABEL=[^ ]*/ /" $GUMMIBOOT_CFGS
300 # delete any root= strings
301 sed -i "s/ root=[^ ]*/ /" $GUMMIBOOT_CFGS
302 # add the root= and other standard boot options
303 sed -i "s@options *@options root=PARTUUID=$rootuuid rw $rootwait quiet @" $GUMMIBOOT_CFGS
304 # if RMC feature presents, append global kernel command line fragment when it exists.
305 if [ -f "${RMC_DB}" ] && [ -f "${RMC_CMD}" ]; then
306 if ${RMC_CMD} -B KBOOTPARAM -d "${RMC_DB}" -o /tmp/kbootparam; then
307 sed -i "/^[ \t]*options/ s/$/ $(cat /tmp/kbootparam)/" $GUMMIBOOT_CFGS
308 rm /tmp/kbootparam
309 fi
310 fi
311fi
312
313cp /run/media/$1/vmlinuz /boot
314
315umount /src_root
316umount /tgt_root
317umount /boot
318
319sync
320
321echo "Remove your installation media, and press ENTER"
322
323read enter
324
325echo "Rebooting..."
326reboot -f
diff --git a/common/recipes-core/initrdscripts/initramfs-live-install-efi_%.bbappend b/common/recipes-core/initrdscripts/initramfs-live-install-efi_%.bbappend
new file mode 100644
index 00000000..81fe7b79
--- /dev/null
+++ b/common/recipes-core/initrdscripts/initramfs-live-install-efi_%.bbappend
@@ -0,0 +1 @@
FILESEXTRAPATHS_prepend := "${THISDIR}/files:"