中斷上下文 和 module_init

來源:互聯網
上載者:User

為什麼在中斷上下文中不能休眠?

1.中斷處理的時候,不應該發生進程切換,因為在中斷context中,唯一能打斷當前中斷handler的只有更高優先順序的中斷,它不會被進程打斷(這點對於softirq,tasklet也一樣,因此這些bottom half也不能休眠),如果在中斷context中休眠,則沒有辦法喚醒它,因為所有的wake_up_xxx都是針對某個進程而言的,而在中斷context中,沒有進程的概念,沒有一個task_struct(這點對於softirq和tasklet一樣),因此真的休眠了,比如調用了會導致block的常式,核心幾乎肯定會死.

2.schedule()在切換進程時,儲存當前的進程上下文(CPU寄存器的值、進程的狀態以及堆棧中的內容),以便以後恢複此進程運行。中斷髮生後,核心會先儲存當前被中斷的進程上下文(在調用中斷處理常式後恢複);
但在中斷處理常式裡,CPU寄存器的值肯定已經變化了吧(最重要的程式計數器PC、堆棧SP等),如果此時因為睡眠或阻塞操作調用了schedule(),則儲存的進程上下文就不是當前的進程context了.所以不可以在中斷處理常式中調用schedule()。

3.2.4核心中schedule()函數本身在進來的時候判斷是否處於中斷上下文:
if(unlikely(in_interrupt()))
BUG();
因此,強行調用schedule()的結果就是核心BUG,但我看2.6.18的核心schedule()的實現卻沒有這句,改掉了.

4.中斷handler會使用被中斷的進程核心堆棧,但不會對它有任何影響,因為handler使用完後會完全清除它使用的那部分堆棧,恢複被中斷前的原貌.

 

module_init和module_exit

void init(void)

{

    init_a();

    init_b();

}

 如果再加入一個初始化函數呢,那麼再init_b()後面再加一行:

init_c();

這樣確實能完成我們的功能,但這樣有一定的問題,就是不能獨立的添加初始化函數,每次添加一個新的函數都要修改init函數,blob中的初始化函數就是完全獨立的,只要用一個宏來修飾一下:

void init_a(void)

{

}

__initlist(init_a, 1);

它是通過這個宏來實現初始化函數列表的呢?

先來看__initlist的定義:

#define __init __attribute__((unused, __section__(".initlist")))

#define __initlist(fn, lvl) \
static initlist_t __init_##fn __init = { \
 magic:    INIT_MAGIC, \
 callback: fn, \
 level:   lvl }

看來就是定義了一個結構體,存了初始化函數的指標,沒什麼特別的。請注意:__section__(".initlist")

這個屬性起什麼作用呢?它告訴連接器這個變數存放在.initlist區段,如果所有的初始化函數都是用這個宏,那麼每個函數會有對應的一個initlist_t結構體變數存放在.initlist區段,也就是說我們可以在.initlist區段找到所有初始化函數的指標。怎麼找到.initlist區段的地址呢?

extern u32 __initlist_start;
extern u32 __initlist_end;

這兩個變數起作用了,__initlist_start是.initlist區段的開始,__initlist_end是結束,通過這兩個變數我們就可以訪問到所有的初始化函數了。

 這兩個變數在那定義的呢?

在一個連接器指令檔裡

 . = ALIGN(4);
 .initlist : {
  __initlist_start = .;
  *(.initlist)
  __initlist_end = .;
 }
這兩個變數的值正好定義在.initlist區段的開始和結束位址,所以我們能通過這兩個變數訪問到所有的初始化函數。

與此類似,核心中也是用到這種方法,所以我們寫驅動的時候比較獨立,不用我們自己添加代碼在一個固定的地方來調用我們自己的初始化函數和退出函數,連接器已經為我們做好了。當然module_init還有其他的特性,比如:我們的初始化函數在完成初始化後,代碼佔用的空間會被釋放


 

5.處於中斷context時候,核心是不可搶佔的,因此,如果休眠,則核心一定掛起

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.