ARM64 AArch64 Linux啓動

AArch64 Linux啓動算法

AArch64異常模型由許多異常級別(EL0-EL3)組成,EL0和EL1具備安全和非安全兩種模式對應。
EL2是hypervisor,僅存在於非安全模式。 EL3是最高優先級,僅在安全模式下存在。編程

出於本文檔的目的,咱們將使用術語「引導加載程序」來簡單地定義在控制傳遞到Linux內核以前
在CPU上執行的全部軟件。 這可能包括安全監視器和管理程序代碼,或者它可能只是一些準備
最小引導環境的指令。緩存

本質上,引導加載程序應該提供(至少)如下功能:
1.設置並初始化RAM
2.設置設備樹
3.解壓縮內核映像
4.調用內核映像安全

1.設置和初始化內存(必須)
引導加載程序將查找並初始化內核靜態數據所要用到的全部RAM。 
它將全部數據以機器執行順序放到內存裏。(它可使用內部算法自動定位和調整全部RAM,
或者它可使用機器中RAM的知識,或者引導加載程序設計者認爲合適的任何其餘方法。)網絡

2.設置設備樹(必須)
設備樹blob(dtb)必須放在8字節對齊地址上,且大小不得超過2MB。 
因爲dtb將使用最大2MB的塊進行可緩存映射,所以不得將其放置在必須與
任何特定屬性映射的任何2M區域內。架構

注意:v4.2以前的版本還要求將DTB放在512 MB區域內,從內核Image下面的text_offset字節開始。app

3.解壓內核(可選)
AArch64內核當前不提供解壓縮器,所以若是使用壓縮的Image目標(例如Image.gz),
則須要由引導加載程序執行解壓縮(gzip等)。 對於未實現此要求的引導加載程序,
可使用未壓縮的Image目標。es5

4.引導內核(必須)
一個壓縮的內核鏡像包含了一個64字節的頭部信息:
  u32 code0;            /* Executable code */
  u32 code1;            /* Executable code */
  u64 text_offset;        /* Image load offset, little endian */
  u64 image_size;        /* Effective Image size, little endian */有效鏡像大小
  u64 flags;            /* kernel flags, little endian */
  u64 res2    = 0;        /* reserved */
  u64 res3    = 0;        /* reserved */
  u64 res4    = 0;        /* reserved */
  u32 magic    = 0x644d5241;    /* Magic number, little endian, "ARM\x64" */
  u32 res5;                /* reserved (used for PE COFF offset) */
  
說明:
- 在V3.17版本以後,除非另有說明,不然都是小端模式設計

- code0和code1是負責分支到文本????調試

- 在經過EFI啓動時,最初會跳過code0 / code1。res5是PE頭的偏移量,
PE頭具備EFI入口點(efi_stub_entry)。當stub完成其工做時,它會跳轉到code0以恢復正常啓動過程。

- 在v3.17以前,未指定text_offset的字節順序。 在這些狀況下,image_size爲零,
而且text_offset在內核的字節順序中爲0x80000。 在image_size爲非零的狀況下,
image_size是little-endian,必須遵照。 在image_size爲零的狀況下,
能夠假設text_offset爲0x80000。

- The flags field (introduced in v3.17) is a little-endian 64-bit field
  composed as follows:
  Bit 0:    Kernel endianness.  1 if BE, 0 if LE.
  Bit 1-2:    Kernel Page size.
            0 - Unspecified.
            1 - 4K
            2 - 16K
            3 - 64K
  Bit 3:    Kernel physical placement
            0 - 2MB aligned base should be as close as possible
                to the base of DRAM, since memory below it is not
                accessible via the linear mapping
            1 - 2MB aligned base may be anywhere in physical
                memory
  Bits 4-63:    Reserved.

- 當image_size爲零時,引導加載程序應該在內核映像結束後當即嘗試保留儘量多的
內存供內核使用。 所需的空間量將根據所選功能而有所不一樣,而且其實是未綁定的。

鏡像必須放在 2MB對齊的基地址偏移 text_offset地址中,並會在那裏調用執行。   
2 MB對齊的基址和鏡像的開頭之間的區域對內核沒有特殊意義,能夠用於其餘目的。 
至少從映像開頭的image_size字節必須是空閒的,以供內核使用。
注意:v4.6以前的版本沒法使用低於Image物理偏移量的內存,所以建議將Image放置在
儘量靠近系統RAM啓動位置的位置。

若是initrd / initramfs在引導時傳遞給內核,它必須徹底駐留在最大32GB的1GB對齊
物理內存窗口中,徹底覆蓋內核Image。

向內核描述的任何內存(即便是在image開頭之下)也沒有被標記爲從內核保留
(例如,在設備樹中具備memreserve區域)將被認爲是內核可用的。

在跳轉到內核執行以前,必須知足如下條件:
1.關掉全部支持DMA的設備,以便內存不會被網絡數據包或磁盤數據破壞。 
這將爲您節省大量的調試時間。

2.主CPU的通用寄存器設置爲:
  x0 = physical address of device tree blob (dtb) in system RAM.
  x1 = 0 (reserved for future use)
  x2 = 0 (reserved for future use)
  x3 = 0 (reserved for future use)

3. CPU模式
在PSTATE.DAIF中屏蔽全部中斷(Debug, SError, IRQ and FIQ).
CPU必須位於EL2(推薦以便訪問虛擬化擴展)或非安全EL1。

4. cache、mmu
mmu必須關閉
icache必須關閉
必須將與加載的內核映像相對應的地址範圍清除到PoC。 
在存在啓用高速緩存的系統高速緩存或其餘連貫主控器的狀況下,
這一般須要經過VA而不是set/way操做來維護高速緩存。
必須配置而且能夠啓用經過VA操做遵循架構緩存維護的系統緩存。
必須配置和禁用不遵循VA操做(不推薦)的架構緩存維護的系統緩存。

5.系統定時器
必須設置CNTFRQ定時器頻率,而且CNTVOFF必須在全部CPU上編程爲一致的值。 
若是在EL1進入內核,CNTHCTL_EL2必須設置爲有效,EL1PCTEN(位0)。

6.Coherency
在進入內核時,內核引導的全部CPU必須是同一個一致性域的一部分。 
這可能須要IMPLEMENTATION DEFINED初始化,以便可以在每一個CPU上接收維護操做。

7.系統寄存器
在進入內核映像的異常級別的全部可寫架構系統寄存器必須由更高異常級別的軟件初始化,
以防止在UNKNOWN狀態下執行。

對於在v3模式下使用GICv3中斷控制器的系統:
    - 若是存在EL3:
     ICC_SRE_EL3.Enable(第3位)必須初始化爲0b1。
     必須將ICC_SRE_EL3.SRE(位0)初始化爲0b1。
    - 若是在EL1進入內核:
     必須將ICC.SRE_EL2.Enable(第3位)初始化爲0b1
     必須將ICC_SRE_EL2.SRE(位0)初始化爲0b1。
    -  DT或ACPI表必須描述GICv3中斷控制器。

對於在兼容性(v2)模式下使用GICv3中斷控制器的系統:
    - 若是存在EL3:
     必須將ICC_SRE_EL3.SRE(位0)初始化爲0b0。
    - 若是在EL1輸入內核:
     必須將ICC_SRE_EL2.SRE(位0)初始化爲0b0。
    -  DT或ACPI表必須描述GICv2中斷控制器。

上述CPU模式,高速緩存,MMU,架構定時器,一致性和系統寄存器的要求適用於全部CPU。
全部CPU必須在相同的異常級別中進入內核。

指望引導加載程序如下列方式進入每一個CPU的內核:

 - 主CPU必須直接跳轉到內核映像的第一條指令。此CPU傳遞的設備樹blob必須包含每一個cpu節點
 的「enable-method」屬性。支持的啓用方法以下所述。

  預計引導加載程序將生成這些設備樹屬性,並在內核進入以前將它們插入到blob中。

 - 具備「spin-table」enable-method的CPU必須在其cpu節點中具備「cpu-release addr」屬性。
 此屬性標識天然對齊的64位零初始化內存位置。

  這些CPU應該在內核的保留區域內自旋(經過設備樹中的/ memreserve / region與內核通訊)
輪詢它們的cpu-release-addr位置,該位置必須包含在保留區域中。能夠插入wfe指令以減小
繁忙循環的開銷,而且將由主CPU發出sev。當讀取cpu-release-addr指向的位置返回非零值時,
CPU必須跳轉到該值。該值將寫爲單個64位little-endian值,所以CPU必須在讀取以前將讀取值
轉換爲其本機字節序。

 - 具備「psci」啓用方法的CPU應該保留在內核以外(即,在內存節點中向內核描述的內存區域以外,  或者在內存中由/ memreserve / region描述的內存的保留區域以外)設備樹)。內核將按照ARM文檔  編號ARM DEN 0022A(「ARM處理器上的電源狀態協調接口系統軟件」)中的描述發出CPU_ON調用,  以將CPU帶入內核。    設備樹須要包含psci節點,具體描述見Documentation/devicetree/bindings/arm/psci.txt.   -輔助寄存器設置:   x0 = 0 (reserved for future use)   x1 = 0 (reserved for future use)   x2 = 0 (reserved for future use)   x3 = 0 (reserved for future use)

相關文章
相關標籤/搜索