Linux Kconfig及Makefile學習

內核源碼樹的目錄下都有兩個文檔 Kconfig (2.4版本是Config.in)和Makefile。分布到各目錄的Kconfig構成了一個分布式的內核配置數據庫,每個Kconfig分別描述了 所屬目錄源文檔相關的內核配置菜單。在內核配置make menuconfig時,從Kconfig中讀出菜單,用戶選擇后保存到.config的內核配置文檔中。在內核編譯時,主Makefile調用這 個.config,就知道了用戶的選擇。


上面的內容說明了,Kconfig就是對應著內核的配置菜單。假如要想添加新的驅動到內核的源碼中,能夠修改Kconfig,這樣就能夠選擇這個驅動,假如想使這個驅動被編譯,要修改Makefile。所以,添加新的驅動時需要修改的文檔有兩種(注意不只是兩個)
*Kconfig
*Makefile

---------------------------------------------------------------------------------------------
Kconfig

1.先了解一下Kconfig的語法:
一個典型的內核配置菜單如下:
menu "Network device support"
config NETDEVICES
??????? bool "Enable Net Devices"
??????? depends on NET
??????? default y
?????? help
?????????????? This is help desciption。
...
endmenu
包含在menu/endmenu中的內容會成為Network device support的子菜單。每一個子菜單項都是由config來定義的。congfig下方的那些bool、depends on、default、help等為config的屬性,用于定義該菜單項的類型、依賴項、默認值、幫助信息等。

2. 補充說明一下類型定義部分:
每個config菜單項都要有類型定義: bool布爾類型、 tristate三態(內建、模塊、移除)、string字符串、 hex十六進制、 integer整型。
例如:
config HELLO_MODULE
bool "hello test module"
bool 類型的只能選中或不選中,顯示為[ ]; tristate類型的菜單項多了編譯成內核模塊的選項,顯示為< > , 假如選擇編譯成內核模塊,則會在.config中生成一個 CONFIG_HELLO_MODULE=m的配置,假如選擇內建,就是直接編譯成內核影響,就會在.config中生成一個 CONFIG_HELLO_MODULE=y的配置. hex十六進制類型顯示為( )。

3. 目錄層次迭代
在Kconfig中有類似語句:source "drivers/usb/Kconfig"
用來包含(或嵌套)新的Kconfig文件,這樣便可以使各個目錄管理各自的配置內容,使不必把那些配置都寫在同一個文件里,方便修改和管理。

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

Makefile

2.6內核的Makefile分為5個組成部分:
?????? 1. 最頂層的Makefile
?????? 2. 內核的.config配置文件
?????? 3.?? 在arch/$(ARCH) 目錄下的體系結構相關的Makefile?
?????? 4. 在s目錄下的 Makefile.* 文件,是一些Makefile的通用規則?
?????? 5. 各級目錄下的大概約500個kbuild Makefile文件

頂層的Makefile文件讀取 .config文件的內容,并總體上負責build內核和模塊。Arch Makefile則提供補充體系結構相關的信息。 s目錄下的Makefile文件包含了所有用來根據kbuild Makefile 構建內核所需的定義和規則。


Kbuild Makefile
對于Makefiles的不同組成部分,有一些不同的語法規則。針對的對象也不同,對于大部分內核模塊或設備驅動的開發者和使用者來說,最常接觸到的就是 各層目錄下基于kbuild架構的kbuild Makefile文件。Kbuild Makefile核心內容主要包括:

1.目標定義
目標定義就是用來定義哪些內容要做為模塊編譯,哪些要編譯鏈接進內核。如:

obj-y += foo.o

表示要由foo.c或者foo.s文件編譯得到 foo.o并鏈接進內核,而obj-m則表示該文件要作為模塊編譯。 除了y,m以外的obj-x形式的目標都不會被編譯。而更常見的做法是根據.config文件的CONFIG_ 變量來決定文件的編譯方式(該變量如何起作用見文末另一篇文章的鏈接),如:
obj-$(CONFIG_EXT2) += ext2.o

除了obj-形式的目標以外,還有lib-y library庫,hostprogs-y 主機程序等目標,但是基本都應用在特定的目錄和場合下。


2.多文件模塊的定義?
最簡單的kbuild Makefile如上一節一句話的形式就夠了,如果一個模塊由多個文件組成,那么稍微復雜一些,采用模塊名加 –objs后綴或者 –y后綴的形式來定義模塊的組成文件。如以下例子:
obj-$(CONFIG_EXT2) += ext2.o
ext2-y := balloc.o bitmap.o

或者寫成如-objs的形式:
obj-$(CONFIG_EXT2) += ext2.o
ext2-objs := balloc.o bitmap.o

模塊的名字為ext2,如果CONFIG_EXT2 的值是m,由balloc.o和bitmap.o兩個目標文件最終鏈接生成ext2.o 直至ext2.ko文件,如果CONFIG_EXT2的值是y,生成的 ext2.o將被鏈接進built-in.o最終鏈接進內核。


3.目錄層次的迭代
如下例:
obj-$(CONFIG_EXT2) += ext2/

如果CONFIG_EXT2 的值為y或m,kbuild將會將ext2目錄列入向下迭代的目標中。

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

模塊的編譯

編譯模塊的時候,你可以將模塊放在代碼樹中,用Make modules的方式來編譯你的模塊
此時Makefile內容很簡單,例如:obj-$(CONFIG_EXT2) += ext2.o 即可。

也可以將模塊相關文件目錄放在代碼樹以外的位置,用如下命令來編譯模塊:
make -C <path to kernel src> M=$PWD modules

‘-C’指定代碼樹的位置,M=$PWD 或 M=`PWD` 告訴kbuild回到當前目錄來執行build操作。
當然,我們也可以為其寫一個Makefile,這里介紹一個教通用的Makefile(2.6版本):

# Makefile2.6?
ifneq ($(KERNELRELEASE),)?
#kbuild syntax. dependency relationshsip of files and target modules are listed here.?
obj-m := hello.o?
hello-objs := hello.o???
else?
PWD := $(shell pwd)?
KDIR := /lib/modules/$(shell uname -r)/build?
all:
$(MAKE) -C $(KDIR) M=$(PWD) modules
clean:?
rm -rf .*.cmd *.o *.mod.c *.ko .tmp_versions?
endif?

此例子驅動目錄叫做hello,實際中需要將下面的hello換成自己的目錄名稱。其中代碼樹路徑是自動獲取的。之后在目錄下直接執行make命令即可,不再用敲上面一大長串命令。

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

在添加新驅動時,需要創建Kconfig、Makefile文件,且需要修改父目錄Kconfig、Makefile這兩個文件以便將自己的驅動包含進去。例子見:為Android內核添加新驅動,并添加到menuconfig菜單【實踐簡記】

在linux2.6.x/Documentation/kbuild目錄下有周詳的介紹有關kconfig、makefile的知識。

例子:

為Android內核添加新驅動,并添加到menuconfig菜單【實踐簡記】

為Android內核添加新驅動,并提供menuconfig選項

為Android的Linux內核2.6.25添加驅動。

1. 在drives目錄下添加hello目錄,內含hello.c Kconfig Makefile

hello.c內容:
#include <linux/init.h>
#include <linux/module.h>
MODULE_LICENSE("Dual BSD/GPL");

static int hello_init(void)
{
??????? printk(KERN_ALERT"Hello, world\n");
??????? return 0;
}
static void hello_exit(void)
{

??????? printk(KERN_ALERT"Goodbye, cruel world\n");
}

module_init(hello_init);
module_exit(hello_exit);

Kconfig內容:
config HELLO
tristate "Hello Driver added by Dong"?
default n
help
?? test for adding driver to menuconfig.

MakeFile內容:
obj-$(CONFIG_HELLO) += hello.o


2. 上面的Kconfig文件再加上下面的兩個配置,可使hello項出現在配置菜單中。
在arch/arm/Kconfig menu "Device Drivers" endmenu之間添加
source "drivers/hello/Kconfig"

在drivers/Kconfig menu "Device Drivers" endmenu之間添加
source "drivers/hello/Kconfig"

(不知為什么arch/arm/Kconfig中竟然含有Drivers里Kconfig內容的一個復本,
實驗證明只對drivers/Kconfig中修改內容無效。)

3.修改Drivers目錄下的Makefile文件,添加如下行,
obj-$(CONFIG_HELLO) += hello/
當CONFIG_HELLO為y或m時,使系統能找到hello驅動的makefile。

linux-2.6.25目錄下make menuconfig,在Device Drivers菜單下選中Hello Driver added by Dong項比如M,作為module。然后保存配置,執行make命令,就可以看到 CC [M] drivers/hello/hello.o 的log了,hello目錄里生成了hello.o hello.ko的等文件。

流程:
假如在make menuconfig時配置Hello Driver added by Dong為M(即編為模塊,而不是編進linux內核)
則.config中就會多一行CONFIG_HELLO = m
如此一來,drivers/Makefile中obj-$(CONFIG_HELLO) += hello/就變成了obj-m +=hello/
于是執行make命令時,便會進入hello目錄里找makefile,MakeFile內容obj-$(CONFIG_HELLO) += hello.o 變成了obj-m +=hello.o,所以hello.c就被編譯成模塊了


本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/253334.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/253334.shtml
英文地址,請注明出處:http://en.pswp.cn/news/253334.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Linux編程 23 shell編程(結構化條件判斷 命令if -then , if-then ... elif-then ...else,if test)...

一.概述 在上一篇里講到了shell腳本&#xff0c;shell按照命令在腳本中出現的順序依次進行處理&#xff0c;對于順序操作已經足夠了&#xff0c;但許多程序要求對shell腳本中的命令加入一些邏輯流程控制&#xff0c;這樣的命令通常叫做 結構化命令。 1.1 使用if - then語句 --最…

Scala-Spark digamma stackoverflow問題

這兩天在用spark做點擊率的貝葉斯平滑&#xff0c;參考雅虎的論文進行了一番嘗試。 先上代碼&#xff1a; 1 # click_count, show_count # this method takes time2 def do_smooth(data_list):3 import scipy.special as sp4 a, b, i 1.0, 1.0, 05 da, db a, b6 …

IIS接口詳細介紹

1. 概述 I2S Inter-IC Sound Integrated Interchip Sound IIS&#xff0c;是飛利浦在1986年定義&#xff08;1996年修訂&#xff09;的數字音頻傳輸標準&#xff0c;用于數字音頻數據在系統內器件之間傳輸&#xff0c;例如編解碼器CODEC、DSP、數字輸入/輸出接口、ADC、DAC…

UVA - 10934 Dropping water balloons(裝滿水的氣球)(dp)

題意&#xff1a;有k個氣球&#xff0c;n層樓&#xff0c;求出至少需要多少次實驗能確定氣球的硬度。氣球不會被實驗所“磨損”。 分析&#xff1a; 1、dp[i][j]表示第i個氣球&#xff0c;測試j次所能確定的最高樓層。 2、假設第i-1個氣球測試j-1次所確定的最高樓層是a, 若第i個…

繼承進階

先講一個例子&#xff1a; #老師有生日&#xff0c;怎么組合哪&#xff1f; class Birthday: # 生日def __init__(self,year,month,day):self.year yearself.month monthself.day dayclass Teacher: # 老師<br>def __init__(self,name,birth):self.name nameself.b…

PCM接口詳細介紹--TDM方式

1. 概述 PCM = Pulse Code Modulation 是通過等時間隔(即采樣率時鐘周期)采樣將模擬信號數字化的方法。圖為4 bit 采樣深度的PCM數據量化示意圖: PCM數字音頻接口,說明接口傳輸的音頻數據是通過PCM方式采樣得到的,區別于PDM形式;IIS傳輸的也是PCM類型數據,屬于其一個特…

網站同源策略

所謂"同源"指的是"三個相同"&#xff1a;協議&#xff0c;域名&#xff0c;端口。 舉例來說&#xff0c;http://www.example.com/dir/page.html這個網址&#xff0c;協議是http://&#xff0c;域名是www.example.com&#xff0c;端口是80&#xff08;默認端…

Kconfig文件結構(圖文)簡介

1 Kconfig和Makefile 毫不夸張地說&#xff0c;Kconfig和Makefile是我們瀏覽內核代碼時最為依仗的兩個文件。基本上&#xff0c;Linux 內核中每一個目錄下邊都會有一個Kconfig文件和一個Makefile文件。Kconfig和Makefile就好似一個城市的地圖&#xff0c;地圖引導我們去 認識一…

PDM接口介紹

1. 概述 PDM Pulse Density Modulation是一種用數字信號表示模擬信號的調制方法。 PDM則使用遠高于PCM采樣率的時鐘采樣調制模擬分量&#xff0c;只有1位輸出&#xff0c;要么為0&#xff0c;要么為1。因此通過PDM方式表示的數字音頻也被稱為Oversampled 1-bit Audio。相比P…

js正則學習分享

http://www.cnblogs.com/rubylouvre/archive/2010/03/09/1681222.htmlhttp://www.cnblogs.com/tylerdonet/p/4262251.html //正整數 /^[0-9]*[1-9][0-9]*$/; //負整數 /^-[0-9]*[1-9][0-9]*$/; //正浮點數 /^(([0-9]\.[0-9]*[1-9][0-9]*)|([0-9]*[1-9][0-9]*\.[0-9])|([0-9]*[1…

Linux系統下UDP發送和接收廣播消息小例子

分類&#xff1a; 網絡通信 2013-01-07 10:54 1336人閱讀 評論(6) 收藏 舉報 [cpp] view plaincopyprint?// 發送端 #include <iostream> #include <stdio.h> #include <sys/socket.h> #include <unistd.h> #include <sys/types.h>…

Kaggle 泰坦尼克

入門kaggle&#xff0c;開始機器學習應用之旅。 參看一些入門的博客&#xff0c;感覺pandas&#xff0c;sklearn需要熟練掌握&#xff0c;同時也學到了一些很有用的tricks&#xff0c;包括數據分析和機器學習的知識點。下面記錄一些有趣的數據分析方法和一個自己擼的小程序。 1…

語音交互設備 前端信號處理技術和語音交互過程介紹

一、前端信號處理 1. 語音檢測&#xff08;VAD&#xff09; 語音檢測&#xff08;英文一般稱為 Voice Activity Detection&#xff0c;VAD&#xff09;的目標是&#xff0c;準確的檢測出音頻信號的語音段起始位置&#xff0c;從而分離出語音段和非語音段&#xff08;靜音或噪…

css中偽類與偽元素的區別

一&#xff1a;偽類&#xff1a;1:定義&#xff1a;css偽類用于向某些選擇器添加特殊效果。 偽類其實與普通的css類相類似&#xff0c;可以為已有的元素添加樣式&#xff0c;但是他只有處于dom無法描述的狀態下才能為文檔樹中的元素添加樣式&#xff0c;所以將其稱為偽類。 2:偽…

【BZOJ1500】[NOI2005]維修數列 Splay

【BZOJ1500】[NOI2005]維修數列 Description Input 輸入的第1 行包含兩個數N 和M(M ≤20 000)&#xff0c;N 表示初始時數列中數的個數&#xff0c;M表示要進行的操作數目。第2行包含N個數字&#xff0c;描述初始時的數列。以下M行&#xff0c;每行一條命令&#xff0c;格式參見…

bzoj2588: Spoj 10628. Count on a tree(樹上第k大)(主席樹)

每個節點繼承父節點的樹&#xff0c;則答案為query(root[x]root[y]-root[lca(x,y)]-root[fa[lca(x,y)]]) #include<iostream> #include<cstring> #include<cstdlib> #include<cstdio> #include<algorithm> using namespace std; const int maxn1…

圖文詳解YUV420數據格式

YUV格式有兩大類&#xff1a;planar和packed。 對于planar的YUV格式&#xff0c;先連續存儲所有像素點的Y&#xff0c;緊接著存儲所有像素點的U&#xff0c;隨后是所有像素點的V。 對于packed的YUV格式&#xff0c;每個像素點的Y,U,V是連續交*存儲的。 YUV&#xff0c;分為三個…

USB通信接口介紹

1. 概述 Usb Universal Serial Bus全稱通用串行總線&#xff0c;是一種支持熱插拔的高速串行傳輸總線&#xff0c;使用差分信號來傳輸數據。 USB設備可以直接和host通信&#xff0c;或者通過hub和host通信。一個USB系統中僅有一個USB主機&#xff0c;設備包括功能設備和hub&…

關于java中BufferedReader的read()及readLine()方法的使用心得

BufferedReader的readLine()方法是阻塞式的, 如果到達流末尾, 就返回null, 但如果client的socket末經關閉就銷毀, 則會產生IO異常. 正常的方法就是使用socket.close()關閉不需要的socket. 從一個有若干行的文件中依次讀取各行&#xff0c;處理后輸出&#xff0c;如果用以下方法…

HDCVI——一種創新性的高清視頻傳輸方案

什么是HDCVI 2012年11月&#xff0c;大華技術股份有限公司發布了具有自主知識產權的同軸高清傳輸接口技術HDCVI。HDCVI技術是一種基于已有SYV75-3或SYV75-5同軸電纜的高清視頻傳輸方法&#xff0c;能夠在低成本和較低質量的同軸電纜上實現超長距離高清視頻信號的可靠傳輸。相比…