日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > linux >内容正文

linux

Linux Kernel/optee/ATF等操作系统的异常向量表的速查

發布時間:2025/3/21 linux 34 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Linux Kernel/optee/ATF等操作系统的异常向量表的速查 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

引流關鍵詞: IRQ,FIQ,Serror, 中斷,同步異常,異步異常,TF-A,TF-M,ATF,TrustedFirmware,trustzone,TEE,optee,trusty,tlk,lk,armv8,armv9,arm,secureboot,BL31,BL32,BL1,BL2,hypervisor,終端安全,secureboot,security,virtulization

快速鏈接:
.
👉👉👉 個人博客筆記導讀目錄(全部) 👈👈👈


說明:
在默認情況下,本文講述的都是ARMV8-aarch64架構,linux kernel 5.14, optee3.14, TF-A 2.4, armv8.8

目錄

      • 硬件:armv8-aarch64\arch以及armv7的向量表和基地址寄存器介紹
        • 1、ARMV8 aarch64的異常向量表介紹
        • 2、ARMV8 aarch32的異常向量表介紹
        • 3、ARMV7 4的異常向量表介紹
        • 4、ARMV8 aarch64的向量表基地址
        • 5、ARMV8 aarch的向量表基地址
        • 6、ARMV7的向量表基地址
      • 軟件:各個系統的異常向量表(Linux, optee, ATF ...32位/64位)
        • 1、Linux Kernel 中arm64定義的向量表
        • 2、Linux Kernel 中arm定義的向量表
        • 3、optee中arm64定義的異常向量表
        • 4、optee中arm定義的異常向量表
        • 5、在ATF中arm64異常向量表的實現定義
        • 6、、在ATF中arm64異常向量表的實現定義
      • 軟件:各個系統的向量表基地址的設置(Linux, optee, ATF ...32位/64位)
        • 1、linux kernel的arm64下設置向量表基地址VBAR
        • 2、linux kernel的arm32下設置向量表基地址VBAR
        • 3、optee中arm64設置向量表基地址VBAR_EL1
        • 4、optee中arm設置向量表基地址VBAR_EL1

  • 軟件中定義的向量表,是否和ARM文檔中的向量offset一致
  • 向量表的基地址是否寫入到了VBAR寄存器

硬件:armv8-aarch64\arch以及armv7的向量表和基地址寄存器介紹

1、ARMV8 aarch64的異常向量表介紹


我們可以看出,實際上有四組表,每組表有四個異常入口,分別對應同步異常,IRQ,FIQ和serror。

  • 如果發生異常后并沒有exception level切換,并且發生異常之前使用的棧指針是SP_EL0,那么使用第一組異常向量表。
  • 如果發生異常后并沒有exception level切換,并且發生異常之前使用的棧指針是SP_EL1/2/3,那么使用第二組異常向量表。
  • 如果發生異常導致了exception level切換,并且發生異常之前的exception
    level運行在AARCH64模式,那么使用第三組異常向量表。
  • 如果發生異常導致了exception level切換,并且發生異常之前的exception
    level運行在AARCH32模式,那么使用第四組異常向量表。

另外我們還可以看到的一點是,每一個異常入口不再僅僅占用4bytes的空間,而是占用0x80 bytes空間,也就是說,每一個異常入口可以放置多條指令,而不僅僅是一條跳轉指令

2、ARMV8 aarch32的異常向量表介紹

3、ARMV7 4的異常向量表介紹

4、ARMV8 aarch64的向量表基地址

VBAR(Vector Base Address Register)的寄存器有:

(如果是aarch64)

  • VBAR_EL1
  • VBAR_EL2
  • VBAR_EL3

在開啟MMU的系統,VBAR中寫入的是虛擬地址,以VBAR_EL1為例,介紹下field的使用:

Bits [10:0] reserved

Bits [11:63]:
如果不支持ARMv8.2-LVA(Large VA support:使用64kb頁面時,有效虛擬地址達到52bit)
(1)、如果支持tagged addresses, bits [55:48]必需都是一樣的
(2)、如果不支持tagged addresses , bits [63:48] 必需都是一樣的
如果支持ARMv8.2-LVA(Large VA support:使用64kb頁面時,有效虛擬地址達到52bit)
(1)、如果支持tagged addresses , bits [55:52] 必需都是一樣的
(2)、如果不支持tagged addresses , bits [63:52] 必需都是一樣的

該寄存器的低11bit是reserve的,11~63表示了Vector Base Address,因此這里的異常向量表基地址是2K對齊的

5、ARMV8 aarch的向量表基地址

如果是aarch32

  • VBAR
  • HVBAR
  • MVBAR

6、ARMV7的向量表基地址

TODO

軟件:各個系統的異常向量表(Linux, optee, ATF …32位/64位)

1、Linux Kernel 中arm64定義的向量表

(linux/arch/arm64/kernel/entry.S)/** Exception vectors.*/.pushsection ".entry.text", "ax".align 11 SYM_CODE_START(vectors)kernel_ventry 1, sync_invalid // Synchronous EL1tkernel_ventry 1, irq_invalid // IRQ EL1tkernel_ventry 1, fiq_invalid // FIQ EL1tkernel_ventry 1, error_invalid // Error EL1tkernel_ventry 1, sync // Synchronous EL1hkernel_ventry 1, irq // IRQ EL1hkernel_ventry 1, fiq // FIQ EL1hkernel_ventry 1, error // Error EL1hkernel_ventry 0, sync // Synchronous 64-bit EL0kernel_ventry 0, irq // IRQ 64-bit EL0kernel_ventry 0, fiq // FIQ 64-bit EL0kernel_ventry 0, error // Error 64-bit EL0#ifdef CONFIG_COMPATkernel_ventry 0, sync_compat, 32 // Synchronous 32-bit EL0kernel_ventry 0, irq_compat, 32 // IRQ 32-bit EL0kernel_ventry 0, fiq_compat, 32 // FIQ 32-bit EL0kernel_ventry 0, error_compat, 32 // Error 32-bit EL0 #elsekernel_ventry 0, sync_invalid, 32 // Synchronous 32-bit EL0kernel_ventry 0, irq_invalid, 32 // IRQ 32-bit EL0kernel_ventry 0, fiq_invalid, 32 // FIQ 32-bit EL0kcernel_ventry 0, error_invalid, 32 // Error 32-bit EL0 #endif SYM_CODE_END(vectors)

注意.align=7,說明該段代碼是以2^7=128字節對其的,這和向量表中每一個offset的大小是一致的
代碼看似非常復雜,其實最終跳轉到了b el\()\el\()_\label, 翻譯一下,其實就是跳轉到了如下這樣的函數中

el1_sync_invalid el1_irq_invalid el1_fiq_invalid el1_error_invalidel1_sync el1_irq el1_fiq el1_error el0_sync el0_irq el0_fiq el0_error

2、Linux Kernel 中arm定義的向量表

.section .stubs, "ax", %progbits __stubs_start:@ This must be the first word.word vector_swi.section .vectors, "ax", %progbits __vectors_start:W(b) vector_rstW(b) vector_undW(ldr) pc, __vectors_start + 0x1000W(b) vector_pabtW(b) vector_dabtW(b) vector_addrexcptnW(b) vector_irqW(b) vector_fiq

3、optee中arm64定義的異常向量表

(core/arch/arm/kernel/thread_a64.S).section .text.thread_excp_vect.align 11, INV_INSN FUNC thread_excp_vect , :/* -----------------------------------------------------* EL1 with SP0 : 0x0 - 0x180* -----------------------------------------------------*/.align 7, INV_INSN el1_sync_sp0:store_xregs sp, THREAD_CORE_LOCAL_X0, 0, 3b el1_sync_abortcheck_vector_size el1_sync_sp0.align 7, INV_INSN el1_irq_sp0:store_xregs sp, THREAD_CORE_LOCAL_X0, 0, 3b elx_irqcheck_vector_size el1_irq_sp0.align 7, INV_INSN el1_fiq_sp0:store_xregs sp, THREAD_CORE_LOCAL_X0, 0, 3b elx_fiqcheck_vector_size el1_fiq_sp0.align 7, INV_INSN el1_serror_sp0:b el1_serror_sp0check_vector_size el1_serror_sp0/* -----------------------------------------------------* Current EL with SP1: 0x200 - 0x380* -----------------------------------------------------*/.align 7, INV_INSN el1_sync_sp1:b el1_sync_sp1check_vector_size el1_sync_sp1.align 7, INV_INSN el1_irq_sp1:b el1_irq_sp1check_vector_size el1_irq_sp1.align 7, INV_INSN el1_fiq_sp1:b el1_fiq_sp1check_vector_size el1_fiq_sp1.align 7, INV_INSN el1_serror_sp1:b el1_serror_sp1check_vector_size el1_serror_sp1/* -----------------------------------------------------* Lower EL using AArch64 : 0x400 - 0x580* -----------------------------------------------------*/.align 7, INV_INSN el0_sync_a64:restore_mappingmrs x2, esr_el1mrs x3, sp_el0lsr x2, x2, #ESR_EC_SHIFTcmp x2, #ESR_EC_AARCH64_SVCb.eq el0_svcb el0_sync_abortcheck_vector_size el0_sync_a64.align 7, INV_INSN el0_irq_a64:restore_mappingb elx_irqcheck_vector_size el0_irq_a64.align 7, INV_INSN el0_fiq_a64:restore_mappingb elx_fiqcheck_vector_size el0_fiq_a64.align 7, INV_INSN el0_serror_a64:b el0_serror_a64check_vector_size el0_serror_a64/* -----------------------------------------------------* Lower EL using AArch32 : 0x0 - 0x180* -----------------------------------------------------*/.align 7, INV_INSN el0_sync_a32:restore_mappingmrs x2, esr_el1mrs x3, sp_el0lsr x2, x2, #ESR_EC_SHIFTcmp x2, #ESR_EC_AARCH32_SVCb.eq el0_svcb el0_sync_abortcheck_vector_size el0_sync_a32.align 7, INV_INSN el0_irq_a32:restore_mappingb elx_irqcheck_vector_size el0_irq_a32.align 7, INV_INSN el0_fiq_a32:restore_mappingb elx_fiqcheck_vector_size el0_fiq_a32.align 7, INV_INSN el0_serror_a32:b el0_serror_a32check_vector_size el0_serror_a32

align 7,對齊方式為7,也就是0x80對齊,恰好符合armv7-aarch64中文檔中的向量表的offset偏移

4、optee中arm定義的異常向量表

(core/arch/arm/kernel/thread_a32.S).section .text.thread_excp_vect.align 5 FUNC thread_excp_vect , : UNWIND( .fnstart) UNWIND( .cantunwind)b . /* Reset */b thread_und_handler /* Undefined instruction */b thread_svc_handler /* System call */b thread_pabort_handler /* Prefetch abort */b thread_dabort_handler /* Data abort */b . /* Reserved */b thread_irq_handler /* IRQ */b thread_fiq_handler /* FIQ */

一條指令占4個字節,所以這里也是和aarch32的異常向量表的offset一一對應的

5、在ATF中arm64異常向量表的實現定義

在ATF的代碼中,在不同的階段有著不同的異常向量表:

  • 在bl1階段使用bl1_exceptions
  • 在bl2階段使用bl2_entrypoint
  • 在bl31及其之后使用runtime_exceptions
func bl1_entrypoint ......el3_entrypoint_common \_set_endian=1 \_warm_boot_mailbox=!PROGRAMMABLE_RESET_ADDRESS \_secondary_cold_boot=!COLD_BOOT_SINGLE_CPU \_init_memory=1 \_init_c_runtime=1 \_exception_vectors=bl1_exceptionsfunc bl2_entrypointel3_entrypoint_common \_set_endian=0 \_warm_boot_mailbox=0 \_secondary_cold_boot=0 \_secondary_cpu = 0 \_init_memory=0 \_init_c_runtime=1 \_exception_vectors=bl2_vectorfunc bl31_entrypoint ......el3_entrypoint_common \_set_endian=0 \_warm_boot_mailbox=0 \_secondary_cold_boot=0 \_init_memory=0 \_init_c_runtime=1 \_exception_vectors=runtime_exceptions

我們常說的ATF中的向量表,其實就是bl31之后使用runtime_exceptions向量表,下面重點介紹下

(注意 : 帶unhandled的都是未實現的)

  • 用于處理EL0產生異常時的entire(對應第一行向量表)
vector_entry sync_exception_sp_el0 b report_unhandled_exception check_vector_size sync_exception_sp_el0 vector_entry irq_sp_el0 b report_unhandled_interrupt check_vector_size irq_sp_el0 vector_entry fiq_sp_el0 b report_unhandled_interrupt check_vector_size fiq_sp_el0 vector_entry serror_sp_el0 b report_unhandled_exception check_vector_size serror_sp_el0
  • 用于處理當前ELx產生異常時的entire(對應第二行向量表)
vector_entry sync_exception_sp_elx b report_unhandled_exception check_vector_size sync_exception_sp_elx vector_entry irq_sp_elx b report_unhandled_interrupt check_vector_size irq_sp_elx vector_entry fiq_sp_elx b report_unhandled_interrupt check_vector_size fiq_sp_elx vector_entry serror_sp_elx b report_unhandled_exception check_vector_size serror_sp_elx
  • 用于處理AArch64指令產生的異常,且發生了EL的遷移的entire(對應第三行向量表)
vector_entry sync_exception_aarch64 handle_sync_exception check_vector_size sync_exception_aarch64 vector_entry irq_aarch64 handle_interrupt_exception irq_aarch64 check_vector_size irq_aarch64 vector_entry fiq_aarch64 handle_interrupt_exception fiq_aarch64 check_vector_size fiq_aarch64 vector_entry serror_aarch64 b report_unhandled_exception check_vector_size serror_aarch64
  • 用于處理AArch32指令產生的異常,且發生了EL的遷移的entire(對應第四行向量表)
vector_entry sync_exception_aarch32 handle_sync_exception check_vector_size sync_exception_aarch32 vector_entry irq_aarch32 handle_interrupt_exception irq_aarch32 check_vector_size irq_aarch32 vector_entry fiq_aarch32 handle_interrupt_exception fiq_aarch32 check_vector_size fiq_aarch32 vector_entry serror_aarch32 b report_unhandled_exception check_vector_size serror_aarch32

6、、在ATF中arm64異常向量表的實現定義

TODO

軟件:各個系統的向量表基地址的設置(Linux, optee, ATF …32位/64位)

1、linux kernel的arm64下設置向量表基地址VBAR

在__primary_switched將vectors寫入到了VBAR_EL1

__primary_switched:adrp x4, init_thread_unionadd sp, x4, #THREAD_SIZEadr_l x5, init_taskmsr sp_el0, x5 // Save thread_infoadr_l x8, vectors // load VBAR_EL1 with virtualmsr vbar_el1, x8 // vector table addressisbstp xzr, x30, [sp, #-16]!mov x29, spstr_l x21, __fdt_pointer, x5 // Save FDT pointer..b start_kernel ENDPROC(__primary_switched)

2、linux kernel的arm32下設置向量表基地址VBAR

Linux Kernel的arm的異常向量表定義在__vectors_start處

在vmlinux.lds.S描述了__vectors_start的起始位置,從0xffff0000開始**

(kernel-4.14/arch/arm/kernel/vmlinux.lds.S) __vectors_start = .; .vectors 0xffff0000 : AT(__vectors_start) {*(.vectors) } . = __vectors_start + SIZEOF(.vectors); __vectors_end = .;__stubs_start = .; .stubs ADDR(.vectors) + 0x1000 : AT(__stubs_start) {*(.stubs) } . = __stubs_start + SIZEOF(.stubs); __stubs_end = .;

在nommu.c中,setup_vectors_base函數通過操作cp15協處理器來寫入VBAR.

(kernel-4.14/arch/arm/mm/nommu.c) static unsigned long __init setup_vectors_base(void) {unsigned long reg = get_cr();set_cr(reg | CR_V); //其實就是將CR_V寫入到了cp15, 也就是寫入到了VBAR寄存器.return 0xffff0000; } static inline void set_cr(unsigned long val) {asm volatile("mcr p15, 0, %0, c1, c0, 0 @ set CR": : "r" (val) : "cc");isb(); }

而CR_V的定義在cp15.h中,恰好就是0xffff0000(也就是最地址處,空出64KB的地方,給vector使用)

(kernel-4.14/arch/arm/include/asm/cp15.h) #define CR_M (1 << 0) /* MMU enable */ #define CR_A (1 << 1) /* Alignment abort enable */ #define CR_C (1 << 2) /* Dcache enable */ #define CR_W (1 << 3) /* Write buffer enable */ #define CR_P (1 << 4) /* 32-bit exception handler */ #define CR_D (1 << 5) /* 32-bit data address range */ #define CR_L (1 << 6) /* Implementation defined */ #define CR_B (1 << 7) /* Big endian */ #define CR_S (1 << 8) /* System MMU protection */ #define CR_R (1 << 9) /* ROM MMU protection */ #define CR_F (1 << 10) /* Implementation defined */ #define CR_Z (1 << 11) /* Implementation defined */ #define CR_I (1 << 12) /* Icache enable */ #define CR_V (1 << 13) /* Vectors relocated to 0xffff0000 */ #define CR_RR (1 << 14) /* Round Robin cache replacement */ #define CR_L4 (1 << 15) /* LDR pc can set T bit */ #define CR_DT (1 << 16)

setup_vectors_base是在開機的時候調用的

setup_arch ----> arm_memblock_init ----> arm_mm_memblock_reserve ---> setup_vectors_base

3、optee中arm64設置向量表基地址VBAR_EL1

get_excp_vect()函數獲取到thread_a64.S中定義的向量表thread_excp_vect地址

(core/arch/arm/kernel/thread.c) static vaddr_t get_excp_vect(void) { #ifdef CFG_CORE_WORKAROUND_SPECTRE_BP_SECuint32_t midr = read_midr();if (get_midr_implementer(midr) != MIDR_IMPLEMENTER_ARM)return (vaddr_t)thread_excp_vect;switch (get_midr_primary_part(midr)) { #ifdef ARM32case CORTEX_A8_PART_NUM:case CORTEX_A9_PART_NUM:case CORTEX_A17_PART_NUM: #endifcase CORTEX_A57_PART_NUM:case CORTEX_A72_PART_NUM:case CORTEX_A73_PART_NUM:case CORTEX_A75_PART_NUM:return select_vector((vaddr_t)thread_excp_vect_workaround); #ifdef ARM32case CORTEX_A15_PART_NUM:return select_vector((vaddr_t)thread_excp_vect_workaround_a15); #endifdefault:return (vaddr_t)thread_excp_vect;} #endif /*CFG_CORE_WORKAROUND_SPECTRE_BP_SEC*/return (vaddr_t)thread_excp_vect; }

在thread_init_per_cpu()時,將向量表基地址寫入到VBAR_EL1

void thread_init_per_cpu(void) {size_t pos = get_core_pos();struct thread_core_local *l = thread_get_core_local();init_sec_mon(pos);set_tmp_stack(l, GET_STACK(stack_tmp[pos]) - STACK_TMP_OFFS);set_abt_stack(l, GET_STACK(stack_abt[pos]));thread_init_vbar(get_excp_vect()); }

thread_init_vbar函數完成將基地址寫入VBAR_EL1(將參數1寫入到VBAR_EL1)

(core/arch/arm/kernel/thread_a64.S) FUNC thread_init_vbar , :msr vbar_el1, x0 ret END_FUNC thread_init_vbar

4、optee中arm設置向量表基地址VBAR_EL1

其流程同aarch64的流程相同,都是thread_init_per_cpu()---->thread_init_vbar ()

(core/arch/arm/kernel/thread_a32.S) FUNC thread_init_vbar , : UNWIND( .fnstart)/* Set vector (VBAR) */write_vbar r0bx lr UNWIND( .fnend) END_FUNC thread_init_vbar

總結

以上是生活随笔為你收集整理的Linux Kernel/optee/ATF等操作系统的异常向量表的速查的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 黄色三级免费 | 水牛影视av一区二区免费 | 国产91一区 | 伊人激情 | 中文字字幕码一二三区 | 91久久久久久久久久 | 18禁一区二区| 日韩第1页 | 久久精品免费观看 | 98视频在线 | 亚洲日b视频 | 国产精品一区麻豆 | 毛片网络 | 精品国产乱 | 精品久久久久亚洲 | 健身教练巨大粗爽gay视频 | 麻豆视频在线看 | 亚洲色图美腿丝袜 | 午夜av一区二区三区 | 亚洲视频在线播放免费 | 久久婷婷色综合 | 狠狠的日 | 日韩va亚洲va欧美va久久 | 午夜在线视频免费观看 | 日韩乱码人妻无码中文字幕 | 无码熟妇人妻av | 日本xx视频 | 91传媒网站 | 男操女视频网站 | 亚欧成人精品 | 香蕉视频一区二区三区 | 久久精品中文字幕 | 琪琪五月天| 啪啪网站免费看 | www.浪潮av.com | 性生交生活影碟片 | 国产精品zjzjzj在线观看 | 免费黄色网页 | 亚洲20p| 久久99热人妻偷产国产 | 自拍av在线 | av高清在线| 天天艹天天操 | 亚洲男人天堂久久 | 国产在线精品一区二区三区 | 国产成人精品一区在线播放 | 久久系列| 亚洲欧美日韩色 | 免费荫蒂添的好舒服视频 | 性猛交娇小69hd | 国产二级毛片 | 日韩av手机在线 | 久久精品第一页 | 老熟女毛茸茸 | 亚洲一区二区三区麻豆 | 一级久久久 | 午夜影院免费在线观看 | 在线免费看av| 青青草自拍偷拍 | www色婷婷| 国产精品作爱 | 亚洲干干干| 久久人妻少妇嫩草av无码专区 | 51精品国产人成在线观看 | 日韩av在线播放观看 | 超碰成人免费电影 | 成人va在线观看 | 日韩影院一区 | 激情视频网站 | 国产精品一区二区白浆 | 欧美区一区二区三 | 国产亚洲精品美女久久久久 | 精品国产九九九 | 香蕉久久久久久久av网站 | 天天操天天干天天舔 | av网子| 免费在线不卡视频 | 国产香蕉网| 人妻久久久一区二区三区 | 97人妻精品一区二区免费 | 成人性视频免费网站 | 欧美高清在线 | 美女隐私无遮挡网站 | 福利社区一区二区 | 欧洲精品一区二区三区久久 | 美女精品在线观看 | 人人模人人干 | 少妇又白又嫩又色又粗 | 日本成人动漫在线观看 | 新天堂av| 久久久精彩视频 | 综合伊人久久 | 黄色一区二区视频 | 亚洲一区二区播放 | 777中文字幕 | 日韩av免费在线 | 中文字幕国产一区二区 | 日本白嫩的bbw | 超碰97在线免费观看 |