提交 97c1f841 编写于 作者: M MikeBeaton

OpenLinuxBoot: Boot from standalone /boot partition

上级 bab4ef84
...@@ -11,6 +11,9 @@ OpenCore Changelog ...@@ -11,6 +11,9 @@ OpenCore Changelog
- Added global MSR 35h fix to `ProvideCurrentCpuInfo`, allowing `-cpu host` in KVM - Added global MSR 35h fix to `ProvideCurrentCpuInfo`, allowing `-cpu host` in KVM
- Fixed potential memory corruption with AVX acceleration enabled - Fixed potential memory corruption with AVX acceleration enabled
- Added `LogModules` for positive and negative log filtering by modules - Added `LogModules` for positive and negative log filtering by modules
- Renamed OpenLinuxBoot driver argument from `partuuidopts:{PARTUUID}` to `autoopts:{PARTUUID}`
- Supported booting Linux from stand-alone `/boot` partition without `/loader/entries` files (user must specify full kernel boot options)
- Handled XML entities in driver arguments
#### v0.7.8 #### v0.7.8
- Updated ocvalidate to warn about insecure `DmgLoading` with secure `SecureBootModel` (already disallowed in runtime) - Updated ocvalidate to warn about insecure `DmgLoading` with secure `SecureBootModel` (already disallowed in runtime)
......
cc719727cce977f2aed6cdaa5b88c23f a0a659b25c35186210abda2a59316cf0
...@@ -6405,7 +6405,7 @@ log when booting (or attempting to boot) a given distro against the options seen ...@@ -6405,7 +6405,7 @@ log when booting (or attempting to boot) a given distro against the options seen
\texttt{cat /proc/cmdline} when the same distro has been booted via its native bootloader. \texttt{cat /proc/cmdline} when the same distro has been booted via its native bootloader.
In general (for safety and security of the running distro) these options should match, and if they do not In general (for safety and security of the running distro) these options should match, and if they do not
it is recommended to use the driver arguments below (in particular \texttt{LINUX\_BOOT\_ADD\_RO}, it is recommended to use the driver arguments below (in particular \texttt{LINUX\_BOOT\_ADD\_RO},
\texttt{LINUX\_BOOT\_ADD\_RW}, \texttt{partuuidopts} and \texttt{autoopts}) to modify the options as required. \texttt{LINUX\_BOOT\_ADD\_RW}, \texttt{autoopts:\{PARTUUID\}} and \texttt{autoopts}) to modify the options as required.
Note however that the following differences are normal and do not need to be fixed: Note however that the following differences are normal and do not need to be fixed:
\begin{itemize} \begin{itemize}
\tightlist \tightlist
...@@ -6433,9 +6433,15 @@ The default parameter values should work well with no changes under most circums ...@@ -6433,9 +6433,15 @@ The default parameter values should work well with no changes under most circums
options for the driver may be specified in \texttt{UEFI/Drivers/Arguments}: options for the driver may be specified in \texttt{UEFI/Drivers/Arguments}:
\begin{itemize} \begin{itemize}
\tightlist
\item \texttt{flags} - Default: all flags are set except the following:
\begin{itemize}
\tightlist \tightlist
\item \texttt{flags} - Default: all flags except \texttt{LINUX\_BOOT\_ADD\_DEBUG\_INFO} and \item \texttt{LINUX\_BOOT\_ADD\_RW},
\texttt{LINUX\_BOOT\_LOG\_VERBOSE} are set. \medskip \item \texttt{LINUX\_BOOT\_LOG\_VERBOSE} and
\item \texttt{LINUX\_BOOT\_ADD\_DEBUG\_INFO}.
\end{itemize}
\medskip
Available flags are: \medskip Available flags are: \medskip
...@@ -6489,14 +6495,14 @@ options for the driver may be specified in \texttt{UEFI/Drivers/Arguments}: ...@@ -6489,14 +6495,14 @@ options for the driver may be specified in \texttt{UEFI/Drivers/Arguments}:
option on autodetected distros; should be harmless but very slightly slow down boot time (due to requried option on autodetected distros; should be harmless but very slightly slow down boot time (due to requried
remount as read-write) on distros which do not require it. remount as read-write) on distros which do not require it.
When there are multiple distros and it is required to specify this option for specific distros only, use When there are multiple distros and it is required to specify this option for specific distros only, use
\texttt{partuuidopts:\{partuuid\}+=ro} to manually add the option where required, instead of using this flag. \texttt{autoopts:\{PARTUUID\}+=ro} to manually add the option where required, instead of using this flag.
\item \texttt{0x00000800} (bit \texttt{11}) --- \texttt{LINUX\_BOOT\_ADD\_RW}, \item \texttt{0x00000800} (bit \texttt{11}) --- \texttt{LINUX\_BOOT\_ADD\_RW},
Like \texttt{LINUX\_BOOT\_ADD\_RO}, this option applies to autodetected Linux only. It is not Like \texttt{LINUX\_BOOT\_ADD\_RO}, this option applies to autodetected Linux only. It is not
required for most distros (which usually require either \texttt{ro} or nothing to be added to required for most distros (which usually require either \texttt{ro} or nothing to be added to
detected boot options), but is required on some Arch-derived distros, e.g. EndeavourOS. detected boot options), but is required on some Arch-derived distros, e.g. EndeavourOS.
When there are multiple distros and it is required to specify this option for specific distros only, use When there are multiple distros and it is required to specify this option for specific distros only, use
\texttt{partuuidopts:\{partuuid\}+=rw} to manually add the option where required, instead of using this flag. \texttt{autoopts:\{PARTUUID\}+=rw} to manually add the option where required, instead of using this flag.
If this option and \texttt{LINUX\_BOOT\_ADD\_RO} are both specified, only this option is applied If this option and \texttt{LINUX\_BOOT\_ADD\_RO} are both specified, only this option is applied
and \texttt{LINUX\_BOOT\_ADD\_RO} is ignored. and \texttt{LINUX\_BOOT\_ADD\_RO} is ignored.
...@@ -6520,12 +6526,12 @@ options for the driver may be specified in \texttt{UEFI/Drivers/Arguments}: ...@@ -6520,12 +6526,12 @@ options for the driver may be specified in \texttt{UEFI/Drivers/Arguments}:
add or remove, using syntax such as \texttt{flags+=0xC000} to add all debugging add or remove, using syntax such as \texttt{flags+=0xC000} to add all debugging
options or \texttt{flags-=0x400} to remove the \texttt{LINUX\_BOOT\_ADD\_RO} option. \medskip options or \texttt{flags-=0x400} to remove the \texttt{LINUX\_BOOT\_ADD\_RO} option. \medskip
\item \texttt{partuuidopts:\{partuuid\}[+]="\{options\}"} - Default: not set. \medskip \item \texttt{autoopts:\{PARTUUID\}[+]="\{options\}"} - Default: not set. \medskip
Allows specifying kernel options for a given partition only. If specified with \texttt{+=} then Allows manually specifying kernel options to use in autodetect mode for a given partition only. If specified
these are used in addition to autodetected options, if specified with \texttt{=} they are used instead. with \texttt{+=} then these are used in addition to any autodetected options, if specified with \texttt{=}
Used for autodetected Linux only. Values specified here are never used for entries created from they are used instead. Used for autodetected Linux only. Values specified here are never used for entries created
\texttt{/loader/entries/*.conf} files. from \texttt{/loader/entries/*.conf} files.
\medskip \medskip
\emph{Note}: The \texttt{partuuid} value to be specified here is typically the same as the \texttt{PARTUUID} \emph{Note}: The \texttt{partuuid} value to be specified here is typically the same as the \texttt{PARTUUID}
...@@ -6533,15 +6539,15 @@ options for the driver may be specified in \texttt{UEFI/Drivers/Arguments}: ...@@ -6533,15 +6539,15 @@ options for the driver may be specified in \texttt{UEFI/Drivers/Arguments}:
\texttt{cat /proc/cmdline}) for autodetected Debian-style distros, but is not the same for \texttt{cat /proc/cmdline}) for autodetected Debian-style distros, but is not the same for
Fedora-style distros booted from \texttt{/loader/entries/*.conf} files. \medskip Fedora-style distros booted from \texttt{/loader/entries/*.conf} files. \medskip
Typically this option should not be needed in the latter case, but in case it is, to find out the unique Typically this option should not be needed for \texttt{/loader/entries} distros, but in case it is to find out the
partition uuid to use look for \texttt{LNX:} entries in the OpenCore debug log file. Alternatively, and unique partition uuid to use look for \texttt{LNX:} entries in the OpenCore debug log file. Alternatively, and
for more advanced scenarios, it is possible to examine how the distro's partitions are mounted using the for more advanced scenarios, it is possible to examine how the distro's partitions are mounted using the
Linux \texttt{mount} command, and then find out the partuuid of relevant mounted partitions by examining the Linux \texttt{mount} command, and then find out the partuuid of relevant mounted partitions by examining the
output of \texttt{ls -l /dev/disk/by-partuuid}. \medskip output of \texttt{ls -l /dev/disk/by-partuuid}. \medskip
\item \texttt{autoopts[+]="\{options\}"} - Default: None specified. The kernel options to use \item \texttt{autoopts[+]="\{options\}"} - Default: None specified. The kernel options to use
for autodetected Linux only. The value here is never used for entries created from for autodetected Linux only. The value here is never used for entries created from
\texttt{/loader/entries/*.conf} files. \texttt{partuuidopts} may be more suitable where there are multiple \texttt{/loader/entries/*.conf} files. \texttt{autoopts:\{PARTUUID\}} may be more suitable where there are multiple
distros, but \texttt{autoopts} with no PARTUUID required is more convenient for just one distro. distros, but \texttt{autoopts} with no PARTUUID required is more convenient for just one distro.
If specified with \texttt{+=} then these are used in addition to autodetected options, if specified If specified with \texttt{+=} then these are used in addition to autodetected options, if specified
with \texttt{=} they are used instead. As example usage, it is possible to use \texttt{+=} format to add with \texttt{=} they are used instead. As example usage, it is possible to use \texttt{+=} format to add
...@@ -6565,8 +6571,12 @@ boot \texttt{\{boot\}/vmlinuz*} kernel files directly. It links these automatica ...@@ -6565,8 +6571,12 @@ boot \texttt{\{boot\}/vmlinuz*} kernel files directly. It links these automatica
kernel version in the filename -- to their associated \texttt{\{boot\}/init*} ramdisk files. kernel version in the filename -- to their associated \texttt{\{boot\}/init*} ramdisk files.
This applies to most Debian-related distros, including Debian itself, Ubuntu and variants. This applies to most Debian-related distros, including Debian itself, Ubuntu and variants.
When autodetecting, OpenLinuxBoot looks in \texttt{/etc/default/grub} for kernel boot options and When autodetecting in \texttt{/boot} as part of the root filesystem, OpenLinuxBoot looks in \texttt{/etc/default/grub}
\texttt{/etc/os-release} for the distro name. for kernel boot options and \texttt{/etc/os-release} for the distro name. When autodetecting in a standalone boot
partition (i.e. when \texttt{/boot} has its own mount point), OpenLinuxBoot cannot autodetect kernel arguments and
all kernel arguments except \texttt{initrd=...} must be fully specified by hand using \texttt{autoopts=...} or
\texttt{autoopts:\{partuuid\}=...} (\texttt{+=} variants of these options will not work, as these only add additional
arguments).
BootLoaderSpecByDefault (but not pure Boot Loader Specification) can expand GRUB variables BootLoaderSpecByDefault (but not pure Boot Loader Specification) can expand GRUB variables
in the \texttt{*.conf} files -- and this is used in practice in certain distros such as CentOS. in the \texttt{*.conf} files -- and this is used in practice in certain distros such as CentOS.
......
\documentclass[]{article} \documentclass[]{article}
%DIF LATEXDIFF DIFFERENCE FILE %DIF LATEXDIFF DIFFERENCE FILE
%DIF DEL PreviousConfiguration.tex Fri Feb 11 00:24:26 2022 %DIF DEL PreviousConfiguration.tex Thu Feb 10 01:48:29 2022
%DIF ADD ../Configuration.tex Fri Feb 25 23:37:24 2022 %DIF ADD ../Configuration.tex Sun Feb 27 08:57:52 2022
\usepackage{lmodern} \usepackage{lmodern}
\usepackage{amssymb,amsmath} \usepackage{amssymb,amsmath}
...@@ -118,7 +118,7 @@ ...@@ -118,7 +118,7 @@
%DIF HYPERREF PREAMBLE %DIF PREAMBLE %DIF HYPERREF PREAMBLE %DIF PREAMBLE
\providecommand{\DIFadd}[1]{\texorpdfstring{\DIFaddtex{#1}}{#1}} %DIF PREAMBLE \providecommand{\DIFadd}[1]{\texorpdfstring{\DIFaddtex{#1}}{#1}} %DIF PREAMBLE
\providecommand{\DIFdel}[1]{\texorpdfstring{\DIFdeltex{#1}}{}} %DIF PREAMBLE \providecommand{\DIFdel}[1]{\texorpdfstring{\DIFdeltex{#1}}{}} %DIF PREAMBLE
%DIF COLORLISTINGS PREAMBLE %DIF PREAMBLE %DIF LISTINGS PREAMBLE %DIF PREAMBLE
\RequirePackage{listings} %DIF PREAMBLE \RequirePackage{listings} %DIF PREAMBLE
\RequirePackage{color} %DIF PREAMBLE \RequirePackage{color} %DIF PREAMBLE
\lstdefinelanguage{DIFcode}{ %DIF PREAMBLE \lstdefinelanguage{DIFcode}{ %DIF PREAMBLE
...@@ -6475,7 +6475,7 @@ log when booting (or attempting to boot) a given distro against the options seen ...@@ -6475,7 +6475,7 @@ log when booting (or attempting to boot) a given distro against the options seen
\texttt{cat /proc/cmdline} when the same distro has been booted via its native bootloader. \texttt{cat /proc/cmdline} when the same distro has been booted via its native bootloader.
In general (for safety and security of the running distro) these options should match, and if they do not In general (for safety and security of the running distro) these options should match, and if they do not
it is recommended to use the driver arguments below (in particular \texttt{LINUX\_BOOT\_ADD\_RO}, it is recommended to use the driver arguments below (in particular \texttt{LINUX\_BOOT\_ADD\_RO},
\texttt{LINUX\_BOOT\_ADD\_RW}, \texttt{partuuidopts} and \texttt{autoopts}) to modify the options as required. \texttt{LINUX\_BOOT\_ADD\_RW}, \texttt{\DIFdelbegin \DIFdel{partuuidopts}\DIFdelend \DIFaddbegin \DIFadd{autoopts:\{PARTUUID\}}\DIFaddend } and \texttt{autoopts}) to modify the options as required.
Note however that the following differences are normal and do not need to be fixed: Note however that the following differences are normal and do not need to be fixed:
\begin{itemize} \begin{itemize}
\tightlist \tightlist
...@@ -6503,9 +6503,17 @@ The default parameter values should work well with no changes under most circums ...@@ -6503,9 +6503,17 @@ The default parameter values should work well with no changes under most circums
options for the driver may be specified in \texttt{UEFI/Drivers/Arguments}: options for the driver may be specified in \texttt{UEFI/Drivers/Arguments}:
\begin{itemize} \begin{itemize}
\tightlist
\item \texttt{flags} - Default: all flags \DIFdelbegin \DIFdel{except }\texttt{\DIFdel{LINUX\_BOOT\_ADD\_DEBUG\_INFO}} %DIFAUXCMD
\DIFdelend \DIFaddbegin \DIFadd{are set except the following:
}\begin{itemize}
\tightlist \tightlist
\item \texttt{flags} - Default: all flags except \texttt{LINUX\_BOOT\_ADD\_DEBUG\_INFO} and \item \texttt{\DIFadd{LINUX\_BOOT\_ADD\_RW}}\DIFadd{,
\texttt{LINUX\_BOOT\_LOG\_VERBOSE} are set. \medskip }\item \texttt{\DIFadd{LINUX\_BOOT\_LOG\_VERBOSE}} \DIFaddend and
\DIFdelbegin \texttt{\DIFdel{LINUX\_BOOT\_LOG\_VERBOSE}} %DIFAUXCMD
\DIFdel{are set . }\DIFdelend \DIFaddbegin \item \texttt{\DIFadd{LINUX\_BOOT\_ADD\_DEBUG\_INFO}}\DIFadd{.
}\end{itemize}
\DIFaddend \medskip
Available flags are: \medskip Available flags are: \medskip
...@@ -6559,14 +6567,14 @@ options for the driver may be specified in \texttt{UEFI/Drivers/Arguments}: ...@@ -6559,14 +6567,14 @@ options for the driver may be specified in \texttt{UEFI/Drivers/Arguments}:
option on autodetected distros; should be harmless but very slightly slow down boot time (due to requried option on autodetected distros; should be harmless but very slightly slow down boot time (due to requried
remount as read-write) on distros which do not require it. remount as read-write) on distros which do not require it.
When there are multiple distros and it is required to specify this option for specific distros only, use When there are multiple distros and it is required to specify this option for specific distros only, use
\texttt{partuuidopts:\{partuuid\}+=ro} to manually add the option where required, instead of using this flag. \texttt{\DIFdelbegin \DIFdel{partuuidopts}\DIFdelend \DIFaddbegin \DIFadd{autoopts}\DIFaddend :\{\DIFdelbegin \DIFdel{partuuid}\DIFdelend \DIFaddbegin \DIFadd{PARTUUID}\DIFaddend \}+=ro} to manually add the option where required, instead of using this flag.
\item \texttt{0x00000800} (bit \texttt{11}) --- \texttt{LINUX\_BOOT\_ADD\_RW}, \item \texttt{0x00000800} (bit \texttt{11}) --- \texttt{LINUX\_BOOT\_ADD\_RW},
Like \texttt{LINUX\_BOOT\_ADD\_RO}, this option applies to autodetected Linux only. It is not Like \texttt{LINUX\_BOOT\_ADD\_RO}, this option applies to autodetected Linux only. It is not
required for most distros (which usually require either \texttt{ro} or nothing to be added to required for most distros (which usually require either \texttt{ro} or nothing to be added to
detected boot options), but is required on some Arch-derived distros, e.g. EndeavourOS. detected boot options), but is required on some Arch-derived distros, e.g. EndeavourOS.
When there are multiple distros and it is required to specify this option for specific distros only, use When there are multiple distros and it is required to specify this option for specific distros only, use
\texttt{partuuidopts:\{partuuid\}+=rw} to manually add the option where required, instead of using this flag. \texttt{\DIFdelbegin \DIFdel{partuuidopts}\DIFdelend \DIFaddbegin \DIFadd{autoopts}\DIFaddend :\{\DIFdelbegin \DIFdel{partuuid}\DIFdelend \DIFaddbegin \DIFadd{PARTUUID}\DIFaddend \}+=rw} to manually add the option where required, instead of using this flag.
If this option and \texttt{LINUX\_BOOT\_ADD\_RO} are both specified, only this option is applied If this option and \texttt{LINUX\_BOOT\_ADD\_RO} are both specified, only this option is applied
and \texttt{LINUX\_BOOT\_ADD\_RO} is ignored. and \texttt{LINUX\_BOOT\_ADD\_RO} is ignored.
...@@ -6590,12 +6598,12 @@ options for the driver may be specified in \texttt{UEFI/Drivers/Arguments}: ...@@ -6590,12 +6598,12 @@ options for the driver may be specified in \texttt{UEFI/Drivers/Arguments}:
add or remove, using syntax such as \texttt{flags+=0xC000} to add all debugging add or remove, using syntax such as \texttt{flags+=0xC000} to add all debugging
options or \texttt{flags-=0x400} to remove the \texttt{LINUX\_BOOT\_ADD\_RO} option. \medskip options or \texttt{flags-=0x400} to remove the \texttt{LINUX\_BOOT\_ADD\_RO} option. \medskip
\item \texttt{partuuidopts:\{partuuid\}[+]="\{options\}"} - Default: not set. \medskip \item \texttt{\DIFdelbegin \DIFdel{partuuidopts}\DIFdelend \DIFaddbegin \DIFadd{autoopts}\DIFaddend :\{\DIFdelbegin \DIFdel{partuuid}\DIFdelend \DIFaddbegin \DIFadd{PARTUUID}\DIFaddend \}[+]="\{options\}"} - Default: not set. \medskip
Allows specifying kernel options for a given partition only. If specified with \texttt{+=} then Allows \DIFaddbegin \DIFadd{manually }\DIFaddend specifying kernel options \DIFaddbegin \DIFadd{to use in autodetect mode }\DIFaddend for a given partition only. If specified
these are used in addition to autodetected options, if specified with \texttt{=} they are used instead. with \texttt{+=} then these are used in addition to \DIFaddbegin \DIFadd{any }\DIFaddend autodetected options, if specified with \texttt{=}
Used for autodetected Linux only. Values specified here are never used for entries created from they are used instead. Used for autodetected Linux only. Values specified here are never used for entries created
\texttt{/loader/entries/*.conf} files. from \texttt{/loader/entries/*.conf} files.
\medskip \medskip
\emph{Note}: The \texttt{partuuid} value to be specified here is typically the same as the \texttt{PARTUUID} \emph{Note}: The \texttt{partuuid} value to be specified here is typically the same as the \texttt{PARTUUID}
...@@ -6603,15 +6611,15 @@ options for the driver may be specified in \texttt{UEFI/Drivers/Arguments}: ...@@ -6603,15 +6611,15 @@ options for the driver may be specified in \texttt{UEFI/Drivers/Arguments}:
\texttt{cat /proc/cmdline}) for autodetected Debian-style distros, but is not the same for \texttt{cat /proc/cmdline}) for autodetected Debian-style distros, but is not the same for
Fedora-style distros booted from \texttt{/loader/entries/*.conf} files. \medskip Fedora-style distros booted from \texttt{/loader/entries/*.conf} files. \medskip
Typically this option should not be needed in the latter case, but in case it is, to find out the unique Typically this option should not be needed \DIFdelbegin \DIFdel{in the latter case}\DIFdelend \DIFaddbegin \DIFadd{for }\texttt{\DIFadd{/loader/entries}} \DIFadd{distros}\DIFaddend , but in case it is \DIFdelbegin \DIFdel{, }\DIFdelend to find out the
partition uuid to use look for \texttt{LNX:} entries in the OpenCore debug log file. Alternatively, and unique partition uuid to use look for \texttt{LNX:} entries in the OpenCore debug log file. Alternatively, and
for more advanced scenarios, it is possible to examine how the distro's partitions are mounted using the for more advanced scenarios, it is possible to examine how the distro's partitions are mounted using the
Linux \texttt{mount} command, and then find out the partuuid of relevant mounted partitions by examining the Linux \texttt{mount} command, and then find out the partuuid of relevant mounted partitions by examining the
output of \texttt{ls -l /dev/disk/by-partuuid}. \medskip output of \texttt{ls -l /dev/disk/by-partuuid}. \medskip
\item \texttt{autoopts[+]="\{options\}"} - Default: None specified. The kernel options to use \item \texttt{autoopts[+]="\{options\}"} - Default: None specified. The kernel options to use
for autodetected Linux only. The value here is never used for entries created from for autodetected Linux only. The value here is never used for entries created from
\texttt{/loader/entries/*.conf} files. \texttt{partuuidopts} may be more suitable where there are multiple \texttt{/loader/entries/*.conf} files. \texttt{\DIFdelbegin \DIFdel{partuuidopts}\DIFdelend \DIFaddbegin \DIFadd{autoopts:\{PARTUUID\}}\DIFaddend } may be more suitable where there are multiple
distros, but \texttt{autoopts} with no PARTUUID required is more convenient for just one distro. distros, but \texttt{autoopts} with no PARTUUID required is more convenient for just one distro.
If specified with \texttt{+=} then these are used in addition to autodetected options, if specified If specified with \texttt{+=} then these are used in addition to autodetected options, if specified
with \texttt{=} they are used instead. As example usage, it is possible to use \texttt{+=} format to add with \texttt{=} they are used instead. As example usage, it is possible to use \texttt{+=} format to add
...@@ -6635,8 +6643,13 @@ boot \texttt{\{boot\}/vmlinuz*} kernel files directly. It links these automatica ...@@ -6635,8 +6643,13 @@ boot \texttt{\{boot\}/vmlinuz*} kernel files directly. It links these automatica
kernel version in the filename -- to their associated \texttt{\{boot\}/init*} ramdisk files. kernel version in the filename -- to their associated \texttt{\{boot\}/init*} ramdisk files.
This applies to most Debian-related distros, including Debian itself, Ubuntu and variants. This applies to most Debian-related distros, including Debian itself, Ubuntu and variants.
When autodetecting, OpenLinuxBoot looks in \texttt{/etc/default/grub} for kernel boot options and When autodetecting \DIFaddbegin \DIFadd{in }\texttt{\DIFadd{/boot}} \DIFadd{as part of the root filesystem}\DIFaddend , OpenLinuxBoot looks in \texttt{/etc/default/grub}
\texttt{/etc/os-release} for the distro name. for kernel boot options and \texttt{/etc/os-release} for the distro name. \DIFaddbegin \DIFadd{When autodetecting in a standalone boot
partition (i.e. when }\texttt{\DIFadd{/boot}} \DIFadd{has its own mount point), OpenLinuxBoot cannot autodetect kernel arguments and
all kernel arguments except }\texttt{\DIFadd{initrd=...}} \DIFadd{must be fully specified by hand using }\texttt{\DIFadd{autoopts=...}} \DIFadd{or
}\texttt{\DIFadd{autoopts:\{partuuid\}=...}} \DIFadd{(}\texttt{\DIFadd{+=}} \DIFadd{variants of these options will not work, as these only add additional
arguments).
}\DIFaddend
BootLoaderSpecByDefault (but not pure Boot Loader Specification) can expand GRUB variables BootLoaderSpecByDefault (but not pure Boot Loader Specification) can expand GRUB variables
in the \texttt{*.conf} files -- and this is used in practice in certain distros such as CentOS. in the \texttt{*.conf} files -- and this is used in practice in certain distros such as CentOS.
......
...@@ -37,7 +37,7 @@ typedef enum PARSE_VARS_STATE_ { ...@@ -37,7 +37,7 @@ typedef enum PARSE_VARS_STATE_ {
#define SHIFT_TOKEN(pos, token, offset) do { \ #define SHIFT_TOKEN(pos, token, offset) do { \
CopyMem ((UINT8 *)(token) + (offset), (token), (UINT8 *)(pos) - (UINT8 *)(token)); \ CopyMem ((UINT8 *)(token) + (offset), (token), (UINT8 *)(pos) - (UINT8 *)(token)); \
(token) = (UINT8 *)(token) + (offset); \ (token) = (UINT8 *)(token) + (offset); \
(pos) = (UINT8 *)(token) + (offset); \ (pos) = (UINT8 *)(pos) + (offset); \
} while (0) } while (0)
VOID VOID
...@@ -516,6 +516,7 @@ OcParseVars ( ...@@ -516,6 +516,7 @@ OcParseVars (
State = PARSE_VARS_SHELL_EXPANSION; State = PARSE_VARS_SHELL_EXPANSION;
} else if (Ch == L'\\') { } else if (Ch == L'\\') {
SHIFT_TOKEN (Pos, Value, IsUnicode ? sizeof (CHAR16) : sizeof (CHAR8)); SHIFT_TOKEN (Pos, Value, IsUnicode ? sizeof (CHAR16) : sizeof (CHAR8));
Ch = IsUnicode ? *((CHAR16 *) Pos) : *((CHAR8 *) Pos);
} else if ( } else if (
(State == PARSE_VARS_VALUE && (OcIsSpace (Ch) || Ch == CHAR_NULL)) || (State == PARSE_VARS_VALUE && (OcIsSpace (Ch) || Ch == CHAR_NULL)) ||
(State == PARSE_VARS_QUOTED_VALUE && Ch == '"')) { (State == PARSE_VARS_QUOTED_VALUE && Ch == '"')) {
......
...@@ -104,6 +104,7 @@ OcLoadDrivers ( ...@@ -104,6 +104,7 @@ OcLoadDrivers (
CONST CHAR8 *DriverComment; CONST CHAR8 *DriverComment;
CHAR8 *DriverFileName; CHAR8 *DriverFileName;
CONST CHAR8 *DriverArguments; CONST CHAR8 *DriverArguments;
CONST CHAR8 *UnescapedArguments;
DriversToConnectIterator = NULL; DriversToConnectIterator = NULL;
if (DriversToConnect != NULL) { if (DriversToConnect != NULL) {
...@@ -208,7 +209,19 @@ OcLoadDrivers ( ...@@ -208,7 +209,19 @@ OcLoadDrivers (
FreePool (Driver); FreePool (Driver);
continue; continue;
} }
if (!OcAppendArgumentsToLoadedImage (LoadedImage, &DriverArguments, 1, TRUE)) { UnescapedArguments = XmlUnescapeString (DriverArguments);
if (UnescapedArguments == NULL) {
DEBUG ((
DEBUG_ERROR,
"OC: Cannot unescape arguments for driver %a at %u\n",
DriverFileName,
Index
));
gBS->UnloadImage (ImageHandle);
FreePool (Driver);
continue;
}
if (!OcAppendArgumentsToLoadedImage (LoadedImage, &UnescapedArguments, 1, TRUE)) {
DEBUG (( DEBUG ((
DEBUG_ERROR, DEBUG_ERROR,
"OC: Unable to apply arguments to driver %a at %u - %r!\n", "OC: Unable to apply arguments to driver %a at %u - %r!\n",
...@@ -218,8 +231,10 @@ OcLoadDrivers ( ...@@ -218,8 +231,10 @@ OcLoadDrivers (
)); ));
gBS->UnloadImage (ImageHandle); gBS->UnloadImage (ImageHandle);
FreePool (Driver); FreePool (Driver);
FreePool ((CHAR8 *)UnescapedArguments);
continue; continue;
} }
FreePool ((CHAR8 *)UnescapedArguments);
} }
Status = gBS->StartImage ( Status = gBS->StartImage (
......
...@@ -25,6 +25,7 @@ ...@@ -25,6 +25,7 @@
#define GRUB_DEFAULT_FILE L"\\etc\\default\\grub" #define GRUB_DEFAULT_FILE L"\\etc\\default\\grub"
#define OS_RELEASE_FILE L"\\etc\\os-release" #define OS_RELEASE_FILE L"\\etc\\os-release"
#define AUTODETECT_DIR L"\\boot" #define AUTODETECT_DIR L"\\boot"
#define ROOT_DIR L"\\"
#define ROOT_FS_FILE L"\\bin\\sh" #define ROOT_FS_FILE L"\\bin\\sh"
STATIC STATIC
...@@ -59,6 +60,26 @@ STATIC ...@@ -59,6 +60,26 @@ STATIC
CHAR8 CHAR8
*mEtcDefaultGrubFileContents; *mEtcDefaultGrubFileContents;
STATIC
OC_FLEX_ARRAY
*mPerPartuuidAutoOpts;
STATIC
CHAR16
*mCurrentPartuuidAutoOpts;
STATIC
CHAR16
*mCurrentPartuuidAutoOptsPlus;
STATIC
CHAR16
*mGlobalAutoOpts;
STATIC
CHAR16
*mGlobalAutoOptsPlus;
STATIC STATIC
EFI_STATUS EFI_STATUS
ProcessVmlinuzFile ( ProcessVmlinuzFile (
...@@ -129,15 +150,18 @@ CreateAsciiRelativePath ( ...@@ -129,15 +150,18 @@ CreateAsciiRelativePath (
) )
{ {
UINTN Size; UINTN Size;
BOOLEAN UseDir;
UseDir = !(DirectoryPathLength == 1 && DirectoryPath[0] == L'\\');
Size = DirectoryPathLength + FilePathLength + 2; Size = (UseDir ? DirectoryPathLength : 0) + FilePathLength + 2;
*Dest = AllocatePool (Size); *Dest = AllocatePool (Size);
if (*Dest == NULL) { if (*Dest == NULL) {
return EFI_OUT_OF_RESOURCES; return EFI_OUT_OF_RESOURCES;
} }
AsciiSPrint (*Dest, Size, "%s\\%s", DirectoryPath, FilePath); AsciiSPrint (*Dest, Size, "%s\\%s", UseDir ? DirectoryPath : L"", FilePath);
return EFI_SUCCESS; return EFI_SUCCESS;
} }
...@@ -210,26 +234,31 @@ AutodetectTitle ( ...@@ -210,26 +234,31 @@ AutodetectTitle (
STATIC STATIC
EFI_STATUS EFI_STATUS
LoadOsRelease ( LoadOsRelease (
IN CONST EFI_FILE_PROTOCOL *RootDirectory IN CONST EFI_FILE_PROTOCOL *RootDirectory,
IN CONST BOOLEAN IsStandaloneBoot
) )
{ {
EFI_STATUS Status; EFI_STATUS Status;
BOOLEAN ReadRequired; BOOLEAN TryReading;
mEtcOsReleaseOptions = NULL; mEtcOsReleaseOptions = NULL;
mEtcOsReleaseFileContents = NULL; mEtcOsReleaseFileContents = NULL;
mPrettyName = NULL; mPrettyName = NULL;
ReadRequired = (mDiskLabel == NULL); TryReading = (mDiskLabel == NULL);
DEBUG_CODE_BEGIN (); DEBUG_CODE_BEGIN ();
ReadRequired = TRUE; TryReading = TRUE;
DEBUG_CODE_END (); DEBUG_CODE_END ();
if (IsStandaloneBoot) {
TryReading = FALSE;
}
// //
// Load distro name from /etc/os-release. // Load distro name from /etc/os-release.
// //
if (ReadRequired) { if (TryReading) {
mEtcOsReleaseFileContents = OcReadFileFromDirectory (RootDirectory, OS_RELEASE_FILE, NULL, 0); mEtcOsReleaseFileContents = OcReadFileFromDirectory (RootDirectory, OS_RELEASE_FILE, NULL, 0);
if (mEtcOsReleaseFileContents == NULL) { if (mEtcOsReleaseFileContents == NULL) {
DEBUG ((DEBUG_WARN, "LNX: %s not found\n", OS_RELEASE_FILE)); DEBUG ((DEBUG_WARN, "LNX: %s not found\n", OS_RELEASE_FILE));
...@@ -265,7 +294,8 @@ LoadOsRelease ( ...@@ -265,7 +294,8 @@ LoadOsRelease (
STATIC STATIC
EFI_STATUS EFI_STATUS
LoadDefaultGrub ( LoadDefaultGrub (
IN CONST EFI_FILE_PROTOCOL *RootDirectory IN CONST EFI_FILE_PROTOCOL *RootDirectory,
IN CONST BOOLEAN IsStandaloneBoot
) )
{ {
EFI_STATUS Status; EFI_STATUS Status;
...@@ -273,6 +303,10 @@ LoadDefaultGrub ( ...@@ -273,6 +303,10 @@ LoadDefaultGrub (
mEtcDefaultGrubOptions = NULL; mEtcDefaultGrubOptions = NULL;
mEtcDefaultGrubFileContents = NULL; mEtcDefaultGrubFileContents = NULL;
if (IsStandaloneBoot) {
return EFI_SUCCESS;
}
// //
// Load kernel options from /etc/default/grub. // Load kernel options from /etc/default/grub.
// //
...@@ -426,135 +460,186 @@ InsertRootOption ( ...@@ -426,135 +460,186 @@ InsertRootOption (
return CreateRootPartuuid (NewOption); return CreateRootPartuuid (NewOption);
} }
//
// TODO: Options for rescue versions. Would it be better e.g. just to add "ro" and nothing else?
// However on some installs (e.g. where modules to load are specified in the kernel opts) this
// would not boot at all.
// Maybe upgrade to partuuidopts:{partuuid}r="...": user options for rescue kernels on specified partuuid?
//
STATIC STATIC
VOID
GetCurrentPartuuidAutoOpts (
VOID
)
{
UINTN Index;
AUTOOPTS *AutoOpts;
mCurrentPartuuidAutoOpts = NULL;
mCurrentPartuuidAutoOptsPlus = NULL;
for (Index = 0; Index < mPerPartuuidAutoOpts->Count; Index++) {
AutoOpts = OcFlexArrayItemAt (mPerPartuuidAutoOpts, Index);
if (CompareMem (&gPartuuid, &AutoOpts->Guid, sizeof (EFI_GUID)) == 0) {
if (AutoOpts->PlusOpts) {
mCurrentPartuuidAutoOptsPlus = AutoOpts->Opts;
} else {
mCurrentPartuuidAutoOpts = AutoOpts->Opts;
}
}
}
}
EFI_STATUS EFI_STATUS
AutodetectBootOptions ( InternalPreloadAutoOpts (
IN CONST BOOLEAN IsRescue,
IN OC_FLEX_ARRAY *Options IN OC_FLEX_ARRAY *Options
) )
{ {
EFI_STATUS Status; EFI_STATUS Status;
UINTN Index; UINTN Index;
UINTN InsertIndex;
UINTN OptionCount;
OC_PARSED_VAR *Option; OC_PARSED_VAR *Option;
EFI_GUID Guid; AUTOOPTS *AutoOpts;
CHAR8 *AsciiStrValue;
CHAR8 *GrubVarName; mGlobalAutoOpts = NULL;
BOOLEAN FoundOptions; mGlobalAutoOptsPlus = NULL;
BOOLEAN PlusOpts;
CHAR8 *AddRxOption;
OptionCount = 0; mPerPartuuidAutoOpts = OcFlexArrayInit (sizeof (AUTOOPTS), NULL);
if (gParsedLoadOptions != NULL) { if (mPerPartuuidAutoOpts == NULL) {
OptionCount = gParsedLoadOptions->Count; return EFI_OUT_OF_RESOURCES;
} }
FoundOptions = FALSE; if (Options == NULL) {
return EFI_SUCCESS;
}
// //
// Look for user-specified options for this partuuid. // Look for autoopts.
// Remember that although args are ASCII in the OC config file, they are // Remember that although args are ASCII in the OC config file, they are
// Unicode by the time they get passed as UEFI LoadOptions. // Unicode by the time they get passed as UEFI LoadOptions.
// //
for (Index = 0; Index < OptionCount; Index++) { for (Index = 0; Index < Options->Count; Index++) {
Option = OcFlexArrayItemAt (gParsedLoadOptions, Index); Option = OcFlexArrayItemAt (Options, Index);
// //
// partuuidopts:{partuuid}[+]="...": user options for specified partuuid. // autoopts:{partuuid}[+]="...": user options for specified partuuid.
// //
if (OcUnicodeStartsWith (Option->Unicode.Name, L"partuuidopts:", TRUE)) { if (OcUnicodeStartsWith (Option->Unicode.Name, L"autoopts:", TRUE)) {
if (Option->Unicode.Value == NULL) { if (Option->Unicode.Value == NULL) {
DEBUG ((DEBUG_WARN, "LNX: Missing value for %s\n", Option->Unicode.Name)); DEBUG ((DEBUG_WARN, "LNX: Missing value for %s\n", Option->Unicode.Name));
continue; continue;
} }
Status = StrToGuid (&Option->Unicode.Name[L_STR_LEN (L"partuuidopts:")], &Guid); AutoOpts = OcFlexArrayAddItem (mPerPartuuidAutoOpts);
Status = StrToGuid (&Option->Unicode.Name[L_STR_LEN (L"autoopts:")], &AutoOpts->Guid);
if (EFI_ERROR (Status)) { if (EFI_ERROR (Status)) {
DEBUG ((DEBUG_WARN, "LNX: Cannot parse partuuid from %s - %r\n", Option->Unicode.Name, Status)); DEBUG ((DEBUG_WARN, "LNX: Cannot parse partuuid from %s - %r\n", Option->Unicode.Name, Status));
OcFlexArrayDiscardItem (mPerPartuuidAutoOpts, FALSE);
continue; continue;
} }
if (CompareMem (&gPartuuid, &Guid, sizeof (EFI_GUID)) != 0) { AutoOpts->Opts = Option->Unicode.Value;
DEBUG (( AutoOpts->PlusOpts = OcUnicodeEndsWith (Option->Unicode.Name, L"+", FALSE);
(gLinuxBootFlags & LINUX_BOOT_LOG_VERBOSE) == 0 ? DEBUG_VERBOSE : DEBUG_INFO, } else if (StrCmp (Option->Unicode.Name, L"autoopts") == 0) {
"LNX: No match partuuidopts:%g != %g\n",
&Guid,
&gPartuuid
));
} else {
PlusOpts = OcUnicodeEndsWith (Option->Unicode.Name, L"+", FALSE);
DEBUG ((
(gLinuxBootFlags & LINUX_BOOT_LOG_VERBOSE) == 0 ? DEBUG_VERBOSE : DEBUG_INFO,
"LNX: Using partuuidopts%a=\"%s\"\n",
PlusOpts ? "+" : "",
Option->Unicode.Value
));
Status = AddOption (Options, Option->Unicode.Value, TRUE);
if (EFI_ERROR (Status)) {
return Status;
}
if (!PlusOpts) {
return EFI_SUCCESS;
}
FoundOptions = TRUE;
}
}
}
//
// Use global defaults, if user has defined any.
//
for (Index = 0; Index < OptionCount; Index++) {
Option = OcFlexArrayItemAt (gParsedLoadOptions, Index);
//
// Don't use autoopts if partition specific partuuidopts already found.
//
if (!FoundOptions && StrCmp (Option->Unicode.Name, L"autoopts") == 0) {
if (Option->Unicode.Value == NULL) { if (Option->Unicode.Value == NULL) {
DEBUG ((DEBUG_WARN, "LNX: Missing value for %s\n", Option->Unicode.Name)); DEBUG ((DEBUG_WARN, "LNX: Missing value for %s\n", Option->Unicode.Name));
continue; continue;
} }
DEBUG (( mGlobalAutoOpts = Option->Unicode.Value;
(gLinuxBootFlags & LINUX_BOOT_LOG_VERBOSE) == 0 ? DEBUG_VERBOSE : DEBUG_INFO,
"LNX: Using %s=\"%s\"\n",
Option->Unicode.Name,
Option->Unicode.Value
));
Status = AddOption (Options, Option->Unicode.Value, TRUE);
return Status;
} else if (StrCmp (Option->Unicode.Name, L"autoopts+") == 0) { } else if (StrCmp (Option->Unicode.Name, L"autoopts+") == 0) {
if (Option->Unicode.Value == NULL) { if (Option->Unicode.Value == NULL) {
DEBUG ((DEBUG_WARN, "LNX: Missing value for %s\n", Option->Unicode.Name)); DEBUG ((DEBUG_WARN, "LNX: Missing value for %s\n", Option->Unicode.Name));
continue; continue;
} }
DEBUG (( mGlobalAutoOptsPlus = Option->Unicode.Value;
(gLinuxBootFlags & LINUX_BOOT_LOG_VERBOSE) == 0 ? DEBUG_VERBOSE : DEBUG_INFO, }
"LNX: Using %s=\"%s\"\n", }
Option->Unicode.Name,
Option->Unicode.Value
));
Status = AddOption (Options, Option->Unicode.Value, TRUE); return EFI_SUCCESS;
if (EFI_ERROR (Status)) { }
return Status;
}
FoundOptions = TRUE; //
// TODO: Options for rescue versions. Would it be better e.g. just to add "ro" and nothing else?
// However on some installs (e.g. where modules to load are specified in the kernel opts) this
// would not boot at all.
// Maybe upgrade to autoopts:{partuuid}r="...": user options for rescue kernels on specified partuuid?
//
STATIC
EFI_STATUS
AutodetectBootOptions (
IN CONST BOOLEAN IsRescue,
IN CONST BOOLEAN IsStandaloneBoot,
IN OC_FLEX_ARRAY *Options
)
{
EFI_STATUS Status;
UINTN Index;
UINTN InsertIndex;
CHAR8 *AsciiStrValue;
CHAR8 *GrubVarName;
BOOLEAN FoundOptions;
CHAR8 *AddRxOption;
FoundOptions = FALSE;
//
// Do we have user-specified options for this partuuid?
//
if (mCurrentPartuuidAutoOpts) {
DEBUG ((
(gLinuxBootFlags & LINUX_BOOT_LOG_VERBOSE) == 0 ? DEBUG_VERBOSE : DEBUG_INFO,
"LNX: Using autoopts:%g%a=\"%s\"\n",
&gPartuuid,
"",
mCurrentPartuuidAutoOpts
));
Status = AddOption (Options, mCurrentPartuuidAutoOpts, TRUE);
return Status;
}
if (mCurrentPartuuidAutoOptsPlus) {
DEBUG ((
(gLinuxBootFlags & LINUX_BOOT_LOG_VERBOSE) == 0 ? DEBUG_VERBOSE : DEBUG_INFO,
"LNX: Using autoopts:%g%a=\"%s\"\n",
&gPartuuid,
"+",
mCurrentPartuuidAutoOptsPlus
));
Status = AddOption (Options, mCurrentPartuuidAutoOptsPlus, TRUE);
if (EFI_ERROR (Status)) {
return Status;
} }
FoundOptions = TRUE;
} }
//
// Don't use autoopts if partition specific autoopts:{partuuid} already found.
//
if (!FoundOptions && mGlobalAutoOpts) {
DEBUG ((
(gLinuxBootFlags & LINUX_BOOT_LOG_VERBOSE) == 0 ? DEBUG_VERBOSE : DEBUG_INFO,
"LNX: Using autoopts%a=\"%s\"\n",
"",
mGlobalAutoOpts
));
Status = AddOption (Options, mGlobalAutoOpts, TRUE);
return Status;
} else if (mGlobalAutoOptsPlus) {
DEBUG ((
(gLinuxBootFlags & LINUX_BOOT_LOG_VERBOSE) == 0 ? DEBUG_VERBOSE : DEBUG_INFO,
"LNX: Using autoopts%a=\"%s\"\n",
"+",
mGlobalAutoOptsPlus
));
Status = AddOption (Options, mGlobalAutoOptsPlus, TRUE);
if (EFI_ERROR (Status)) {
return Status;
}
FoundOptions = TRUE;
}
//
// Should only have attempted to detect kernels on standalone boot partition if we had full user options.
//
ASSERT (!IsStandaloneBoot);
// //
// Code only reaches here and below if has been nothing or only += options above. // Code only reaches here and below if has been nothing or only += options above.
...@@ -661,7 +746,8 @@ AutodetectBootOptions ( ...@@ -661,7 +746,8 @@ AutodetectBootOptions (
STATIC STATIC
EFI_STATUS EFI_STATUS
GenerateEntriesForVmlinuzFiles ( GenerateEntriesForVmlinuzFiles (
IN CHAR16 *DirectoryPath IN CHAR16 *DirectoryPath,
IN CONST BOOLEAN IsStandaloneBoot
) )
{ {
EFI_STATUS Status; EFI_STATUS Status;
...@@ -780,7 +866,7 @@ GenerateEntriesForVmlinuzFiles ( ...@@ -780,7 +866,7 @@ GenerateEntriesForVmlinuzFiles (
// //
// Add all options. // Add all options.
// //
Status = AutodetectBootOptions (IsRescue, Entry->Options); Status = AutodetectBootOptions (IsRescue, IsStandaloneBoot, Entry->Options);
if (EFI_ERROR (Status)) { if (EFI_ERROR (Status)) {
return Status; return Status;
} }
...@@ -791,42 +877,35 @@ GenerateEntriesForVmlinuzFiles ( ...@@ -791,42 +877,35 @@ GenerateEntriesForVmlinuzFiles (
STATIC STATIC
EFI_STATUS EFI_STATUS
InternalAutodetectLinux ( AutodetectLinuxAtDirectory (
IN EFI_FILE_PROTOCOL *RootDirectory, IN EFI_FILE_PROTOCOL *RootDirectory,
IN EFI_FILE_PROTOCOL *VmlinuzDirectory,
IN CHAR16 *AutodetectDir,
IN CONST BOOLEAN IsStandaloneBoot,
OUT OC_PICKER_ENTRY **Entries, OUT OC_PICKER_ENTRY **Entries,
OUT UINTN *NumEntries OUT UINTN *NumEntries
) )
{ {
EFI_STATUS Status; EFI_STATUS Status;
EFI_FILE_PROTOCOL *VmlinuzDirectory;
EFI_FILE_PROTOCOL *RootFsFile; EFI_FILE_PROTOCOL *RootFsFile;
//
// For now we are only searching in /boot.
// vmlinuz files in / should not require autodetect, as
// they should be accompanied by /loader/entries (Fedora-style),
// and vmlinuz files in /boot not accompanied by /loader/entries
// is Debian-style, so it seems sensible to wait to see what
// else there is rather than speculatively adding directories.
//
Status = OcSafeFileOpen (RootDirectory, &VmlinuzDirectory, AUTODETECT_DIR, EFI_FILE_MODE_READ, 0);
if (EFI_ERROR (Status)) {
return Status;
}
mVmlinuzFiles = NULL; mVmlinuzFiles = NULL;
mInitrdFiles = NULL; mInitrdFiles = NULL;
Status = OcSafeFileOpen (RootDirectory, &RootFsFile, ROOT_FS_FILE, EFI_FILE_MODE_READ, 0); Status = EFI_SUCCESS;
if (!EFI_ERROR (Status)) {
Status = OcEnsureDirectoryFile (RootFsFile, FALSE); if (!IsStandaloneBoot) {
Status = OcSafeFileOpen (RootDirectory, &RootFsFile, ROOT_FS_FILE, EFI_FILE_MODE_READ, 0);
if (!EFI_ERROR (Status)) {
Status = OcEnsureDirectoryFile (RootFsFile, FALSE);
if (EFI_ERROR (Status)) {
DEBUG ((DEBUG_WARN, "LNX: %s found but not a %a - %r\n", ROOT_FS_FILE, "file", Status));
}
RootFsFile->Close (RootFsFile);
}
if (EFI_ERROR (Status)) { if (EFI_ERROR (Status)) {
DEBUG ((DEBUG_WARN, "LNX: %s found but not a %a - %r\n", ROOT_FS_FILE, "file", Status)); DEBUG ((DEBUG_WARN, "LNX: AutodetectLinux not root fs - %r\n", Status));
} }
RootFsFile->Close (RootFsFile);
}
if (EFI_ERROR (Status)) {
DEBUG ((DEBUG_WARN, "LNX: Does not appear to be root filesystem - %r\n", Status));
} }
if (!EFI_ERROR (Status)) { if (!EFI_ERROR (Status)) {
...@@ -866,12 +945,12 @@ InternalAutodetectLinux ( ...@@ -866,12 +945,12 @@ InternalAutodetectLinux (
Status = EFI_OUT_OF_RESOURCES; Status = EFI_OUT_OF_RESOURCES;
} else { } else {
LoadAppleDiskLabel (VmlinuzDirectory); LoadAppleDiskLabel (VmlinuzDirectory);
Status = LoadOsRelease (RootDirectory); Status = LoadOsRelease (RootDirectory, IsStandaloneBoot);
if (!EFI_ERROR (Status)) { if (!EFI_ERROR (Status)) {
Status = LoadDefaultGrub (RootDirectory); Status = LoadDefaultGrub (RootDirectory, IsStandaloneBoot);
} }
if (!EFI_ERROR (Status)) { if (!EFI_ERROR (Status)) {
Status = GenerateEntriesForVmlinuzFiles (AUTODETECT_DIR); Status = GenerateEntriesForVmlinuzFiles (AutodetectDir, IsStandaloneBoot);
} }
FreeEtcFiles (); FreeEtcFiles ();
} }
...@@ -895,25 +974,70 @@ InternalAutodetectLinux ( ...@@ -895,25 +974,70 @@ InternalAutodetectLinux (
OcFlexArrayFree (&mInitrdFiles); OcFlexArrayFree (&mInitrdFiles);
} }
VmlinuzDirectory->Close (VmlinuzDirectory);
return Status; return Status;
} }
STATIC
EFI_STATUS EFI_STATUS
AutodetectLinux ( DoAutodetectLinux (
IN EFI_FILE_PROTOCOL *RootDirectory, IN EFI_FILE_PROTOCOL *RootDirectory,
IN EFI_FILE_PROTOCOL *VmlinuzDirectory,
IN CHAR16 *AutodetectDir,
IN CONST BOOLEAN IsStandaloneBoot,
OUT OC_PICKER_ENTRY **Entries, OUT OC_PICKER_ENTRY **Entries,
OUT UINTN *NumEntries OUT UINTN *NumEntries
) )
{ {
EFI_STATUS Status; EFI_STATUS Status;
Status = InternalAutodetectLinux (RootDirectory, Entries, NumEntries); Status = AutodetectLinuxAtDirectory (RootDirectory, VmlinuzDirectory, AutodetectDir, IsStandaloneBoot, Entries, NumEntries);
DEBUG (( DEBUG ((
(EFI_ERROR (Status) && Status != EFI_NOT_FOUND) ? DEBUG_WARN : DEBUG_INFO, (EFI_ERROR (Status) && Status != EFI_NOT_FOUND) ? DEBUG_WARN : DEBUG_INFO,
"LNX: AutodetectLinux - %r\n", "LNX: AutodetectLinux %s - %r\n",
Status)); AutodetectDir,
Status
));
return Status;
}
EFI_STATUS
InternalAutodetectLinux (
IN EFI_FILE_PROTOCOL *RootDirectory,
OUT OC_PICKER_ENTRY **Entries,
OUT UINTN *NumEntries
)
{
EFI_STATUS Status;
EFI_FILE_PROTOCOL *VmlinuzDirectory;
GetCurrentPartuuidAutoOpts ();
//
// Autodetect at /boot if present.
//
Status = OcSafeFileOpen (RootDirectory, &VmlinuzDirectory, AUTODETECT_DIR, EFI_FILE_MODE_READ, 0);
if (!EFI_ERROR (Status)) {
Status = DoAutodetectLinux (RootDirectory, VmlinuzDirectory, AUTODETECT_DIR, FALSE, Entries, NumEntries);
VmlinuzDirectory->Close (VmlinuzDirectory);
}
//
// Try to autodetect kernels at / only if detecting at /boot failed and we have full user-specified
// options, since we can't autodetect any options on standalone /boot (unless we parse grub.cfg for
// boot entries, and even then not all standalone boot setups have it).
//
if (EFI_ERROR (Status)) {
if (mCurrentPartuuidAutoOpts != NULL || (mGlobalAutoOpts != NULL && mCurrentPartuuidAutoOptsPlus == NULL)) {
Status = DoAutodetectLinux (RootDirectory, RootDirectory, ROOT_DIR, TRUE, Entries, NumEntries);
} else {
DEBUG ((
(gLinuxBootFlags & LINUX_BOOT_LOG_VERBOSE) == 0 ? DEBUG_VERBOSE : DEBUG_INFO,
"LNX: Not trying to autodetect kernel on possible standalone /boot partition without full autoopts\n"
));
}
}
return Status; return Status;
} }
...@@ -62,12 +62,12 @@ ...@@ -62,12 +62,12 @@
#define LINUX_BOOT_USE_LATEST BIT9 #define LINUX_BOOT_USE_LATEST BIT9
/* /*
If set, add "ro" as initial option to all distros. Can be specified per If set, add "ro" as initial option to all distros. Can be specified per
FS by using argument partuuidopts:{partuuid}+=ro instead. FS by using argument autoopts:{partuuid}+=ro instead.
*/ */
#define LINUX_BOOT_ADD_RO BIT10 #define LINUX_BOOT_ADD_RO BIT10
/* /*
If set, add "rw" as initial option to all distros. Can be specified per If set, add "rw" as initial option to all distros. Can be specified per
FS by using argument partuuidopts:{partuuid}+=rw instead. FS by using argument autoopts:{partuuid}+=rw instead.
*/ */
#define LINUX_BOOT_ADD_RW BIT11 #define LINUX_BOOT_ADD_RW BIT11
/* /*
...@@ -97,6 +97,7 @@ ...@@ -97,6 +97,7 @@
LINUX_BOOT_ALLOW_AUTODETECT | \ LINUX_BOOT_ALLOW_AUTODETECT | \
LINUX_BOOT_USE_LATEST | \ LINUX_BOOT_USE_LATEST | \
LINUX_BOOT_ADD_RO | \ LINUX_BOOT_ADD_RO | \
LINUX_BOOT_ADD_RW | \
LINUX_BOOT_ALLOW_CONF_AUTO_ROOT | \ LINUX_BOOT_ALLOW_CONF_AUTO_ROOT | \
LINUX_BOOT_LOG_VERBOSE | \ LINUX_BOOT_LOG_VERBOSE | \
LINUX_BOOT_ADD_DEBUG_INFO \ LINUX_BOOT_ADD_DEBUG_INFO \
...@@ -119,12 +120,6 @@ extern UINTN gLinuxBootFlags; ...@@ -119,12 +120,6 @@ extern UINTN gLinuxBootFlags;
*/ */
extern OC_PICKER_CONTEXT *gPickerContext; extern OC_PICKER_CONTEXT *gPickerContext;
/*
Stored parsed load options.
Would be freed at driver unload, if that happened.
*/
extern OC_FLEX_ARRAY *gParsedLoadOptions;
/* /*
The array of loader entries, either really from *.conf files or generated by autodetect. The array of loader entries, either really from *.conf files or generated by autodetect.
*/ */
...@@ -153,11 +148,6 @@ typedef struct GRUB_VAR_ GRUB_VAR; ...@@ -153,11 +148,6 @@ typedef struct GRUB_VAR_ GRUB_VAR;
*/ */
typedef struct LOADER_ENTRY_ LOADER_ENTRY; typedef struct LOADER_ENTRY_ LOADER_ENTRY;
/*
Forward declaration of VMLINUZ_FILE structure.
*/
typedef struct VMLINUZ_FILE_ VMLINUZ_FILE;
/* /*
GRUB vars. GRUB vars.
*/ */
...@@ -329,17 +319,34 @@ struct LOADER_ENTRY_ { ...@@ -329,17 +319,34 @@ struct LOADER_ENTRY_ {
BOOLEAN DuplicateIdScanned; BOOLEAN DuplicateIdScanned;
}; };
struct VMLINUZ_FILE_ { typedef struct VMLINUZ_FILE_ {
CHAR16 *FileName; CHAR16 *FileName;
CHAR16 *Version; CHAR16 *Version;
UINTN StrLen; UINTN StrLen;
}; } VMLINUZ_FILE;
/*
Autodetect options.
*/
typedef struct AUTOOPTS_ {
EFI_GUID Guid;
CHAR16 *Opts;
BOOLEAN PlusOpts;
} AUTOOPTS;
/*
Load autoopts.
*/
EFI_STATUS
InternalPreloadAutoOpts (
IN OC_FLEX_ARRAY *Options
);
/* /*
Autodetect. Autodetect.
*/ */
EFI_STATUS EFI_STATUS
AutodetectLinux ( InternalAutodetectLinux (
IN EFI_FILE_PROTOCOL *RootDirectory, IN EFI_FILE_PROTOCOL *RootDirectory,
OUT OC_PICKER_ENTRY **Entries, OUT OC_PICKER_ENTRY **Entries,
OUT UINTN *NumEntries OUT UINTN *NumEntries
......
...@@ -21,10 +21,11 @@ ...@@ -21,10 +21,11 @@
#include <Protocol/OcBootEntry.h> #include <Protocol/OcBootEntry.h>
UINTN gLinuxBootFlags = LINUX_BOOT_ALL & ~(LINUX_BOOT_ADD_DEBUG_INFO | LINUX_BOOT_LOG_VERBOSE); UINTN gLinuxBootFlags = LINUX_BOOT_ALL & ~(LINUX_BOOT_ADD_DEBUG_INFO | LINUX_BOOT_LOG_VERBOSE | LINUX_BOOT_ADD_RW);
OC_FLEX_ARRAY *mParsedLoadOptions;
OC_PICKER_CONTEXT *gPickerContext; OC_PICKER_CONTEXT *gPickerContext;
OC_FLEX_ARRAY *gParsedLoadOptions;
OC_FLEX_ARRAY *gLoaderEntries; OC_FLEX_ARRAY *gLoaderEntries;
EFI_GUID gPartuuid; EFI_GUID gPartuuid;
CHAR8 *gFileSystemType; CHAR8 *gFileSystemType;
...@@ -237,17 +238,16 @@ OcGetLinuxBootEntries ( ...@@ -237,17 +238,16 @@ OcGetLinuxBootEntries (
// if no /loader/entries/*.conf files are present, but also if there // if no /loader/entries/*.conf files are present, but also if there
// are only unusable files in there. // are only unusable files in there.
// //
if (EFI_ERROR (Status)) { if (EFI_ERROR (Status)
&& (gLinuxBootFlags & LINUX_BOOT_ALLOW_AUTODETECT) != 0) {
// //
// Auto-detect vmlinuz and initrd files on own root filesystem (Debian-like). // Auto-detect vmlinuz and initrd files on own root filesystem (Debian-like).
// //
if ((gLinuxBootFlags & LINUX_BOOT_ALLOW_AUTODETECT) != 0) { Status = InternalAutodetectLinux (
Status = AutodetectLinux ( RootDirectory,
RootDirectory, Entries,
Entries, NumEntries
NumEntries );
);
}
} }
RootDirectory->Close (RootDirectory); RootDirectory->Close (RootDirectory);
...@@ -285,17 +285,31 @@ UefiMain ( ...@@ -285,17 +285,31 @@ UefiMain (
return Status; return Status;
} }
Status = OcParseLoadOptions (LoadedImage, &gParsedLoadOptions); //
// Keep mParsedLoadOptions kicking around, as all found options link into its memory.
//
Status = OcParseLoadOptions (LoadedImage, &mParsedLoadOptions);
if (!EFI_ERROR (Status)) { if (!EFI_ERROR (Status)) {
AddBootFlags = 0; AddBootFlags = 0;
RemoveBootFlags = 0; RemoveBootFlags = 0;
OcParsedVarsGetInt (gParsedLoadOptions, L"flags", &gLinuxBootFlags, TRUE); OcParsedVarsGetInt (mParsedLoadOptions, L"flags", &gLinuxBootFlags, TRUE);
OcParsedVarsGetInt (gParsedLoadOptions, L"flags+", &AddBootFlags, TRUE); OcParsedVarsGetInt (mParsedLoadOptions, L"flags+", &AddBootFlags, TRUE);
OcParsedVarsGetInt (gParsedLoadOptions, L"flags-", &RemoveBootFlags, TRUE); OcParsedVarsGetInt (mParsedLoadOptions, L"flags-", &RemoveBootFlags, TRUE);
gLinuxBootFlags |= AddBootFlags; gLinuxBootFlags |= AddBootFlags;
gLinuxBootFlags &= ~RemoveBootFlags; gLinuxBootFlags &= ~RemoveBootFlags;
} else if (Status != EFI_NOT_FOUND) { } else {
return Status; if (Status != EFI_NOT_FOUND) {
return Status;
}
ASSERT (mParsedLoadOptions == NULL);
}
if ((gLinuxBootFlags & LINUX_BOOT_ALLOW_AUTODETECT) != 0) {
Status = InternalPreloadAutoOpts (mParsedLoadOptions);
if (EFI_ERROR (Status)) {
return Status;
}
} }
Status = gBS->InstallMultipleProtocolInterfaces ( Status = gBS->InstallMultipleProtocolInterfaces (
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册