資料介紹
不知道在什幺時(shí)候,Linux 出現(xiàn)了 module 這種東西,的確,它是 Linux 的一大革新。有了 module 之后,寫 device driver 不再是一項(xiàng)惡夢(mèng),修改 kernel 也不再是一件痛苦的事了。因?yàn)槟悴恍枰看我獪y(cè)試 driver 就重新 compile kernel 一次。那簡直是會(huì)累死人。Module 可以允許我們動(dòng)態(tài)的改變 kernel,加載 device driver,而且它也能縮短我們 driver development 的時(shí)間。在這篇文章里,我將要跟各位介紹一下 module 的原理,以及如何寫一個(gè) module。
module 翻譯成中文就是模塊,不過,事實(shí)上去翻譯這個(gè)字一點(diǎn)都沒意義。在講模塊之前,我先舉一個(gè)例子。相信很多人都用過 RedHat。在 RedHat 里,我們可以執(zhí)行 sndconfig,它可以幫我們 config 聲卡。config 完之后如果捉得到你的聲卡,那你的聲卡馬上就可以動(dòng)了,而且還不用重新激活計(jì)算機(jī)。這是怎幺做的呢 ? 就是靠module。module 其實(shí)是一般的程序。但是它可以被動(dòng)態(tài)載到 kernel 里成為 kernel的一部分。載到 kernel 里的 module 它具有跟 kernel 一樣的權(quán)力。可以 access 任何 kernel 的 data structure。你聽過 kdebug 嗎 ? 它是用來 debug kernel 的。它就是先將它本身的一個(gè) module 載到 kernel 里,而在 user space 的 gdb 就可以經(jīng)由跟這個(gè) module 溝通,得知 kernel 里的 data structure 的值,除此之外,還可以經(jīng)由載到 kernel 的 module 去更改 kernel 里 data structure。
我們知道,在寫 C 程序的時(shí)候,一個(gè)程序只能有一個(gè) main。Kernel 本身其實(shí)也是一個(gè)程序,它本身也有個(gè) main,叫 start_kernel()。當(dāng)我們把一個(gè) module 載到 kernel 里的時(shí)候,它會(huì)跟 kernel 整合在一起,成為 kernel 的一部分。請(qǐng)各位想想,那 module 可以有 main 嗎 ? 答案很明顯的,是 No。理由很簡單。一個(gè)程序只能有一個(gè) main。在使用 module 時(shí),有一點(diǎn)要記住的是 module 是處于被動(dòng)的角色。它是提供某些功能讓別人去使用的。
Kernel 里有一個(gè)變量叫 module_list,每當(dāng) user 將一個(gè) module 載到 kernel 里的時(shí)候,這個(gè) module 就會(huì)被記錄在 module_list 里面。當(dāng) kernel 要使用到這個(gè) module 提供的 function 時(shí),它就會(huì)去 search 這個(gè) list,找到 module,然后再使用其提供的 function 或 variable。每一個(gè) module 都可以 export 一些 function 或變量來讓別人使用。除此之外,module 也可以使用已經(jīng)載到 kernel 里的 module 提供的 function。這種情形叫做 module stack。比方說,module A 用到 module B 的東西,那在加載 module A 之前必須要先加載 module B。否則 module A 會(huì)無法加載。除了 module 會(huì) export 東西之外,kernel 本身也會(huì) export 一些 function 或 variable。同樣的,module 也可以使用 kernel 所 export 出來的東西。由于大家平時(shí)都是撰寫 user space 的程序,所以,當(dāng)突然去寫 module 的時(shí)候,會(huì)把平時(shí)寫程序用的 function 拿到 module 里使用。像是 printf 之類的東西。我要告訴各位的是,module 所使用的 function 或 variable,要嘛就是自己寫在 module 里,要嘛就是別的 module 提供的,再不就是 kernel 所提供的。你不能使用一般 libc 或 glibc所提供的 function。像 printf 之類的東西。這一點(diǎn)可能是各位要多小心的地方。(也許你可以先 link 好,再載到 kernel,我好象試過,但是忘了)
剛才我們說到 kernel 本身會(huì) export 出一些 function 或 variable 來讓 module 使用,但是,我們不是萬能的,我們?cè)蹒壑?kernel 有開放那里東西讓我們使用呢 ? Linux 提供一個(gè) command,叫 ksyms,你只要執(zhí)行 ksyms -a 就可以知道 kernel 或目前載到 kernel 里的 module 提供了那些 function 或 variable。底下是我的系統(tǒng)的情形:
c0216ba0 drive_info_R744aa133
c01e4a44 boot_cpu_data_R660bd466
c01e4ac0 EISA_bus_R7413793a
c01e4ac4 MCA_bus_Rf48a2c4c
c010cc34 __verify_write_R203afbeb
。 . 。 . 。
在 kernel 里,有一個(gè) symbol table 是用來記錄 export 出去的 function 或 variable。除此之外,也會(huì)記錄著那個(gè) module export 那些 function。上面幾行中,表示 kernel 提供了 drive_info 這個(gè) function/variable。所以,我們可以在 kernel 里直接使用它,等載到 kernel 里時(shí),會(huì)自動(dòng)做好 link 的動(dòng)作。由此,我們可以知道,module 本身其實(shí)是還沒做 link 的一些 object code。一切都要等到 module 被加載 kernel 之后,link 才會(huì)完成。各位應(yīng)該可以看到 drive_info 后面還接著一些奇怪的字符串。_R744aa133,這個(gè)字符串是根據(jù)目前 kernel 的版本再做些 encode 得出來的結(jié)果。為什幺額外需要這一個(gè)字符串呢 ?
Linux 不知道從那個(gè)版本以來,就多了一個(gè) config 的選項(xiàng),叫做 Set version number in symbols of module。這是為了避免對(duì)系統(tǒng)造成不穩(wěn)定。我們知道 Linux 的 kernel 更新的很快。在 kernel 更新的過程,有時(shí)為了效率起見,會(huì)對(duì)某些舊有的 data structure 或 function 做些改變,而且一變可能有的 variable 被拿掉,有的 function 的 prototype 跟原來的都不太一樣。如果這種情形發(fā)生的時(shí)候,那可能以前 2.0.33 版本的 module 拿到 2.2.1 版本的 kernel 使用,假設(shè)原來 module 使用了 2.0.33 kernel 提供的變量叫 A,但是到了 2.2.1 由于某些原因必須把 A 都設(shè)成 NULL。那當(dāng)此 module 用在 2.2.1 kernel 上時(shí),如果它沒去檢查 A 的值就直接使用的話,就會(huì)造成系統(tǒng)的錯(cuò)誤。也許不會(huì)整個(gè)系統(tǒng)都死掉,但是這個(gè) module 肯定是很難發(fā)揮它的功能。為了這個(gè)原因,Linux 就在 compile module 時(shí),把 kernel 版本的號(hào)碼 encode 到各個(gè) exported function 和 variable 里。
所以,剛才也許我們不應(yīng)該講 kernel 提供了 drive_info,而應(yīng)該說 kernel 提供了 driver_info_R744aa133 來讓我們使用。這樣也許各位會(huì)比較明白。也就是說,kernel 認(rèn)為它提供的 driver_info_R744aa133 這個(gè)東西,而不是 driver_info。所以,我們可以發(fā)現(xiàn)有的人在加載 module 時(shí),系統(tǒng)都一直告訴你某個(gè) function 無法 resolved。這就是因?yàn)?kernel 里沒有你要的 function,要不然就是你的 module 里使用的 function 跟 kernel encode 的結(jié)果不一樣。所以無法 resolve。解決方式,要嘛就是將 kernel 里的 set version 選項(xiàng)關(guān)掉,要嘛就是將 module compile 成 kernel 有辦法接受的型式。
那有人就會(huì)想說,如果 kernel 認(rèn)定它提供的 function 名字叫做 driver_info_R744aa133 的話,那我們寫程序時(shí),是不是用到這個(gè) funnction 的地方都改成 driver_info_R744aa133 就可以了。答案是 Yes。但是,如果每個(gè) function 都要你這樣寫,你不會(huì)覺得很煩嗎 ? 比方說,我們?cè)趯?driver 時(shí),很多人都會(huì)用到 printk 這個(gè) function。這是 kernel 所提供的 function。它的功能跟 printf 很像。用法也幾乎都一樣。是 debug 時(shí)很好用的東西。如果我們 module 里用了一百次 printk,那是不是我們也要打一百次的 printk_Rdd132261 呢 ? 當(dāng)然不是,聰明的人馬上會(huì)想到用 #define printk printk_Rdd132261 就好了嘛。所以啰,Linux 很體貼的幫我們做了這件事。
如果各位的系統(tǒng)有將 set version 的選項(xiàng)打開的話,那大家可以到 /usr/src/linux/include/linux/modules 這個(gè)目錄底下。這個(gè)目錄底下有所多的 。.ver檔案。這些檔案其實(shí)就是用來做 #define 用的。我們來看看 ksyms.ver 這個(gè)檔案里,里面有一行是這樣子的 :
#define printk _set_ver(printk)
set_ver 是一個(gè) macro,就是用來在 printk 后面加上 version number 的。有興趣的朋友可以自行去觀看這個(gè) macro 的寫法。用了這些 ver 檔,我們就可以在 module 里直接使用 printk 這樣的名字了。而這些 ver 檔會(huì)自動(dòng)幫我們做好 #define 的動(dòng)作。可是,我們可以發(fā)現(xiàn)這個(gè)目錄有很多很多的 ver 檔。有時(shí)候,我們?cè)蹒壑牢覀円艚械?function 是在那個(gè) ver 檔里有定義呢 ? Linux 又幫我們做了一件事。/usr/src/linux/include/linux/modversions.h 這個(gè)檔案已經(jīng)將全部的 ver 檔都加進(jìn)來了。所以在我們的 module 里只要 include 這個(gè)檔,那名字的問題都解決了。但是,在此,我們奉勸各位一件事,不要將 modversions.h 這個(gè)檔在 module 里 include 進(jìn)來,如果真的要,那也要加上以下數(shù)行:
#ifdef MODVERSIONS
#include 《linux/modversions.h》;
#endif
加入這三行的原因是,避免這個(gè) module 在沒有設(shè)定 kernel version 的系統(tǒng)上,將 modversions.h 這個(gè)檔案 include 進(jìn)來。各位可以去試試看,當(dāng)你把 set version 的選項(xiàng)關(guān)掉時(shí),modversions.h 和 modules 這個(gè)目錄都會(huì)不見。如果沒有上面三行,那 compile 就不會(huì)過關(guān)。所以一般來講,modversions.h 我們會(huì)選擇在 compile 時(shí)傳給 gcc 使用。就像下面這個(gè)樣子。
gcc -c -D__KERNEL__ -DMODULE -DMODVERSIONS main.c
-include usr/src/linux/include/linux/modversions.h
在這個(gè) command line 里,我們看到了 -D__KERNEL__,這是說要定義 __KERNEL__ 這個(gè) constant。很多跟 kernel 有關(guān)的 header file,都必須要定義這個(gè) constant 才能 include 的。所以建議你最好將它定義起來。另外還有一個(gè) -DMODVERSIONS。這個(gè) constant 我剛才忘了講。剛才我們說要解決 fucntion 或 variable 名字 encode 的方式就是要 include modversions.h,其實(shí)除此之外,你還必須定義 MODVERSIONS 這個(gè) constant。再來就是 MODULE 這個(gè) constant。其實(shí),只要是你要寫 module 就一定要定義這個(gè)變量。而且你還要 include module.h 這個(gè)檔案,因?yàn)?_set_ver 就是定義在這里的。
講到這里,相信各位應(yīng)該對(duì) module 有一些認(rèn)識(shí)了,以后遇到 module unresolved 應(yīng)該不會(huì)感到困惑了,應(yīng)該也有辦法解決了。
剛才講的都是使用別人的 function 上遇到的名字 encode 問題。但是,如果我們自己的 module 想要 export 一些東西讓別的 module 使用呢。很簡單。在 default 上,在你的 module 里所有的 global variable 和 function 都會(huì)被認(rèn)定為你要 export 出去的。所以,如果你的 module 里有 10 個(gè) global variable,經(jīng)由 ksyms,你可以發(fā)現(xiàn)這十個(gè) variable 都會(huì)被 export 出去。這當(dāng)然是個(gè)很方便的事啦,但是,你知道,有時(shí)候我們根本不想把所有的 variable 都 export 出去,萬一有個(gè) module 沒事亂改我們的 variable 怎幺辦呢 ? 所以,在很多時(shí)候,我們都只會(huì)限定幾個(gè)必要的東西 export 出去。在 2.2.1 之前的 kernel (不是很確定) 可以利用 register_symtab 來幫我們。但是,現(xiàn)在更新的版本早就出來了。所以,在此,我會(huì)介紹 kernel 2.2.1 里所提供的。kernel 2.2.1 里提供了一個(gè) macro,叫做 EXPORT_SYMBOL,這是用來幫我們選擇要 export 的 variable 或 function。比方說,我要 export 一個(gè)叫 full 的 variable,那我只要在 module 里寫:
EXPORT_SYMBOL(full);
module 翻譯成中文就是模塊,不過,事實(shí)上去翻譯這個(gè)字一點(diǎn)都沒意義。在講模塊之前,我先舉一個(gè)例子。相信很多人都用過 RedHat。在 RedHat 里,我們可以執(zhí)行 sndconfig,它可以幫我們 config 聲卡。config 完之后如果捉得到你的聲卡,那你的聲卡馬上就可以動(dòng)了,而且還不用重新激活計(jì)算機(jī)。這是怎幺做的呢 ? 就是靠module。module 其實(shí)是一般的程序。但是它可以被動(dòng)態(tài)載到 kernel 里成為 kernel的一部分。載到 kernel 里的 module 它具有跟 kernel 一樣的權(quán)力。可以 access 任何 kernel 的 data structure。你聽過 kdebug 嗎 ? 它是用來 debug kernel 的。它就是先將它本身的一個(gè) module 載到 kernel 里,而在 user space 的 gdb 就可以經(jīng)由跟這個(gè) module 溝通,得知 kernel 里的 data structure 的值,除此之外,還可以經(jīng)由載到 kernel 的 module 去更改 kernel 里 data structure。
我們知道,在寫 C 程序的時(shí)候,一個(gè)程序只能有一個(gè) main。Kernel 本身其實(shí)也是一個(gè)程序,它本身也有個(gè) main,叫 start_kernel()。當(dāng)我們把一個(gè) module 載到 kernel 里的時(shí)候,它會(huì)跟 kernel 整合在一起,成為 kernel 的一部分。請(qǐng)各位想想,那 module 可以有 main 嗎 ? 答案很明顯的,是 No。理由很簡單。一個(gè)程序只能有一個(gè) main。在使用 module 時(shí),有一點(diǎn)要記住的是 module 是處于被動(dòng)的角色。它是提供某些功能讓別人去使用的。
Kernel 里有一個(gè)變量叫 module_list,每當(dāng) user 將一個(gè) module 載到 kernel 里的時(shí)候,這個(gè) module 就會(huì)被記錄在 module_list 里面。當(dāng) kernel 要使用到這個(gè) module 提供的 function 時(shí),它就會(huì)去 search 這個(gè) list,找到 module,然后再使用其提供的 function 或 variable。每一個(gè) module 都可以 export 一些 function 或變量來讓別人使用。除此之外,module 也可以使用已經(jīng)載到 kernel 里的 module 提供的 function。這種情形叫做 module stack。比方說,module A 用到 module B 的東西,那在加載 module A 之前必須要先加載 module B。否則 module A 會(huì)無法加載。除了 module 會(huì) export 東西之外,kernel 本身也會(huì) export 一些 function 或 variable。同樣的,module 也可以使用 kernel 所 export 出來的東西。由于大家平時(shí)都是撰寫 user space 的程序,所以,當(dāng)突然去寫 module 的時(shí)候,會(huì)把平時(shí)寫程序用的 function 拿到 module 里使用。像是 printf 之類的東西。我要告訴各位的是,module 所使用的 function 或 variable,要嘛就是自己寫在 module 里,要嘛就是別的 module 提供的,再不就是 kernel 所提供的。你不能使用一般 libc 或 glibc所提供的 function。像 printf 之類的東西。這一點(diǎn)可能是各位要多小心的地方。(也許你可以先 link 好,再載到 kernel,我好象試過,但是忘了)
剛才我們說到 kernel 本身會(huì) export 出一些 function 或 variable 來讓 module 使用,但是,我們不是萬能的,我們?cè)蹒壑?kernel 有開放那里東西讓我們使用呢 ? Linux 提供一個(gè) command,叫 ksyms,你只要執(zhí)行 ksyms -a 就可以知道 kernel 或目前載到 kernel 里的 module 提供了那些 function 或 variable。底下是我的系統(tǒng)的情形:
c0216ba0 drive_info_R744aa133
c01e4a44 boot_cpu_data_R660bd466
c01e4ac0 EISA_bus_R7413793a
c01e4ac4 MCA_bus_Rf48a2c4c
c010cc34 __verify_write_R203afbeb
。 . 。 . 。
在 kernel 里,有一個(gè) symbol table 是用來記錄 export 出去的 function 或 variable。除此之外,也會(huì)記錄著那個(gè) module export 那些 function。上面幾行中,表示 kernel 提供了 drive_info 這個(gè) function/variable。所以,我們可以在 kernel 里直接使用它,等載到 kernel 里時(shí),會(huì)自動(dòng)做好 link 的動(dòng)作。由此,我們可以知道,module 本身其實(shí)是還沒做 link 的一些 object code。一切都要等到 module 被加載 kernel 之后,link 才會(huì)完成。各位應(yīng)該可以看到 drive_info 后面還接著一些奇怪的字符串。_R744aa133,這個(gè)字符串是根據(jù)目前 kernel 的版本再做些 encode 得出來的結(jié)果。為什幺額外需要這一個(gè)字符串呢 ?
Linux 不知道從那個(gè)版本以來,就多了一個(gè) config 的選項(xiàng),叫做 Set version number in symbols of module。這是為了避免對(duì)系統(tǒng)造成不穩(wěn)定。我們知道 Linux 的 kernel 更新的很快。在 kernel 更新的過程,有時(shí)為了效率起見,會(huì)對(duì)某些舊有的 data structure 或 function 做些改變,而且一變可能有的 variable 被拿掉,有的 function 的 prototype 跟原來的都不太一樣。如果這種情形發(fā)生的時(shí)候,那可能以前 2.0.33 版本的 module 拿到 2.2.1 版本的 kernel 使用,假設(shè)原來 module 使用了 2.0.33 kernel 提供的變量叫 A,但是到了 2.2.1 由于某些原因必須把 A 都設(shè)成 NULL。那當(dāng)此 module 用在 2.2.1 kernel 上時(shí),如果它沒去檢查 A 的值就直接使用的話,就會(huì)造成系統(tǒng)的錯(cuò)誤。也許不會(huì)整個(gè)系統(tǒng)都死掉,但是這個(gè) module 肯定是很難發(fā)揮它的功能。為了這個(gè)原因,Linux 就在 compile module 時(shí),把 kernel 版本的號(hào)碼 encode 到各個(gè) exported function 和 variable 里。
所以,剛才也許我們不應(yīng)該講 kernel 提供了 drive_info,而應(yīng)該說 kernel 提供了 driver_info_R744aa133 來讓我們使用。這樣也許各位會(huì)比較明白。也就是說,kernel 認(rèn)為它提供的 driver_info_R744aa133 這個(gè)東西,而不是 driver_info。所以,我們可以發(fā)現(xiàn)有的人在加載 module 時(shí),系統(tǒng)都一直告訴你某個(gè) function 無法 resolved。這就是因?yàn)?kernel 里沒有你要的 function,要不然就是你的 module 里使用的 function 跟 kernel encode 的結(jié)果不一樣。所以無法 resolve。解決方式,要嘛就是將 kernel 里的 set version 選項(xiàng)關(guān)掉,要嘛就是將 module compile 成 kernel 有辦法接受的型式。
那有人就會(huì)想說,如果 kernel 認(rèn)定它提供的 function 名字叫做 driver_info_R744aa133 的話,那我們寫程序時(shí),是不是用到這個(gè) funnction 的地方都改成 driver_info_R744aa133 就可以了。答案是 Yes。但是,如果每個(gè) function 都要你這樣寫,你不會(huì)覺得很煩嗎 ? 比方說,我們?cè)趯?driver 時(shí),很多人都會(huì)用到 printk 這個(gè) function。這是 kernel 所提供的 function。它的功能跟 printf 很像。用法也幾乎都一樣。是 debug 時(shí)很好用的東西。如果我們 module 里用了一百次 printk,那是不是我們也要打一百次的 printk_Rdd132261 呢 ? 當(dāng)然不是,聰明的人馬上會(huì)想到用 #define printk printk_Rdd132261 就好了嘛。所以啰,Linux 很體貼的幫我們做了這件事。
如果各位的系統(tǒng)有將 set version 的選項(xiàng)打開的話,那大家可以到 /usr/src/linux/include/linux/modules 這個(gè)目錄底下。這個(gè)目錄底下有所多的 。.ver檔案。這些檔案其實(shí)就是用來做 #define 用的。我們來看看 ksyms.ver 這個(gè)檔案里,里面有一行是這樣子的 :
#define printk _set_ver(printk)
set_ver 是一個(gè) macro,就是用來在 printk 后面加上 version number 的。有興趣的朋友可以自行去觀看這個(gè) macro 的寫法。用了這些 ver 檔,我們就可以在 module 里直接使用 printk 這樣的名字了。而這些 ver 檔會(huì)自動(dòng)幫我們做好 #define 的動(dòng)作。可是,我們可以發(fā)現(xiàn)這個(gè)目錄有很多很多的 ver 檔。有時(shí)候,我們?cè)蹒壑牢覀円艚械?function 是在那個(gè) ver 檔里有定義呢 ? Linux 又幫我們做了一件事。/usr/src/linux/include/linux/modversions.h 這個(gè)檔案已經(jīng)將全部的 ver 檔都加進(jìn)來了。所以在我們的 module 里只要 include 這個(gè)檔,那名字的問題都解決了。但是,在此,我們奉勸各位一件事,不要將 modversions.h 這個(gè)檔在 module 里 include 進(jìn)來,如果真的要,那也要加上以下數(shù)行:
#ifdef MODVERSIONS
#include 《linux/modversions.h》;
#endif
加入這三行的原因是,避免這個(gè) module 在沒有設(shè)定 kernel version 的系統(tǒng)上,將 modversions.h 這個(gè)檔案 include 進(jìn)來。各位可以去試試看,當(dāng)你把 set version 的選項(xiàng)關(guān)掉時(shí),modversions.h 和 modules 這個(gè)目錄都會(huì)不見。如果沒有上面三行,那 compile 就不會(huì)過關(guān)。所以一般來講,modversions.h 我們會(huì)選擇在 compile 時(shí)傳給 gcc 使用。就像下面這個(gè)樣子。
gcc -c -D__KERNEL__ -DMODULE -DMODVERSIONS main.c
-include usr/src/linux/include/linux/modversions.h
在這個(gè) command line 里,我們看到了 -D__KERNEL__,這是說要定義 __KERNEL__ 這個(gè) constant。很多跟 kernel 有關(guān)的 header file,都必須要定義這個(gè) constant 才能 include 的。所以建議你最好將它定義起來。另外還有一個(gè) -DMODVERSIONS。這個(gè) constant 我剛才忘了講。剛才我們說要解決 fucntion 或 variable 名字 encode 的方式就是要 include modversions.h,其實(shí)除此之外,你還必須定義 MODVERSIONS 這個(gè) constant。再來就是 MODULE 這個(gè) constant。其實(shí),只要是你要寫 module 就一定要定義這個(gè)變量。而且你還要 include module.h 這個(gè)檔案,因?yàn)?_set_ver 就是定義在這里的。
講到這里,相信各位應(yīng)該對(duì) module 有一些認(rèn)識(shí)了,以后遇到 module unresolved 應(yīng)該不會(huì)感到困惑了,應(yīng)該也有辦法解決了。
剛才講的都是使用別人的 function 上遇到的名字 encode 問題。但是,如果我們自己的 module 想要 export 一些東西讓別的 module 使用呢。很簡單。在 default 上,在你的 module 里所有的 global variable 和 function 都會(huì)被認(rèn)定為你要 export 出去的。所以,如果你的 module 里有 10 個(gè) global variable,經(jīng)由 ksyms,你可以發(fā)現(xiàn)這十個(gè) variable 都會(huì)被 export 出去。這當(dāng)然是個(gè)很方便的事啦,但是,你知道,有時(shí)候我們根本不想把所有的 variable 都 export 出去,萬一有個(gè) module 沒事亂改我們的 variable 怎幺辦呢 ? 所以,在很多時(shí)候,我們都只會(huì)限定幾個(gè)必要的東西 export 出去。在 2.2.1 之前的 kernel (不是很確定) 可以利用 register_symtab 來幫我們。但是,現(xiàn)在更新的版本早就出來了。所以,在此,我會(huì)介紹 kernel 2.2.1 里所提供的。kernel 2.2.1 里提供了一個(gè) macro,叫做 EXPORT_SYMBOL,這是用來幫我們選擇要 export 的 variable 或 function。比方說,我要 export 一個(gè)叫 full 的 variable,那我只要在 module 里寫:
EXPORT_SYMBOL(full);
下載該資料的人也在下載
下載該資料的人還在閱讀
更多 >
- 原理圖 Silex Pmod Module
- μModule Design and Manufacturing Resources
- 基于TQQ1212下的1900/2017.5 MHz Dual Band Saw Filter Module
- 基于TQM7M6025下的Power Amplifier Module
- iMX6-Rex-Module電路原理圖 17次下載
- CC3000 WiFi module 17次下載
- Camera Module Introduction 0次下載
- Ultrathin μModule Power Products 13次下載
- AY-G2PL Module_原理圖 6次下載
- LPC2103_module 4次下載
- LED_Chaser_IO_Module 0次下載
- BTM0505,pdf (Bluetooth Module)
- LCD Module Interface Applicati
- 設(shè)備驅(qū)動(dòng)的入門教程 (教你如何寫驅(qū)動(dòng))
- PXI_Module_Description File Sp 0次下載
- 高效率微型封裝降壓型μModule器件 789次閱讀
- 如何寫要被C調(diào)用的匯編函數(shù) 1307次閱讀
- 利用μModule穩(wěn)壓器進(jìn)行信號(hào)電平轉(zhuǎn)換適用于正負(fù)反相應(yīng)用 1503次閱讀
- 如何寫一個(gè)架構(gòu)設(shè)計(jì) 1008次閱讀
- 如何寫一個(gè)公用工具來進(jìn)行Excel的導(dǎo)入導(dǎo)出 1506次閱讀
- 利用Python生成module instance 1285次閱讀
- 如何在IP的kernel module里設(shè)置并使用IP interrupt 661次閱讀
- 如何寫一個(gè)Linux設(shè)備驅(qū)動(dòng)程序 4532次閱讀
- 如何寫一個(gè)Solidity智能合約 2513次閱讀
- 如何寫一個(gè)會(huì)講笑話的Python程序 3079次閱讀
- 降壓型μModule穩(wěn)壓器LTM?8064 1182次閱讀
- 如何寫一個(gè)簡短的Python代碼做一個(gè)換臉程序的詳細(xì)概述 4533次閱讀
- 如何寫一個(gè)簡短(200行)的Python腳本 5552次閱讀
- 詳解嵌入式Linux設(shè)備驅(qū)動(dòng)篇module_init 5579次閱讀
- 寫verilog代碼要有硬件的概念 2884次閱讀
下載排行
本周
- 1TC358743XBG評(píng)估板參考手冊(cè)
- 1.36 MB | 330次下載 | 免費(fèi)
- 2開關(guān)電源基礎(chǔ)知識(shí)
- 5.73 MB | 6次下載 | 免費(fèi)
- 3100W短波放大電路圖
- 0.05 MB | 4次下載 | 3 積分
- 4嵌入式linux-聊天程序設(shè)計(jì)
- 0.60 MB | 3次下載 | 免費(fèi)
- 5基于FPGA的光纖通信系統(tǒng)的設(shè)計(jì)與實(shí)現(xiàn)
- 0.61 MB | 2次下載 | 免費(fèi)
- 6基于FPGA的C8051F單片機(jī)開發(fā)板設(shè)計(jì)
- 0.70 MB | 2次下載 | 免費(fèi)
- 751單片機(jī)窗簾控制器仿真程序
- 1.93 MB | 2次下載 | 免費(fèi)
- 8基于51單片機(jī)的RGB調(diào)色燈程序仿真
- 0.86 MB | 2次下載 | 免費(fèi)
本月
- 1OrCAD10.5下載OrCAD10.5中文版軟件
- 0.00 MB | 234315次下載 | 免費(fèi)
- 2555集成電路應(yīng)用800例(新編版)
- 0.00 MB | 33564次下載 | 免費(fèi)
- 3接口電路圖大全
- 未知 | 30323次下載 | 免費(fèi)
- 4開關(guān)電源設(shè)計(jì)實(shí)例指南
- 未知 | 21548次下載 | 免費(fèi)
- 5電氣工程師手冊(cè)免費(fèi)下載(新編第二版pdf電子書)
- 0.00 MB | 15349次下載 | 免費(fèi)
- 6數(shù)字電路基礎(chǔ)pdf(下載)
- 未知 | 13750次下載 | 免費(fèi)
- 7電子制作實(shí)例集錦 下載
- 未知 | 8113次下載 | 免費(fèi)
- 8《LED驅(qū)動(dòng)電路設(shè)計(jì)》 溫德爾著
- 0.00 MB | 6653次下載 | 免費(fèi)
總榜
- 1matlab軟件下載入口
- 未知 | 935054次下載 | 免費(fèi)
- 2protel99se軟件下載(可英文版轉(zhuǎn)中文版)
- 78.1 MB | 537796次下載 | 免費(fèi)
- 3MATLAB 7.1 下載 (含軟件介紹)
- 未知 | 420026次下載 | 免費(fèi)
- 4OrCAD10.5下載OrCAD10.5中文版軟件
- 0.00 MB | 234315次下載 | 免費(fèi)
- 5Altium DXP2002下載入口
- 未知 | 233046次下載 | 免費(fèi)
- 6電路仿真軟件multisim 10.0免費(fèi)下載
- 340992 | 191185次下載 | 免費(fèi)
- 7十天學(xué)會(huì)AVR單片機(jī)與C語言視頻教程 下載
- 158M | 183278次下載 | 免費(fèi)
- 8proe5.0野火版下載(中文版免費(fèi)下載)
- 未知 | 138040次下載 | 免費(fèi)
評(píng)論