ARM64 的多核啟動流程分析
工作中遇到的多核 ARM CPU 越來越多,總結分享一些多核啟動的知識,希望能幫助更多小伙伴。
在 ARM64 架構下如果想要啟動多核,有 spin-table 和 psci 兩種方式,下面針對這兩種啟動流程進行分析。
代碼版本
boot-wrapper-aarch64 version : 28932c41e14d730b8b9a7310071384178611fb32
linux v5.14
多核 CPU 的啟動方式
嵌入式系統(tǒng)的啟動的基本流程是先運行 ?,然后由 ?引導啟動 kernel,這里無論啟動的是 rt-thread 或者是 linux 原理都是一樣的。bootloaderbootloader
上電后所有的 ?都會從 ?里面開始執(zhí)行代碼,為了防止并發(fā)造成的一些問題,需要將除了 ?以外的 ?攔截下來,這樣才能保證啟動的順序是可控的。CPUbootromprimary cpucpu
【文章福利】小編推薦自己的Linux內核技術交流群:【891587639】整理了一些個人覺得比較好的學習書籍、視頻資料共享在群文件里面,有需要的可以自行添加哦!?。。ê曨l教程、電子書、實戰(zhàn)項目及代碼)? ? ??


spin-table 啟動方法
在啟動的過程中, 中有一道柵欄,它攔住了除了 ?外的其他 。 直接往下運行,進行設備初始化以及運行 。其他 ?則在柵欄外進入睡眠狀態(tài)。bootloadercpu0cpucpu0Kernelcpu0
cpu0 在初始化 ?的時候,會在 ?里面填入一個地址并喚醒其他 。這時睡眠的 ?接受到信號,醒來的時候會先檢查 ?這個地址里面的數(shù)據(jù)是不是有效。如果該地址是有效的(非 0 ),意味著自己需要真正開始啟動了,接下來他會跳轉到。smpcpu-release-addrcpucpucpu-release-addr
下面我們看看 ?里面的實現(xiàn),在 ?中有如下描述:arm64arch/arm64/boot/dts/xxx.dts
在 ?中處理了向其他 cpu 發(fā)送信號的方法:arch/arm64/kernel/smp_spin_table.c
1、先是獲取 release_addr 的虛擬地址
2、向該地址寫入從 cpu 的入口地址
3、通過 sev() 指令喚醒其他 cpu
Bootloader 部分以 ?中的代碼做示例,非主 CPU 會輪詢檢查 mbox(其地址等同cpu-release-addr)中的值,當其值為 0 的時候繼續(xù)睡眠,否則就跳轉到內核執(zhí)行,代碼如下所示:boot-wrapper-aarch64
PSCI 啟動方法
另外一種 enable-method 就是 PSCI,依舊先從 kernel 開始分析。先看 ?文件,里面 ?節(jié)點選擇了PSCI 的方法:arch/arm64/boot/dts/mediatek/mt8173.dtsicpu
并且有一個 PSCI 的節(jié)點:
在 PSCI 中的節(jié)點詳細說明請參考文檔:kernel/Documentation/devicetree/bindings/arm/psci.txt。在此僅說一下方法 字段。該字段有兩個可選值:smc 和 hvc。表示調用 PSCI 功能使用什么指令。smc、hvc、svc 這些指令都是由低運行級別向更高級別請求服務的指令。
和系統(tǒng)調用一樣。調用了該指令,cpu 會進入異常切入更高的權限。異常處理程序根據(jù)下面?zhèn)魃蟻淼膮?shù)決定給予什么服務,smc 陷入 EL3,hvc 陷入 EL2,svc 陷入EL1。在 ARMv8 里面,EL3 總是是安全 狀態(tài),EL2 是虛擬機管態(tài),EL1 是普通的系統(tǒng)態(tài)。
接下來可以看看 ?里面的代碼,psci_ops.cpu_on 最終調用 smc call:arch/arm64/kernel/psci.c
Bootloader 以 ?作分析,看 psci.c 里的 psci_call 實現(xiàn)函數(shù),通過 fid 與 PSCI_CPU_OFF 和 PSCI_CPU_ON 相比,找出需要執(zhí)行的動作:boot-wrapper-aarch64
當然 ?里也需要同樣的定義:
總結
目前比較主流的多核啟動方式是 PSCI,一般正式的產(chǎn)品都有 ATF,通過 PSCI 可以實現(xiàn) CPU 的開啟關閉以及掛起等操作。在實際的移植工作過程中,如果有帶有 ATF 的 bootloader 那多核移植就相對容易很多,如果沒有的話,也可以采用 spin_table 的方式來啟動多核。
