From 946a83c478943914bcf576bd772689ef74c27fdd Mon Sep 17 00:00:00 2001 From: root Date: Sat, 22 Jun 2013 01:28:29 -0700 Subject: Sat Jun 22 01:28:11 PDT 2013 --- extra/efilinux-efi/PKGBUILD | 62 ++ extra/efilinux-efi/efilinux-efi.install | 23 + extra/php-xcache/PKGBUILD | 6 +- extra/refind-efi/PKGBUILD | 211 +++++++ .../UDK-MdePkg-Revert-PathNodeCount.patch | 660 +++++++++++++++++++++ extra/refind-efi/refind-efi.install | 31 + .../refind_include_more_shell_paths.patch | 13 + extra/refind-efi/refind_linux.conf | 5 + 8 files changed, 1008 insertions(+), 3 deletions(-) create mode 100644 extra/efilinux-efi/PKGBUILD create mode 100644 extra/efilinux-efi/efilinux-efi.install create mode 100644 extra/refind-efi/PKGBUILD create mode 100644 extra/refind-efi/UDK-MdePkg-Revert-PathNodeCount.patch create mode 100644 extra/refind-efi/refind-efi.install create mode 100644 extra/refind-efi/refind_include_more_shell_paths.patch create mode 100644 extra/refind-efi/refind_linux.conf (limited to 'extra') diff --git a/extra/efilinux-efi/PKGBUILD b/extra/efilinux-efi/PKGBUILD new file mode 100644 index 000000000..bd75029c5 --- /dev/null +++ b/extra/efilinux-efi/PKGBUILD @@ -0,0 +1,62 @@ +# Contributor : Keshav Padram <(the.ridikulus.rat) (aatt) (gemmaeiil) (ddoott) (ccoomm)> + +_gitroot="git://git.kernel.org/pub/scm/boot/efilinux/efilinux.git" +_gitname="efilinux" +_gitbranch="master" + +pkgname="efilinux-efi" +pkgver="1.0" +pkgrel="8" +pkgdesc="Simple UEFI Linux bootloader - Precursor to EFISTUB" +url="https://github.com/mfleming/efilinux" +arch=('x86_64' 'i686') +license=('GPL') +makedepends=('gnu-efi-libs') +depends=('dosfstools' 'efibootmgr') +options=('!strip') +install="${pkgname}.install" + +source=("${_gitname}::git+${_gitroot}#branch=${_gitbranch}") +sha1sums=('SKIP') + +[[ "${CARCH}" == "x86_64" ]] && _EFI_ARCH="x86_64" +[[ "${CARCH}" == "i686" ]] && _EFI_ARCH="ia32" + +[[ "${CARCH}" == "x86_64" ]] && _EFI_S_ARCH="x64" +[[ "${CARCH}" == "i686" ]] && _EFI_S_ARCH="ia32" + +build() { + + rm -rf "${srcdir}/efilinux-${pkgver}/" || true + cp -r "${srcdir}/${_gitname}" "${srcdir}/efilinux-${pkgver}" + + cd "${srcdir}/efilinux-${pkgver}/" + + ## Add "-fno-strict-aliasing -fno-stack-protector -fno-stack-check -mno-sse -mno-mmx" to CFLAGS + sed 's|-DEFI_FUNCTION_WRAPPER|-fno-strict-aliasing -fno-stack-protector -fno-stack-check -mno-sse -mno-mmx -DEFI_FUNCTION_WRAPPER|g' -i "${srcdir}/efilinux-${pkgver}/Makefile" + + ## Add -DGNU_EFI_USE_MS_ABI to CFLAGS + sed 's|-DEFI_FUNCTION_WRAPPER|-DEFI_FUNCTION_WRAPPER -DGNU_EFI_USE_MS_ABI|g' -i "${srcdir}/efilinux-${pkgver}/Makefile" + + ## Add -m64 for x86_64 build + sed 's|CFLAGS += -mno-red-zone|CFLAGS += -m64 -mno-red-zone|g' -i "${srcdir}/efilinux-${pkgver}/Makefile" + + ## Unset all compiler FLAGS + unset CFLAGS + unset CPPFLAGS + unset CXXFLAGS + unset LDFLAGS + unset MAKEFLAGS + + make CRT0="/usr/lib/crt0-efi-${_EFI_ARCH}.o" LDSCRIPT="/usr/lib/elf_${_EFI_ARCH}_efi.lds" + +} + +package() { + + cd "${srcdir}/efilinux-${pkgver}/" + + install -d "${pkgdir}/usr/lib/efilinux/" + install -D -m0644 "${srcdir}/efilinux-${pkgver}/efilinux.efi" "${pkgdir}/usr/lib/efilinux/efilinux${_EFI_S_ARCH}.efi" + +} diff --git a/extra/efilinux-efi/efilinux-efi.install b/extra/efilinux-efi/efilinux-efi.install new file mode 100644 index 000000000..6d6e817c5 --- /dev/null +++ b/extra/efilinux-efi/efilinux-efi.install @@ -0,0 +1,23 @@ +post_install() { + + cat << EOF + +efilinux has been installed at /usr/lib/efilinux/*.efi + +Copy the efi application for your UEFI ARCH to a sub-directory of +/EFI/ and add an entry to firmware boot menu using efibootmgr +or mactel-boot (for Macs) + +Usage instructions at http://thread.gmane.org/gmane.linux.kernel/1172645 +and http://article.gmane.org/gmane.linux.kernel/1175060 + +EOF + +} + +post_upgrade() { + + post_install + +} + diff --git a/extra/php-xcache/PKGBUILD b/extra/php-xcache/PKGBUILD index 37470f59a..ad9442b53 100644 --- a/extra/php-xcache/PKGBUILD +++ b/extra/php-xcache/PKGBUILD @@ -1,8 +1,8 @@ -# $Id: PKGBUILD 175092 2013-01-13 14:39:10Z pierre $ +# $Id: PKGBUILD 188803 2013-06-21 12:38:37Z pierre $ # Maintainer: Pierre Schmitz pkgname=php-xcache -pkgver=3.0.1 +pkgver=3.0.3 pkgrel=1 arch=('i686' 'x86_64') pkgdesc='A PHP opcode cacher' @@ -12,7 +12,7 @@ license=('custom') source=("http://xcache.lighttpd.net/pub/Releases/${pkgver}/xcache-${pkgver}.tar.bz2" 'xcache.ini') backup=('etc/php/conf.d/xcache.ini') -md5sums=('45086010bc4f82f506c08be1c556941b' +md5sums=('8e9d59785725747f9f099af2bd54ddd2' '8fd9ce537ada9463c4b0c042243158c0') build() { diff --git a/extra/refind-efi/PKGBUILD b/extra/refind-efi/PKGBUILD new file mode 100644 index 000000000..028af2afd --- /dev/null +++ b/extra/refind-efi/PKGBUILD @@ -0,0 +1,211 @@ +# $Id: PKGBUILD 188814 2013-06-21 19:48:54Z tpowa $ +# Maintainer: Tobias Powalowski +# Contributor: Keshav Padram <(the.ridikulus.rat) (aatt) (gemmaeiil) (ddoott) (ccoomm)> + +####### +_TIANOCORE_SVN_URL="https://svn.code.sf.net/p/edk2/code/branches/UDK2010.SR1" +# BaseTools MdePkg MdeModulePkg IntelFrameworkPkg IntelFrameworkModulePkg +_TIANO_DIR_="tianocore-udk-svn" +####### + +####### +_TIANOCORE_PKG="Mde" +_TIANOCORE_TARGET="RELEASE" +_UDK_TARGET="${_TIANOCORE_PKG}Pkg/${_TIANOCORE_PKG}Pkg.dsc" +_COMPILER="GCC46" +####### + +pkgname="refind-efi" +pkgver="0.6.12" +pkgrel="2" +pkgdesc="Rod Smith's fork of rEFIt UEFI Boot Manager - built with Tianocore UDK libs" +url="http://www.rodsbooks.com/refind/index.html" +arch=('x86_64' 'i686') +license=('GPL3' 'custom') + +makedepends=('subversion' 'python2') +depends=('dosfstools' 'efibootmgr') +optdepends=('mactel-boot: For bless command in Apple Mac systems' + 'bash: For /usr/bin/refind-mkfont script' + 'imagemagick: For /usr/bin/refind-mkfont script') + +options=('!strip' 'docs' '!makeflags') + +install="${pkgname}.install" + +source=("http://downloads.sourceforge.net/refind/refind-src-${pkgver}.zip" + 'UDK-MdePkg-Revert-PathNodeCount.patch' + 'refind_linux.conf') + +for _DIR_ in BaseTools MdePkg MdeModulePkg IntelFrameworkPkg IntelFrameworkModulePkg ; do + source+=("${_TIANO_DIR_}/${_DIR_}::svn+${_TIANOCORE_SVN_URL}/${_DIR_}") +done + +sha1sums=('aabac34b2a30e16c5fd105777b9245c2ed0496e4' + '4d1992699f9b48dd2b7e6bd6c0b25fc065f75894' + '3d53eb615c3363d45feb95b9bfbf1d5491bf1c24' + 'SKIP' + 'SKIP' + 'SKIP' + 'SKIP' + 'SKIP') + +[[ "${CARCH}" == "x86_64" ]] && _TIANO_ARCH="X64" +[[ "${CARCH}" == "i686" ]] && _TIANO_ARCH="IA32" + +[[ "${CARCH}" == "x86_64" ]] && _TIANO_S_ARCH="x64" +[[ "${CARCH}" == "i686" ]] && _TIANO_S_ARCH="ia32" + +_tianocore_udk_common() { + + ## Unset all FLAGS + unset CFLAGS + unset CPPFLAGS + unset CXXFLAGS + unset LDFLAGS + unset MAKEFLAGS + + ## Setup UDK Environment variables + export _UDK_DIR="${srcdir}/${_TIANO_DIR_}_build" + export EDK_TOOLS_PATH="${_UDK_DIR}/BaseTools" + + rm -rf "${_UDK_DIR}/" || true + mkdir -p "${_UDK_DIR}/" + + for _DIR_ in BaseTools MdePkg MdeModulePkg IntelFrameworkPkg IntelFrameworkModulePkg ; do + mv "${srcdir}/${_DIR_}" "${_UDK_DIR}/${_DIR_}" + done + + cd "${_UDK_DIR}/" + + ## Fix PcdMaximumPathNodeCount compile error + patch -Np1 -R -i "${srcdir}/UDK-MdePkg-Revert-PathNodeCount.patch" + echo + + ## Cleanup UDK config files + rm -rf "${_UDK_DIR}/Build/" || true + rm -rf "${_UDK_DIR}/Conf/" || true + mkdir -p "${_UDK_DIR}/Conf/" + mkdir -p "${_UDK_DIR}/Build/" + + ## UDK BaseTools requires python2 + sed 's|python |python2 |g' -i "${EDK_TOOLS_PATH}/BinWrappers/PosixLike"/* || true + sed 's|python |python2 |g' -i "${EDK_TOOLS_PATH}/Tests/GNUmakefile" + + ## Fix GCC Warning as error + sed 's|-Werror |-Wno-error -Wno-unused-but-set-variable |g' -i "${EDK_TOOLS_PATH}/Source/C/Makefiles/header.makefile" || true + sed 's|-Werror |-Wno-error -Wno-unused-but-set-variable |g' -i "${EDK_TOOLS_PATH}/Conf/tools_def.template" || true + + ## Fix GCC >=4.7 error - gcc: error: unrecognized command line option '-melf_x86_64' + sed 's| -m64 --64 -melf_x86_64| -m64|g' -i "${EDK_TOOLS_PATH}/Conf/tools_def.template" || true + sed 's|--64 | |g' -i "${EDK_TOOLS_PATH}/Conf/tools_def.template" || true + sed 's| -m64 -melf_x86_64| -m64|g' -i "${EDK_TOOLS_PATH}/Conf/tools_def.template" || true + + ## Remove GCC -g debug option and add -0s -mabi=ms + sed 's|DEFINE GCC_ALL_CC_FLAGS = -g |DEFINE GCC_ALL_CC_FLAGS = -Os -mabi=ms |g' -i "${EDK_TOOLS_PATH}/Conf/tools_def.template" || true + sed 's|DEFINE GCC44_ALL_CC_FLAGS = -g |DEFINE GCC44_ALL_CC_FLAGS = -Os -mabi=ms |g' -i "${EDK_TOOLS_PATH}/Conf/tools_def.template" || true + + ## Fix UDK Target Platform + sed "s|ACTIVE_PLATFORM = Nt32Pkg/Nt32Pkg.dsc|ACTIVE_PLATFORM = ${_UDK_TARGET}|g" -i "${EDK_TOOLS_PATH}/Conf/target.template" || true + sed "s|TARGET = DEBUG|TARGET = ${_TIANOCORE_TARGET}|g" -i "${EDK_TOOLS_PATH}/Conf/target.template" || true + sed "s|TOOL_CHAIN_TAG = MYTOOLS|TOOL_CHAIN_TAG = ${_COMPILER}|g" -i "${EDK_TOOLS_PATH}/Conf/target.template" || true + + ## Setup UDK Environment + chmod +x "${_UDK_DIR}/BaseTools/BuildEnv" + source "${_UDK_DIR}/BaseTools/BuildEnv" BaseTools + echo + + ## Compile UDK BaseTools + make -C "${EDK_TOOLS_PATH}" + echo + + ## Compile UDK x86_64-UEFI Libraries + "${EDK_TOOLS_PATH}/BinWrappers/PosixLike/build" -p "${_UDK_TARGET}" -a "${_TIANO_ARCH}" -b "${_TIANOCORE_TARGET}" -t "${_COMPILER}" + echo + + ## Fix UDK Target ARCH for rEFInd + sed "s|IA32|${_TIANO_ARCH}|g" -i "${_UDK_DIR}/Conf/target.txt" || true + +} + +build() { + + _tianocore_udk_common + echo + + cd "${srcdir}/refind-${pkgver}/" + + ## Fix UDK Path in rEFInd Makefiles + sed "s|EDK2BASE = /usr/local/UDK2010/MyWorkSpace|EDK2BASE = ${_UDK_DIR}|g" -i "${srcdir}/refind-${pkgver}/Make.tiano" || true + sed "s|EDK2BASE = /usr/local/UDK2010/MyWorkSpace|EDK2BASE = ${_UDK_DIR}|g" -i "${srcdir}/refind-${pkgver}/filesystems/Make.tiano" || true + sed "s|EDK2BASE = /usr/local/UDK2010/MyWorkSpace|EDK2BASE = ${_UDK_DIR}|g" -i "${srcdir}/refind-${pkgver}/gptsync/Make.tiano" || true + + ## Unset all FLAGS + unset CFLAGS + unset CPPFLAGS + unset CXXFLAGS + unset LDFLAGS + unset MAKEFLAGS + + ## Compile refind.efi + make tiano + + ## Compile UEFI FS drivers + make fs + +} + +package() { + + ## Install the rEFInd UEFI application + install -d "${pkgdir}/usr/lib/refind/" + install -D -m0644 "${srcdir}/refind-${pkgver}/refind/refind_${_TIANO_S_ARCH}.efi" "${pkgdir}/usr/lib/refind/refind_${_TIANO_S_ARCH}.efi" + + ## Install UEFI drivers built from rEFInd + install -d "${pkgdir}/usr/lib/refind/drivers_${_TIANO_S_ARCH}/" + install -D -m0644 "${srcdir}/refind-${pkgver}/drivers_${_TIANO_S_ARCH}"/*.efi "${pkgdir}/usr/lib/refind/drivers_${_TIANO_S_ARCH}/" + + ## Install UEFI applications built from rEFInd + install -d "${pkgdir}/usr/lib/refind/tools_${_TIANO_S_ARCH}" + install -D -m0644 "${srcdir}/refind-${pkgver}/gptsync/gptsync_${_TIANO_S_ARCH}.efi" "${pkgdir}/usr/lib/refind/tools_${_TIANO_S_ARCH}/gptsync_${_TIANO_S_ARCH}.efi" + + ## Install the rEFInd config file + install -d "${pkgdir}/usr/lib/refind/config/" + install -D -m0644 "${srcdir}/refind-${pkgver}/refind.conf-sample" "${pkgdir}/usr/lib/refind/config/refind.conf" + install -D -m0644 "${srcdir}/refind_linux.conf" "${pkgdir}/usr/lib/refind/config/refind_linux.conf" + + ## Install the rEFInd docs + install -d "${pkgdir}/usr/share/refind/docs/html/" + install -d "${pkgdir}/usr/share/refind/docs/Styles/" + install -D -m0644 "${srcdir}/refind-${pkgver}/docs/refind"/* "${pkgdir}/usr/share/refind/docs/html/" + install -D -m0644 "${srcdir}/refind-${pkgver}/docs/Styles"/* "${pkgdir}/usr/share/refind/docs/Styles/" + install -D -m0644 "${srcdir}/refind-${pkgver}/README.txt" "${pkgdir}/usr/share/refind/docs/README" + install -D -m0644 "${srcdir}/refind-${pkgver}/NEWS.txt" "${pkgdir}/usr/share/refind/docs/NEWS" + rm -f "${pkgdir}/usr/share/refind/docs/html/.DS_Store" || true + + ## Install the rEFInd fonts + install -d "${pkgdir}/usr/share/refind/fonts/" + install -D -m0644 "${srcdir}/refind-${pkgver}/fonts"/* "${pkgdir}/usr/share/refind/fonts/" + rm -f "${pkgdir}/usr/share/refind/fonts/mkfont.sh" + + ## Install the rEFInd mkfont.sh + install -d "${pkgdir}/usr/bin/" + install -D -m0755 "${srcdir}/refind-${pkgver}/fonts/mkfont.sh" "${pkgdir}/usr/bin/refind-mkfont" + + ## Install the rEFInd icons + install -d "${pkgdir}/usr/share/refind/icons/" + install -D -m0644 "${srcdir}/refind-${pkgver}/icons"/* "${pkgdir}/usr/share/refind/icons/" + + ## Install the rEFInd images + install -d "${pkgdir}/usr/share/refind/images/" + install -D -m0644 "${srcdir}/refind-${pkgver}/images"/*.{png,bmp} "${pkgdir}/usr/share/refind/images/" + + ## Install the rEFInd keys + install -d "${pkgdir}/usr/share/refind/keys/" + install -D -m0644 "${srcdir}/refind-${pkgver}/keys"/* "${pkgdir}/usr/share/refind/keys/" + + ## Install the rEFIt license file, since rEFInd is a fork of rEFIt + install -d "${pkgdir}/usr/share/licenses/refind/" + install -D -m0644 "${srcdir}/refind-${pkgver}/LICENSE.txt" "${pkgdir}/usr/share/licenses/refind/LICENSE" + +} diff --git a/extra/refind-efi/UDK-MdePkg-Revert-PathNodeCount.patch b/extra/refind-efi/UDK-MdePkg-Revert-PathNodeCount.patch new file mode 100644 index 000000000..1b8f5a44b --- /dev/null +++ b/extra/refind-efi/UDK-MdePkg-Revert-PathNodeCount.patch @@ -0,0 +1,660 @@ +commit 771729c77fa49cf0ff17491f371003c4f5d66f85 +Author: niruiyu +Date: Mon Sep 24 03:20:35 2012 +0000 + + Add new API IsDevicePathValid() to UefiDevicePathLib. + + Signed-off-by: Ruiyu Ni + Reviewed-by: Liming Gao + Reviewed-by: Kinney Michael D + + git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@13737 6f19259b-4bc3-4df7-8a09-765794883524 + +diff --git a/MdePkg/Include/Library/DevicePathLib.h b/MdePkg/Include/Library/DevicePathLib.h +index 68b1f1b..37acd45 100644 +--- a/MdePkg/Include/Library/DevicePathLib.h ++++ b/MdePkg/Include/Library/DevicePathLib.h +@@ -4,7 +4,7 @@ + This library provides defines, macros, and functions to help create and parse + EFI_DEVICE_PATH_PROTOCOL structures. + +-Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.
++Copyright (c) 2006 - 2012, Intel Corporation. All rights reserved.
+ This program and the accompanying materials are licensed and made available under + the terms and conditions of the BSD License that accompanies this distribution. + The full text of the license may be found at +@@ -21,6 +21,28 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + #define END_DEVICE_PATH_LENGTH (sizeof (EFI_DEVICE_PATH_PROTOCOL)) + + /** ++ Determine whether a given device path is valid. ++ If DevicePath is NULL, then ASSERT(). ++ ++ @param DevicePath A pointer to a device path data structure. ++ @param MaxSize The maximum size of the device path data structure. ++ ++ @retval TRUE DevicePath is valid. ++ @retval FALSE The length of any node node in the DevicePath is less ++ than sizeof (EFI_DEVICE_PATH_PROTOCOL). ++ @retval FALSE If MaxSize is not zero, the size of the DevicePath ++ exceeds MaxSize. ++ @retval FALSE If PcdMaximumDevicePathNodeCount is not zero, the node ++ count of the DevicePath exceeds PcdMaximumDevicePathNodeCount. ++**/ ++BOOLEAN ++EFIAPI ++IsDevicePathValid ( ++ IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath, ++ IN UINTN MaxSize ++ ); ++ ++/** + Returns the Type field of a device path node. + + Returns the Type field of the device path node specified by Node. +@@ -123,7 +145,8 @@ IsDevicePathEndType ( + Determines if a device path node is an end node of an entire device path. + + Determines if a device path node specified by Node is an end node of an entire device path. +- If Node represents the end of an entire device path, then TRUE is returned. Otherwise, FALSE is returned. ++ If Node represents the end of an entire device path, then TRUE is returned. ++ Otherwise, FALSE is returned. + + If Node is NULL, then ASSERT(). + +@@ -143,7 +166,8 @@ IsDevicePathEnd ( + Determines if a device path node is an end node of a device path instance. + + Determines if a device path node specified by Node is an end node of a device path instance. +- If Node represents the end of a device path instance, then TRUE is returned. Otherwise, FALSE is returned. ++ If Node represents the end of a device path instance, then TRUE is returned. ++ Otherwise, FALSE is returned. + + If Node is NULL, then ASSERT(). + +@@ -169,6 +193,7 @@ IsDevicePathEndInstance ( + + If Node is NULL, then ASSERT(). + If NodeLength >= 0x10000, then ASSERT(). ++ If NodeLength < sizeof (EFI_DEVICE_PATH_PROTOCOL), then ASSERT(). + + @param Node A pointer to a device path node data structure. + @param Length The length, in bytes, of the device path node. +@@ -208,13 +233,14 @@ SetDevicePathEndNode ( + /** + Returns the size of a device path in bytes. + +- This function returns the size, in bytes, of the device path data structure specified by +- DevicePath including the end of device path node. If DevicePath is NULL, then 0 is returned. ++ This function returns the size, in bytes, of the device path data structure ++ specified by DevicePath including the end of device path node. ++ If DevicePath is NULL or invalid, then 0 is returned. + +- @param DevicePath A pointer to a device path data structure. +- +- @retval 0 DevicePath is NULL. +- @retval Others The size of a device path in bytes. ++ @param DevicePath A pointer to a device path data structure. ++ ++ @retval 0 If DevicePath is NULL or invalid. ++ @retval Others The size of a device path in bytes. + + **/ + UINTN +@@ -235,7 +261,7 @@ GetDevicePathSize ( + + @param DevicePath A pointer to a device path data structure. + +- @retval NULL DevicePath is NULL. ++ @retval NULL DevicePath is NULL or invalid. + @retval Others A pointer to the duplicated device path. + + **/ +@@ -263,6 +289,7 @@ DuplicateDevicePath ( + @param SecondDevicePath A pointer to a device path data structure. + + @retval NULL If there is not enough memory for the newly allocated buffer. ++ @retval NULL If FirstDevicePath or SecondDevicePath is invalid. + @retval Others A pointer to the new device path if success. + Or a copy an end-of-device-path if both FirstDevicePath and SecondDevicePath are NULL. + +@@ -316,6 +343,7 @@ AppendDevicePathNode ( + and a new end-of-device-path-instance node is inserted between. + If DevicePath is NULL, then a copy if DevicePathInstance is returned. + If DevicePathInstance is NULL, then NULL is returned. ++ If DevicePath or DevicePathInstance is invalid, then NULL is returned. + If there is not enough memory to allocate space for the new device path, then NULL is returned. + The memory is allocated from EFI boot services memory. It is the responsibility of the caller to + free the memory allocated. +@@ -341,6 +369,7 @@ AppendDevicePathInstance ( + point to the next device path instance in the device path (or NULL if no more) and updates Size + to hold the size of the device path instance copy. + If DevicePath is NULL, then NULL is returned. ++ If DevicePath points to a invalid device path, then NULL is returned. + If there is not enough memory to allocate space for the new device path, then NULL is returned. + The memory is allocated from EFI boot services memory. It is the responsibility of the caller to + free the memory allocated. +@@ -394,12 +423,13 @@ CreateDeviceNode ( + Determines if a device path is single or multi-instance. + + This function returns TRUE if the device path specified by DevicePath is multi-instance. +- Otherwise, FALSE is returned. If DevicePath is NULL, then FALSE is returned. ++ Otherwise, FALSE is returned. ++ If DevicePath is NULL or invalid, then FALSE is returned. + + @param DevicePath A pointer to a device path data structure. + + @retval TRUE DevicePath is multi-instance. +- @retval FALSE DevicePath is not multi-instance, or DevicePath is NULL. ++ @retval FALSE DevicePath is not multi-instance, or DevicePath is NULL or invalid. + + **/ + BOOLEAN +diff --git a/MdePkg/Library/UefiDevicePathLib/UefiDevicePathLib.c b/MdePkg/Library/UefiDevicePathLib/UefiDevicePathLib.c +index db065e4..a91a7a3 100644 +--- a/MdePkg/Library/UefiDevicePathLib/UefiDevicePathLib.c ++++ b/MdePkg/Library/UefiDevicePathLib/UefiDevicePathLib.c +@@ -8,7 +8,7 @@ + environment varibles. Multi-instance device paths should never be placed + on a Handle. + +- Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.
++ Copyright (c) 2006 - 2012, Intel Corporation. All rights reserved.
+ This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at +@@ -28,6 +28,7 @@ + #include + #include + #include ++#include + + // + // Template for an end-of-device path node. +@@ -42,6 +43,61 @@ GLOBAL_REMOVE_IF_UNREFERENCED CONST EFI_DEVICE_PATH_PROTOCOL mUefiDevicePathLib + }; + + /** ++ Determine whether a given device path is valid. ++ If DevicePath is NULL, then ASSERT(). ++ ++ @param DevicePath A pointer to a device path data structure. ++ @param MaxSize The maximum size of the device path data structure. ++ ++ @retval TRUE DevicePath is valid. ++ @retval FALSE The length of any node node in the DevicePath is less ++ than sizeof (EFI_DEVICE_PATH_PROTOCOL). ++ @retval FALSE If MaxSize is not zero, the size of the DevicePath ++ exceeds MaxSize. ++ @retval FALSE If PcdMaximumDevicePathNodeCount is not zero, the node ++ count of the DevicePath exceeds PcdMaximumDevicePathNodeCount. ++**/ ++BOOLEAN ++EFIAPI ++IsDevicePathValid ( ++ IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath, ++ IN UINTN MaxSize ++ ) ++{ ++ UINTN Count; ++ UINTN Size; ++ UINTN NodeLength; ++ ++ ASSERT (DevicePath != NULL); ++ ++ for (Count = 0, Size = 0; !IsDevicePathEnd (DevicePath); DevicePath = NextDevicePathNode (DevicePath)) { ++ NodeLength = DevicePathNodeLength (DevicePath); ++ if (NodeLength < sizeof (EFI_DEVICE_PATH_PROTOCOL)) { ++ return FALSE; ++ } ++ ++ if (MaxSize > 0) { ++ Size += NodeLength; ++ if (Size + END_DEVICE_PATH_LENGTH > MaxSize) { ++ return FALSE; ++ } ++ } ++ ++ if (PcdGet32 (PcdMaximumDevicePathNodeCount) > 0) { ++ Count++; ++ if (Count >= PcdGet32 (PcdMaximumDevicePathNodeCount)) { ++ return FALSE; ++ } ++ } ++ } ++ ++ // ++ // Only return TRUE when the End Device Path node is valid. ++ // ++ return (BOOLEAN) (DevicePathNodeLength (DevicePath) == END_DEVICE_PATH_LENGTH); ++} ++ ++/** + Returns the Type field of a device path node. + + Returns the Type field of the device path node specified by Node. +@@ -106,8 +162,12 @@ DevicePathNodeLength ( + IN CONST VOID *Node + ) + { ++ UINTN Length; ++ + ASSERT (Node != NULL); +- return ReadUnaligned16 ((UINT16 *)&((EFI_DEVICE_PATH_PROTOCOL *)(Node))->Length[0]); ++ Length = ReadUnaligned16 ((UINT16 *)&((EFI_DEVICE_PATH_PROTOCOL *)(Node))->Length[0]); ++ ASSERT (Length >= sizeof (EFI_DEVICE_PATH_PROTOCOL)); ++ return Length; + } + + /** +@@ -227,7 +287,8 @@ IsDevicePathEndInstance ( + be used to set the contents of the Length field. + + If Node is NULL, then ASSERT(). +- If NodeLength >= 0x10000, then ASSERT(). ++ If NodeLength >= SIZE_64KB, then ASSERT(). ++ If NodeLength < sizeof (EFI_DEVICE_PATH_PROTOCOL), then ASSERT(). + + @param Node A pointer to a device path node data structure. + @param Length The length, in bytes, of the device path node. +@@ -243,7 +304,7 @@ SetDevicePathNodeLength ( + ) + { + ASSERT (Node != NULL); +- ASSERT (Length < 0x10000); ++ ASSERT ((Length >= sizeof (EFI_DEVICE_PATH_PROTOCOL)) && (Length < SIZE_64KB)); + return WriteUnaligned16 ((UINT16 *)&((EFI_DEVICE_PATH_PROTOCOL *)(Node))->Length[0], (UINT16)(Length)); + } + +@@ -277,12 +338,12 @@ SetDevicePathEndNode ( + Returns the size of a device path in bytes. + + This function returns the size, in bytes, of the device path data structure +- specified by DevicePath including the end of device path node. If DevicePath +- is NULL, then 0 is returned. ++ specified by DevicePath including the end of device path node. ++ If DevicePath is NULL or invalid, then 0 is returned. + + @param DevicePath A pointer to a device path data structure. +- +- @retval 0 If DevicePath is NULL. ++ ++ @retval 0 If DevicePath is NULL or invalid. + @retval Others The size of a device path in bytes. + + **/ +@@ -298,6 +359,10 @@ GetDevicePathSize ( + return 0; + } + ++ if (!IsDevicePathValid (DevicePath, 0)) { ++ return 0; ++ } ++ + // + // Search for the end of the device path structure + // +@@ -324,7 +389,7 @@ GetDevicePathSize ( + + @param DevicePath A pointer to a device path data structure. + +- @retval NULL If DevicePath is NULL. ++ @retval NULL DevicePath is NULL or invalid. + @retval Others A pointer to the duplicated device path. + + **/ +@@ -370,6 +435,7 @@ DuplicateDevicePath ( + @param SecondDevicePath A pointer to a device path data structure. + + @retval NULL If there is not enough memory for the newly allocated buffer. ++ @retval NULL If FirstDevicePath or SecondDevicePath is invalid. + @retval Others A pointer to the new device path if success. + Or a copy an end-of-device-path if both FirstDevicePath and SecondDevicePath are NULL. + +@@ -398,6 +464,10 @@ AppendDevicePath ( + return DuplicateDevicePath (FirstDevicePath); + } + ++ if (!IsDevicePathValid (FirstDevicePath, 0) || !IsDevicePathValid (SecondDevicePath, 0)) { ++ return NULL; ++ } ++ + // + // Allocate space for the combined device path. It only has one end node of + // length EFI_DEVICE_PATH_PROTOCOL. +@@ -500,6 +570,7 @@ AppendDevicePathNode ( + path instance and a new end-of-device-path-instance node is inserted between. + If DevicePath is NULL, then a copy if DevicePathInstance is returned. + If DevicePathInstance is NULL, then NULL is returned. ++ If DevicePath or DevicePathInstance is invalid, then NULL is returned. + If there is not enough memory to allocate space for the new device path, then + NULL is returned. + The memory is allocated from EFI boot services memory. It is the responsibility +@@ -531,6 +602,10 @@ AppendDevicePathInstance ( + return NULL; + } + ++ if (!IsDevicePathValid (DevicePath, 0) || !IsDevicePathValid (DevicePathInstance, 0)) { ++ return NULL; ++ } ++ + SrcSize = GetDevicePathSize (DevicePath); + InstanceSize = GetDevicePathSize (DevicePathInstance); + +@@ -559,6 +634,7 @@ AppendDevicePathInstance ( + DevicePath to point to the next device path instance in the device path (or NULL + if no more) and updates Size to hold the size of the device path instance copy. + If DevicePath is NULL, then NULL is returned. ++ If DevicePath points to a invalid device path, then NULL is returned. + If there is not enough memory to allocate space for the new device path, then + NULL is returned. + The memory is allocated from EFI boot services memory. It is the responsibility +@@ -596,6 +672,10 @@ GetNextDevicePathInstance ( + return NULL; + } + ++ if (!IsDevicePathValid (*DevicePath, 0)) { ++ return NULL; ++ } ++ + // + // Find the end of the device path instance + // +@@ -681,13 +761,14 @@ CreateDeviceNode ( + + This function returns TRUE if the device path specified by DevicePath is + multi-instance. +- Otherwise, FALSE is returned. If DevicePath is NULL, then FALSE is returned. ++ Otherwise, FALSE is returned. ++ If DevicePath is NULL or invalid, then FALSE is returned. + + @param DevicePath A pointer to a device path data structure. + + @retval TRUE DevicePath is multi-instance. +- @retval FALSE DevicePath is not multi-instance or DevicePath +- is NULL. ++ @retval FALSE DevicePath is not multi-instance, or DevicePath ++ is NULL or invalid. + + **/ + BOOLEAN +@@ -702,6 +783,10 @@ IsDevicePathMultiInstance ( + return FALSE; + } + ++ if (!IsDevicePathValid (DevicePath, 0)) { ++ return FALSE; ++ } ++ + Node = DevicePath; + while (!IsDevicePathEnd (Node)) { + if (IsDevicePathEndInstance (Node)) { +@@ -776,15 +861,14 @@ FileDevicePath ( + IN CONST CHAR16 *FileName + ) + { +- UINT16 Size; ++ UINTN Size; + FILEPATH_DEVICE_PATH *FilePath; + EFI_DEVICE_PATH_PROTOCOL *DevicePath; + EFI_DEVICE_PATH_PROTOCOL *FileDevicePath; + + DevicePath = NULL; + +- Size = (UINT16) StrSize (FileName); +- ++ Size = StrSize (FileName); + FileDevicePath = AllocatePool (Size + SIZE_OF_FILEPATH_DEVICE_PATH + END_DEVICE_PATH_LENGTH); + if (FileDevicePath != NULL) { + FilePath = (FILEPATH_DEVICE_PATH *) FileDevicePath; +diff --git a/MdePkg/Library/UefiDevicePathLib/UefiDevicePathLib.inf b/MdePkg/Library/UefiDevicePathLib/UefiDevicePathLib.inf +index c34301d..2ae151d 100644 +--- a/MdePkg/Library/UefiDevicePathLib/UefiDevicePathLib.inf ++++ b/MdePkg/Library/UefiDevicePathLib/UefiDevicePathLib.inf +@@ -3,7 +3,7 @@ + # + # Device Path Library that layers on top of the Memory Allocation Library. + # +-# Copyright (c) 2007 - 2010, Intel Corporation. All rights reserved.
++# Copyright (c) 2007 - 2012, Intel Corporation. All rights reserved.
+ # + # This program and the accompanying materials + # are licensed and made available under the terms and conditions of the BSD License +@@ -42,8 +42,10 @@ + MemoryAllocationLib + DebugLib + BaseMemoryLib +- ++ PcdLib + + [Protocols] + gEfiDevicePathProtocolGuid ## CONSUMES + ++[Pcd] ++ gEfiMdePkgTokenSpaceGuid.PcdMaximumDevicePathNodeCount +diff --git a/MdePkg/Library/UefiDevicePathLibDevicePathProtocol/UefiDevicePathLib.c b/MdePkg/Library/UefiDevicePathLibDevicePathProtocol/UefiDevicePathLib.c +index 8275dd6..1052988 100644 +--- a/MdePkg/Library/UefiDevicePathLibDevicePathProtocol/UefiDevicePathLib.c ++++ b/MdePkg/Library/UefiDevicePathLibDevicePathProtocol/UefiDevicePathLib.c +@@ -2,7 +2,7 @@ + Library instance that implement UEFI Device Path Library class based on protocol + gEfiDevicePathUtilitiesProtocolGuid. + +- Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.
++ Copyright (c) 2006 - 2012, Intel Corporation. All rights reserved.
+ This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at +@@ -24,6 +24,7 @@ + #include + #include + #include ++#include + + EFI_DEVICE_PATH_UTILITIES_PROTOCOL *mDevicePathUtilities = NULL; + +@@ -72,6 +73,61 @@ DevicePathLibConstructor ( + } + + /** ++ Determine whether a given device path is valid. ++ If DevicePath is NULL, then ASSERT(). ++ ++ @param DevicePath A pointer to a device path data structure. ++ @param MaxSize The maximum size of the device path data structure. ++ ++ @retval TRUE DevicePath is valid. ++ @retval FALSE The length of any node node in the DevicePath is less ++ than sizeof (EFI_DEVICE_PATH_PROTOCOL). ++ @retval FALSE If MaxSize is not zero, the size of the DevicePath ++ exceeds MaxSize. ++ @retval FALSE If PcdMaximumDevicePathNodeCount is not zero, the node ++ count of the DevicePath exceeds PcdMaximumDevicePathNodeCount. ++**/ ++BOOLEAN ++EFIAPI ++IsDevicePathValid ( ++ IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath, ++ IN UINTN MaxSize ++ ) ++{ ++ UINTN Count; ++ UINTN Size; ++ UINTN NodeLength; ++ ++ ASSERT (DevicePath != NULL); ++ ++ for (Count = 0, Size = 0; !IsDevicePathEnd (DevicePath); DevicePath = NextDevicePathNode (DevicePath)) { ++ NodeLength = DevicePathNodeLength (DevicePath); ++ if (NodeLength < sizeof (EFI_DEVICE_PATH_PROTOCOL)) { ++ return FALSE; ++ } ++ ++ if (MaxSize > 0) { ++ Size += NodeLength; ++ if (Size + END_DEVICE_PATH_LENGTH > MaxSize) { ++ return FALSE; ++ } ++ } ++ ++ if (PcdGet32 (PcdMaximumDevicePathNodeCount) > 0) { ++ Count++; ++ if (Count >= PcdGet32 (PcdMaximumDevicePathNodeCount)) { ++ return FALSE; ++ } ++ } ++ } ++ ++ // ++ // Only return TRUE when the End Device Path node is valid. ++ // ++ return (BOOLEAN) (DevicePathNodeLength (DevicePath) == END_DEVICE_PATH_LENGTH); ++} ++ ++/** + Returns the Type field of a device path node. + + Returns the Type field of the device path node specified by Node. +@@ -136,8 +192,12 @@ DevicePathNodeLength ( + IN CONST VOID *Node + ) + { ++ UINTN Length; ++ + ASSERT (Node != NULL); +- return ReadUnaligned16 ((UINT16 *)&((EFI_DEVICE_PATH_PROTOCOL *)(Node))->Length[0]); ++ Length = ReadUnaligned16 ((UINT16 *)&((EFI_DEVICE_PATH_PROTOCOL *)(Node))->Length[0]); ++ ASSERT (Length >= sizeof (EFI_DEVICE_PATH_PROTOCOL)); ++ return Length; + } + + /** +@@ -256,7 +316,8 @@ IsDevicePathEndInstance ( + be used to set the contents of the Length field. + + If Node is NULL, then ASSERT(). +- If NodeLength >= 0x10000, then ASSERT(). ++ If NodeLength >= SIZE_64KB, then ASSERT(). ++ If NodeLength < sizeof (EFI_DEVICE_PATH_PROTOCOL), then ASSERT(). + + @param Node A pointer to a device path node data structure. + @param Length The length, in bytes, of the device path node. +@@ -272,7 +333,7 @@ SetDevicePathNodeLength ( + ) + { + ASSERT (Node != NULL); +- ASSERT (Length < 0x10000); ++ ASSERT ((Length >= sizeof (EFI_DEVICE_PATH_PROTOCOL)) && (Length < SIZE_64KB)); + return WriteUnaligned16 ((UINT16 *)&((EFI_DEVICE_PATH_PROTOCOL *)(Node))->Length[0], (UINT16)(Length)); + } + +@@ -305,13 +366,14 @@ SetDevicePathEndNode ( + /** + Returns the size of a device path in bytes. + +- This function returns the size, in bytes, of the device path data structure specified by +- DevicePath including the end of device path node. If DevicePath is NULL, then 0 is returned. ++ This function returns the size, in bytes, of the device path data structure ++ specified by DevicePath including the end of device path node. ++ If DevicePath is NULL or invalid, then 0 is returned. + +- @param DevicePath A pointer to a device path data structure. +- +- @retval 0 If DevicePath is NULL. +- @retval Others The size of a device path in bytes. ++ @param DevicePath A pointer to a device path data structure. ++ ++ @retval 0 If DevicePath is NULL or invalid. ++ @retval Others The size of a device path in bytes. + + **/ + UINTN +@@ -336,7 +398,7 @@ GetDevicePathSize ( + + @param DevicePath A pointer to a device path data structure. + +- @retval NULL If DevicePath is NULL. ++ @retval NULL If DevicePath is NULL or invalid. + @retval Others A pointer to the duplicated device path. + + **/ +@@ -367,6 +429,7 @@ DuplicateDevicePath ( + @param SecondDevicePath A pointer to a device path data structure. + + @retval NULL If there is not enough memory for the newly allocated buffer. ++ @retval NULL If FirstDevicePath or SecondDevicePath is invalid. + @retval Others A pointer to the new device path if success. + Or a copy an end-of-device-path if both FirstDevicePath and + SecondDevicePath are NULL. +@@ -431,6 +494,7 @@ AppendDevicePathNode ( + path instance and a new end-of-device-path-instance node is inserted between. + If DevicePath is NULL, then a copy if DevicePathInstance is returned. + If DevicePathInstance is NULL, then NULL is returned. ++ If DevicePath or DevicePathInstance is invalid, then NULL is returned. + If there is not enough memory to allocate space for the new device path, then + NULL is returned. + The memory is allocated from EFI boot services memory. It is the responsibility +@@ -524,15 +588,16 @@ CreateDeviceNode ( + /** + Determines if a device path is single or multi-instance. + +- This function returns TRUE if the device path specified by DevicePath is ++ This function returns TRUE if the device path specified by DevicePath is + multi-instance. +- Otherwise, FALSE is returned. If DevicePath is NULL, then FALSE is returned. ++ Otherwise, FALSE is returned. ++ If DevicePath is NULL or invalid, then FALSE is returned. + + @param DevicePath A pointer to a device path data structure. + + @retval TRUE DevicePath is multi-instance. +- @retval FALSE DevicePath is not multi-instance or DevicePath +- is NULL. ++ @retval FALSE DevicePath is not multi-instance, or DevicePath ++ is NULL or invalid. + + **/ + BOOLEAN +diff --git a/MdePkg/Library/UefiDevicePathLibDevicePathProtocol/UefiDevicePathLibDevicePathProtocol.inf b/MdePkg/Library/UefiDevicePathLibDevicePathProtocol/UefiDevicePathLibDevicePathProtocol.inf +index 3393830..16b47e3 100644 +--- a/MdePkg/Library/UefiDevicePathLibDevicePathProtocol/UefiDevicePathLibDevicePathProtocol.inf ++++ b/MdePkg/Library/UefiDevicePathLibDevicePathProtocol/UefiDevicePathLibDevicePathProtocol.inf +@@ -4,7 +4,7 @@ + # Device Path Library that layers on top of the UEFI 2.0 Device Path Protocol. + # This library is not available for EFI 1.10 modules. + # +-# Copyright (c) 2007 - 2011, Intel Corporation. All rights reserved.
++# Copyright (c) 2007 - 2012, Intel Corporation. All rights reserved.
+ # + # This program and the accompanying materials + # are licensed and made available under the terms and conditions of the BSD License +@@ -44,11 +44,14 @@ + MemoryAllocationLib + BaseLib + DebugLib +- ++ PcdLib + + [Protocols] + gEfiDevicePathProtocolGuid ## CONSUMES + gEfiDevicePathUtilitiesProtocolGuid ## CONSUMES + ++[Pcd] ++ gEfiMdePkgTokenSpaceGuid.PcdMaximumDevicePathNodeCount ++ + [Depex.common.DXE_DRIVER, Depex.common.DXE_RUNTIME_DRIVER, Depex.common.DXE_SAL_DRIVER, Depex.common.DXE_SMM_DRIVER] + gEfiDevicePathUtilitiesProtocolGuid +diff --git a/MdePkg/MdePkg.dec b/MdePkg/MdePkg.dec +index b29cb01..aefba3f 100644 +--- a/MdePkg/MdePkg.dec ++++ b/MdePkg/MdePkg.dec +@@ -1287,6 +1287,9 @@ + ## Indicates the maximum node number of linked list + gEfiMdePkgTokenSpaceGuid.PcdMaximumLinkedListLength|1000000|UINT32|0x00000003 + ++ ## Indicates the maximum node number of device path ++ gEfiMdePkgTokenSpaceGuid.PcdMaximumDevicePathNodeCount|0|UINT32|0x00000029 ++ + ## Indicates the timeout tick of holding spin lock + gEfiMdePkgTokenSpaceGuid.PcdSpinLockTimeout|10000000|UINT32|0x00000004 + diff --git a/extra/refind-efi/refind-efi.install b/extra/refind-efi/refind-efi.install new file mode 100644 index 000000000..e43f6cb61 --- /dev/null +++ b/extra/refind-efi/refind-efi.install @@ -0,0 +1,31 @@ +post_install() { + + cat << EOF + +rEFInd UEFI applications have been installed at /usr/lib/refind/refind_*.efi + +Other UEFI applications have been installed at /usr/lib/refind/tools_*/ + +UEFI drivers have deen installed at /usr/lib/refind/drivers_*/ + +Copy the efi application (according to your UEFI ARCH) +and /usr/lib/refind/config/refind.conf to a sub-directory of /EFI/ +and add an entry to firmware boot menu using efibootmgr or mactel-boot (for Macs) + +rEFInd Icons have been installed at /usr/share/refind/icons/ +rEFInd Fonts have been installed at /usr/share/refind/fonts/ + +HTML Documentation is available at /usr/share/refind/docs/html/ + +More info: https://wiki.archlinux.org/index.php/UEFI_Bootloaders#Using_rEFInd + +EOF + +} + +post_upgrade() { + + post_install + +} + diff --git a/extra/refind-efi/refind_include_more_shell_paths.patch b/extra/refind-efi/refind_include_more_shell_paths.patch new file mode 100644 index 000000000..078322e1a --- /dev/null +++ b/extra/refind-efi/refind_include_more_shell_paths.patch @@ -0,0 +1,13 @@ +diff --git a/refind/main.c b/refind/main.c +index beac3bf..1a2cf58 100644 +--- a/refind/main.c ++++ b/refind/main.c +@@ -62,5 +62,5 @@ + #define SHELL_NAMES L"\\EFI\\tools\\shell.efi,\\EFI\\tools\\shellia32.efi,\\shellia32.efi" + #define DRIVER_DIRS L"drivers,drivers_ia32" + #else +-#define SHELL_NAMES L"\\EFI\\tools\\shell.efi" ++#define SHELL_NAMES L"\\EFI\\tools\\shell.efi,\\shell.efi" + #define DRIVER_DIRS L"drivers" + #endif + diff --git a/extra/refind-efi/refind_linux.conf b/extra/refind-efi/refind_linux.conf new file mode 100644 index 000000000..a34536b37 --- /dev/null +++ b/extra/refind-efi/refind_linux.conf @@ -0,0 +1,5 @@ +## This file should be present in the same directory as the EFISTUB kernel and initramfs files +## More info at http://www.rodsbooks.com/refind/linux.html , http://www.rodsbooks.com/efi-bootloaders/efistub.html + +"Boot with defaults" "root=PARTUUID=XXXXXXXX rootfstype=XXXX ro" +"Boot to terminal" "root=PARTUUID=XXXXXXXX rootfstype=XXXX ro systemd.unit=multi-user.target" -- cgit v1.2.3-54-g00ecf