亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频

? 歡迎來到蟲蟲下載站! | ?? 資源下載 ?? 資源專輯 ?? 關于我們
? 蟲蟲下載站

?? 中斷.txt

?? 講解linux內核 系統中斷 部分經典講義
?? TXT
?? 第 1 頁 / 共 5 頁
字號:
while ((long)(jiffies - timer_jiffies) >= 0) {
        struct timer_list *timer;
        if (!tv1.index) {
                int n = 1;
                do {
                        cascade_timers(tvecs[n]);
                } while (tvecs[n]->index == 1 && ++n < NOOF_TVECS);
        }
        while ((timer = tv1.vec[tv1.index])) {
                void (*fn)(unsigned long) = timer->function;
                unsigned long data = timer->data;
                detach_timer(timer);
                timer->next = timer->prev = NULL;
                sti();
                fn(data);
                cli();
        }
        ++timer_jiffies;
        tv1.index = (tv1.index + 1) & TVR_MASK;
}
sti();
}
對run_timer_list函數的說明如下:
關中。
判斷jiffies是否大等于timer_jiffies,若不是,goto 8。
判斷tv1.index是否為0(即此時系統已經掃描過整個tv1的256個timer_list鏈表,又回到的第一個鏈表處,此時需重整TVECS結構),若是,置n為1;若不是,goto 
6。
調用cascade_timers()函數把TVECS[n]中由其index指定的那條鏈表上的timer放到TVECS[n-1]中來。注意:調用cascade_timers()函數后,index已經加1。
判斷TVECS[n]->index是否為1,即原來為0。如果是(表明TVECS[n]上所有都已經掃描一遍,此時需對其后一級的TVECS[++n]調用cascade_timers()進行重整),把n加1,goto 
4。
執行tv1.vec上由tv1->index指定的那條鏈表上的所有timer的服務函數,并把該timer從鏈表中移走。在執行服務函數的過程中,允許中斷。
timer_jiffies加1,tv1->index加1,若tv1->index等于256,則重新置為0,goto 2。
開中,返回。
Linux提供了兩種定時器服務。一種早期的由timer_struct等結構描述,由run_old_times函數處理。另一種“新”的服務由timer_list等結構描述,由add_timer、del_timer、cascade_time和run_timer_list等函數處理。
早期的定時器服務利用如下數據結構:
struct timer_struct {
    unsigned long expires;  /*本定時器被喚醒的時刻 */
    void (*fn)(void);       /* 定時器喚醒后的處理函數 */
}
struct timer_struct timer_table[32];  /*最多可同時啟用32個定時器 */
unsigned long timer_active;        /* 每位對應一定時器,置1表示啟用 */
新的定時器服務依靠鏈表結構突破了32個的限制,利用如下的數據結構:
struct timer_list {
    struct timer_list *next;
    struct timer_list *prev;
    unsigned long expires;
    unsigned long data;          /* 用來存放當前進程的PCB塊的指針,可作為參數傳
    void (*function)(unsigned long);  給function */
}

表示上述數據結構的圖示如下:

    在這里,順便簡單介紹一下舊的timer機制的運作情況。
    系統在每次調用函數do_bottom_half時,都會調用一次函數run_old_timers()。
函數run_old_timers()
該函數處理的很簡單,只不過依次掃描timer_table中的32個定時器,若掃描到的定時器已經到期,并且已經被激活,則執行該timer的服務函數。
間隔定時器itimer
系統為每個進程提供了三個間隔定時器。當其中任意一個定時器到期時,就會發出一個信號給進程,同時,定時器重新開始運作。三種定時器描述如下:
ITIMER_REAL  真實時鐘,到期時送出SIGALRM信號。
ITIMER_VIRTUAL  僅在進程運行時的計時,到期時送出SIGVTALRM信號。
ITIMER_PROF  
不僅在進程運行時計時,在系統為進程運作而運行時它也計時,與ITIMER_VIRTUAL對比,該定時器通常為那些在用戶態和核心態空間運行的應用所花去的時間計時,到期時送出SIGPROF信號。
與itimer有關的數據結構定義如下:
struct timespec {
        long        tv_sec;                /* seconds */
        long        tv_nsec;        /* nanoseconds */
};
struct timeval {
        int        tv_sec;                /* seconds */
        int        tv_usec;        /* microseconds */
};
struct  itimerspec {
        struct  timespec it_interval;    /* timer period */
        struct  timespec it_value;       /* timer expiration */
};
struct        itimerval {
        struct        timeval it_interval;        /* timer interval */
        struct        timeval it_value;        /* current value */
};
這三種定時器在task_struct中定義:
struct task_struct {
    ……
    unsigned long timeout;
    unsigned long it_real_value,it_prof_value,it_virt_value;
    unsigned long it_real_incr,it_prof_incr,it_virt_incr;
    struct timer_list real_timer;
    ……
}
在進程創建時,系統把it_real_fn函數的入口地址賦給real_timer.function。(見sched.h)
我們小組分析了三個系統調用:sys_getitimer,sys_setitimer,sys_alarm。
在這三個系統調用中,需用到以下一些函數:
函數static int _getitimer(int which, struct itimerval *value)
該函數的運行過程大致如下:
根據傳進的參數which按三種itimer分別處理:
若是ITIMER_REAL,則設置interval為current進程的it_real_incr,val設置為0;判斷current進程的real_timer有否設置并掛入TVECS結構中,若有,設置val為current進程real_timer的expires,并把real_timer重新掛到TVECS結構中,接著把val與當前jiffies作比較,若小等于當前jiffies,則說明該real_timer已經到期,于是重新設置val為當前jiffies的值加1。最后把val減去當前jiffies的值,goto 
2。
若是ITIMER_VIRTUAL,則分別設置interval,val的值為current進程的it_virt_incr、it_virt_value,goto 
2。
若是ITIMER_PROF,則分別設置interval,val的值為current進程的it_prof_incr、it_prof_value,goto 2。
   (2)調用函數jiffiestotv把val,interval的jiffies值轉換為timeval,返回0。
函數 int _setitimer(int which, struct itimerval *value, struct itimerval *ovalue)
該函數的運行過程大致如下:
調用函數tvtojiffies把value中的interval和value轉換為jiffies i 和 j。
判斷指針ovalue是否為空,若空,goto ;若不空,則把由which指定類型的itimer存入ovalue中,若存放不成功,goto 4;
根據which指定的itimer按三種類型分別處理:
若是ITIMER_REAL,則從TVECS結構中取出current進程的real_timer,并重新設置current進程的it_real_value和it_real_incr為j和i。若j等于0,goto 
4;若不等于0,則把當前jiffies的值加上定時器剩余時間j,得到觸發時間。若i小于j,則表明I已經溢出,應該重新設為ULONG_MAX。最后把current進程的real_timer的expires設為i,把設置過的real_timer重新加入TVECS結構,goto 
4。
若是ITIMER_VIRTUAL,則設置current進程的it-_virt_value和it_virt_incr為j和i。
若是ITIMER_PROF,則設置current進程的it-_prof_value和it_prof_incr為j和i。
   (4)返回0。
函數verify_area(int type, const void *addr, unsigned long size)
該函數的主要功能是對以addr為始址的,長度為size的一塊存儲區是否有type類型的操作權利。
函數memcpy_tofs(to, from, n)
該函數的主要功能是從以from為始址的存儲區中取出長度為n的一塊數據放入以to為始址的存儲區。
函數memcpy_fromfs(from, to, n)
該函數的主要功能是從以from為始址的存儲區中取出長度為n的一塊數據放入以to為始址的存儲區。
函數memset((char*)&set_buffer, 0, sizeof(set_buffer))
該函數的主要功能是把set_buffer中的內容置為0,在這里,即把it_value和it_interval置為0。
現在,我簡單介紹一下這三個系統調用:
系統調用sys_getitimer(int which, struct itimerval *value)
首先,若value為NULL,則返回-EFAULT,說明這是一個bad address。
其次,把which類型的itimer取出放入get_buffer。
再次,若存放成功,再確認對value的寫權利。
最后,則把get_buffer中的itimer取出,拷入value。
系統調用sys_setitimer(int which, struct itimerval *value,struct itimerval *ovalue)
首先,判斷value是否為NULL,若不是,則確認對value是否有讀的權利,并把set_buffer中的數據拷入value;若value為NULL,則把set_buffer中的內容置為0,即把it_value和it_interval置為0。
其次,判斷ovalue是否為NULL,若不是,則確認對ovalue是否有寫的權利。
再次,調用函數_setitimer設置由which指定類型的itimer。
最后,調用函數memcpy_tofs把get_buffer中的數據拷入ovalue,返回。
系統調用sys_alarm(unsigned int seconds)
該系統調用重新設置進程的real_itimer,若seconds為0,則把原先的alarm定時器刪掉。并且設interval為0,故只觸發一次,并把舊的real_timer存入oldalarm,并返回oldalarm。
[目錄]




from aka


[目錄]




硬件中斷

硬件中斷
硬件中斷概述
中斷可以用下面的流程來表示:
中斷產生源 --> 中斷向量表 (idt) --> 中斷入口 ( 一般簡單處理后調用相應的函數) --->do_IRQ--> 后續處理(軟中斷等工作)
具體地說,處理過程如下:
中斷信號由外部設備發送到中斷芯片(模塊)的引腳
中斷芯片將引腳的信號轉換成數字信號傳給CPU,例如8259主芯片引腳0發送的是0x20
CPU接收中斷后,到中斷向量表IDT中找中斷向量
根據存在中斷向量中的數值找到向量入口
由向量入口跳轉到一個統一的處理函數do_IRQ
在do_IRQ中可能會標注一些軟中斷,在執行完do_IRQ后執行這些軟中斷。
下面一一介紹。
8259芯片
本文主要參考周明德《微型計算機系統原理及應用》和billpan的相關帖子
1.中斷產生過程
(1)如果IR引腳上有信號,會使中斷請求寄存器(Interrupt Request Register,IRR)相應的位置位,比如圖中, IR3, IR4, 
IR5上有信號,那么IRR的3,4,5為1
(2)如果這些IRR中有一個是允許的,也就是沒有被屏蔽,那么就會通過INT向CPU發出中斷請求信號。屏蔽是由中斷屏蔽寄存器(Interrupt Mask 
Register,IMR)來控制的,比如圖中位3被置1,也就是IRR位3的信號被屏蔽了。在圖中,還有4,5的信號沒有被屏蔽,所以,會向CPU發出請求信號。
(3)如果CPU處于開中斷狀態,那么在執行指令的最后一個周期,在INTA上做出回應,并且關中斷.
(4)8259A收到回應后,將中斷服務寄存器(In-Service Register)置位,而將相應的IRR復位:
8259芯片會比較IRR中的中斷的優先級,如上圖中,由于IMR中位3處于屏蔽狀態,所以實際上只是比較IR4,I5,缺省情況下,IR0最高,依次往下,IR7最低(這種優先級可以被設置),所以上圖中,ISR被設置為4.
(5)在CPU發出下一個INTA信號時,8259將中斷號送到數據線上,從而能被CPU接收到,這里有個問題:比如在上圖中,8259獲得的是數4,但是CPU需要的是中斷號(并不為4),從而可以到idt找相應的向量。所以有一個從ISR的信號到中斷號的轉換。在Linux的設置中,4對應的中斷號是0x24.
(6)如果8259處于自動結束中斷(Automatic End of Interrupt 
AEOI)狀態,那么在剛才那個INTA信號結束前,8259的ISR復位(也就是清0),如果不處于這個狀態,那么直到CPU發出EOI指令,它才會使得ISR復位。
2.一些相關專題
(1)從8259
在x86單CPU的機器上采用兩個8259芯片,主芯片如上圖所示,x86模式規定,從8259將它的INT腳與主8259的IR2相連,這樣,如果從8259芯片的引腳IR8-IR15上有中斷,那么會在INT上產生信號,主8259在IR2上產生了一個硬件信號,當它如上面的步驟處理后將IR2的中斷傳送給CPU,收到應答后,會通過CAS通知從8259芯片,從8259芯片將IRQ中斷號送到數據線上,從而被CPU接收。
由此,我猜測它產生的所有中斷在主8259上優先級為2,不知道對不對。
(2)關于屏蔽
從上面可以看出,屏蔽有兩種方法,一種作用于CPU, 通過清除IF標記,使得CPU不去響應8259在INT上的請求。也就是所謂關中斷。
另一種方法是,作用于8259,通過給它指令設置IMR,使得相應的IRR不參與ISR(見上面的(4)),被稱為禁止(disable),反之,被稱為允許(enable).
每次設置IMR只需要對端口0x21(主)或0xA1(從)輸出一個字節即可,字節每位對應于IMR每位,例如:
outb(cached_21,0x21);
為了統一處理16個中斷,Linux用一個16位cached_irq_mask變量來記錄這16個中斷的屏蔽情況:
static unsigned int cached_irq_mask = 0xffff;
為了分別對應于主從芯片的8位IMR,將這16位cached_irq_mask分成兩個8位的變量:
#define __byte(x,y) (((unsigned char *)&(y))[x])
#define cached_21 (__byte(0,cached_irq_mask))
#define cached_A1 (__byte(1,cached_irq_mask))
在禁用某個irq的時候,調用下面的函數:
void disable_8259A_irq(unsigned int irq){
unsigned int mask = 1 << irq;
unsigned long flags;
spin_lock_irqsave(&i8259A_lock, flags);
cached_irq_mask |= mask;                /*-- 對這16位變量設置 */
if (irq & 8)                            /*-- 看是對主8259設置還是對從芯片設置 */
outb(cached_A1,0xA1);                   /*-- 對從8259芯片設置 */
else
outb(cached_21,0x21);                   /*-- 對主8259芯片設置 */
spin_unlock_irqrestore(&i8259A_lock, flags);
}

(3)關于中斷號的輸出

8259在ISR里保存的只是irq的ID,但是它告訴CPU的是中斷向量ID,比如ISR保存時鐘中斷的ID 
0,但是在通知CPU卻是中斷號0x20.因此需要建立一個映射。在8259芯片產生的IRQ號必須是連續的,也就是如果irq0對應的是中斷向量0x20,那么irq1對應的就是0x21,...
在i8259.c/init_8259A()中,進行設置:
outb_p(0x11, 0x20); /* ICW1: select 8259A-1 init */
outb_p(0x20 + 0, 0x21); /* ICW2: 8259A-1 IR0-7 mapped to 0x20-0x27 */
outb_p(0x04, 0x21); /* 8259A-1 (the master) has a slave on IR2 */

?? 快捷鍵說明

復制代碼 Ctrl + C
搜索代碼 Ctrl + F
全屏模式 F11
切換主題 Ctrl + Shift + D
顯示快捷鍵 ?
增大字號 Ctrl + =
減小字號 Ctrl + -
亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频
欧美日韩免费观看一区二区三区| 色综合久久久网| 波多野结衣亚洲| 精品欧美黑人一区二区三区| 亚洲欧美色综合| 99综合电影在线视频| 26uuuu精品一区二区| 久久国产精品色| 91在线视频网址| 久久久高清一区二区三区| 精品一区二区三区久久久| 69久久99精品久久久久婷婷 | 老色鬼精品视频在线观看播放| 欧美在线看片a免费观看| 一区二区三区四区不卡在线| 欧美日韩精品欧美日韩精品| 亚洲人成伊人成综合网小说| 国产·精品毛片| 国产精品欧美极品| 成人app软件下载大全免费| 国产欧美日韩在线视频| 99久久99久久久精品齐齐| 亚洲精品成人少妇| 欧美一区二区三区公司| 麻豆国产91在线播放| 在线精品视频小说1| 蜜桃视频第一区免费观看| 久久精品一区四区| 欧美午夜精品免费| 精品一区二区三区久久| 国产精品夫妻自拍| 欧美伦理影视网| 国产精品一级在线| 一区二区三区欧美| 久久精品亚洲精品国产欧美kt∨| 人禽交欧美网站| 久久久久久久电影| 欧美日韩一区视频| 丁香婷婷综合激情五月色| 五月激情六月综合| 亚洲国产高清在线观看视频| 欧美一级在线观看| 欧美日韩视频在线一区二区| 国产精品系列在线播放| 午夜激情久久久| 亚洲精品你懂的| 国产午夜亚洲精品理论片色戒| 日韩精品资源二区在线| 国产在线精品一区在线观看麻豆| 亚洲国产日韩a在线播放性色| 91精品国产aⅴ一区二区| 99国产精品久久久久| 99视频在线观看一区三区| 国产久卡久卡久卡久卡视频精品| 一区在线观看视频| 国产精品乱码妇女bbbb| 亚洲人成网站影音先锋播放| 久久久精品影视| 久久综合久久综合久久综合| 日韩欧美一级特黄在线播放| 3d动漫精品啪啪1区2区免费| 欧美日韩日本视频| 欧美一区二区在线免费播放| 欧美精品一级二级| 欧美人体做爰大胆视频| 3atv一区二区三区| 欧美成人精品1314www| 久久久久久久久伊人| 久久嫩草精品久久久久| 久久精品一区二区三区四区| 久久―日本道色综合久久| 欧美一级黄色片| 日韩免费高清av| 久久久久久麻豆| 国产精品久久看| 免费观看在线综合色| 99国产精品99久久久久久| 91精品国产欧美日韩| 国产精品乱子久久久久| 国产精品1区2区| 精品福利二区三区| 首页综合国产亚洲丝袜| 高清不卡一区二区| 91精品国产麻豆| 亚洲国产另类av| 91麻豆免费观看| 国产精品久久久久影院| 国产精品一区二区x88av| 久久亚洲一区二区三区四区| 欧美aaa在线| 欧美精品一级二级| 午夜视频久久久久久| 欧美午夜精品电影| 亚洲一区二区视频在线| 欧美三级电影在线观看| 亚洲精品视频免费看| 99国产一区二区三精品乱码| 久久这里只精品最新地址| 国产在线日韩欧美| 久久天堂av综合合色蜜桃网| 国产在线精品国自产拍免费| 精品国产免费人成电影在线观看四季| 视频精品一区二区| 精品国产区一区| 国产精品一区二区在线播放| 亚洲欧美日韩在线| 欧美日韩小视频| 国产成人一级电影| 亚洲一区二区欧美| 日韩精品一区二区三区老鸭窝| 国产精品白丝jk白祙喷水网站 | a4yy欧美一区二区三区| 亚洲视频在线一区观看| 欧美日韩国产综合草草| 国产一区二区三区不卡在线观看 | 欧美男生操女生| 国产成人精品综合在线观看| 国产精品麻豆久久久| 欧美精品视频www在线观看| 国产一区二区三区精品视频| 亚洲第一久久影院| 欧美三级视频在线观看| 国产成人自拍在线| 九一久久久久久| 五月婷婷综合网| 亚洲日本乱码在线观看| 欧美精品一区二区三区高清aⅴ| 色成人在线视频| 成人免费的视频| 国产高清在线精品| 日本女优在线视频一区二区| 一区二区三区欧美| 亚洲免费在线视频一区 二区| 精品处破学生在线二十三| 欧美日韩精品三区| 欧美体内she精高潮| 欧美日韩日本视频| 精品视频123区在线观看| 色婷婷av一区二区| 色呦呦日韩精品| 日韩午夜精品电影| 在线不卡一区二区| 日韩欧美一级二级| 欧美xxxxxxxxx| 国产日韩v精品一区二区| 日韩你懂的电影在线观看| 日韩精品中文字幕一区二区三区| 9191久久久久久久久久久| 欧美一区二区精品在线| 日韩欧美高清一区| 国产视频在线观看一区二区三区| 久久精品男人天堂av| 国产精品拍天天在线| 亚洲少妇中出一区| 天堂精品中文字幕在线| 国内精品视频一区二区三区八戒| 国产精品一区专区| 一本高清dvd不卡在线观看| 欧美一级黄色片| 亚洲国产精品精华液ab| 夜夜嗨av一区二区三区中文字幕| 日韩激情一二三区| 91美女片黄在线观看91美女| 日韩三级电影网址| 国产精品不卡在线| 天天操天天综合网| 成人综合在线观看| 欧美精品 国产精品| 亚洲欧美综合在线精品| 日韩电影在线看| 99re热视频这里只精品| 欧美一级日韩一级| 一区二区三区资源| 狠狠色丁香婷综合久久| 欧美专区亚洲专区| 国产精品乱码久久久久久| 国产精品亚洲视频| 精品国产伦一区二区三区观看体验| 亚洲摸摸操操av| 国产99一区视频免费 | 欧美亚洲综合久久| 中文成人综合网| 欧美亚洲综合色| 日韩美女久久久| 97久久精品人人澡人人爽| 久久精品人人做人人爽人人| 国模冰冰炮一区二区| 久久嫩草精品久久久精品一| 韩国精品免费视频| 精品国产成人系列| 免费成人美女在线观看| 欧美亚洲国产一区二区三区 | 欧美日韩国产在线播放网站| 亚洲精品菠萝久久久久久久| 91福利社在线观看| 午夜精品免费在线观看| 日韩三级.com| 国产精品一区一区三区| 亚洲国产成人一区二区三区| av在线免费不卡|