最美情侣中文字幕电影,在线麻豆精品传媒,在线网站高清黄,久久黄色视频

歡迎光臨散文網(wǎng) 會(huì)員登陸 & 注冊(cè)

解析Linux中斷子系統(tǒng)之中斷映射

2023-06-05 19:57 作者:補(bǔ)給站Linux內(nèi)核  | 我要投稿

中斷是當(dāng)前計(jì)算機(jī)系統(tǒng)的基礎(chǔ)功能,也是系統(tǒng)響應(yīng)外設(shè)事件的必備橋梁。不同的架構(gòu)對(duì)中斷控制器有不同的設(shè)計(jì)理念,本文針對(duì)ARM公司提供的通用中斷控制器(GIC,Generic Interrupt Controller)介紹在linux系統(tǒng)中的硬件中斷號(hào)與軟件中斷號(hào)的映射過(guò)程。
首先,我們先來(lái)理解一下硬件中斷號(hào)和軟件中斷號(hào)。

  • 硬件中斷號(hào):GIC為每一個(gè)硬件中斷源都分配了一個(gè)唯一編號(hào),稱為硬件中斷號(hào),用于區(qū)分不同的中斷源。GIC-v3支持的硬件中斷類型和分配的硬件中斷號(hào)范圍如下圖所示。

?IC?分配的中斷號(hào)范圍

  • 軟件中斷號(hào):系統(tǒng)在中斷注冊(cè)和中斷處理過(guò)程中使用到的中斷號(hào)。有的地方也稱為虛擬中斷號(hào)。

為什么要進(jìn)行中斷映射呢?簡(jiǎn)單來(lái)講,軟件可以不需要關(guān)注該中斷在硬件上是哪個(gè)中斷來(lái)源。簡(jiǎn)單的SOC內(nèi)部對(duì)中斷的管理也比較簡(jiǎn)單,通常會(huì)有一個(gè)全局的中斷狀態(tài)寄存器來(lái)記錄外設(shè)中斷,這樣直接將硬件中斷號(hào)線性映射到軟件中斷號(hào)即可。但是隨著芯片技術(shù)的發(fā)展,SOC越來(lái)越復(fù)雜,通常內(nèi)部會(huì)有多個(gè)中斷控制器(比如GIC interrupt controller, GPIO interrupt controller), 每一個(gè)中斷控制器對(duì)應(yīng)多個(gè)中斷號(hào),而硬件中斷號(hào)在不同的中斷控制器上是會(huì)重復(fù)編碼, 這時(shí)僅僅用硬中斷號(hào)已經(jīng)不能唯一標(biāo)識(shí)一個(gè)外設(shè)中斷。尤其在多個(gè)中斷控制器級(jí)聯(lián)的情況下,會(huì)變得更加復(fù)雜。這樣對(duì)軟件編程來(lái)講極不友好,作為軟件工程師,我們更愿意集中精力關(guān)注軟件層面的內(nèi)容。?接下來(lái),我們看看Linux系統(tǒng)中斷映射過(guò)程涉及到的數(shù)據(jù)結(jié)構(gòu),數(shù)據(jù)結(jié)構(gòu)詳細(xì)信息請(qǐng)參看Linux內(nèi)核源碼。

?□ struct irq_desc,中斷描述符,每個(gè)irq都會(huì)在系統(tǒng)中分配一個(gè)該數(shù)據(jù)結(jié)構(gòu),用于描述該irq的相關(guān)信息,包含了irqaction 。

□struct irq_domain/struct irq_chip, 是對(duì)中斷控制器的軟件抽象。

?irq_domain 側(cè)重于對(duì)級(jí)聯(lián)關(guān)系的描述,以及該中斷控制器對(duì)某個(gè)中斷響應(yīng)的描述在struct irq_domain_ops中進(jìn)行組織。irq_domain中的linear_revmap[] 和 revmap_tree 用于該domain中hwirq的map。

irq_chip 側(cè)重對(duì)該中斷控制器響應(yīng)中斷過(guò)程的描述。


□struct irq_data, 是中斷映射的關(guān)鍵數(shù)據(jù)結(jié)構(gòu),映射過(guò)程這要是填充該數(shù)據(jù)結(jié)構(gòu)中的irq與hwirq。irq 為軟件系統(tǒng)分配的虛擬中斷號(hào),hwirq為該domain分配的硬件中斷號(hào)。

?

Linux系統(tǒng)中斷映射過(guò)程涉及到的數(shù)據(jù)結(jié)構(gòu)間的關(guān)系如下:



映射過(guò)程大致分為如下幾個(gè)過(guò)程:

?????1. 系統(tǒng)維護(hù)全局allocated_irqs

?????2. 中斷控制器的初始化

?????3. 軟件中斷號(hào)的獲取與映射

?????4. 硬件中斷號(hào)的獲取與映射

一、系統(tǒng)維護(hù)全局allocated_irqs

在開(kāi)了CONFIG_SPARSE_IRQ的系統(tǒng)中,系統(tǒng)中維護(hù)的全局allocated_irqs有NR_IRQS + 8196 位,每一位代表一個(gè)軟件中斷號(hào)。在virq的申請(qǐng)過(guò)程中,既可以單個(gè)中斷號(hào)申請(qǐng),也可以幾個(gè)中斷號(hào)一起申請(qǐng)。在申請(qǐng)過(guò)程中,從allocated_irqs的低位到高位查詢第一個(gè)連續(xù)N個(gè)空閑的位作為軟件中斷號(hào)。

系統(tǒng)中的allocated_irqs 定義如下:


【文章福利】小編推薦自己的Linux內(nèi)核技術(shù)交流群:【749907784】整理了一些個(gè)人覺(jué)得比較好的學(xué)習(xí)書(shū)籍、視頻資料共享在群文件里面,有需要的可以自行添加哦?。。。ê曨l教程、電子書(shū)、實(shí)戰(zhàn)項(xiàng)目及代碼)? ??



、中斷控制器的初始化

?中斷控制器通過(guò)IRQCHIP_DECLARE 宏注冊(cè)到__irqchip_of_table,系統(tǒng)開(kāi)機(jī)初始化階段 start_kernel() => init_IRQ()=> irqchip_init 調(diào)度到注冊(cè)的gic_of_init() 對(duì)GIC進(jìn)行初始化。



Gic_of_init中注冊(cè)domain相關(guān)的處理函數(shù),其中g(shù)ic_irq_domain_translate()將DTS中解析的中斷信息翻譯得到HWirq。通過(guò)irq_domain_create_tree() 申請(qǐng)一個(gè)domain內(nèi)存,賦值后加入到全局的 irq_domain_list中。同時(shí),設(shè)置中斷處理入口函數(shù)。




、軟件中斷號(hào)的獲取與映射

?kernel_init() => kernel_init_freeable() => do_pre_smp_initcalls()=> do_one_initcall() => arm64_device_init() => of_platform_populate()=> of_platform_bus_create() => of_platform_device_create_pdata() =>of_device_alloc()

?? Of_device_alloc()中,想通過(guò)of_irq_count() 從dts node中計(jì)算出該node中的irq 數(shù)量。然后對(duì)應(yīng)每一個(gè)irq 調(diào)用of_irq_to_resource() => of_irq_get() 獲取軟件中斷號(hào)。of_irq_get() 調(diào)用of_irq_parse_one() 從dts中收集該中斷的相關(guān)信息如觸發(fā)方式,中斷號(hào),中斷類型等信息并記錄在oirq結(jié)構(gòu)體中。然后調(diào)用irq_create_of_mapping()進(jìn)行中斷映射并返回軟件中斷號(hào)。



?irq_create_of_mapping() => irq_create_fwspec_mapping()通過(guò)irq_domain_translate()調(diào)用 gic_of_init()過(guò)程中注冊(cè)的gic_irq_domain_translate() 進(jìn)行翻譯得到hwirq。然后調(diào)用irq_find_mapping() 嘗試通過(guò)domain->revmap_tree 獲取irq_data,從而后去irq。如果獲取到irq說(shuō)明該中斷已完成映射,無(wú)需再進(jìn)行下去。如果沒(méi)有獲取到irq,說(shuō)明該中斷沒(méi)有進(jìn)行過(guò)映射,繼續(xù)往下。irq_create_mapping()中先通過(guò)bitmap_find_next_zero_area() 從allocated_irqs中找到第一個(gè)空閑位 start作為軟件中斷號(hào)。然后申請(qǐng)一個(gè)中斷描述符irq_desc,完成相關(guān)賦值后,將軟件中斷號(hào)作為鍵值把irq_desc 加入到irq_desc_tree 基樹(shù)上。此后,

就可以通過(guò)irq從irq_desc_tree 基樹(shù)上快速獲取對(duì)應(yīng)的irq_desc,從而獲取其他相關(guān)信息。




、硬件中斷號(hào)的獲取與映射

irq_create_fwspec_mapping()先調(diào)用irq_domain_translate()獲取到硬件中斷號(hào),由于預(yù)留了SGI,PPI的中斷號(hào),這里需要加上對(duì)應(yīng)的中斷號(hào)偏移。然后在irq_domain_associate()中通過(guò)給該irq_data->hwirq賦值為獲取到的硬件中斷號(hào),同時(shí)在irq_domain_set_mapping()中進(jìn)行映射建立起hwirq與irq_data之間的聯(lián)系。
irq_domain_set_mapping()中的映射包含兩個(gè)部分,一是在該控制器支持一定的線性映射前提下,當(dāng)hwirq <domain->revmap_size時(shí)進(jìn)行線性映射。否則以hwirq作為鍵值將irq_data放入該domain的revmap_tree基樹(shù)中,搭建起通過(guò)hwirq快速查詢virq的途徑。


五、總結(jié)

通過(guò)以上操作,可以以virq=>從irq_desc_tree中獲取該irq的中斷描述符結(jié)構(gòu)體desc=> 再?gòu)膁esc中獲取irq_data=> 進(jìn)而獲取hwirq;也可以通過(guò)hwirq=>從該domain的revmap_tree中獲取對(duì)應(yīng)的irq_data=> 從而獲取 data->irq。?本文大體講訴了linux kernel中斷映射的解析與映射過(guò)程,并沒(méi)有對(duì)具體的代碼展開(kāi)詳細(xì)的講解。讀者可以根據(jù)梳理的框架進(jìn)行代碼詳情的研究。


原文作者:內(nèi)核工匠




解析Linux中斷子系統(tǒng)之中斷映射的評(píng)論 (共 條)

分享到微博請(qǐng)遵守國(guó)家法律
绥宁县| 龙山县| 湘潭市| 五大连池市| 嘉鱼县| 繁峙县| 阳山县| 宁河县| 仪陇县| 丽水市| 通河县| 鸡东县| 仲巴县| 泗洪县| 永丰县| 本溪市| 从化市| 太谷县| 沅陵县| 伊宁市| 镶黄旗| 资溪县| 灵宝市| 阿瓦提县| 滦南县| 兴业县| 博客| 遂川县| 上栗县| 虎林市| 筠连县| 兴海县| 巴林左旗| 武宁县| 定日县| 江华| 家居| 长海县| 泰来县| 合水县| 九江市|