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

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 运维知识 > linux >内容正文

linux

[ARM异常]-linux中(aarch/aarch64)异常向量表介绍

發(fā)布時(shí)間:2025/3/21 linux 46 豆豆
生活随笔 收集整理的這篇文章主要介紹了 [ARM异常]-linux中(aarch/aarch64)异常向量表介绍 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

文章目錄

      • 1、ARM的異常向量表基地址寄存器--VBAR
        • 1.1、armv8 : VBAR寄存器
        • 1.2、armv7 : VBAR寄存器
      • 2、ARM的異常向量表的定義
        • 2.1 armv8 :異常向量表offset的定義
        • 2.2 armv8 : 在linux kernel中異常向量表的實(shí)現(xiàn)定義
        • 2.3 armv8 : 在ATF中異常向量表的實(shí)現(xiàn)定義
        • 2.4 armv8 : 異常向量表總結(jié)和示例:
        • 2.5 armv7 :異常向量表offset的定義
        • 2.6 armv7 : 在linux kernel中異常向量表的實(shí)現(xiàn)定義
      • 3、總結(jié):


★★★ 友情鏈接 : 個(gè)人博客導(dǎo)讀首頁—點(diǎn)擊此處 ★★★

1、ARM的異常向量表基地址寄存器–VBAR

1.1、armv8 : VBAR寄存器

1.2、armv7 : VBAR寄存器

2、ARM的異常向量表的定義

2.1 armv8 :異常向量表offset的定義


實(shí)際上有四組表,每組表有四個(gè)異常入口,分別對應(yīng)同步異常,IRQ,FIQ和出錯(cuò)異常。

  • 如果發(fā)生異常并不會(huì)導(dǎo)致exception level切換,并且使用的棧指針是SP_EL0,那么使用第一組異常向量表。
  • 如果發(fā)生異常并不會(huì)導(dǎo)致exception level切換,并且使用的棧指針是SP_EL1/2/3,那么使用第二組異常向量表。
  • 如果發(fā)生異常會(huì)導(dǎo)致exception level切換,并且比目的exception level低一級(jí)的exception
    level運(yùn)行在AARCH64模式,那么使用第三組異常向量表。
  • 如果發(fā)生異常會(huì)導(dǎo)致exception level切換,并且比目的exception level低一級(jí)的exception
    level運(yùn)行在AARCH32模式,那么使用第四組異常向量表。

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

2.2 armv8 : 在linux kernel中異常向量表的實(shí)現(xiàn)定義

我們再來看在linux kernel中定義的異常向量表

.align 11 ENTRY(vectors) (1)kernel_ventry 1, sync_invalid // Synchronous EL1tkernel_ventry 1, irq_invalid // IRQ EL1tkernel_ventry 1, fiq_invalid // FIQ EL1tkernel_ventry 1, error_invalid // Error EL1t (2)kernel_ventry 1, sync // Synchronous EL1hkernel_ventry 1, irq // IRQ EL1hkernel_ventry 1, fiq_invalid // FIQ EL1hkernel_ventry 1, error_invalid // Error EL1h (3)kernel_ventry 0, sync // Synchronous 64-bit EL0kernel_ventry 0, irq // IRQ 64-bit EL0kernel_ventry 0, fiq_invalid // FIQ 64-bit EL0kernel_ventry 0, error_invalid // Error 64-bit EL0 (4) #ifdef CONFIG_COMPATkernel_ventry 0, sync_compat, 32 // Synchronous 32-bit EL0kernel_ventry 0, irq_compat, 32 // IRQ 32-bit EL0kernel_ventry 0, fiq_invalid_compat, 32 // FIQ 32-bit EL0kernel_ventry 0, error_invalid_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 EL0kernel_ventry 0, error_invalid, 32 // Error 32-bit EL0 #endif END(vectors)

第(1)段對應(yīng)的是第一行向量表、第(2)段對應(yīng)的是第二行向量表、第(3)段對應(yīng)的是第三行向量表、第四段對應(yīng)的是第一行向量表.
帶invalid后綴的,都是未實(shí)現(xiàn)的。然后我們抽出實(shí)現(xiàn)了的部分,僅4行:

kernel_ventry 1, sync // Synchronous EL1h kernel_ventry 1, irq // IRQ EL1h kernel_ventry 0, sync // Synchronous 64-bit EL0 kernel_ventry 0, irq // IRQ 64-bit EL0

他們對應(yīng)的函數(shù)分別是:
el1_sync //在kernel mode中調(diào)用svc指令,觸發(fā)同步異常
el1_irq //在kernel mode中觸發(fā)了irq異步異常
el0_sync //在user mode中調(diào)用svc指令,觸發(fā)同步異常
el0_irq //在user mode中觸發(fā)了irq異步異常

2.3 armv8 : 在ATF中異常向量表的實(shí)現(xiàn)定義

在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中的向量表,其實(shí)就是bl31之后使用runtime_exceptions向量表,下面重點(diǎn)介紹下

(注意 : 帶unhandled的都是未實(shí)現(xiàn)的)

  • 用于處理EL0產(chǎn)生異常時(shí)的entire(對應(yīng)第一行向量表)
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
  • 用于處理當(dāng)前ELx產(chǎn)生異常時(shí)的entire(對應(yīng)第二行向量表)
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指令產(chǎn)生的異常,且發(fā)生了EL的遷移的entire(對應(yīng)第三行向量表)
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指令產(chǎn)生的異常,且發(fā)生了EL的遷移的entire(對應(yīng)第四行向量表)
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

2.4 armv8 : 異常向量表總結(jié)和示例:

以異步異常irq為例
(1)、當(dāng)irq產(chǎn)生,如果該irq被target到了EL3,那么將使用VBAR_EL3寄存器中的基地址.
我們知道armv8有四組異常向量表,對應(yīng)表格四行。然后再看使用哪組表:
cpu運(yùn)行在EL0時(shí)產(chǎn)生了irq, 切未發(fā)生EL級(jí)別切換(中斷需被target到EL0),使用第一組表,這個(gè)條件不會(huì)存在.
cpu是在EL3時(shí)產(chǎn)生的irq, 未發(fā)生EL級(jí)別切換,使用第二組表,跳轉(zhuǎn)到VBAR_EL3 + 0x280處,對應(yīng)的irq_sp_elx函數(shù)
cpu運(yùn)行在aarch64級(jí)別,在EL1/EL2時(shí)產(chǎn)生的irq,發(fā)生了EL級(jí)別切換,使用第三組表,跳轉(zhuǎn)到VBAR_EL3 + 0x480處,對應(yīng)的irq_aarch64函數(shù)
cpu運(yùn)行在aarch32級(jí)別,在EL1/EL2時(shí)產(chǎn)生的irq,發(fā)生了EL級(jí)別切換,使用第四組表,跳轉(zhuǎn)到VBAR_EL3 + 0x680處,對應(yīng)的irq_aarch32函數(shù)

(2)、當(dāng)irq產(chǎn)生,如果該irq被target到了EL1,那么將使用VBAR_EL1寄存器中的基地址.
我們知道armv8有四組異常向量表,對應(yīng)表格四行。然后再看使用哪組表:
cpu運(yùn)行在EL0時(shí)產(chǎn)生了irq, 切未發(fā)生EL級(jí)別切換(中斷需被target到EL0),使用第一組表,這個(gè)條件不會(huì)存在.
cpu是在EL1時(shí)產(chǎn)生的irq, 未發(fā)生EL級(jí)別切換,使用第二組表,跳轉(zhuǎn)到VBAR_EL1 + 0x280處,對應(yīng)的el1_irq函數(shù)
cpu運(yùn)行在aarch64級(jí)別,在EL0時(shí)產(chǎn)生的irq,發(fā)生了EL級(jí)別切換,使用第三組表,跳轉(zhuǎn)到VBAR_EL1 + 0x480處,對應(yīng)的el0_irq函數(shù)
cpu運(yùn)行在aarch32級(jí)別,在EL0時(shí)產(chǎn)生的irq,發(fā)生了EL級(jí)別切換,使用第四組表,跳轉(zhuǎn)到VBAR_EL1 + 0x680處,對應(yīng)的irq_invalid函數(shù),也就是未實(shí)現(xiàn)

2.5 armv7 :異常向量表offset的定義


2.6 armv7 : 在linux kernel中異常向量表的實(shí)現(xiàn)定義

.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、總結(jié):

1、在armv7下使用的是data abort、prefetch abort、undefined instruction,在armv8下使用的是SError.
2、在linux kernel中,armv7體系下均已實(shí)現(xiàn)data abort、prefetch abort、undefined instruction異常處理函數(shù),在linux kernel的armv8體系下,沒有實(shí)現(xiàn)SError異常處理
3、在linux kernel的armv8體系中,未實(shí)現(xiàn)fiq函數(shù)
4、
在armv7的向量表offset中,每一個(gè)異常入口都是占4 bytes,是這樣排的:0x1c 0x18 0x10 0x0c 0x08 0x04
在armv8的向量表offset中,每一個(gè)異常入口都是占0x80bytes,是這樣排的00 0x80 0x100 0x180 0x200 0x280…
那么我們在linux kernel中定義的向量表,是怎樣和上面的offset對應(yīng)上的?

W(b) vector_irq W(b) vector_fiq

5、在armv7中,VBAR是banked的,在linux/tee各有一份拷貝. 在armv7中,沒有g(shù)ic的cpu interface。所以armv7的芯片只能使用gicv2.
在gicv2中,FIQ表示安全中斷,給TEE用的,IRQ表示非安全中斷,給Linux用的.

  • 當(dāng)cpu在REE(linux)執(zhí)行時(shí),來了一個(gè)非安全中斷(linux中斷、IRQ), 那么cpu陷入異常,跳轉(zhuǎn)到 "normal VBAR + irq offset“ 處, 也就是linux irq中斷處理函數(shù)
  • 當(dāng)cpu在REE(linux)執(zhí)行時(shí),來了一個(gè)安全中斷(tee中斷、FIQ),那么cpu陷入異常,跳轉(zhuǎn)到 "normal VBAR + fiq offset“ 處,也就是linux fiq中斷處理函數(shù)
  • 當(dāng)cpu在TEE(tee)執(zhí)行時(shí),來了一個(gè)安全中斷(TEE中斷、FIQ), 那么cpu陷入異常,跳轉(zhuǎn)到 "secure VBAR + fiq offset“ 處, 也就是tee irq中斷處理函數(shù)
  • 當(dāng)cpu在TEE(tee)執(zhí)行時(shí),來了一個(gè)非安全中斷(linux中斷、irq),那么cpu陷入異常,跳轉(zhuǎn)到 "secure VBAR + irq offset“ 處,也就是tee fiq中斷處理函數(shù), 在該函數(shù)中會(huì)主動(dòng)將cpu切換到linux進(jìn)行處理.

6、如果在某一時(shí)刻,將發(fā)送給cpu0的IPI_RESCHEDULE(SGI=2)中斷屏蔽了,過了一會(huì)再恢復(fù). 這樣會(huì)對linux系統(tǒng)有影響嗎?
內(nèi)核的中斷屏蔽,是將cpu的PSTATE.I置0了。 local_disable_irq后,gic再產(chǎn)生的中斷,ARM Core不會(huì)去處理,也就不會(huì)清除gic寄存器中的中斷狀態(tài). 等到 local_enable_irq后, 該中斷還會(huì)再送給ARM Core. 所以這種情況中斷不會(huì)丟失…
所以在某一時(shí)刻屏蔽了IPI_RESCHEDULE,也只是屏蔽,也沒有去清gic中相關(guān)寄存器。所以等到恢復(fù)屏蔽后,應(yīng)該也不會(huì)丟中斷

《新程序員》:云原生和全面數(shù)字化實(shí)踐50位技術(shù)專家共同創(chuàng)作,文字、視頻、音頻交互閱讀

總結(jié)

以上是生活随笔為你收集整理的[ARM异常]-linux中(aarch/aarch64)异常向量表介绍的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。