Cortex-M23 Cortex-M33 TrustZone ARMv8-M

ARMv8-M架構新變革 Cortex-M軟體開發放利多(上)

2017-11-06
採用ARMv8-M架構的新一代安謀國際(ARM) Cortex-M處理器Cortex-M23與Cortex-M33將許多最佳化TrustZone安全功能導入微控制器(MCU)領域。這些新功能讓用戶更容易開發出超低功耗的安全解決方案,瞄準包括物聯網(IoT)或版圖更大的嵌入式產品市場。本文除了從軟體開發者的角度探討各項新功能,還詳述開發者該如何運用這些新安全功能作為基礎,著手開發各種安全無虞的嵌入式產品。
受益全新ARMv8-M架構 Cortex-M23/M33性能大躍進 

於2016年10月發表的ARM Cortex-M23與Cortex-M33處理器透過全新ARMv8-M架構,使原本就已相當成功的Cortex-M處理器家族陣容更為堅強。與前一版架構相比,新架構導入一系列架構變革,從軟體開發者的角度來看這些改變都顯而易見。 

此外,這些處理器還擁有許多功能,這裡將介紹其中幾個軟體開發者必須熟悉的領域,當他們著手把程式移植到新處理器時才知道該如何運用這些新功能。 

首先,來看Cortex-M23與Cortex-M33處理器與前一代Cortex-M處理器的關連(圖1)。先前的Cortex-M處理器以ARMv6-M和ARMv7-M架構為基礎。 

圖1 Cortex-M處理器的架構演進
ARMv6-M架構支援較小的指令集以及較少的系統功能,主要針對超低功耗設計進行最佳化。Cortex-M0與Cortex-M0+處理器兩者都採用ARMv6-M架構,閘極數僅12K。這些處理器適合大多數通用資料處理與I/O控制作業,並與採用ARMv7-M架構的處理器維持向上相容性。 

ARMv7-M架構則支援較大的指令集,包含針對數位訊號處理(DSP)與浮點運算的選項指令。Cortex-M3、Cortex-M4以及Cortex-M7處理器依序維持向上相容性,每系列處理器採用ARMv7-M指令集中的指令數量逐系列增加。這些處理器適用於需要較複雜的資料處理之應用,以及效能需求較高的系統。 

ARMv8-M架構分為兩個子系列(Sub-profiles),其區分方法類似ARMv6-M與ARMv7-M之間的劃分法。其中基線(Baseline)子系列是針對超低功耗設計進行最佳化,而主線(Mainline)子系列則瞄準性能較強悍但仍要求省電的系統。 

Cortex-M23處理器滿足了眾多受限制應用的各種需求。M23採用ARMv8-M基線架構,支援的功能係為Cortex-M0+處理器的超集合,它的功耗與Cortex-M0+處理器相似。 

Cortex-M33處理器則滿足了各種多功能應用的需求。它採用ARMv8-M主線架構,主要瞄準主流微控制器/系統單晶片(SoC)設計。其效能略高於現有的Cortex-M3與Cortex-M4處理器,而且比類似組態的處理器更省電。另外,它還支援許多以往Cortex-M3與Cortex-M4設計所沒有的功能。 

ARMv8-M架構其中一項關鍵強化就是推出名為TrustZone的安全延伸。TrustZone除了把執行環境分成兩種安全狀態外,還多加入一層安全屏障,建立更安全的狀態(信任區域)。這樣的配置協助系統抵禦各種類型的攻擊。有關TrustZone如何保護嵌入式系統的細節,詳述於2016年Embedded World大會發表的《智慧連網時代嵌入式處理器演進的下一步》(https://community.arm.com/docs/DOC-11532)。在此不再贅述這些細節,本文僅探討軟體開發部分。 

Cortex-M23與Cortex-M33處理器具有高度設定彈性。晶片開發商可自行選擇要在晶片中搭載哪些功能。舉例來說,巢狀向量中斷控制器(NVIC)裡的中斷數量可自行設定,另外像是記憶體保護單元(MPU)在內的系統資源也可自行選擇搭配。ARM Cortex-M33處理器方面,一些指令集的子集合也屬於選配,其中包括DSP延伸(如SIMD、飽和演算法)以及單精度浮點運算單元(FPU)。 

因此,Cortex-M33處理器能運用在與Cortex-M3(沒有延伸、沒有FPU)、Cortex-M4、或任何其他組合相似的組態。 

TrustZone技術加持 軟體運作確保安全無虞

Cortex-M23與Cortex-M33都屬於32位元處理器,並採用和先前幾代Cortex-M處理器一樣在架構中定義的記憶體地圖概念。此外,運用巢狀向量中斷控制器執行中斷控制以及架構定義的休眠模式,這部分仍維持不變。在大多數情況下,將軟體從先前設計移植到新處理器,相較之下更為簡單。當然,在系統層面,記憶體地圖與周邊元件的編程模式依舊未變。 

TrustZone技術是ARMv8-M架構的一部分。在支援TrustZone的系統中,軟體區分為安全軟體與非安全軟體兩大類。安全軟體是在安全位址空間中執行,並能存取安全與非安全位址。一般而言,安全軟體含有多種元件,這些元件對裝置的安全至關重要,包括安全開機、裝置供裝、譯密函式庫、韌體更新等方面。處理器在運行安全軟體時即處於安全狀態。而非安全軟體是在非安全位址空間中執行,且僅能存取非安全位址。大多數程式碼通常是在非安全狀態中執行。當處理器在執行非安全軟體時即處於非安全狀態。 

位址空間的分隔是由處理器執行,利用名為安全歸屬單元(SAU)以及名為建置定義歸屬單元(IDAU)的裝置專屬邏輯區塊進行區隔。記憶體空間組態僅能由安全軟體來控制。 

安全軟體與非安全軟體以不同的程式映像分開進行編譯。不過,安全與非安全軟體能利用直接函式呼叫進行互動,而例外處理程序能自動切換至不同處理器狀態。 

由於TrustZone安全延伸屬於選項功能,因此有些採用Cortex-M23與Cortex-M33處理器的裝置可能不支援TrustZone。如果不支援TrustZone安全延伸技術,處理器就永遠處於非安全狀態。 

非安全軟體開發

對於大多數軟體開發者而言,其程式都會在非安全狀態下運行。應用情境包括:沒有TrustZone的裝置;配備TrustZone的裝置,但其TrustZone功能並沒有被啟用;以及配備有TrustZone的裝置,軟體會存取安全區域中的應用程式介面(API)。 

在這些情況中,在非安全狀態運行的處理器,其運行模式類似先前沒有TrustZone的Cortex-M處理器。然而,由於架構出現許多強化,因此有幾個部分軟體開發者仍須多加留意。 

第一種情境是MPU的編程者模式已有改變。第二種情境是EXC_RETURN值(這個特殊值用來觸發例外回傳)經過延伸,影響層面涵蓋到即時作業系統(RTOS)。第三種情境則是向量表的初始位址不一定是0x00000000(不同於先前的Cortex-M0/M0+/M3/M4處理器,其初始位址都固定在0x00000000)。 

第四種情境是對於Cortex-M33元件的用戶,與Cortex-M3/M4相比。其中,不同於Cortex-M3和Cortex-M4,並沒有Cortex-M33的位元帶(Bit Band)功能。而移除了SCB->AIRCR(應用中斷與重置控制暫存器)裡的VECTRESET位元。軟體必須運用系統重置要求(SYSRESETREQ)位元來產生自我重置程序。 

第五種情境則是對於Cortex-M23元件的用戶,用C/C++撰寫的程式碼可以重新編譯,藉以善加運用過去Cortex-M0/Cortex-M0+沒有的指令。 

在上述第三種情境中(非安全軟體從安全區呼叫API),軟體開發者會收到標頭檔案,內含函式原型以及一個匯出函式庫(或其他形式的資訊),讓連結器能為安全軟體產生正確的函式呼叫。在C/C++環境中,這些API只是正常的「外部」函式,因此不須要掌握TrustZone如何運行的特殊知識,就能運用安全API所提供的各項功能。 

安全軟體開發

對於支援TrustZone的元件,當針對安全區域開發軟體時,開發者通常必須同時撰寫安全與非安全的程式映像,才能測試兩者之間的互動。許多軟體開發環境支援多專案的工作空間,因此同步開發的工作會比較簡單,執行流程中可能含有多個步驟。舉例來說,安全程式的專案檔經過編譯與連結,然後針對安全API產生匯出函式庫;接著再編譯非安全專案檔,並把輸出函式庫匯入專案檔,供連結階段使用;安全與非安全映像之後,再載入到測試平台(像是微控制器機板)進行測試。 

所有影響到非安全軟體(如上所述)的架構強化,也都影響到安全軟體的開發。安全軟體專案檔的編程者模式大部分和非安全環境相同,僅有下列幾點差異。 

首先,一些資源像是SysTick計時器與MPU都是成組的(Banked),安全軟體除了能存取非安全MPU與SysTick,還能透過非安全的別名位址存取System Control Block暫存器。 

安全軟體能設定哪些資源開放給非安全軟體使用。舉例來說,它能設定SAU與任何系統層級保護控制器,該控制器負責分隔各種系統資源(像是記憶體與周邊元件)。 

在Cortex-M23上運行的軟體安全能運用堆疊限制暫存器來偵測堆疊溢位,而非安全區域則沒有堆疊限制暫存器。Cortex-M33處理器在安全與非安全區域都支援堆疊限制暫存器。 

安全軟體能決定哪些處理器內部資源能由非安全軟體來控制。舉例來說,安全軟體能設定NVIC_ITNS[n]暫存器定義哪些中斷屬於安全,以及哪些中斷屬於非安全。而對於一些僅搭載一個SysTick計時器並採用Cortex-M23的裝置,安全軟體能決定SysTick計時器是供安全模式使用或供非安全模式使用。此外,軟體安全能決定深層休眠與系統重置要求功能是否能從非安全區域存取。安全軟體能決定包括HardFault、BusFault以及NMI例外能否由安全或非安全軟體來處理。 

安全軟體開發者必須運用ARM C語言延伸(ARM C Language Extensions, ACLE)所定義的各種C語言延伸功能,讓安全與非安全軟體進行正確的互動。此外,安全API可以透過非安全軟體呼叫,但必須小心撰寫與檢查以避免安全漏洞。 

開發工具更新 

除了軟體程式碼的更新外,軟體開發工具亦須在架構上進行相對的更新,包括以下兩者。 

・編譯器工具鏈 

許多C/C++工具鏈已進行更新,以支援ARMv8-M架構。這方面的更新包括:支援ARMv8-M架構中定義的新指令(ARMv8-M基線內含比ARMv6-M額外增加的指令)。此外,許多新指令亦加入到ARMv8-M主線與基線版本,藉以支援TrustZone與C11功能;並且支援ACLE功能--藉以開發安全軟體,軟體開發者必須加入ACLE定義的巨集、歸屬以及固有函式,藉以開發TrustZone軟體。 

・除錯工具 

除錯工具(通常為開發套件的一部分)亦須升級才能支援ARMv8-M。除錯器的變更包括:支援處理器中的多種新暫存器,例如堆疊限制暫存器、除錯驗證支援暫存器等;在許多除錯元件中支援新編程者模式;Cortex-M23與Cortex-M33增強指令追蹤支援(兩款處理器都能支援MTB或ETM指令追蹤功能);TrustZone亦承襲了各種除錯工具在除錯驗證支援方面的要求。 

JTAG與Serial Wire除錯協定依舊未變,因此在大多數情況下,除錯探測(Probe)裝置/配接器(Adapter)硬體都可搭配ARMv8-M處理器重複使用。但在更新韌體時可能須用到除錯Probes裝置。 

TrustZone範例說明 除錯驗證一步到位 

使用TrustZone技術有許多方式。在針對各種物聯網應用所設計的微控制器方面,晶片製造商可設計出各種微控制晶片,例如:安全開機、譯密函式庫以及相關資源,置於安全區域並受TrustZone所保護;高價值韌體,例如通訊協定堆疊,都能加入到安全記憶體中並受妥善保護;微控制器軟體開發者可運用通過驗證的API來存取各種安全功能,但不能直接存取安全硬體功能,也無法針對受保護的高價值韌體進行逆向工程;額外的晶片層級保護功能可用來防範出廠後的產品被外界入侵讀取。 

圖2顯示基本的系統開機作業。其中,步驟1代表安全狀態下的系統開機,以安全開機模式進行安全檢查,然後再執行各種啟動作業,像是C語言啟動與SAU編程。步驟2是安全韌體分支連結到非安全程式的進入點。非安全程式擁有自己的重置處理器、C語言啟動程式碼以及硬體啟動(如周邊元件)程序。這和從安全程式碼啟動並沒有衝突,因為安全與非安全程式碼的堆疊(Stack)與堆積(Heap)空間是分隔開來的。步驟3則是指在非安全程式的執行階段,程式可以呼叫安全API。接著步驟4,在某些情況,安全API可能必須呼叫非安全的回呼(Call-back)函式(如硬體驅動程式)。 

圖2 支援TrustZone技術Cortex-M核心微控制器中軟體作業流程範例
產品開發的不同階段,可能必須變更除錯存取權限,這方面可利用處理器的除錯驗證功能來執行(圖3)。舉例來說,終端產品開發商購入微控制晶片時,安全程式記憶體可能已被編程並鎖定,微控制器軟體開發者無法使用除錯工具直接檢視安全程式碼或存取安全周邊元件(包括安全儲存、譯密加速器等)的內容。 

圖3 產品生命週期除錯驗證的例子
處理器層級上的除錯驗證,是由多個組態訊號負責控制,讓晶片製造商能藉由加入特定控制硬體,自行決定如何控制除錯驗證程序。 

由於有除錯驗證功能,支援ARMv8-M的除錯工具必須支援各種不同的情境。舉例來說,在僅啟用非安全除錯時,可能有以下三種情境。 

第一種情境是,在執行安全程式碼時處理器不能停止。若在這個階段發出中止要求,中止要求就會被擱置,當切換到非安全狀態時就會停止處理器。 

第二種情境為,除錯軟體無法以單步執行模式進入安全程式碼。若軟體開發者使用單步執行模式對一段非安全程式碼進行除錯,若程式碼呼叫一個安全API,則單步執行程序就會被擋下。接著,在啟動安全API時除錯器就會中止SG(安全閘道器)指令,當執行另一個步驟時,它會繼續運行以執行安全API,當回到非安全程式碼時就會中止。 

第三種則是追蹤作業(例如透過ETM/MTB執行指令追蹤)在安全程式碼作業中全程被關閉,以防止安全資訊外洩。 

在某些狀況中,MCU廠商能提供額外的保護功能,如eXecute Only Memory (XOM)記憶體。XOM是一種韌體保護技巧,程式記憶體空間的一部分僅支援程式執行,除錯器或任何軟體都無法讀回記憶體的內容。可參閱MCU廠商的文件,確認產品提供的保護功能。 

新架構帶來新改變 性能發揮有賴小調整

由於Cortex-M23/M33中的一些功能是先前Cortex-M0/M0+/M3/M4處理器所沒有的,因此軟體開發者必須修改其程式碼才能充分利用這些功能。 

指令集 

Cortex-M23支援的指令集遠大於Cortex-M0/M0+所支援的指令集,因此程式碼必須重新編譯才能使用額外增加的指令,造就出更好的效能與縮減程式碼長度。而且,RTOS進行更新後,即能以排他存取模式執行旗標作業。不同於SVC型態的旗艦作業,運用排他模式進行存取可避免對中斷延遲產生任何影響。此外,RTOS可使用相同的旗艦碼運用在ARMv8-M主線與基線處理器上。 

由於Cortex-M33採用更有效率的管線設計,因此Cortex-M3/M4的程式轉移到Cortex-M33之後可獲得顯著的效能提升。然而,某些編譯器還針對Cortex-M33的管線特性進行進一步的最佳化,因此使用這些較新編譯器重新編譯程式碼,可能還會獲得額外的效能提升。 

堆疊限制功能 

另一種獲高度推崇的安全措施就是安全軟體使用堆疊限制功能來偵測堆疊溢位。若少了這項功能,安全程式中的堆疊溢位可能導致安全資訊外洩,可能引發防禦漏洞,讓非安全使用者危及安全軟體(像是修改回傳堆疊)。 

對於非安全軟體而言,Cortex-M33(ARMv8-M主線)有支援堆疊限制功能,但在Cortex-M23(ARMv8-M基線)並沒有支援。如果使用Cortex-M23,堆疊溢位偵測功能可透過以下方式建置:使用MPU(像是某些RTOS使用MPU來偵測堆疊溢位);使用RTOS,在行程切換時就會建置堆疊範圍檢查機制;主要軟體使用非安全程序堆疊指標(PSP_NS),並在靜態隨機存取記憶體(SRAM)空間的開頭設置行程堆疊(如果在執行緒碼中發生堆疊溢位,就會存取無效的SRAM空間,進而觸發HardFault例外狀況)。 

新的記憶體保護單元功能 

新的記憶體保護單元(MPU)是一種可編程的硬體單元,可用來定義記憶體存取權限以及各種記憶體屬性。一般而言,在RTOS環境中,應用程式任務都是在非優先存取模式中執行,有些RTOS則能設定MPU,讓程式任務僅能存取分派給它們的記憶體空間。藉由這樣的保護機制,程式任務就不會損毀作業系統或其他任務所使用的資料,因此提高了系統的可靠度。 

在RTOS環境中,每次行程切換(Context Switch) MPU都會重新設定,藉以讓不同的程式任務能存取記憶體系統中的不同區塊。另外,MPU還定義了各種記憶體屬性,例如定義哪些記憶體空間能設置快取。 

ARMv8-M架構為MPU定義了一種新的編程者模式,造就出更有彈性的區域定義。這方面ARM不是把MPU區域的上限設為平方值,並要求MPU區域的啟始位址必須為區域大小的倍數,新的設計規定MPU區域使用的起始位址與終止位址其增減單位必須為32位元組。 

MPU組態選項亦有所增強。Cortex-M0+/M3/M4中的MPU能支援八個區域,而Cortex-M7則支援八或十六個區域。在Cortex-M23與Cortex-M33中,可以有兩個MPU(一個負責安全程式另一個負責非安全程式),兩者可以單獨配置四、八、十二或十六個區域。 

ARMv8-M中的MPU,在記憶體屬性定義方面和ARMv6-M或ARMv7-M有一些差異。在先前的架構中,記憶體分成一般記憶體(如ROM、RAM)、裝置記憶體以及嚴格排序(Strongly Ordered)記憶體。在ARMv8-M架構中,只有一般與裝置記憶體,裝置記憶體種類可根據三種屬性進一步細分為四類。三種屬性包括E/nE(允許或不允許先期回應)、R/nR(允許或不允許存取重排)、G/nG(允許或不允許存取收集,例如合併)。四種裝置類別則為Device-nGnRnE(等於先前架構中的嚴格排序記憶體)、Device-nGnRE(等於先前架構中可緩衝裝置)、Device-nGRE以及Device-GRE。 

有關MPU編程模式的詳細資訊可參閱《ARMv8-M平台的記憶體保護單元》(https://developer.arm.com/products/architecture/m-profile/docs/100699/latest/introduction)。 

即時作業系統 

如先前所述,ARMv8-M中有許多功能可以強化即時作業系統(RTOS)的運作。RTOS軟體開發者可詳閱《ARMv8-M平台的RTOS設計考量因素》作為參考。 

協同處理器 

Cortex-M33處理器擁有一個協同處理器介面,能支援到八個協同處理器。晶片設計者可運用協同處理器介面擴增硬體加速器,用來加速各種特殊作業,若沒有使用加速器,這類作業就須要執行更長的原生指令程序。 

每個協同處理器可以配置多個硬體暫存器。在概念上,這些暫存器就像是周邊暫存器,但設置在另外的位址空間(不在4GB記憶體位址空間內)。協同處理器介面提供一個高速機制,在處理器的暫存器庫區(Bank)以及協同處理器暫存器之間傳輸資料--它能在一個週期內讀取/寫入32位元或64位元的資料。由於傳輸作業不會受主匯流排介面上其他匯流排流量所影響,因此可用一個位址設定一個暫存器,所提供的效能會高於使用記憶體映射硬體加速器。 

要使用協同處理器功能,包括啟動協同處理器,可透過CPACR(協同處理器存取控制暫存器)進行控制;運用協同處理器指令(像是行內組譯)或透過ACLE定義的固有指令來存取協同處理器。 

表1歸納出各種協同處理器指令。每個資料傳輸指令也可加入到運算元,用來定義所需的協同處理器作業。協同處理器的數量、運算元以及協同處理器暫存器都與裝置相關。 

ACLE定義了許多固有函式(Intrinsic Function),讓使用者在C/C++語言編程環境(表2)中更容易存取這些指令。 

表1 Cortex-M33處理器支援的協同處理器指令
協同處理器介面具有TrustZone感知能力。安全軟體可將每個協同處理器定義為安全或非安全,僅須設定非安全存取控制暫存器(NSACR)暫存器。若協同處理器被設定為安全,那麼從非安全軟體存取協同處理器就會觸發缺陷例外狀況。此外,該介面還有一個邊帶訊號(Sideband Signal)用來指定安全屬性,藉以精細控制哪個協同處理器暫存器屬於安全或非安全。 

表2 ACLE針對協同處理器存取定義的固有函式
TrustZone技術有亮點 ARMv8-M架構被看好

運用TrustZone技術,Cortex-M23與Cortex-M33處理器為裝置帶來效率以及最佳化的安全,因此,軟體必須予以更新以充分發揮新處理器功能,而安全軟體則須審慎地撰寫以避免產生任何防禦漏洞。 

為了讓安全軟體開發者的工作更為簡單,ACLE已進行更新,納入CMSE安全延伸功能,讓軟體開發者在移植C/C++程式碼時能存取各種安全功能。這些功能讓安全與非安全軟體元件之間能有效率地互動,並確保資訊的處理安全無虞。 

(本文作者為安謀國際處理器事業部資深嵌入式技術經理)

本站使用cookie及相關技術分析來改善使用者體驗。瞭解更多

我知道了!