OpenCoreKernel: Improve KernelArch implementation

This commit is contained in:
vit9696 2020-08-29 16:18:59 +03:00
parent b5c74d3e62
commit 250c1eefae
10 changed files with 283 additions and 83 deletions

Binary file not shown.

View File

@ -762,7 +762,7 @@ for extensive messages that should not appear in NVRAM log that is heavily limit
When trying to find the problematic change it is useful to rely on
\href{https://git-scm.com/docs/git-bisect}{\texttt{git-bisect}} functionality.
There also are some unnoficial resources that provide per-commit binary
There also are some unofficial resources that provide per-commit binary
builds of OpenCore, like \href{https://dortania.github.io/builds}{Dortania}.
\section{ACPI}\label{acpi}
@ -2298,20 +2298,20 @@ blocking.
\textbf{Description}: Prefer specified kernel architecture (\texttt{Auto}, \texttt{i386},
\texttt{i386-user32}, \texttt{x86\_64}) when available.
On macOS 10.7 and earlier XNU kernel may not boot with the usual \texttt{x86\_64} architecture,
and the exact choice depends on many factors including boot arguments, SMBIOS, and operating
system type. This setting will use the specified architecture to boot macOS when it is supported
by the macOS and the configuration:
On macOS 10.7 and earlier XNU kernel can boot with architectures different from
the usual \texttt{x86\_64}. This setting will use the specified architecture to boot
macOS when it is supported by the macOS and the configuration:
\begin{itemize}
\tightlist
\item \texttt{Auto} --- Choose the preferred architecture automatically.
\item \texttt{i386} --- Use \texttt{i386} (32-bit) kernel when available.
\item \texttt{i386-user32} --- Use \texttt{i386} (32-bit) kernel when available
and force the use of 32-bit userspace even on 64-bit capable processors
(similar to \texttt{-legacy} boot argument). This mode is relevant for older Pentium
processors with \texttt{x86\_64} support but without \texttt{SSSE3}, which
on macOS 10.6 will result in some applications crashing.
and force the use of 32-bit userspace on 64-bit capable processors.
On macOS 64-bit capable processors are assumed to support \texttt{SSSE3}.
This is not the case for older 64-bit capable Pentium processors, which
cause some applications to crash on macOS~10.6. The behaviour corresponds
to \texttt{-legacy} kernel boot argument.
\item \texttt{x86\_64} --- Use \texttt{x86\_64} (64-bit) kernel when available.
\end{itemize}
@ -2321,28 +2321,41 @@ blocking.
\tightlist
\item \texttt{arch} argument in image arguments (e.g. when launched
via UEFI Shell) or in \texttt{boot-args} variable overrides any compatibility
checks and forces the specified architecture, ending this algorithm.
checks and forces the specified architecture, completing this algorithm.
\item OpenCore build architecture restricts capabilities to \texttt{i386}
and \texttt{i386-user32} mode in 32-bit firmware variant.
and \texttt{i386-user32} mode for the 32-bit firmware variant.
\item Determined EfiBoot version restricts architecture choice:
\begin{itemize}
\item 10.4-10.5 --- \texttt{i386} or \texttt{i386-user32}
\item 10.6-10.7 --- \texttt{i386}, \texttt{i386-user32}, or \texttt{x86\_64}
\item 10.8 or newer --- \texttt{x86\_64}
\end{itemize}
\item \texttt{CPUID} capabilities restrict capabilities to
\texttt{i386-user32} if \texttt{SSSE3} is not available
and \texttt{KernelArch} is set to \texttt{Auto}.
\item SMBIOS model information and EfiBoot version restrict
architecture choice and define architecture preference for client
and server operating systems according to the table below.
\item \texttt{KernelArch} setting updates architecture preference
for both client and server operating systems if the architecture
is supported and \texttt{KernelArch} is not \texttt{Auto}.
\item EfiBoot decides on server boot picking either server
or client preference.
\item If \texttt{KernelArch} is set to \texttt{Auto} and \texttt{SSSE3}
is not supported by the CPU, capabilities are restricted to \texttt{i386-user32}
if supported by EfiBoot.
\item Board identifier (from SMBIOS) based on EfiBoot version
disables \texttt{x86\_64} support on an unsupported model
if any \texttt{i386} variant is supported. \texttt{Auto}
is not consulted here as the list is not overridable in EfiBoot.
\item \texttt{KernelArch} restricts the support to the explicitly
specified architecture (when not set to \texttt{Auto}) if
the architecture remains present in the capabilities.
\item The best supported architecture is chosen in this order:
\texttt{x86\_64}, \texttt{i386}, \texttt{i386-user32}.
\end{enumerate}
Unlike macOS~10.7, where select boards identifiers are treated as the \texttt{i386}
only machines, and macOS~10.5 or earlier, where \texttt{x86\_64} is not supported
by the macOS kernel, macOS~10.6 is very special. The architecture choice on macOS~10.6
depends on many factors including not only the board identifier, but also macOS
product type (client vs server), macOS point release, and RAM amount. The detection
of them all is complicated and not practical, because several point releases had genuine
bugs and failed to properly perform the server detection in the first place.
For this reason OpenCore on macOS~10.6 will fallback to \texttt{x86\_64}
architecture whenever it is supported by the board at all, just like on macOS~10.7.
As a reference here is the 64-bit Mac model compatibility corresponding to actual
EfiBoot behaviour on macOS 10.6.8 and 10.7.5.
\begin{center}
\begin{tabular}{|p{0.9in}|c|c|c|c|}
\hline
@ -2365,15 +2378,6 @@ blocking.
\end{tabular}
\end{center}
\emph{Note 1}: Unlike 10.7 and newer, on 10.6 many models support 64-bit
kernel loading but have it disabled by default. Information about 10.6
64-bit Mac model compatibility is incorrect on Apple support website
and does not correspond to actual EfiBoot behaviour.
\emph{Note 2}: Older 10.6 server versions will start in client mode due
to a bug in EfiBoot. Consider using this preference to workaround
the issue.
\item
\texttt{KernelCache}\\
\textbf{Type}: \texttt{plist\ string}\\

Binary file not shown.

View File

@ -1,7 +1,7 @@
\documentclass[]{article}
%DIF LATEXDIFF DIFFERENCE FILE
%DIF DEL PreviousConfiguration.tex Tue Aug 25 23:11:15 2020
%DIF ADD ../Configuration.tex Tue Aug 25 23:11:15 2020
%DIF DEL PreviousConfiguration.tex Sat Aug 8 20:55:30 2020
%DIF ADD ../Configuration.tex Sat Aug 29 16:17:38 2020
\usepackage{lmodern}
\usepackage{amssymb,amsmath}
@ -663,14 +663,19 @@ one should also install \href{https://www.nasm.us}{NASM} and
The latest Xcode version is recommended for use despite the toolchain name. Example
command sequence may look as follows:
\begin{lstlisting}[caption=Compilation Commands, label=compile, style=ocbash]
git clone --recursive --depth=1 https://github.com/acidanthera/audk UDK
\DIFmodbegin
\begin{lstlisting}[caption=Compilation Commands, label=compile, style=ocbash,alsolanguage=DIFcode]
%DIF < git clone --recursive --depth=1 https://github.com/acidanthera/audk UDK
%DIF > git clone --depth=1 https://github.com/acidanthera/audk UDK
cd UDK
git clone https://github.com/acidanthera/OpenCorePkg
%DIF < git clone https://github.com/acidanthera/OpenCorePkg
%DIF > git submodule update --init --recommend-shallow
%DIF > git clone --depth=1 https://github.com/acidanthera/OpenCorePkg
source edksetup.sh
make -C BaseTools
build -a X64 -b RELEASE -t XCODE5 -p OpenCorePkg/OpenCorePkg.dsc
\end{lstlisting}
\DIFmodend
For IDE usage Xcode projects are available in the root of the repositories. Another
approach could be \href{https://www.sublimetext.com}{Sublime Text} with
@ -824,7 +829,7 @@ for extensive messages that should not appear in NVRAM log that is heavily limit
When trying to find the problematic change it is useful to rely on
\href{https://git-scm.com/docs/git-bisect}{\texttt{git-bisect}} functionality.
\DIFaddbegin \DIFadd{There also are some unnoficial resources that provide per-commit binary
\DIFaddbegin \DIFadd{There also are some unofficial resources that provide per-commit binary
builds of OpenCore, like }\href{https://dortania.github.io/builds}{Dortania}\DIFadd{.
}\DIFaddend
@ -2366,36 +2371,70 @@ blocking.
\textbf{\DIFadd{Type}}\DIFadd{: }\texttt{\DIFadd{plist\ string}}\\
\textbf{\DIFadd{Failsafe}}\DIFadd{: }\texttt{\DIFadd{Auto}}\\
\textbf{\DIFadd{Description}}\DIFadd{: Prefer specified kernel architecture (}\texttt{\DIFadd{Auto}}\DIFadd{, }\texttt{\DIFadd{i386}}\DIFadd{,
}\texttt{\DIFadd{x86\_64}}\DIFadd{) when available.
}\texttt{\DIFadd{i386-user32}}\DIFadd{, }\texttt{\DIFadd{x86\_64}}\DIFadd{) when available.
}
\DIFadd{On macOS 10.7 and earlier XNU kernel may not boot with the usual }\texttt{\DIFadd{x86\_64}} \DIFadd{architecture,
and the exact choice depends on many factors including boot arguments, SMBIOS, and operating
system type. This setting will use the specified architecture to boot macOS when it is supported
by the macOS and the configuration. Below is the algorithm determining the kernel architecture.
\DIFadd{On macOS 10.7 and earlier XNU kernel can boot with architectures different from
the usual }\texttt{\DIFadd{x86\_64}}\DIFadd{. This setting will use the specified architecture to boot
macOS when it is supported by the macOS and the configuration:
}
\begin{itemize}
\tightlist
\item \texttt{\DIFadd{Auto}} \DIFadd{--- Choose the preferred architecture automatically.
}\item \texttt{\DIFadd{i386}} \DIFadd{--- Use }\texttt{\DIFadd{i386}} \DIFadd{(32-bit) kernel when available.
}\item \texttt{\DIFadd{i386-user32}} \DIFadd{--- Use }\texttt{\DIFadd{i386}} \DIFadd{(32-bit) kernel when available
and force the use of 32-bit userspace on 64-bit capable processors.
On macOS 64-bit capable processors are assumed to support }\texttt{\DIFadd{SSSE3}}\DIFadd{.
This is not the case for older 64-bit capable Pentium processors, which
cause some applications to crash on macOS~10.6. The behaviour corresponds
to }\texttt{\DIFadd{-legacy}} \DIFadd{kernel boot argument.
}\item \texttt{\DIFadd{x86\_64}} \DIFadd{--- Use }\texttt{\DIFadd{x86\_64}} \DIFadd{(64-bit) kernel when available.
}\end{itemize}
\DIFadd{Below is the algorithm determining the kernel architecture.
}
\begin{enumerate}
\tightlist
\item \texttt{\DIFadd{arch}} \DIFadd{argument in image arguments (e.g. when launched
via UEFI Shell) or in }\texttt{\DIFadd{boot-args}} \DIFadd{variable override any compatibility
checks and force the specified architecture.
via UEFI Shell) or in }\texttt{\DIFadd{boot-args}} \DIFadd{variable overrides any compatibility
checks and forces the specified architecture, completing this algorithm.
}\item \DIFadd{OpenCore build architecture restricts capabilities to }\texttt{\DIFadd{i386}}
\DIFadd{and }\texttt{\DIFadd{i386-user32}} \DIFadd{mode for the 32-bit firmware variant.
}\item \DIFadd{Determined EfiBoot version restricts architecture choice:
}\begin{itemize}
\item \DIFadd{10.4-10.5 --- }\texttt{\DIFadd{i386}}
\item \DIFadd{10.6-10.7 --- }\texttt{\DIFadd{i386}} \DIFadd{or }\texttt{\DIFadd{x86\_64}}
\item \DIFadd{10.4-10.5 --- }\texttt{\DIFadd{i386}} \DIFadd{or }\texttt{\DIFadd{i386-user32}}
\item \DIFadd{10.6-10.7 --- }\texttt{\DIFadd{i386}}\DIFadd{, }\texttt{\DIFadd{i386-user32}}\DIFadd{, or }\texttt{\DIFadd{x86\_64}}
\item \DIFadd{10.8 or newer --- }\texttt{\DIFadd{x86\_64}}
\end{itemize}
\item \DIFadd{SMBIOS model information and EfiBoot version restrict
architecture choice and define architecture preference for client
and server operating systems according to the table below.
}\item \texttt{\DIFadd{KernelArch}} \DIFadd{setting updates architecture preference
for both client and server operating systems if the architecture
is supported and }\texttt{\DIFadd{KernelArch}} \DIFadd{is not }\texttt{\DIFadd{Auto}}\DIFadd{.
}\item \DIFadd{EfiBoot decides on server boot picking either server
or client preference.
\item \DIFadd{If }\texttt{\DIFadd{KernelArch}} \DIFadd{is set to }\texttt{\DIFadd{Auto}} \DIFadd{and }\texttt{\DIFadd{SSSE3}}
\DIFadd{is not supported by the CPU, capabilities are restricted to }\texttt{\DIFadd{i386-user32}}
\DIFadd{if supported by EfiBoot.
}\item \DIFadd{Board identifier (from SMBIOS) based on EfiBoot version
disables }\texttt{\DIFadd{x86\_64}} \DIFadd{support on an unsupported model
if any }\texttt{\DIFadd{i386}} \DIFadd{variant is supported. }\texttt{\DIFadd{Auto}}
\DIFadd{is not consulted here as the list is not overridable in EfiBoot.
}\item \texttt{\DIFadd{KernelArch}} \DIFadd{restricts the support to the explicitly
specified architecture (when not set to }\texttt{\DIFadd{Auto}}\DIFadd{) if
the architecture remains present in the capabilities.
}\item \DIFadd{The best supported architecture is chosen in this order:
}\texttt{\DIFadd{x86\_64}}\DIFadd{, }\texttt{\DIFadd{i386}}\DIFadd{, }\texttt{\DIFadd{i386-user32}}\DIFadd{.
}\end{enumerate}
\DIFadd{Unlike macOS~10.7, where select boards identifiers are treated as the }\texttt{\DIFadd{i386}}
\DIFadd{only machines, and macOS~10.5 or earlier, where }\texttt{\DIFadd{x86\_64}} \DIFadd{is not supported
by the macOS kernel, macOS~10.6 is very special. The architecture choice on macOS~10.6
depends on many factors including not only the board identifier, but also macOS
product type (client vs server), macOS point release, and RAM amount. The detection
of them all is complicated and not practical, because several point releases had genuine
bugs and failed to properly perform the server detection in the first place.
For this reason OpenCore on macOS~10.6 will fallback to }\texttt{\DIFadd{x86\_64}}
\DIFadd{architecture whenever it is supported by the board at all, just like on macOS~10.7.
As a reference here is the 64-bit Mac model compatibility corresponding to actual
EfiBoot behaviour on macOS 10.6.8 and 10.7.5.
}
\begin{center}
\begin{tabular}{|p{0.9in}|c|c|c|c|}
\hline
@ -2418,17 +2457,6 @@ blocking.
\end{tabular}
\end{center}
\emph{\DIFadd{Note 1}}\DIFadd{: Unlike 10.7 and newer, on 10.6 many models support 64-bit
kernel loading but have it disabled by default. Information about 10.6
64-bit Mac model compatibility is incorrect on Apple support website
and does not correspond to actual EfiBoot behaviour.
}
\emph{\DIFadd{Note 2}}\DIFadd{: Older 10.6 server versions will start in client mode due
to a bug in EfiBoot. Consider using this preference to workaround
the issue.
}
\item
\texttt{\DIFadd{KernelCache}}\\
\textbf{\DIFadd{Type}}\DIFadd{: }\texttt{\DIFadd{plist\ string}}\\
@ -4857,7 +4885,7 @@ similar to the builtin text interface.
OpenCanopy requires graphical resources located in \texttt{Resources} directory to run.
Sample resources (fonts and images) can be found in
\href{https://github.com/acidanthera/OcBinaryData}{OcBinaryData repository}. You can find customised icons over the internet
\href{https://github.com/acidanthera/OcBinaryData}{OcBinaryData repository}. You can find customised icons over the internet
(e.g. \href{https://github.com/blackosx/OpenCanopyIcons}{here} or \href{https://applelife.ru/threads/kastomizacija-opencanopy.2945020/}{there}).
OpenCanopy provides full support for \texttt{PickerAttributes} and offers a configurable

Binary file not shown.

View File

@ -1142,6 +1142,24 @@ OcAppendArgumentToCmd (
IN CONST UINTN ArgumentLength
);
/**
Append 1 or more arguments to Loaded Image protocol.
@param[in,out] LoadedImage Loaded Image protocol instance.
@param[in] Arguments Argument array.
@param[in] ArgumentCount Number of arguments in the array.
@param[in] Replace Whether to append to existing arguments or replace.
@retval TRUE on success.
**/
BOOLEAN
OcAppendArgumentsToLoadedImage (
IN OUT EFI_LOADED_IMAGE_PROTOCOL *LoadedImage,
IN CONST CHAR8 **Arguments,
IN UINT32 ArgumentCount,
IN BOOLEAN Replace
);
/**
Perform NVRAM UEFI variable deletion.
**/

View File

@ -101,6 +101,8 @@ GetMacInfo (
@param[in] ProductName Product to get information for.
@param[in] KernelVersion Kernel version.
@retval TRUE if supported.
**/
BOOLEAN
IsMacModel64BitCompatible (

View File

@ -19,6 +19,7 @@
#include <Library/MemoryAllocationLib.h>
#include <Library/OcBootManagementLib.h>
#include <Library/OcMiscLib.h>
#include <Library/PrintLib.h>
#include <Library/UefiLib.h>
#include <Library/UefiRuntimeServicesTableLib.h>
@ -187,6 +188,79 @@ OcAppendArgumentToCmd (
return TRUE;
}
BOOLEAN
OcAppendArgumentsToLoadedImage (
IN OUT EFI_LOADED_IMAGE_PROTOCOL *LoadedImage,
IN CONST CHAR8 **Arguments,
IN UINT32 ArgumentCount,
IN BOOLEAN Replace
)
{
UINT32 Index;
UINTN ArgumentLength;
UINTN TotalLength;
CHAR16 *NewArguments;
CHAR16 *Walker;
ASSERT (LoadedImage != NULL);
ASSERT (Arguments != NULL);
ASSERT (ArgumentCount > 0);
TotalLength = 0;
//
// Count length including spaces between or '\0' for the last argument.
//
for (Index = 0; Index < ArgumentCount; ++Index) {
ArgumentLength = AsciiStrSize (Arguments[Index]);
if (OcOverflowAddUN (TotalLength, ArgumentLength, &TotalLength)) {
return FALSE;
}
}
if (OcOverflowMulUN (TotalLength, sizeof (CHAR16), &TotalLength)) {
return FALSE;
}
Replace |= LoadedImage->LoadOptionsSize < sizeof (CHAR16);
if (!Replace
&& OcOverflowTriAddUN (TotalLength, sizeof (CHAR16), LoadedImage->LoadOptionsSize, &TotalLength)) {
return FALSE;
}
NewArguments = AllocatePool (TotalLength);
if (NewArguments == NULL) {
return FALSE;
}
Walker = NewArguments;
for (Index = 0; Index < ArgumentCount; ++Index) {
if (Index != 0) {
*Walker++ = ' ';
}
ArgumentLength = AsciiStrLen (Arguments[Index]);
AsciiStrToUnicodeStrS (
Arguments[Index],
Walker,
ArgumentLength + 1
);
Walker += ArgumentLength;
}
if (!Replace) {
*Walker++ = ' ';
CopyMem (Walker, LoadedImage->LoadOptions, LoadedImage->LoadOptionsSize);
Walker += LoadedImage->LoadOptionsSize / sizeof (CHAR16);
*Walker++ = '\0';
}
LoadedImage->LoadOptions = NewArguments;
LoadedImage->LoadOptionsSize = TotalLength;
return TRUE;
}
BOOLEAN
OcCheckArgumentFromEnv (
IN EFI_LOADED_IMAGE *LoadedImage OPTIONAL,

View File

@ -958,7 +958,6 @@ InternalLoadBootEntry (
VOID *EntryData;
UINT32 EntryDataSize;
CONST CHAR8 *Args;
UINT32 ArgsLen;
ASSERT (BootEntry != NULL);
//
@ -1058,18 +1057,17 @@ InternalLoadBootEntry (
if (BootEntry->LoadOptions == NULL && (BootEntry->Type & OC_BOOT_APPLE_ANY) != 0) {
Args = Context->AppleBootArgs;
ArgsLen = (UINT32) AsciiStrLen (Args);
} else {
Args = BootEntry->LoadOptions;
ArgsLen = BootEntry->LoadOptionsSize;
ASSERT (ArgsLen == ((Args == NULL) ? 0 : (UINT32) AsciiStrLen (Args)));
}
if (ArgsLen > 0) {
LoadedImage->LoadOptions = AsciiStrCopyToUnicode (Args, ArgsLen);
if (LoadedImage->LoadOptions != NULL) {
LoadedImage->LoadOptionsSize = ArgsLen * sizeof (CHAR16) + sizeof (CHAR16);
}
if (Args != NULL && Args[0] != '\0') {
OcAppendArgumentsToLoadedImage (
LoadedImage,
&Args,
1,
TRUE
);
}
if (BootEntry->Type == OC_BOOT_EXTERNAL_OS || BootEntry->Type == OC_BOOT_EXTERNAL_TOOL) {

View File

@ -48,8 +48,12 @@ OcKernelConfigureCapabilities (
{
CONST CHAR8 *KernelArch;
CHAR8 *AppleArchValue;
CONST CHAR8 *NewArguments[2];
UINT32 ArgumentCount;
UINT32 RequestedArch;
BOOLEAN HasAppleArch;
BOOLEAN Automatic;
BOOLEAN SnowLeo64;
BOOLEAN Lion64;
//
// Reset to the default value.
@ -76,7 +80,7 @@ OcKernelConfigureCapabilities (
&AppleArchValue
);
if (AppleArchValue) {
if (HasAppleArch) {
mUse32BitKernel = AsciiStrCmp (AppleArchValue, "i386") == 0;
DEBUG ((DEBUG_INFO, "OC: Arch %a overrides capabilities %u\n", AppleArchValue, Capabilities));
FreePool (AppleArchValue);
@ -84,22 +88,94 @@ OcKernelConfigureCapabilities (
}
//
// FIXME: The rest is not complete.
// Determine requested arch.
//
KernelArch = OC_BLOB_GET (&mOcConfiguration->Kernel.Scheme.KernelArch);
Automatic = KernelArch[0] == '\0' || AsciiStrCmp (KernelArch, "Auto") == 0;
if (AsciiStrCmp (KernelArch, "x86_64") == 0) {
RequestedArch = OC_KERN_CAPABILITY_K64_U64;
} else if (AsciiStrCmp (KernelArch, "i386") == 0) {
RequestedArch = OC_KERN_CAPABILITY_K32_U64;
} else if (AsciiStrCmp (KernelArch, "i386-user32") == 0) {
RequestedArch = OC_KERN_CAPABILITY_K32_U32;
} else {
RequestedArch = 0;
}
//
// Determine the current operating system.
//
SnowLeo64 = (Capabilities & (OC_KERN_CAPABILITY_K32_U32 | OC_KERN_CAPABILITY_K32_U64 | OC_KERN_CAPABILITY_K64_U64))
== (OC_KERN_CAPABILITY_K32_U32 | OC_KERN_CAPABILITY_K32_U64 | OC_KERN_CAPABILITY_K64_U64);
Lion64 = (Capabilities & (OC_KERN_CAPABILITY_K32_U32 | OC_KERN_CAPABILITY_K32_U64 | OC_KERN_CAPABILITY_K64_U64))
== (OC_KERN_CAPABILITY_K32_U64 | OC_KERN_CAPABILITY_K64_U64);
//
// In automatic mode, if we do not support SSSE3 and can downgrade to U32, do it.
//
if (Automatic && (Capabilities & OC_KERN_CAPABILITY_K32_U32) != 0
&& (Capabilities & (OC_KERN_CAPABILITY_K32_U64 | OC_KERN_CAPABILITY_K64_U64)) != 0
&& (mOcCpuInfo->Features & CPUID_FEATURE_SSSE3) == 0) {
if (RequestedArch == 0
&& (mOcCpuInfo->Features & CPUID_FEATURE_SSSE3) == 0
&& (Capabilities & OC_KERN_CAPABILITY_K32_U32) != 0
&& (Capabilities & (OC_KERN_CAPABILITY_K32_U64 | OC_KERN_CAPABILITY_K64_U64)) != 0) {
DEBUG ((DEBUG_INFO, "OC: Missing SSSE3 disables U64 capabilities %u\n", Capabilities));
Capabilities &= ~(OC_KERN_CAPABILITY_K32_U64 | OC_KERN_CAPABILITY_K64_U64);
}
//
// If we support K64 mode, check whether the board supports it.
//
if ((Capabilities & OC_KERN_CAPABILITY_K64_U64) != 0
&& !OcPlatformIs64BitSupported (SnowLeo64 ? KERNEL_VERSION_SNOW_LEOPARD_MIN : KERNEL_VERSION_LION_MIN)) {
Capabilities &= ~(OC_KERN_CAPABILITY_K64_U64);
}
//
// If we are not choosing the architecture automatically, try to use the requested one.
// Otherwise try best available.
//
if (RequestedArch != 0 && (Capabilities & RequestedArch) != 0) {
Capabilities = RequestedArch;
} else if ((Capabilities & OC_KERN_CAPABILITY_K64_U64) != 0) {
Capabilities = OC_KERN_CAPABILITY_K64_U64;
} else if ((Capabilities & OC_KERN_CAPABILITY_K32_U64) != 0) {
Capabilities = OC_KERN_CAPABILITY_K32_U64;
} else if ((Capabilities & OC_KERN_CAPABILITY_K32_U32) != 0) {
Capabilities = OC_KERN_CAPABILITY_K32_U32;
} else {
ASSERT (FALSE);
}
//
// Pass arch argument when we are:
// - SnowLeo64 and try to boot x86_64.
// - SnowLeo64 or Lion64 and try to boot i386.
//
ArgumentCount = 0;
if (Capabilities == OC_KERN_CAPABILITY_K64_U64 && SnowLeo64) {
NewArguments[ArgumentCount++] = "arch=x86_64";
} else if (Capabilities != OC_KERN_CAPABILITY_K64_U64 && (SnowLeo64 || Lion64)) {
NewArguments[ArgumentCount++] = "arch=i386";
}
//
// Pass legacy argument when we are booting i386.
//
if (Capabilities == OC_KERN_CAPABILITY_K32_U32
&& OcCheckArgumentFromEnv (LoadedImage, gRT->GetVariable, "-legacy", L_STR_LEN ("-legacy"), NULL)) {
NewArguments[ArgumentCount++] = "-legacy";
}
//
// Update argument list.
//
if (ArgumentCount > 0) {
OcAppendArgumentsToLoadedImage (
LoadedImage,
&NewArguments[0],
ArgumentCount,
FALSE
);
}
//
// If we do not support K64 for this target, force 32.
//