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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

神秘的subsys_initcall【转】

發布時間:2025/5/22 编程问答 25 豆豆
生活随笔 收集整理的這篇文章主要介紹了 神秘的subsys_initcall【转】 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

轉自:http://blog.chinaunix.net/uid-12567959-id-161015.html

在內核代碼里到處都能看到這個subsys_initcall(),而它到底是干什么的呢?讓我們來揭開它的神秘面紗。

?

先來看一段代碼:

---------------------------------------------------------------------

include/linux/init.h

174 /*

175??* Early initcalls run before initializing SMP.

176??*

177??* Only for built-in code, not modules.

178??*/

179 #define early_initcall(fn)????__define_initcall("early",fn,early)

180

181 /*

182??* A "pure" initcall has no dependencies on anything else, and purely

183??* initializes variables that couldn't be statically initialized.

184??*

185??* This only exists for built-in code, not for modules.

186??*/

187 #define pure_initcall(fn)??????????????__define_initcall("",fn,0)

188

189 #define core_initcall(fn)?????????????__define_initcall("1",fn,1)

190 #define core_initcall_sync(fn)??????__define_initcall("1s",fn,1s)

191 #define postcore_initcall(fn)?????????__define_initcall("2",fn,2)

192 #define postcore_initcall_sync(fn)??__define_initcall("2s",fn,2s)

193 #define arch_initcall(fn)?????????????__define_initcall("3",fn,3)

194 #define arch_initcall_sync(fn)??????__define_initcall("3s",fn,3s)

195 #define subsys_initcall(fn)???????????__define_initcall("4",fn,4)

196 #define subsys_initcall_sync(fn)????__define_initcall("4s",fn,4s)

197 #define fs_initcall(fn)???????????????__define_initcall("5",fn,5)

198 #define fs_initcall_sync(fn)????????__define_initcall("5s",fn,5s)

199 #define rootfs_initcall(fn) __define_initcall("rootfs",fn,rootfs)

200 #define device_initcall(fn)???????????__define_initcall("6",fn,6)

201 #define device_initcall_sync(fn)????__define_initcall("6s",fn,6s)

202 #define late_initcall(fn)?????????????__define_initcall("7",fn,7)

203 #define late_initcall_sync(fn)??????__define_initcall("7s",fn,7s)

---------------------------------------------------------------------

類似于subsys_initcall()還有很多,但它們都依賴于__define_initcall(),再來看__define_initcall()的定義:

---------------------------------------------------------------------

include/linux/init.h

?

131 typedef int (*initcall_t)(void);

?

165??*

166??* The `id' arg to __define_initcall() is needed so that multiple

167??* initcalls can point at the same handler without causing duplicate-symbol build errors.

168??*/

169

170 #define __define_initcall(level,fn,id) \

171???????static initcall_t __initcall_##fn##id __used \

172???????__attribute__((__section__(".initcall" level ".init"))) = fn

173

---------------------------------------------------------------------

__define_initcall()宏只是定義一個initcall_t類型的靜態變量,并且聲明要把這個靜態變量放在特定的段里而已。上面我們看到initcall_t即是指向一個無參數有int返回值的函數的指針。

?

許多的子系統都有自己的初始化函數,而這些初始化的函數又根據功能不同被分開在不同的子段里,子段的排列順序則由鏈接決定。為了向后兼容,initcall()把調用,也就是一個個指向初始化函數的函數指針放進設備初始化子段里。

?

在各個平臺的鏈接腳本文件arch/xxx/kernel/vmlinux.lds.S中,我們總能看到下面的語句:

INIT_CALLS

這個宏有如下的定義:

---------------------------------------------------------------------

include/asm-generic/vmlinux.lds.h

606 #define INIT_CALLS???????????????????????????????????????????\

607?????????????????VMLINUX_SYMBOL(__initcall_start) = .;????????\

608?????????????????INITCALLS????????????????????????????????????\

609?????????????????VMLINUX_SYMBOL(__initcall_end) = .;

---------------------------------------------------------------------

INIT_CALLS即是定義一個新的段,而定義段的字段的任務則由宏INITCALLS完成:

---------------------------------------------------------------------

include/asm-generic/vmlinux.lds.h

585 #define INITCALLS????????????????????????????????????????????\

586?????????*(.initcallearly.init)???????????????????????????????\

587?????????VMLINUX_SYMBOL(__early_initcall_end) = .;????????????\

588?????????*(.initcall0.init)???????????????????????????????????\

589?????????*(.initcall0s.init)??????????????????????????????????\

590?????????*(.initcall1.init)???????????????????????????????????\

591?????????*(.initcall1s.init)??????????????????????????????????\

592?????????*(.initcall2.init)???????????????????????????????????\

593?????????*(.initcall2s.init)??????????????????????????????????\

594?????????*(.initcall3.init)???????????????????????????????????\

595?????????*(.initcall3s.init)??????????????????????????????????\

596?????????*(.initcall4.init)???????????????????????????????????\

597?????????*(.initcall4s.init)??????????????????????????????????\

598?????????*(.initcall5.init)???????????????????????????????????\

599?????????*(.initcall5s.init)??????????????????????????????????\

600?????????*(.initcallrootfs.init)??????????????????????????????\

601?????????*(.initcall6.init)???????????????????????????????????\

602?????????*(.initcall6s.init)??????????????????????????????????\

603?????????*(.initcall7.init)???????????????????????????????????\

604?????????*(.initcall7s.init)

---------------------------------------------------------------------

?

而這些初始化函數又是在何時調用的呢?我們看到start_kernel()-> rest_init()-> kernel_init()-> do_basic_setup(void)-> do_initcalls(),而正是do_initcalls()處理了這些初始化函數,其定義為:

---------------------------------------------------------------------

init/main.c

765 extern initcall_t __initcall_start[], __initcall_end[], __early_initcall_end[];

766

767 static void __init do_initcalls(void)

768 {

769?????????initcall_t *fn;

770

771?????????for (fn = __early_initcall_end; fn < __initcall_end; fn++)

772?????????????????do_one_initcall(*fn);

773

774?????????/* Make sure there is no pending stuff from the initcall sequence */

775?????????flush_scheduled_work();

776 }

---------------------------------------------------------------------

do_initcalls()又調用do_one_initcall()函數類處理這些調用。

---------------------------------------------------------------------

init/main.c

715 static char msgbuf[64];

716 static struct boot_trace_call call;

717 static struct boot_trace_ret ret;

718

719 int do_one_initcall(initcall_t fn)

720 {

721??????int count = preempt_count();

722??????ktime_t calltime, delta, rettime;

723

724??????if (initcall_debug) {

725?????????call.caller = task_pid_nr(current);

726?????????printk("calling??%pF @ %i\n", fn, call.caller);

727?????????calltime = ktime_get();

728?????????trace_boot_call(&call, fn);

729?????????enable_boot_trace();

730?????}

731

732?????ret.result = fn();

733

734?????if (initcall_debug) {

735????????disable_boot_trace();

736????????rettime = ktime_get();

737????????delta = ktime_sub(rettime, calltime);

738????????ret.duration = (unsigned long long) ktime_to_ns(delta) >> 10;

739????????trace_boot_ret(&ret, fn);

740????????printk("initcall %pF returned %d after %Ld usecs\n", fn,

741????????ret.result, ret.duration);

742?????}

743

744?????msgbuf[0] = 0;

745

746?????if (ret.result && ret.result != -ENODEV && initcall_debug)

747????????sprintf(msgbuf, "error code %d ", ret.result);

748

749?????if (preempt_count() != count) {

750????????strlcat(msgbuf, "preemption imbalance ", sizeof(msgbuf));

751????????preempt_count() = count;

752?????}

753?????if (irqs_disabled()) {

754????????strlcat(msgbuf, "disabled interrupts ", sizeof(msgbuf));

755????????local_irq_enable();

756?????}

757?????if (msgbuf[0]) {

758????????printk("initcall %pF returned with %s\n", fn, msgbuf);

759?????}

760

761?????return ret.result;

762 }

---------------------------------------------------------------------

總結

以上是生活随笔為你收集整理的神秘的subsys_initcall【转】的全部內容,希望文章能夠幫你解決所遇到的問題。

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

主站蜘蛛池模板: 91网站在线免费看 | 成人h动漫精品一区二区无码 | 午夜天堂精品久久久久 | 亚洲图色av | 成人深夜网站 | 亚洲欧美中文字幕5发布 | 日韩欧美视频 | 韩国av毛片| 欧美成人h版在线观看 | 亚洲综合伊人 | aaaaaav| 国语对白永久免费 | 操啊操 | 日本一级大毛片a一 | china国模大尺度pics | 五月深爱网 | 九九在线观看免费高清版 | 日日日日操 | 成人亚洲玉足脚交系列 | 国产在线xxxx | www.污视频 | 极品探花在线观看 | 日本全黄裸体片 | 一区二区三区免费毛片 | 偷拍自拍一区 | 国产精品二区在线观看 | 日韩中文字幕第一页 | 亚洲天堂高清 | 久久av综合网 | 在线欧美色 | 国产成人综合自拍 | 波多野结衣成人在线 | 蜜臀av性久久久久蜜臀aⅴ四虎 | 日本老妇高潮乱hd | 精品免费在线观看 | 国产在线观看无码免费视频 | 又爽又黄视频 | 三点尽露的大尺度国产 | 91视频在线网站 | 日韩女同强女同hd | 可以看的黄色网 | 色多多视频在线观看 | 久久国产精品网站 | 久久艹这里只有精品 | 亚洲欧美日韩在线 | 亚洲精品成人av | 欧美人交a欧美精品 | 日韩黄色片网站 | 中国人与拘一级毛片 | 一区二区精品视频在线观看 | 天堂色综合 | 又黄又高潮的视频 | 亚洲综合欧美 | 国产精品乱码久久久久久 | 三上悠亚在线观看一区二区 | 亚洲国产一区二区三区a毛片 | 无码国产69精品久久久久网站 | 亚洲一区电影在线观看 | 国产精品123区 | 777午夜 | 中文字幕色片 | 在线看b| www.亚洲人 | 天堂色综合 | a黄色片 | 中文字幕第九页 | 国产精品调教视频 | 有奶水的迷人少妇 | www.av在线视频 | 亚洲一级电影 | 奇米影视777在线观看 | 日本中文字幕免费 | 亚洲综合欧美日韩 | 国产原创91 | 午夜性色福利影院 | 欧美日韩在线中文字幕 | 伊人久久香 | 成人精品视频在线播放 | 成人片免费视频 | 国产盗摄一区二区三区在线 | 精品不卡在线 | 国产美女网站 | 伊人青青久 | 国产一区av在线 | www.色妞| 先锋资源网av | 久久伊人精品 | 肉色欧美久久久久久久免费看 | 国产精品视频一区二区在线观看 | 天天想你在线观看完整版电影免费 | 丰满少妇xbxb毛片日本 | 精品国产1区 | 色就是色网站 | 性欧美videos另类hd | 久久夜色精品国产噜噜亚洲av | 国产精品91一区二区 | 99国产精品国产免费观看 | 国产精品自拍一区 | 亚洲黄色a级片 |