久久精品精选,精品九九视频,www久久只有这里有精品,亚洲熟女乱色综合一区
    分享

    Linux中PowerPC的中斷原理分析

     ningmei0424 2014-04-16

        在了解中斷處理機(jī)制前,先看一下PowerPC的中斷源,這里使用的是e300c3的內(nèi)核,從E300核的角度,中斷源可分為異常和外部中斷,異常是e300內(nèi)核產(chǎn)生的,如出現(xiàn)非法指令,或者是訪問(wèn)存儲(chǔ)器時(shí)出現(xiàn)TLB Miss等情況。這種情況太復(fù)雜了,沒(méi)有深究,這里所說(shuō)的中斷為外部中斷。所謂外部中斷,就是通過(guò)e300外部引腳產(chǎn)生的中斷。E300的外部中斷主要有:int#, cint#, mcp#. 這三根pin分別對(duì)應(yīng)一般中斷,critical中斷和machine check中斷。

        在設(shè)備驅(qū)動(dòng)過(guò)程中,用戶可以使用request_irq函數(shù)將外設(shè)的中斷服務(wù)例程掛載到外部中斷處理程序中。外部中斷處理程序,可以直接處理硬件中斷,但是request_irq函數(shù)試用軟件中斷號(hào)進(jìn)行掛載,因此linux必然采用了某種方式進(jìn)行軟硬件中斷的映射。

        這里需要了解下中斷向量表的概念,就是它將軟件中斷號(hào)與硬件中斷號(hào)聯(lián)系起來(lái),在系統(tǒng)中,中斷源有很多,當(dāng)某一種中斷發(fā)生時(shí),處理器最早進(jìn)入的是處理函數(shù)的地址,就是中斷向量。每種類(lèi)型對(duì)應(yīng)一個(gè)中斷向量號(hào),一系列的中斷號(hào)構(gòu)成中斷向量表。比如驅(qū)動(dòng)程序關(guān)心的外部中斷,當(dāng)這種中斷發(fā)生時(shí),處理器內(nèi)核(e300)就會(huì)到指定寄存器中去取得中斷處理函數(shù)的入口地址。

        硬件中斷號(hào)是當(dāng)中斷發(fā)生時(shí),處理器從外部的PIC(Programable Interrupt Controller)上讀到的數(shù)值。因?yàn)樵赑owerPC Linux中有dts的概念,驅(qū)動(dòng)程序員需要知道自己所負(fù)責(zé)的設(shè)備對(duì)應(yīng)的device node上的interrupt項(xiàng)如何寫(xiě)的問(wèn)題,這里的interrupt上的數(shù)字就是硬件中斷號(hào)。在Linux系統(tǒng)初始化期間,通過(guò)對(duì)PIC的配置,可以將硬件的連接轉(zhuǎn)化成相應(yīng)的硬件中斷號(hào),例如,8315上的8根外設(shè)中斷線IRQ0~IRQ7,可以通過(guò)PIC的配置,分別映射成的硬件中斷號(hào)為10~18,那么當(dāng)IRQ0上有中斷請(qǐng)求時(shí),處理器通過(guò)讀取PIC,就得到P1所對(duì)應(yīng)的硬件中斷號(hào)為10。這些都是硬件層面的東西,當(dāng)驅(qū)動(dòng)程序安裝它們的中斷處理程序時(shí),是基于軟件中斷號(hào)的,也就是內(nèi)核函數(shù)request_irq中的參數(shù)irq是個(gè)軟件中斷號(hào)。

        軟件中斷號(hào)是Linux下的概念,為了支持多平臺(tái)的關(guān)系,Linux不直接用硬件中斷號(hào)索引irq_desc。所以當(dāng)外部中斷發(fā)生時(shí),在外部中斷入口函數(shù)中會(huì)通過(guò)讀取PIC來(lái)獲得本次中斷的硬件中斷號(hào),獲得硬件中斷號(hào)后,會(huì)將其映射成對(duì)應(yīng)的軟件中斷號(hào)來(lái)索引irq_desc數(shù)組,從而獲得該軟件中斷號(hào)上的中斷處理函數(shù)。顯然,這種硬件中斷號(hào)到軟件中斷號(hào)的映射關(guān)系,應(yīng)該在設(shè)備可以處理中斷前就要建立好了。在Linux PowerPC中,這種映射關(guān)系是由函數(shù)irq_of_parse_and_map(struct device_node *dev, int index)來(lái)完成的。

        注意:在8315中,關(guān)于MSI的硬件中斷號(hào),可以在系統(tǒng)全局中斷向量寄存器SIVCR中查詢。另外,其實(shí),如果沒(méi)有軟件中斷號(hào),設(shè)備驅(qū)動(dòng)程序也能以硬件中斷號(hào)作索引掛載處理程序,從功能上說(shuō)沒(méi)有任何問(wèn)題。軟件中斷號(hào)的引入,是為了硬件中斷號(hào)對(duì)OS透明。這樣處理能減少OS對(duì)硬件平臺(tái)的依賴性。

    下面貼些內(nèi)核的代碼,方便細(xì)細(xì)分析:

        linux使用結(jié)構(gòu)體struct irq_map_entry irq_map[NR_IRQS]完成軟件與硬件的中斷號(hào)映射,一般系統(tǒng)自動(dòng)查找可用的軟件號(hào)以對(duì)應(yīng)請(qǐng)求的硬件中斷號(hào)。

        在使用open firmware的系統(tǒng)中,驅(qū)動(dòng)程序在執(zhí)行ruquest_irq之前要先進(jìn)行軟硬件中斷號(hào)的映射,具體通過(guò)函數(shù):
    irq_of_parse_and_map(struct device_node * dev, int index);
        實(shí)現(xiàn),具體函數(shù)調(diào)用過(guò)程如下:
    irq_create_of_mapping(struct device_node * controller, u32 * inspec, unsigned int intsize);
    irq_create_mapping(struct irq_host *host, irq_hw_number_t hwirq);
        程序除了進(jìn)行軟硬件中斷號(hào)的映射外還需要初始后相應(yīng)結(jié)構(gòu)。
    下面看看與中斷相關(guān)的另外幾個(gè)主要數(shù)據(jù)結(jié)構(gòu):
    1、結(jié)構(gòu)體:struct irq_desc(include/linux/irq.h)

    1. struct irq_desc {  
    2.     unsigned int        irq;  
    3.     struct timer_rand_state *timer_rand_state;  
    4.     unsigned int            *kstat_irqs;  
    5. #ifdef CONFIG_INTR_REMAP  
    6.     struct irq_2_iommu      *irq_2_iommu;  
    7. #endif  
    8.     irq_flow_handler_t  handle_irq;  
    9.     struct irq_chip     *chip;  
    10.     struct msi_desc     *msi_desc;  
    11.     void            *handler_data;  
    12.     void            *chip_data;  
    13.     struct irqaction    *action;    /* IRQ action list */  
    14.     unsigned int        status;     /* IRQ status */  
    15.   
    16.     unsigned int        depth;      /* nested irq disables */  
    17.     unsigned int        wake_depth; /* nested wake enables */  
    18.     unsigned int        irq_count;  /* For detecting broken IRQs */  
    19.     unsigned long       last_unhandled; /* Aging timer for unhandled count */  
    20.     unsigned int        irqs_unhandled;  
    21.     raw_spinlock_t      lock;  
    22. #ifdef CONFIG_SMP  
    23.     cpumask_var_t       affinity;  
    24.     const struct cpumask    *affinity_hint;  
    25.     unsigned int        node;  
    26. #ifdef CONFIG_GENERIC_PENDING_IRQ  
    27.     cpumask_var_t       pending_mask;  
    28. #endif  
    29. #endif  
    30.     atomic_t        threads_active;  
    31.     wait_queue_head_t       wait_for_threads;  
    32. #ifdef CONFIG_PROC_FS  
    33.     struct proc_dir_entry   *dir;  
    34. #endif  
    35.     const char      *name;  
    36. } ____cacheline_internodealigned_in_smp;  

    這個(gè)結(jié)構(gòu)體用來(lái)描述中斷源,是用來(lái)連接硬件中斷和驅(qū)動(dòng)程序中通過(guò)request_irq注冊(cè)的中斷處理函數(shù)之間的橋梁。數(shù)組irq_desc[NR_IRQS](NR_IRQS=225)中每一項(xiàng)都對(duì)應(yīng)一個(gè)相應(yīng)的中斷源,他的每一項(xiàng)對(duì)應(yīng)著中斷向量表中的一項(xiàng),即該數(shù)組的第一項(xiàng)對(duì)應(yīng)著中斷向量表中的第32項(xiàng)(中斷向量號(hào)為0x20),往下依次對(duì)應(yīng)。中斷向量表一共有256項(xiàng)。
    部分成員解釋?zhuān)?br> status:或者是0,或者是從一個(gè)特定的集合中抽取的一個(gè)標(biāo)志位(不太清楚)。這些標(biāo)志位代表了IRQ的狀態(tài)--是否被禁止,有關(guān)IRQ的設(shè)備當(dāng)前是否正被自動(dòng)檢測(cè)等。
    chip:是一個(gè)指向hw_interrupt_type(或者irq_chip)的指針。其中定義的函數(shù)是平臺(tái)相關(guān)的(更具體的,是中斷控制器相關(guān)的),很顯然不同平臺(tái)的中斷控制器擁有不同的操作函數(shù),比如enable, disable, mask, unmask某個(gè)中斷的操作。從平臺(tái)移植的角度,chip屏蔽了底層硬件的不同,使得在內(nèi)核中某些代碼成了平臺(tái)無(wú)關(guān)性。但是對(duì)于不同平臺(tái)的Linux,必須由BSP部分負(fù)責(zé)初始化irq_desc中的chip變量。

    action:是一個(gè)指向由irqaction結(jié)構(gòu)體組成的一個(gè)單向鏈表的頭的指針。若一個(gè)IRQ只被一個(gè)中斷源使用,那么該鏈表的長(zhǎng)度就是1,當(dāng)有多個(gè)設(shè)備共享一個(gè)中斷源時(shí),該鏈表就會(huì)由多個(gè)irqaction結(jié)構(gòu)體組成,下面對(duì)此有介紹。
    depth:irq_desc_t的當(dāng)前用戶的個(gè)數(shù),主要用來(lái)保證事件正在處理的過(guò)程中IRQ不會(huì)被禁止。

    從驅(qū)動(dòng)程序開(kāi)發(fā)者角度,不需要直接調(diào)用chip中的函數(shù)。但是在驅(qū)動(dòng)程序request_irq時(shí),因?yàn)橐趇rq_desc所對(duì)應(yīng)的某一項(xiàng)中安裝中斷處理函數(shù),request_irq函數(shù)原型如下:
    int request_irq(unsigned int irq, irq_handler_t handler, unsigned long irqflags, const char *devname, void *dev_id)

    其中第三個(gè)參數(shù)irqflags會(huì)影響到內(nèi)核對(duì)chip中函數(shù)的調(diào)用,所以從這個(gè)角度而言,了解一些chip相關(guān)的中斷enable/disable/mask/unmask對(duì)驅(qū)動(dòng)程序員是有幫助的。
    2、結(jié)構(gòu)體:struct irqaction(include/linux/interrupt.h)

    1. struct irqaction {  
    2.     irq_handler_t handler;  
    3.     unsigned long flags;  
    4.     const char *name;  
    5.     void *dev_id;  
    6.     struct irqaction *next;  
    7.     int irq;  
    8.     struct proc_dir_entry *dir;  
    9.     irq_handler_t thread_fn;  
    10.     struct task_struct *thread;  
    11.     unsigned long thread_flags;  
    12. };  

    這個(gè)結(jié)構(gòu)體包含了處理一種中斷所需要的各種信息,它代表了內(nèi)核接受到特定IRQ之后應(yīng)該采取的操作。
    主要成員:
    handler—該指針?biāo)赶虻暮瘮?shù)就是在中斷服務(wù)程序,當(dāng)中斷發(fā)生時(shí)內(nèi)核便會(huì)調(diào)用這個(gè)指針指向的函數(shù)。
    flags:該標(biāo)志位可以是0,也可以是:SA_INTERRUPT(表示此中斷處理程序是一個(gè)快速中斷處理程序,在2.6中默認(rèn)情況下沒(méi)有這個(gè)標(biāo)志)SA_SAMPLE_RANDOM(表示這個(gè)中斷對(duì)內(nèi)核池有貢獻(xiàn),我理解為就是在中斷時(shí)產(chǎn)生一些隨機(jī)數(shù),這些隨機(jī)數(shù)被用來(lái)作為加密密匙,因?yàn)橹袛嗍请S機(jī)發(fā)生的,如果某種中斷是有頻率的被產(chǎn)生,那么它就不要設(shè)置此標(biāo)志位,還有就是那種設(shè)備容易被攻擊也不應(yīng)該設(shè)置此標(biāo)志位)SA_SHIRQ(此標(biāo)志位表示允許多個(gè)中斷服務(wù)程序共享一個(gè)中斷號(hào),如不設(shè)則一個(gè)程序?qū)?yīng)一個(gè)中斷線)。
    mask:在x86上不會(huì)用到。
    name:產(chǎn)生中斷的硬件的名字.
    dev_id:該標(biāo)志位主要在共享中斷號(hào)時(shí)使用,即你設(shè)置flags=SA_SHIRQ時(shí),有多個(gè)中斷服務(wù)程序共享一個(gè)中斷號(hào)時(shí),內(nèi)核就需要知道在用完中斷程序后該刪除那個(gè)中斷服務(wù)程序。不共享時(shí)此成員為null。
    next:如果flags=SA_SHIRQ,那么這就是指向?qū)α兄邢乱粋€(gè)struct irqaction結(jié)構(gòu)體的指針,否則為空。
    irq:不用說(shuō)這就是中斷號(hào)了。
    3 結(jié)構(gòu)體:struct hw_interrupt_type(include/linux/irq.h)

    1. struct irq_chip {  
    2.     const char  *name;  
    3.     unsigned int    (*startup)(unsigned int irq);  
    4.     void        (*shutdown)(unsigned int irq);  
    5.     void        (*enable)(unsigned int irq);  
    6.     void        (*disable)(unsigned int irq);  
    7.   
    8.     void        (*ack)(unsigned int irq);  
    9.     void        (*mask)(unsigned int irq);  
    10.     void        (*mask_ack)(unsigned int irq);  
    11.     void        (*unmask)(unsigned int irq);  
    12.     void        (*eoi)(unsigned int irq);  
    13.   
    14.     void        (*end)(unsigned int irq);  
    15.     int     (*set_affinity)(unsigned int irq,  
    16.                     const struct cpumask *dest);  
    17.     int     (*retrigger)(unsigned int irq);  
    18.     int     (*set_type)(unsigned int irq, unsigned int flow_type);  
    19.     int     (*set_wake)(unsigned int irq, unsigned int on);  
    20.   
    21.     void        (*bus_lock)(unsigned int irq);  
    22.     void        (*bus_sync_unlock)(unsigned int irq);  
    23.   
    24.     /* Currently used only by UML, might disappear one day.*/  
    25. #ifdef CONFIG_IRQ_RELEASE_METHOD  
    26.     void        (*release)(unsigned int irq, void *dev_id);  
    27. #endif  
    28.     /* 
    29.      * For compatibility, ->typename is copied into ->name. 
    30.      * Will disappear. 
    31.      */  
    32.     const char  *typename;  
    33. };  

    它是用來(lái)描述中斷控制器的,也就是一個(gè)抽象的中斷控制器,其成員是一系列指向函數(shù)的指針。
    typename:給相應(yīng)的控制器起一個(gè)便于理解的名字。
    startup:允許從給定的控制器的IRQ所產(chǎn)生的事件。(基本上與enable相同)
    shutdown:禁止從給定的控制器的IRQ所產(chǎn)生的事件。(基本上與disable相同)
    以上三個(gè)結(jié)構(gòu)體的關(guān)系可以用下面一張圖來(lái)說(shuō)明IRQ結(jié)構(gòu)間的關(guān)系:

     

    數(shù)組irq_desc_t用來(lái)描述中斷的相關(guān)信息,它有225項(xiàng),每一項(xiàng)代表一個(gè)中斷源,其中字段irq(注意這個(gè)字段就是上圖中的handler字段),此結(jié)構(gòu)體用來(lái)描述中斷控制器,action字段用來(lái)描述處理一種中斷所需要的各種信息,它代表了內(nèi)核接受到特定IRQ之后應(yīng)該采取的操作。

      本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買(mǎi)等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
      轉(zhuǎn)藏 分享 獻(xiàn)花(0

      0條評(píng)論

      發(fā)表

      請(qǐng)遵守用戶 評(píng)論公約

      類(lèi)似文章 更多

      主站蜘蛛池模板: 久久亚洲国产精品成人AV秋霞| 亚洲区色欧美另类图片| 亚洲人成小说网站色在线| 被公疯狂玩弄的年轻人妻| 美女又黄又免费的视频| 国产成人一区二区三区免费 | 无码精品人妻一区二区三区免费看 | 成人网站免费观看永久视频下载| 久久国产成人亚洲精品影院老金| 四虎亚洲精品无码| 国产麻豆剧果冻传媒一区| 人妻久久久一区二区三区| 日本久久99成人网站| 国产精品国产三级国产AV主播 | 国产性一交一乱一伦一色一情 | 免费国产黄线在线观看| 亚洲精品动漫免费二区| 狠狠色丁香婷婷综合尤物| 肉大捧一进一出免费视频| 啊轻点灬大JI巴太粗太长了欧美 | 亚洲AV无码之国产精品网址| 中文字幕V亚洲日本在线电影| 色偷偷AV男人的天堂京东热| 熟妇人妻不卡中文字幕| 精品亚洲精品日韩精品| 老色鬼久久亚洲AV综合| 国产久免费热视频在线观看| 99久久精品国产一区二区蜜芽| 国产成人亚洲精品无码电影不卡| 最近中文字幕国产精选| 久久丫精品国产亚洲AV| 精品乱码一区二区三四五区| 99riav国产精品视频| 欧美亚洲另类 丝袜综合网| 色欲国产精品一区成人精品| 99riav国产精品视频| 狠狠色噜噜狠狠狠狠AV| 久久亚洲道色宗和久久| 国产成人亚洲欧美二区综合| 久久精品中文闷骚内射| 无翼乌工口肉肉无遮挡无码18|