Bootloader updaten

Kamikaze

Warrior of Sunlight
Teammitglied
Letztens ist mir aufgefallen, dass der Bootloader irgendeine Fehlermeldung raushaut direkt bevor das Terminal zurückgesetzt wird und der Kernel übernimmt. So fiel mir dann ein, dass ich nie den Bootloader kram mit update. Also habe ich mir jetzt ein kleines Skript geschrieben. Der Output sieht so aus:

Code:
root# updategptboot nvd0
updategptboot> gpart bootcode -b /boot/pmbr nvd0
bootcode written to nvd0
updategptboot> gpart bootcode -p /boot/gptzfsboot -i 1 nvd0
partcode written to nvd0p1
updategptboot> install /boot/loader.efi nvd0p2:/efi/boot/FreeBSD-amd64.efi
updategptboot> efibootmgr -cl "nvd0p2:/efi/boot/FreeBSD-amd64.efi" -L "nvd0/amd64/FreeBSD AprilRyan.norad 12.1-STABLE FreeBSD 12.1-STABLE 4b39aea0c0b(kami/12) S403  amd64"
updategptboot> efibootmgr -a 0000
BootCurrent: 0000
Timeout    : 0 seconds
BootOrder  : 0000, 0003, 2001, 2002, 2003
+Boot0000* nvd0/amd64/FreeBSD AprilRyan.norad 12.1-STABLE FreeBSD 12.1-STABLE 4b39aea0c0b(kami/12) S403  amd64
 Boot0003* nvd1/amd64/FreeBSD AprilRyan.norad 12.1-STABLE FreeBSD 12.1-STABLE 4b39aea0c0b(kami/12) S403  amd64
 Boot2001* EFI USB Device
 Boot2002* EFI DVD/CDROM
 Boot2003* EFI Network
root#

Ich habe bei mir das Bootzeug für EFI und Legacy (BIOS) auf der Platte. Das Skript updated beides, sofern die entsprechenden Partitionen vorhanden sind. Wenn keine freebsd-ufs aber eine freebsd-zfs Partition vorhanden ist wird /boot/gptzfsboot in die freebsd-boot Parition installiert, sonst /boot/gptboot. Ich würde die Entscheidung gerne nach dem Active bit der Partitionen setzen. Aber ich habe schlicht in der gpart Manpage nicht gefunden wie ich das auslese.

In eine EFI Partition wird der Loader installiert.

Vielleicht hat ja noch jemand einen Nutzen davon oder Vorschläge?

Code:
#!/bin/sh
set -fe
readonly arch="$(uname -p)" os="$(uname -s)"
readonly tmpdir="$(mktemp -dt updatezfsboot)"
trap "rmdir ${tmpdir} 2>&- || (umount ${tmpdir} && rmdir ${tmpdir})" EXIT

getefivar() {
	local var tag tail
	efibootmgr | while read -r var tag tail; do
		if [ "$tag" = "$1" ]; then
			var="${var#*Boot}"
			echo "${var%\*}"
			return 0
		fi
	done
}

run() {
	echo "${0##*/}> ${*}"
	"$@"
}

for drive in "$@"; do
	unset efi freebsd_boot freebsd_zfs freebsd_ufs
	if ! gpart show "$drive" >&- 2>&-; then
		echo "no such drive: ${drive}" >&2
		exit 1
	fi
	eval "$(gpart show "$drive" | awk '
	$0 && NR > 1 {
		gsub(/[^[:alnum:]+]/, "_", $4)
		print $4 "=" $3
	}')"
	if [ -z "${freebsd_zfs}${freebsd_ufs}" ]; then
		echo "no freebsd-zfs or ufs partition on ${drive}" >&2
		exit 2
	fi

	if [ -z "${efi}${freebsd_boot}" ]; then
		echo "no efi or freebsd-boot partition on ${drive}" >&2
		exit 3
	fi
	run gpart bootcode -b /boot/pmbr "${drive}" || exit 4
	if [ -n "$freebsd_boot" ]; then
		if [ -n "$freebsd_ufs" ]; then
			run gpart bootcode -p /boot/gptboot -i "${freebsd_boot}" "${drive}" || exit 5
		else
			run gpart bootcode -p /boot/gptzfsboot -i "${freebsd_boot}" "${drive}" || exit 5
		fi
	fi
	if [ -n "$efi" ]; then
		mount -t msdosfs "/dev/${drive}p${efi}" "${tmpdir}" || exit 6
		path="/efi/boot"
		file="${path}/${os}-${arch}.efi"
		echo "${0##*/}> install /boot/loader.efi ${drive}p${efi}:${file}"
		mkdir -p "${tmpdir}${path}" || exit 6
		cp /boot/loader.efi "${tmpdir}${file}" || exit 6
		tag="${drive}/${arch}/${os}"
		label="${tag%/*}/$(uname -a)"
		var="$(getefivar "$tag")"
		if [ -n "$var" ]; then
			efibootmgr -B "$var" >&- || exit 6
		fi
		echo "${0##*/}> efibootmgr -cl \"${drive}p${efi}:${file}\" -L \"${label}\""
		efibootmgr -cl "${tmpdir}${file}" -L "$label" >&- || exit 6
		var="$(getefivar "$tag")"
		if [ -n "$var" ]; then
			run efibootmgr -a "$var" || exit 6
		else
			echo "failed to register efi: ${label}" >&2
			exit 6
		fi
		umount "$tmpdir" || exit 6
	fi
done
 
Hier ist etwas in Arbeit. :D
Code:
kamikaze# gpart show
=>        40  2000409184  nvd0  GPT  (954G)
          40         984     1  freebsd-boot  (492K)
        1024       31744     2  efi  (16M)
       32768    33521664     3  freebsd-swap  (16G)
    33554432  1918894080     4  freebsd-zfs  (915G)
  1952448512    47960712        - free -  (23G)

=>        40  2000409184  nvd1  GPT  (954G)
          40         984     1  freebsd-boot  (492K)
        1024       31744     2  efi  (16M)
       32768    33521664     3  freebsd-swap  (16G)
    33554432  1918894080     4  freebsd-zfs  (915G)
  1952448512    47960712        - free -  (23G)

kamikaze# src/loaderupdate -h
usage: loaderupdate -h
       loaderupdate [-D destdir] [-b bootloader] [-e efiloader] [-p pmbr]
                    device ... [-dn]
       loaderupdate [-D destdir] [-b bootloader] [-e efiloader] [-p pmbr]
                    -a [-dn]
       loaderupdate [-D destdir] [-b bootloader] [-e efiloader] [-p pmbr]
                    -P [-an] [device ...]
        -a, --all         Update loaders of all devices
        -b, --bootloader  The freebsd-boot loader to install, e.g. /boot/gptboot
        -d, --demo        Print the actions that would be performed
        -D, --destdir     The root containing /boot
        -e, --efiloader   The EFI loader to install, e.g. /boot/loader.efi
        -h, --help        Display the list of command arguments
        -n, --noefi       Do not create EFI Boot Manager entries
        -P, --dump        Show the detected partitioning
        -p, --pmbr        The protective MBR image, e.g. /boot/pmbr
kamikaze# src/loaderupdate -Pa
Boot Environment
----------------
destdir:                /
ostype:                 FreeBSD
kernel version:         FreeBSD 12.2-STABLE 760e643de558(kami/12) SCO15M19
kernel arch:            amd64
protective MBR:         /boot/pmbr
freebsd-boot loader:    /boot/gptzfsboot
EFI loader:             /boot/loader.efi

Device nvd0
-----------
    install:            /boot/pmbr > nvd0
    install:            /boot/gptzfsboot > nvd0p1
    install:            /boot/loader.efi > nvd0p2:/efi/FreeBSD/bootamd64.efi
    EFI boot entry:     nvd0/amd64/FreeBSD 12.2-STABLE 760e643de558(kami/12) SCO15M19

Device nvd1
-----------
    install:            /boot/pmbr > nvd1
    install:            /boot/gptzfsboot > nvd1p1
    install:            /boot/loader.efi > nvd1p2:/efi/FreeBSD/bootamd64.efi
    EFI boot entry:     nvd1/amd64/FreeBSD 12.2-STABLE 760e643de558(kami/12) SCO15M19
kamikaze#

Der Kernel Informationen werden direkt mit readelf(1), nm(1) und dd(1) aus dem Kernel unter DESTDIR/boot/kernel/kernel gefummelt. Die Loader Images können von Hand angegeben werden aber der Default für freebsd-boot hängt vom Dateisystem unter dem DESTDIR gemountet ist ab. Der PMBR wird auch nur installiert, wenn eine freebsd-boot Partition vorhanden ist. Gleiches gillt für den EFI boot entry, der wird nur gemacht, wenn eine efi Partition vorhanden ist. Kann aber auch manuell abgeschaltet werden (falls man hier eine Platte für einen anderen Rechner vorbereitet).
 
Zurück
Oben