大數據

雲主機裝黑果實踐(8):利用clover,離我們的目標更接近了

本文關鍵字:clover 黑底白蘋果 無進度條,clover white screen,clover legcay bios video, clover force vesa mode, prevent Mojave switch video boot while booting,Resolution for General Protection Exception/ X64 Exception Type 0D Error

在文章7中我們講到了使用clover來代替chameleon,因為似乎進行到上一文chameleon已經遇到了瓶頸,1,其調試功能嚴重不足,遇到黑屏,我們只能大致猜想是CPU不兼容或顯卡亂配問題,不能從更細粒度上去確定問題所在,指導接下來實踐,2,變色龍只有一種模式,即bios,通過這種方式作fake efi來(填充滿足需要efi引導相關結構的OS數據塊)引導黑果,因此對於現實主機/雲主機功能上受制於從legcay pc的層面去解決問題,功能單一,(比如驅動)靠爬貼能得到解決問題的機會少。對於這二個問題,clover都有解決,clover可以從bios,csm,純uefi去解決問題,提供黑果功能,有更多的驅動亂配和具備更多解決驅動帶來的引導問題的方向,其調試功能一流,直接集成為工具。本文詳細描述在qemu標準雲主機型號(文章6,7所述命令行和libvirt版本i440fx虛擬機方案)上利用clover5070 iso引導運行黑果mojave。

前文簡單描述了利用boot7做cdboot的思路,這裡詳述,我們利用變色龍源碼來生成clover的cdboot7,注意到變色龍的srccdboot下有$(SYMROOT)/cdboot,我們複製這一段為:

$(SYMROOT)/cdboot7:
    @echo "    [NASM] cdboot.s"    
    @$(NASM) cdboot.s -o $(SYMROOT)/cdboot7
    @dd if=$(SYMROOT)/boot7 of=$(SYMROOT)/cdboot7 conv=sync bs=2k seek=1 &> /dev/null

    @# Update cdboot with boot file size info
    @stat -f%z $(SYMROOT)/boot7 \
        | perl -ane "print pack('V',@F[0]);" \
        | dd of=$(SYMROOT)/cdboot7 bs=1 count=4 seek=2044 conv=notrunc &> /dev/null

all embedtheme optionrom: $(DIRS_NEEDED) $(SYMROOT)/cdboot後面加一條$(SYMROOT)/cdboot7,make dist前把clover的boot7放進去$(SYMROOT),cd到src,cdboot下,sudo make all,就會發現symroot下有cdboot7了,使用這個cdboot,就加載了biosblk driver,在virtio blk下可以看到fat32中的EFI,cdboot6不行。

然後準備5070clover iso的config.plist,kexts和drivers下不動任何東西(5070 iso,kexts/other下有一個fakesmc,drivers/bios下有apfs,audiodxe,fsinject,ps2mousedxe,smchelper,usbmousedxe,xhcidxe):

熟悉clover的調試信息與界面,虛擬機調試進系統

Clover的原則是儘量少添加參數,不懂的或不能確定其意義的不要添加(與chameleon一樣他們被集成設計成儘量不必添加任何非必要參數就能啟動一份常見系統,除非真的必要),我們一步一步來,寫出這個config.plist,原則是保留儘可能多的debug。而且與前文寫的變色龍chameleon.boot.plist儘量一一對應,這樣好理解,最終我們寫成這樣:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>

    <key>RtVariables</key>
    <dict>
        <key>BooterConfig</key>
        <string>0x28</string>
        <key>CsrActiveConfig</key>
        <string>0x67</string>
    </dict>

    <key>GUI</key>
    <dict>
        <key>ScreenResolution</key>
        <string>1024x768</string>
        <key>TextOnly</key>
        <true/>
        <key>ConsoleMode</key>
        <string>Min</string>
    </dict>

    <key>Boot</key>
        <dict>
                <key>Arguments</key>
                <string>Kernel="kernel" "Graphics Mode"="1024x768" "Boot Graphics"=No "Text Mode"=Yes -v debug=0x100</string>
        <key>DefaultVolume</key>
        <string>OSXKVM</string>
                <key>Timeout</key>
                <integer>10</integer>

              <key>Debug</key>
                <true/>
        <key>Log</key>
        <true/>
        </dict>

    <key>SystemParameters</key>
    <dict>
        <key>InjectKexts</key>
        <string>Detect</string>
        <key>NoCaches</key>
        <string>No</string>
    </dict>

    <key>KernelAndKextPatches</key>
    <dict>
        <key>KernelToPatch</key>
        <array>
            <dict>
            </dict>
        <array/>

        <key>Debug</key>
        <true/>
    </dict>

    <key>SMBIOS</key>
    <dict>
        <key>BiosReleaseDate</key>
        <string>12/22/2016</string>
        <key>BiosVendor</key>
        <string>Apple Inc.</string>
        <key>BiosVersion</key>
        <string>IM142.88Z.0118.B17.1612221936</string>
        <key>Board-ID</key>
        <string>Mac-27ADBB7B4CEE8E61</string>
        <key>Family</key>
        <string>iMac</string>
        <key>Manufacter</key>
        <string>Apple Inc.</string>
        <key>Manufacturer</key>
        <string>Apple Inc.</string>
        <key>ProductName</key>
        <string>iMac14,2</string>
        <key>SerialNumber</key>
        <string>C02KK5W9F8J2</string>
        <key>Version</key>
        <string>1.0</string>

        <key>Mobile</key>
        <false/>
    </dict>

</dict>
</plist>

解釋一下:

開頭,RtVariables是全局的開SIP,任何黑果引導的先決條件,為了好理解,所以把它寫最前面,GUI和BOOT是菜單選單界面配置(當然,這裡也有本質上的引導參數的餵給邏輯),引導後出現在你面前的就是這個界面,所以寫在第二前面,GUI段面向clover作preboot用,BOOT段面向darwin接手後booting用,注意到我們加了儘可能多的debug支持的情況下,還儘量使用的是文字界面,和preboot/darwinboot一致的分辨率,這是為什麼呢?

因為chamleon或clover引導時,要麼用圖形要麼用文字,chameleon有純文字界面而clover只有圖形模式(文字界面是圖形模擬的textonly,consolemode都是圖形),mojave在啟動時會有二個階段不斷換分辨率,這所有的過程,都涉及到分辨率帶來的顯卡驅動對啟動過程的影響討論,有很多花屏,黑屏,包括前面我們說到的雲機上黑屏,都可能是顯卡驅動導致的,第一要素就是分辨率(vesa顯驅用vesa mode):

vga std顯卡vesa下mode 800x600時,clover preboot沒有進度條,這就是上面GUI段手動設為1024x768以上的原因,猜可能就是800x600與匹配的vesa分辨率任何一種都不符,,邏輯上就不讓過去了(要進入dmsg工具查看log中起作用的vesa mode才能發現原因可是進不去就沒法使用dmsg),為避免顯卡問題在preboot時就halt掉我們的調試過程。這裡應該儘量使用保守的模式(一般clover和變色龍夠智能會幫你選好一般不用幹預),進去mojave時,受到virtualgraphic.kext的支持,分辨率有更多選擇,系統也會自己換分辨率。

所以原則上可以儘量手動保持preboot和darwinboot stage1,stage2二過程,這三個過程儘量使用一致的分辨率(如果有辦法的話,比如修改源碼也行,chameleon->boot2->graphics.c static int setVESAGraphicsMode中默認將vesa設為280,我將它改為267 https://en.wikipedia.org/wiki/VESA_BIOS_Extensions#Modes_defined_by_VESA,注意,vesa3支持刷新率定義但不要用,以免造成意外),這樣的預先處理可以免去很多問題。所以BOOT段OS顯驅發揮作用時再次餵給prelinkedkernel同樣的顯示模式。注意到我還餵了儘量少用graphics mode和使用text mode的參數都是為了規避可能的顯卡問題(餵給kernel as flags的照樣可以設置在chameleon的boot.plist中)。

此時,直到BOOT的所有配置只能完成vga std下的preboot,接下來的 SystemParameters段有大講究,也是顯示相關的,本來啟動darwin後的stage1很順利,開始切換分辨率到stage2時,花屏過不去了,後來加了雖然也會花屏,但一會就過去了,實際起作用的是SystemParameters段,我在裡面加了injecexts和nocache,但實際起作用的是SystemParameters空體這句,不是裡面的任何東西。而且好像它的位置也要放在下面一個平等位。比如它放在SMBIOS下面一個位就沒用。而且這個空體,對vga cirrus下clover preboot也有用,不加這個空段或放到不適當位置時,vga cirrus在clover preboot時顯示End random seed ++++ 白屏,而且一直沒進展,加空段放到BOOT對等位下時,也是白屏,但一會就進入到stage1,stage2。直到這裡為止,已完成clover的引導進入到了darwin的verbose,雖然花屏或白屏,但最終進入系統,這說明這二種顯卡的vesa都生效了,cirrus進入後是800600,vga進入後是19201440,只是進入前都有瑕疵一個開始花屏,一個後面白屏(對比系統報告發現不同,clover下bios變成imac10.1,chameleon保持了按原樣14.2,clover下smbios有好多是可以自動計算的,寫法上可以忽略)

注意到boot段中的Log true似乎並沒有生效。不如直接把dmsg.efi弄出來為tools直觀,好像LogEveryBoot有用。kernel聽說如果不加入此參數"Kernel=...",將默認加載系統緩存(kernelcache)啟動,作用等同於啟動菜單的”without kernelcache“選項。但似乎實測證明也不正確。SystemParameters那二段(clover下沒有UseKernelCache=yes,這二段組合使用模擬了類似的效果,但似乎SystemParameters二條怎麼調clover都是用prelinkedkernel,換成kernel cache這個kernel flags倒是可以https://www.insanelymac.com/forum/topic/99891--/不過沒必要用),prelinkedkernel是自動-f生成或手動使用 kextcache 將 kernel 和 kexts from /System/Library/Caches/com.apple.kext.caches/Startup/kernelcache共同 link 成 PrelinkedKernel,由System/Library/CoreServices/boot.efi啟動,boot.efi 是平臺特定的 EFI Driver(application), 由cloverx64.efi或真實系統的EFI 固件加載, 主要作用是加載 Kernel, 並將控制權移交給 KernelEntry.boot段中的kernel flags都是餵給/Library/Preferences/SystemConfiguration/com.apple.Boot.plist再給kernel或prelinkedkernel的。但是不要直接修改它。會造成文件系統損壞,修改這個文件很容易破壞鏡像。可用clover在內存中patching。

上述啟動過程中的花屏白屏,可能需要專門的驅動和patch過程來解決(vs clover,chameleon在這方面沒有優勢,這就是我們選clover的理由,clover可有csmvideodxe,qemuvideodxe,不過雲機不能用這些,因為csmvideo需要開csm,qemuvidedxe需要開uefi,clover在mbr機上並不可以純uefi,因此也不能使用uefi drivers,比如CsmVideoDxe-64.efi:Clover圖形界面的圖像驅動,可以有更多的分辨率選擇。(僅限於啟動界面)。他基於UEFI BIOS的CSM模塊,因此需要CSM可用。UEFI GOP VBIOS只適用於UEFI引導的系統的,即UEFI引導的Clover和Ozmosis,用傳統BIOS引導系統的同學請繞行)。不過不對引導造成問題,我們就不管了。

搜索花屏白屏,在網上可以爬到很多貼,單一個黑屏就這麼多可能和可能的解決方案。也是初學者學習黑果第一大攔路虎,這裡有趣也最容易讓人棄坑,黑蘋果文化博大精深,到底都是方案,可是不一定適用你那套。

我們可以在GUI段通過custom和scan將dmsg.efi工具形成菜單。查看debug log就更快捷了。跟Uefishell一樣,Uefishell,就是把啟動腳本化,而且是在線腳本語言化,跟grub一樣,接上shell,都可以。但可運行一些.efi程序,load一些驅動,cp,ls一些文件,注意與cloverx64分開,它不可用於引導OSX,cloverx64才是osx lister和OS X booter efi(boot6,7 is the booter itself),osxclover提供了二個efi booter,其實都是同一個文件,就是bootx64和cloverx64,如果充分利用CLOVER,甚至可以打造裝機上的“統一實機雲主機firmware”和統一BOOT環境,讓bootx64是總boot。也許我們以後要把各種OS(包括boot6,7)做成boot+pbr,做成各種os的loader文件,讓所有fat32 boot下的所有boot都呈一個樣歸進EFI.

雲主機上的clover通用保護錯誤和黑屏問題

如果說實機上的白屏,花屏不影響最終啟動,那麼雲主機上的黑屏就是一個實實在在的先決問題了。這之前,還有一個錯誤,就是cloverx64在雲主機上執行會報錯General Protection Exception/ X64 Exception Type 0D Error。這是clover層面的導致出錯。但也有可能是顯卡導致的。The reason is the incompatibility between UEFI graphic drivers & OS(or boot loader).cloverx64只是相當於Os lister+它可以引導osx,Cloverx64一開始在preboot就用了顯卡驅動,不像變色龍在preboot用的是text console。由於大量使用vesa,所以它訪問graphics driver時會發生type 64 exception通用保護錯誤。而變色龍往往在完成preboot啟動後,darwinboot接手涉及到大量vesa時才會黑屏,既然從clover中得知,黑屏可能不是cpu而是從qemu模擬的vga(vgabios inside seabios)到os顯卡驅動導致的,本地就不黑,雲主機就黑,clover也是切換到這種圖形模式就無法輸出了,那麼這樣這種某種cpu保護錯誤還與顯卡問題同源。

那麼,最終這是CPU兼容問題還是第一節顯卡問題在雲主機特殊環境上的新問題?如果我們在chameleon有限的debug下看不到,那麼在clover下豐富的debug支持下能不能看到問題的蛛絲馬跡呢?

不過,可以肯定的是,clover下解決問題嘗試的方向會有很多,在源碼定製上,它基於omvf實現,有很多開源驅動可以定製,擺弄,眾多黑果開發者維護了很多驅動成果。可尋求解決問題的嘗試路徑會更多。

讓我們試目以待。


(此處不設回覆,掃碼到微信參與留言,或直接點擊到原文)

qrcode.png

Leave a Reply

Your email address will not be published. Required fields are marked *