24小時學通Linux內核總結篇(kconfig和Makefile & 講不出再見)html
既然是總結,那麼最後一天我就和你們一塊兒分享一下學習Linux內核的方法以及難點重點吧,但願各路大神多加補充以及討論,互相學習。數據庫
絕不誇張地說,Kconfig和Makefile是咱們瀏覽內核代碼時最爲依仗的兩個文件,分佈在各目錄下的Kconfig構成了一個分佈式的內核配置數據庫,每一個Kconfig分別描述了所屬目錄源文件相關的內核配置菜單。基本上,Linux內核中每個目錄下邊都會有一個Kconfig文件和一個Makefile文件。Kconfig和Makefile就是Linux Kernel迷宮裏的地圖。地圖引導咱們去認識一個城市,而Kconfig和Makefile則可讓咱們瞭解一個Kernel目錄下面的結構。咱們每次瀏覽kernel尋找屬於本身的那一段代碼時,都應該首先看看目錄下的這兩個文件。編程
下面簡要介紹一下Kconfig api
每一個菜單項都有一個關鍵字標識,最多見的就是config。安全
語法:
config symbol多線程
options
<!--[if !supportLineBreakNewLine]-->
<!--[endif]-->app
symbol就是新的菜單項,options是在這個新的菜單項下的屬性和選項分佈式
其中options部分有:函數
一、類型定義:
每一個config菜單項都要有類型定義,bool:布爾類型, tristate三態:內建、模塊、移除, string:字符串, hex:十六進制, integer:整型學習
二、依賴型定義depends on或requires
指此菜單的出現是否依賴於另外一個定義
三、幫助性定義
只是增長幫助用關鍵字help或---help---
<!--[if !supportLineBreakNewLine]-->
<!--[endif]-->
Kconfig文件的基本要素:
1.config條目(entry)
config是關鍵字,表示一個配置選項的開始;緊跟着的TMPFS_POSIX_ACL是配置選項的名稱,省略了前綴"CONFIG_"
bool表示變量類型,即"CONFIG_ TMPFS_POSIX_ACL "的類型,有5種類型:bool、tristate、string、hex和int,其中tristate和string是基本的類型
bool變量的值: y和n
tristate變量的值:y、n和m
string變量的值: 字符串
bool以後的字符串「Tmpfs POSIX Access Control Lists」是提示信息,在配置界面中上下移動光標選中它時,就能夠經過按空格或回車鍵來設置
CONFIG_ TMPFS_POSIX_ACL的值
depends on:表示依賴於XXX,「depends on TMPFS」表示只有當TMPFS配置選項被選中時,當前配置選項的提示信息纔會出現,才能設置當前配置選項
2.menu條目
menu條目用於生成菜單,其格式以下:
menu "Floating poing emulation"
config FPE_NWFPE
..............
config FPE_NWFPE_XP
.............
endmenu
menu以後的Floating poing emulation是菜單名,menu和endmenu間有不少config條目,在配置界面中以下所示:
Floating poing emulation--->
[] FPE_NWFPE
[] FPE_NWFPE_XP
3.choice條目
choice條目將多個相似的配置選項組合在一塊兒,供用戶單選或多選
choice
prompt "ARM system type"
default ARCH_VERSATILE
config ARCH_AAEC2000
.........
config ARCH_REALVIEW
.........
endchoice
prompt "ARM system type"給出提示信息「ARM system type」,光標選中後回車進入就能夠看到多個config條目定義的配置選項 choice條目中定義的變量只有bool和tristate
4.comment條目
comment條目用於定義一些幫助信息,出如今界面的第一行,如在arch/arm/Kconifg中有以下代碼:
menu "Floating point emulation" comment "At least one emulation must be selected" config FPE_NWFPE ......... config FPE_NWFPE_XP
5.source條目
source條目用於讀取另外一個Kconfig文件,如:
source "net/Kconifg"
介紹一下makefile
Makefile可比Kconfig簡略多了,內核的Makefile分爲5個組成部分:
對Makefile函數,咱們從初始化函數開始,針對某個子系統或某個驅動,內核使用subsys_initcall或module_init宏指定初始化函數。在drivers/usb/core/usb.c文件中,咱們能夠發現下面的代碼:
940 subsys_initcall(usb_init); //告訴咱們usb_init是USB子系統真正的初始化函數, 941 module_exit(usb_exit); //將是整個USB子系統的結束時的清理函數
爲了研究USB子系統在內核中的實現,咱們須要從usb_init函數開始看起,,,下面的代碼求大神指教,不懂啊
865 static int __init usb_init(void) 866 { 867 int retval; 868 if (nousb) { 869 pr_info("%s: USB support disabled\n", usbcore_name); 870 return 0; 871 } 872
873 retval = ksuspend_usb_init(); 874 if (retval) 875 goto out; 876 retval = bus_register(&usb_bus_type); 877 if (retval) 878 goto bus_register_failed; 879 retval = usb_host_init(); 880 if (retval) 881 goto host_init_failed; 882 retval = usb_major_init(); 883 if (retval) 884 goto major_init_failed; 885 retval = usb_register(&usbfs_driver); 886 if (retval) 887 goto driver_register_failed; 888 retval = usb_devio_init(); 889 if (retval) 890 goto usb_devio_init_failed; 891 retval = usbfs_init(); 892 if (retval) 893 goto fs_init_failed; 894 retval = usb_hub_init(); 895 if (retval) 896 goto hub_init_failed; 897 retval = usb_register_device_driver(&usb_generic_driver, THIS_MODULE); 898 if (!retval) 899 goto out; 900
901 usb_hub_cleanup(); 902 hub_init_failed: 903 usbfs_cleanup(); 904 fs_init_failed: 905 usb_devio_cleanup(); 906 usb_devio_init_failed: 907 usb_deregister(&usbfs_driver); 908 driver_register_failed: 909 usb_major_cleanup(); 910 major_init_failed: 911 usb_host_cleanup(); 912 host_init_failed: 913 bus_unregister(&usb_bus_type); 914 bus_register_failed: 915 ksuspend_usb_cleanup(); 916 out: 917 return retval; 918 }
API感想(此處我也不懂,API的概念我腦海中還沒創建,貼出來你們一塊兒分享注意一下)
「比起知道你所用技術的重要性,成爲某一個特別領域的專家是不重要的。知道某一個具體API調用一點好處都沒有,當你須要他的時候只要查詢下就行了。」這句話源於我看到的一篇翻譯過來的博客。我想強調的就是,這句話針應用型編程再合適不過,可是內核API就不徹底如此。
內核至關複雜,學習起來很不容易,可是當你學習到必定程度,你會發現,若是本身打算寫內核代碼,到最後要關注的仍然是API接口,只不過這些API絕大部分是跨平臺的,知足可移植性。內核黑客基本上已經標準化、文檔化了這些接口,你所要作的只是調用而已。固然,在使用的時候,最好對可移植性這一話題在內核中的編碼約定爛熟於心,這樣纔會寫出可移植性的代碼。就像應用程序同樣,可使用開發商提供的動態庫API,或者使用開源API。一樣是調用API,不一樣點在於使用內核API要比使用應用API瞭解的東西要多出許多。
當你瞭解了操做系統的實現---這些實現可都是對應用程序的基礎性支撐啊---你再去寫應用程序的時候,應用程序中用到的多線程,定時器,同步鎖機制等等等等,使用共享庫API的時候,聯繫到操做系統,從而把對該API的文檔描述同本身所瞭解到的這些方面在內核中的相應支撐性實現結合起來進行考慮,這會指導你選擇使用哪個API接口,選出效率最高的實現方式。對系統編程很有了解的話,對應用編程不無益處,甚至能夠說是大有好處。
內核文檔
最後來講下相關的內核文檔,內核代碼中包含有大量的文檔,這些文檔對於學習理解內核有着不可估量的價值,記住,在任什麼時候候,它們在咱們心目中的地位都應該高於那些各式的內核參考書,只不過都是英文的了.不過還好,,嘎嘎,大一的時候就把英語六級過了,仍是有點信心的,,不過過去兩年了不知道本身的英語忘光了沒有,下面是一些咱們這些內核新人所應該閱讀的文檔。
README這個文件首先簡單介紹了Linux內核的背景,而後描述瞭如何配置和編譯內核,最後還告訴咱們出現問題時應該怎麼辦。
Documentation/Changes這個文件給出了用來編譯和使用內核所須要的最小軟件包列表。
Documentation/CodingStyle這個文件描述了內核首選的編碼風格,全部代碼都應該遵照裏面定義的規範。
Documentation/SubmittingPatches
Documentation/SubmittingDrivers
Documentation/SubmitChecklist //這三個文件都是描述如何提交代碼的,其中SubmittingPatches給出建立和提交補丁的過程,
SubmittingDrivers描述瞭如何將 設備驅動提交給2.四、2.6等不一樣版本的內核樹,SubmitChecklist則描述了提交代碼以前須要check本身的代碼應該遵照的某些事項。
Documentation/stable_api_nonsense.txt這個文件解釋了爲何內核沒有一個穩定的內部API(到用戶空間的接口——系統調用——是穩定的),它對於理解Linux的開發哲學相當重要,對於將開發平臺從其餘操做系統轉移到Linux的開發者來講也很重要。
Documentation/stable_kernel_rules.txt解釋了穩定版內核(stable releases)發佈的規則,以及如何將補丁提交給這些版本。
Documentation/SecurityBugs內核開發者對安全性問題很是關注,若是你認爲本身發現了這樣的問題,能夠根據這個文件中給出的聯繫方式提交bug,以便可以儘量快的解決這個問題。
Documentation/kernel-docs.txt這個文件列舉了不少內核相關的文檔和書籍,裏面不乏經典之做。
Documentation/applying-patches.txt這個文件回答瞭如何爲內核打補丁。
Documentation/bug-hunting這個文件是有關尋找、提交、修正bug的。
Documentation/HOWTO這個文件將指導你如何成爲一名內核開發者,而且學會如何同內核開發社區合做。它儘量不包括任何關於內核編程的技術細節,但會給你指引一條得到這些知識的正確途徑。
小結
最後一天沒有說到一些具體的關於內核的知識,只是想重點分享一下kconfig和Makefile,這對學習內核來講相當重要,,固然了,上述提到的也是看了好多大牛的文章以及查閱了一些相關知識,你們能夠參考一下一篇文章,具體講了這些,我把連接附在下面:http://blog.chinaunix.net/uid-26258259-id-3783679.html 不知不覺這一系列的文章就要結束了,本身也要好好整理這些天所欠缺的,,很是感謝期間有些讀者對個人支持,很開心和大家分享這些,,接下來要開始新的生活了,,可是咱們的學習仍將繼續,咱們的激情不會褪去,咱們的夢想咱們的青春永恆~~
版權全部,轉載請註明轉載地址:http://www.cnblogs.com/lihuidashen/p/4257007.html