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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > linux >内容正文

linux

LINUX内核中的xx_initcall初始化标号

發布時間:2023/12/10 linux 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 LINUX内核中的xx_initcall初始化标号 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

LINUX內核中的xx_initcall初始化標號

?

田海立@CSDN 2011-07-02

?

????????? LINUX內核中有很多的初始化指示標志postcore_initcall(), arch_initcall(), subsys_initcall(), device_initcall(), etc. 這些起什么作用呢?查閱源代碼(android goldfish-2.6.29)并搜索網上相關文章,對此做一總結。

  • 初始化標號
  • 先看這些宏的定義(定義在文件include/linux/init.h中)

    view plaincopy to clipboardprint?
  • #define?pure_initcall(fn)???????????????__define_initcall("0",fn,0) ??
  • #define?core_initcall(fn)???????????????__define_initcall("1",fn,1) ??
  • #define?core_initcall_sync(fn)??????????__define_initcall("1s",fn,1s) ??
  • #define?postcore_initcall(fn)???????????__define_initcall("2",fn,2) ??
  • #define?postcore_initcall_sync(fn)??????__define_initcall("2s",fn,2s) ??
  • #define?arch_initcall(fn)???????????????__define_initcall("3",fn,3) ??
  • #define?arch_initcall_sync(fn)??????????__define_initcall("3s",fn,3s) ??
  • #define?subsys_initcall(fn)?????????????__define_initcall("4",fn,4) ??
  • #define?subsys_initcall_sync(fn)????????__define_initcall("4s",fn,4s) ??
  • #define?fs_initcall(fn)?????????????????__define_initcall("5",fn,5) ??
  • #define?fs_initcall_sync(fn)????????????__define_initcall("5s",fn,5s) ??
  • #define?rootfs_initcall(fn)?????????????__define_initcall("rootfs",fn,rootfs) ??
  • #define?device_initcall(fn)?????????????__define_initcall("6",fn,6) ??
  • #define?device_initcall_sync(fn)????????__define_initcall("6s",fn,6s) ??
  • #define?late_initcall(fn)???????????????__define_initcall("7",fn,7) ??
  • #define?late_initcall_sync(fn)??????????__define_initcall("7s",fn,7s)??
  • #define pure_initcall(fn) __define_initcall("0",fn,0) #define core_initcall(fn) __define_initcall("1",fn,1) #define core_initcall_sync(fn) __define_initcall("1s",fn,1s) #define postcore_initcall(fn) __define_initcall("2",fn,2) #define postcore_initcall_sync(fn) __define_initcall("2s",fn,2s) #define arch_initcall(fn) __define_initcall("3",fn,3) #define arch_initcall_sync(fn) __define_initcall("3s",fn,3s) #define subsys_initcall(fn) __define_initcall("4",fn,4) #define subsys_initcall_sync(fn) __define_initcall("4s",fn,4s) #define fs_initcall(fn) __define_initcall("5",fn,5) #define fs_initcall_sync(fn) __define_initcall("5s",fn,5s) #define rootfs_initcall(fn) __define_initcall("rootfs",fn,rootfs) #define device_initcall(fn) __define_initcall("6",fn,6) #define device_initcall_sync(fn) __define_initcall("6s",fn,6s) #define late_initcall(fn) __define_initcall("7",fn,7) #define late_initcall_sync(fn) __define_initcall("7s",fn,7s)

    ?

  • __define_initcall
  • 這些宏都用到了__define_initcall(),再看看它的定義(同樣定義在文件include/linux/init.h中)

    view plaincopy to clipboardprint?
  • #define?__define_initcall(level,fn,id)?\ ??
  • ????????static?initcall_t?__initcall_##fn##id?__used?\??
  • ????????__attribute__((__section__(".initcall"?level?".init")))?=?fn??
  • #define __define_initcall(level,fn,id) \static initcall_t __initcall_##fn##id __used \__attribute__((__section__(".initcall" level ".init"))) = fn

    ?

    這其中initcall_t是函數指針,原型如下,

    view plaincopy to clipboardprint?
  • typedef?int?(*initcall_t)(void);??
  • typedef int (*initcall_t)(void);

    ?

    而屬性 __attribute__((__section__())) 則表示把對象放在一個這個由括號中的名稱所指代的section中。

    所以__define_initcall的含義是:

    1) 聲明一個名稱為__initcall_##fn的函數指針;

    2) 將這個函數指針初始化為fn;

    3) 編譯的時候需要把這個函數指針變量放置到名稱為 ".initcall" level ".init"的section中。


    3. ?放置.initcall.init SECTION

    明確了__define_initcall的含義,就知道了是分別將這些初始化標號修飾的函數指針放到各自的section中的。

    SECTION“.initcall”level”.init”被放入INITCALLS(include/asm-generic/vmlinux.lds.h)

    view plaincopy to clipboardprint?
  • #define?INITCALLS???????????????????????????????????????????????????\ ??
  • ????????????*(.initcallearly.init)??????????????????????????????????\??
  • ????????????VMLINUX_SYMBOL(__early_initcall_end)?=?.;???????????????\??
  • ????????????*(.initcall0.init)??????????????????????????????????????\??
  • ????????????*(.initcall0s.init)?????????????????????????????????????\??
  • ????????????*(.initcall1.init)??????????????????????????????????????\??
  • ????????????*(.initcall1s.init)?????????????????????????????????????\??
  • ????????????*(.initcall2.init)??????????????????????????????????????\??
  • ????????????*(.initcall2s.init)?????????????????????????????????????\??
  • ????????????*(.initcall3.init)??????????????????????????????????????\??
  • ????????????*(.initcall3s.init)?????????????????????????????????????\??
  • ????????????*(.initcall4.init)??????????????????????????????????????\??
  • ????????????*(.initcall4s.init)?????????????????????????????????????\??
  • ????????????*(.initcall5.init)??????????????????????????????????????\??
  • ????????????*(.initcall5s.init)?????????????????????????????????????\??
  • ????????????*(.initcallrootfs.init)?????????????????????????????????\??
  • ????????????*(.initcall6.init)??????????????????????????????????????\??
  • ????????????*(.initcall6s.init)?????????????????????????????????????\??
  • ????????????*(.initcall7.init)??????????????????????????????????????\??
  • ????????????*(.initcall7s.init)??
  • #define INITCALLS \*(.initcallearly.init) \VMLINUX_SYMBOL(__early_initcall_end) = .; \*(.initcall0.init) \*(.initcall0s.init) \*(.initcall1.init) \*(.initcall1s.init) \*(.initcall2.init) \*(.initcall2s.init) \*(.initcall3.init) \*(.initcall3s.init) \*(.initcall4.init) \*(.initcall4s.init) \*(.initcall5.init) \*(.initcall5s.init) \*(.initcallrootfs.init) \*(.initcall6.init) \*(.initcall6s.init) \*(.initcall7.init) \*(.initcall7s.init)

    ?

    __initcall_start和__initcall_end以及INITCALLS中定義的SECTION都是在arch/xxx/kernel/vmlinux.lds.S中放在.init段的。

    view plaincopy to clipboardprint?
  • SECTIONS??
  • {??
  • ????????.init?:?{??
  • ????????????????__initcall_start?=?.;??
  • ????????????????????????INITCALLS??
  • ????????????????__initcall_end?=?.;??
  • ????????}??
  • }??
  • SECTIONS {.init : {__initcall_start = .;INITCALLS__initcall_end = .;} }

    ?

    4.?? 初始化.initcallxx.init里的函數

    而這些SECTION里的函數在初始化時被順序執行(init內核線程->do_basic_setup()[main.c#778]->do_initcalls())。

    程序(init/main.c文件do_initcalls()函數)如下,do_initcalls()把.initcallXX.init中的函數按順序都執行一遍。

    view plaincopy to clipboardprint?
  • for?(call?=?__early_initcall_end;?call?<?__initcall_end;?call++)??
  • ????????do_one_initcall(*call);??
  • for (call = __early_initcall_end; call < __initcall_end; call++)do_one_initcall(*call);

    ?

    *************************** 本文完 *****************************

    總結

    以上是生活随笔為你收集整理的LINUX内核中的xx_initcall初始化标号的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。