導入macOSが起動するときに、早い段階で禁止マークが出て停止してしまうことがあります。多くの場合、カーネルを読込むメモリが確保できないエラーです。これをslideオプションで解決します。xxxxxxxx”というようなメッセージが出ていることがあります。下のメッセージは、「0xe590000番地から0x11c01ページのメモリー空間を確保しようとしたけど失敗しました」という意味です。1ページは0x1000バイト、つまり4096バイトのことです。10進数を使ってわかりやすく書くと、「240メガバイトあたりの番地から298メガバイトくらいのメモリー空間を確保しようとしたけど失敗しました」といった感じのエラーです。100番台になってからのMSIマザーボードでよく発生するエラーです。このエラーの特徴は、「何回か起動を試みるとそのうち成功することがある」とか、「大抵は起動するけどたまにこのエラーで起動しない」など、再現性が低いことです。簡単な対策法この問題を直してくれるのが以下のkextです。AptioMemoryFix.efiOsxAptioFix3Drv.efiOsxAptioFixDrv.efiOsxAptioFix2Drv-free2000.efi以下の記事で説明したように、このリストの順番がお勧め順らしいので、上から試して、問題なく起動するkextを使います。一度に2個以上のkextを入れてしまうと、どちらが動くのか定まらないので避けるべきとのことです。macOSCloverで使うEFIドライバhttps://bootmacos.com/entry/2018/07/15/001348(古い情報です。最新情報はこちらをご覧ください。)---------------最近のClover*1でEFIドライバ類が色々と変更されている様です。気づいたところをメモしておきます。64bit移行のためと思われる名称変更EFIドライバフォルダ名だいぶまえにdrivers32というフォルダ...リストの上の方ほど新しく開発されたkextで副作用が少ないらしいです。強力なのが最後のOsxAptioFix2Drv-free2000.efiです。その名前の通りメモリーを強制的に開放させます。どのマザーボードでもほぼ機能する最強のkextです。強力すぎるので、大丈夫なのかという意見はあります。Redditには、OsxAptioFix2Drv-free2000.efiの利用は避けで、slideオプションで対応した方が良いという意見もありました。いえ、私もMSIのマザーボードでOsxAptioFix2Drv-free2000.efiを使い続けていますが、特に問題はありません。slideを使った正しい解決策を試してみます。(カーネル番地乱数化)そもそもどういうことが原因で、カーネル読み込みに失敗するのかを調べました。macOSが起動する際に、カーネルが0x100000以降の番地(10進数で1,048,576、1MB程度です)のメモリーに読み込まれます。実際に何番地に読み込まれるかは定まってなく、ランダムです。上記のエラーの例では、カーネル(またはその一部)を0xe590000番地から始まるメモリー空間に読み込もうとして失敗しています。読み込み番地はセキュリティのためにわざとランダムにしているそうです。カーネルが読み込まれる番地が常に一定だと、その番地を狙って悪さを試みるマルウェアが可能です。特定の番地からプログラムを動かしたり、特定の番地の内容を書き換えることでOS動作を操れてしまうからです。いう操作をされないために、起動毎に違う番地にカーネルを読み込んでいるそうです。Shellで救うhttps://bootmacos.com/entry/2019/04/18/200605UEFIマザーボードには各種設定やファイル表示・変更ができるコマンドラインシェル機能があります。これを使用すればOSが起動する前にファイル変更・移動・削除できるので、誤設定で起動しなくなったマシンを救えます。Shellは、UEFI環境で...マザーボードのメモリーマップを見ることができます。これに使うコマンドがmemmapです。-bとすると画面いっぱいになったところで一旦停止してくれます。タイプすると、その場所にメモリーマップをテキストファイルで保存します。AptioMemoryFix.efiなどの穏当なドライバで問題なく起動するマザーボードもたくさんあります。そのメモリーマップを見てみましょう。以下は、ASUSのZ390マザーボードの例です。(memmapの出力にはAttributesという項目もありますが、長くなるので省略してます。0000000000001FA5ここを見ると、カーネルが読み込まれる可能性のある0x100000番地を先頭に、0x5315CFFF番地までが空き地になっていることがわかります。ページ数にして0x5305D番地の空き地です。1.4GBくらい空いているようです。最初に示したエラーメッセージによると、カーネル読み込みに必要なメモリー量は300MB程度らしいのです。これだけ空いていれば、どの番地に読み込んでも順当にメモリー確保できます。おかげで、このマザーボードではメモリーアロケーションのエラーが出たことはありません。ちなみいこの空き領域の容量は、起動するたびに多少変化することがあるようです。それでも変動は高々100MB程度です。iGPU割り当てメモリー量を変更してもほとんど変化しません。ASUSのメモリーマップはmacOSに適しているようです。失敗するマザーボード一方、最近のMSIマザーボードでAptioMemoryFix.efiなどを使うと、かなりの確率で起動しません。MSIはZ170チップセットモデルからOsxAptioFix2Drv-free2000.efiが手放せなくなってしまいました。どんなメモリーマップになっているのか見てみます。以下はB350Mマザーボードのメモリーマップです。最近のMSIマザーボードでは、どれもこんな感じのメモリーマップです。0000000000000040ASUSとMSIのメモリーマップを比較してみましょう。0x100000番地から先のページ数で示しています。ASUSは0x100000番地から0x53000ページ以上が空き地です。MSIは0x100000番地から0xFF00ページが空き地で、その後0xBページ(10進数で11ページ)が使われていて(小さすぎて図では見えません)、その後、0x67510ページが空いています。MSIマザーボードでは、0x100000番地からは、0xFF00ページ、つまり267MB程度のメモリーしか空いていません。その後に、0x10000000番地から、たったの11ページ、バイト数にして45MBだけ、誰かが使っています。BS_Codeというのがそれです。その後、0x1000B000番地から0x7751AFFF番地まで大量に空き地があります。そのため、0x100000番地から300MB程度を確保しようとすると、使用中の45MBが邪魔をして確保できません。これでエラーが出ます。なんでこんな邪魔なところに使用中のメモリーがあるんだ、という気持ちになります。何度も何度も起動を試みると、たまに起動することもあります。エラーになるかどうかは、上で説明したKASLRが使用する乱数次第です。0x1000B000より大きい番地からメモリー確保しようとした場合は、エラーは出ず、問題なく起動します。書くと、メモリーを確保する開始番地を指定できます。その規則は次のようになっているそうです。200000になりますとなることが知られてます。最近のCPUだけを考えれば、slide値を0x200000倍して0x100000を足すだけなので簡単です。以下ではこの計算が適用できるCPUを前提に説明を進めます。空き地番地をSlideで指定する上記のMSIマザーボードの場合、0x1000B000から、使われていないメモリーが大量にあるので、この番地以降を割り当てたいです。(もしくはそれ以上の値)とすれば良さそうです。この計算は切り捨てになっているので、実は127ではスライド量が足りません。0xFF00000からのメモリー確保がされるので、0x1000b000に引っかかってしまいます。0x10100000になるので、ようやく0x1000B000より大きな番地からの割り当てになります。Argumentに、以下のようにslide=128パラメタを追加すれば、このようなメモリー空き地が不連続な問題を回避できます。(他に必要なパラメータが続く)</string>KASLRを無効にするブートオプションでslide値を指定しても、KASLRが効いているとslide値としては相変わらず乱数(0x00から0xFFまでの乱数)が割り当てられます。ブートオプションのslide値は無視されるようです。slide値を指定すると同時にKASLRを無効にする必要があります。KASLRを無効にするためには、SIPでCSR_ALLOW_UNRESTRICTED_NVRAMフラグを立てる必要があります。これはNVRAMの変更制限を解除するフラグですが、同時にKASLRも解除されるようです。1を6ビットだけ高位にシフトするという意味で、結果は0x40です。CsrActiveConfigに0x40を書いておきます。</dict>7ビット目が1ならば他の数字でも良いです。CsrActiveConfigとして、元々0x03という設定をされていたのであれば、0x43にすれば良いです。0x64という設定をしていたなら、これはすでに7ビット目が立っていますから、そのままで良いです。セキュリティをできるだけ確保するという観点からは、0x40が良いと思います。これでブートオプションで指定したslide値が使用されるようになります。このようなconfig.plist設定で、MSIのマザーボードでもOsxAptioFix2Drv-free2000.efiを使わずに済むようになりました。AptioMemoryFix.efiで動きます。CSR_ALLOW_UNRESTRICTED_NVRAMを許可すると、NVRAMの書き換えでSIPのすべての設定が変更可能になるので、セキュリティは脆弱になります。いえ、Hackintoshなのでconfig.plist書き換えて再起動すればSIPはどのようにも設定できるので、気にすることではないかもしれないです。slideパラメータでカーネル読み込みアドレスが固定されるのでKASLRの恩恵もなくなり、それも弱点になります。これに対しては、時々config.plistのslide値を微妙に書き換えて、人力KASLRしても良いかもしれません。まとめ:マザボ別対処法KASLRが機能していると、Slide値は0から0xFFまで乱数で設定されます。0番地から530MB程度先になります。ここから、300MB程度の領域にカーネルが展開されるわけです。KASLRがどのようなslide値を指定しても、300MBのカーネルが読み込まれるためには、0x100000番地から900MB程度の空き地が必要ということになります。そこで0x100000番地からの空き地がどれくらいあるかによって次の対処法が考えられます。空き地容量の数値は、確保されるメモリーが300MB程度と仮定した場合の目安です。環境によってはもっと必要とされるかもしれません。空き地が900MB以上あるマザボ何もしなくて良いです。ASUSのマザーボードでは0x100000番地から1.4GBくらいの空き地がありました。KASLRがどのように先頭番地を割り当てても平気です。SIPを弱めてKASLRを無効にする必要もありません。macOSに最適なメモリーマップを持つマザーボードと言えます。空き地が300MB以下のマザボslideで空き地番地を指定します。MSIのマザーボードは、0x100000番地からの空き地が267MB程度しかありませんでした。次にある空き地が十分大きくてKASLRの範囲内にあるので、たまに起動しますが、大抵は起動に失敗します。このようなマザボでは、上記で説明したように、KASLRの範囲内にある300MB以上の空き地をslideで指定します。空き地が300MB以上900MB未満のマザボslide=0にします。GAMINGでは、0x100000番地からの空き地は480MBとのことです。この場合は、小さなslide値だと起動しますが(80以下程度)、KASLRで大きなslide値が指定されると失敗します。そこで、slide=0を指定して0x100000から必ず展開するように指定します。興味深く、読みました。MACがMACであるゆえん(独自のロジックボードとBIOSを持つ)の問題なんですね。000000000000000Fとなっており、カーネルロード部分は断片化してないのですね。気になって沿革について調べてみました。BSDが2017年にロードのランダマイズを始めてから、LinuxやWindowsでも同様になっていたのですね。https://news.mynavi.jp/article/20170707-a082/https://qiita.com/satoru_takeuchi/items/5c80c4e255e21c5b4b8aQiitaでは、「クラッカーが攻撃に使うコードやデータのアドレスを割り出すのが困難になります」とありますが、注釈に、「後述のKASLRも含め、困難ではありますが、不可能ではありません。クラッカーと防御側の攻防はいつでもいたちごっこなのです」とあるように、コード自体が動くということは、いずれにしてもカーネルの機能を呼び出してしまうので、終わりはないのですね。^^;大変面白かったです。起動時に何の問題もないマザーボードとエラーを出すマザーボードはメモリマップが違っていたのですね。手持ちのマザーボードのメモリマップをチェックしてみました。000000000000000FASUSマザーではエラーが発生しなかったのですが、0x100000から0xA84D5ページですから2.6GBくらい空いているのですね。これなら何も対策しなくて大丈夫でしょう。対してGYGABYTEマザーでは0x100000から0x1E031ページですから480MBくらいしか空いていません。ここに300MBを確保するためにslide=0が必要だったのだとよくわかりました。