一.linux設備驅動的作用
內核:用於管理軟硬件資源,並提供運行環境。如分配4G虛擬空間等。
linux設備驅動:是連接硬件和內核之間的橋梁。
linux系統按個人理解可按下劃分:
應用層:包括POSIX接口,LIBC,圖形庫等,用於給用戶提供訪問 內核的接口。屬於用戶態,ARM運行在用戶模式(usr)或 者系統模式(sys)下。
內核層:應用程序調用相關接口後,會通過系統調用,執行SWI指 令切換ARM的工作模式到超級用戶(svc)模式下,根據用 戶函數的要求執行相應的操作。
硬件層:硬件設備,當用戶需要操作硬件時,內核會根據驅動接口 操作硬件設備
圖結構如下:
舉一個相對比較邪惡的類比:
在酒店經常會在門縫看到一些卡片,上面說可以通過打電話送貨上門提供某中服務。
二.內核代碼樹介紹
linux-2.6.29
|-arch : 包含和硬件體系結構相關的代碼
|-block : 硬盤調度算法,不是驅動
|-firmware : 固件,如BOIS
|-Documentation: 標准官方文檔
|-dirver : linux設備驅動
|-fs : 內核所支持的文件體系
|-include :頭文件。linux/module.h linux/init.h 常用庫。
|-init :庫文件代碼,C庫函數在內核中的實現。
init/main.c ->start_kernel->內核執行第一條代碼
|-ipc : 進程件通信
|-mm :內存管理
|-kernel : 內核核心部分,包括進程調度等
|-net :網絡協議
|-sound : 所有音頻相關
|
其中,跟設備驅動有關並且經常查閱的文件夾有:
init
include : linux, asm-arm
drivers:
arch:
三.內核補丁:
補丁一般都是基於某個版本內核生成的,用於升級舊內核。
打補丁需要注意:
1.對應版本的補丁只能用於對應版本的內核。
2.如果在已打補丁的內核再打補丁,需要先卸載原來補丁。
打補丁的方法:
1.制作補丁:
diff -Nur linux-2.6.30/ linux-2.6.30.1/ > linux-2.6.30.1.patch
//N為新加的文件全部修改
//linux-2.6.30 舊版本
//linux-2.6.30.1 新版本
//目標補丁
2.打補丁:
cd linux-2.6.30 //!!注意在原文件夾的目錄中打補丁
patch -p1 < ../linux-2.6.30.1.patch //-p1是忽略一級目錄
3.恢復:
cd linux-2.6.30 //!!注意在原文件夾的目錄中打補丁
patch -R < ../linux-2.6.30.1.patch //撤銷補丁
四.內核中的Makefile:
對於內核,Makefile分為5類:
Documentation/kbuild/makefiles.txt描述如下:
The Makefiles have five parts: Makefile 總Makefile,控制內核的編譯 .config 內核配置文件,配置內核時生成, 如make menuconfig後 arch/$(ARCH)/Makefile 對應體系結構的Makefile scripts/Makefile.* Makefile共用的規則 kbuild Makefiles 各子目錄下的Makefile,被上層的Makefile調用。
簡單來說,編譯內核會執行以下兩步驟,它們分別干了以下的事情。
1一般的,我們會拷貝一個對應體系結構的配置文件到主目錄下並改名為 .config,這樣就在make menuconfig生成的圖形配置中 已經有了一些默認的配置,減少用戶的勞動量。不過這一步不做也沒關系的。
2.make menuconfig
2.1、由總Makefile決定編譯的體系結構(ARCH). 編譯工具(CROSS_COMPILE),並知道需要進去哪些內核根下的哪些目錄進行編譯。
2.2、由arch/$(ARCH)/Makefile,決定arch/$(ARCH)下還有 的哪些目錄和文件需要編譯。
2.3、知道了需要編譯的目錄後,遞歸的進入哪些目錄下,讀取每一個Kconfig的信息,生成了圖形配置的界面。
2.4、通過我們在圖形配置界面中選項為[*]、[M]或者[]。
2.5、保存並退出配置,會根據配置生成一份新的配置文件.config,並在同時生成include/config/auto.conf(這是.config的去注釋版)。文件裡面保存著CONFIG_XXXX等變量應該取y還是取m。
3.make
3.1、根據Makefile包含的目錄和配置文件的要求,進去個子目錄進行編譯,最後會在各子目錄下 生成一個.o或者.a文件,然後總Makefile指定的連接腳本 arch/$(ARCH)/kernel/vmlinux.lds生成vmlinux,並通過 壓縮編程bzImage,或者按要求在對應的子目錄下編譯成 模塊。
但是,具體是怎麼生成配置文件的呢?
注:我使用的內核是2.6.29。
1.在總Makefile中,根據以下語句進入需要編譯的目錄
# Objects we will link into vmlinux / subdirs we need to visit init-y := init/ drivers-y := drivers/ sound/ firmware/ net-y := net/ libs-y := lib/ core-y := usr/ endif # KBUILD_EXTMOD core-y += kernel/ mm/ fs/ ipc/ security/ crypto/ block/
上面說明了,根目錄下的init、driver、sound、firmware、net、lib、usr等目錄,在編譯時都會進去讀取目錄下的Makefile並進行編譯。
2.在總Makefile中包含的目錄還是不夠的,內核還需要根據對應的CPU體系架構,
決定還需要將哪些子目錄將要編譯進內核。在總Makefile中有一個語句:
include $(srctree)/arch/$(SRCARCH)/Makefile //在這裡,我定義SRCARCH = arm
可以看出,在總Makefile中進去讀取相應體系 結構的Makefile->arch/$(SRCARCH)/Makefile。
arch/$(SRCARCH)/Makefile中指定arch/$(SRCARCH)路徑下的哪些子目錄需要被編譯。
在 arch/arm/Makefile 下:
head-y := arch/arm/kernel/head$(MMUEXT).o arch/arm/kernel/init_task.o # If we have a machine-specific directory, then include it in the build. core-y += arch/arm/kernel/ arch/arm/mm/ arch/arm/common/ core-y += $(machdirs) $(platdirs) core-$(CONFIG_FPE_NWFPE) += arch/arm/nwfpe/ core-$(CONFIG_FPE_FASTFPE) += $(FASTFPE_OBJ) core-$(CONFIG_VFP) += arch/arm/vfp/ drivers-$(CONFIG_OPROFILE) += arch/arm/oprofile/ libs-y := arch/arm/lib/ $(libs-y)
上面看到,指定需要進入arch/arm/kernel/、arch/arm/mm/、arch/arm/common/ 等目錄編譯,至於core-y、 core-$(CONFIG_FPE_NWFPE)這些是什麼東西呢?
其中,y表示編譯近內核,m表示編譯成模塊(上面沒有,因為默認情況下ARM全部編譯進內核),但$(CONFIG_OPROFILE)又是什麼呢? 這些是根據用戶在make menuconfig中設置後,生成的值賦給了CONFIG_OPROFILE。
3.那make menuconfig後的配置信息是怎麼來的?
這是由各子目錄下的Kconfig提供選項功用戶選擇並配置。
如arch/arm/Kconfig。 所有的配置都是根據arch/$(ARCH)/Kconfig文件通過Kconfig的語法source讀取 各個包含的子目錄Kconfig來生成一個配置界面。每個Makefile目錄下都有一個 對應的Kconfig文件,用於生成配置界面來給用戶決定內核如何配置,配置後會確定一個。 CONFIG_XXX的的值(如上面的CONFIG_OPROFILE),來決定編譯進內核,還是編譯成模塊或者不編譯。
如在arch/arm/Kconfig下:
source "arch/arm/mach-clps711x/Kconfig" source "arch/arm/mach-ep93xx/Kconfig" source "arch/arm/mach-footbridge/Kconfig" source "arch/arm/mach-integrator/Kconfig" source "arch/arm/mach-iop32x/Kconfig" source "arch/arm/mach-iop33x/Kconfig"
這些就是用來指定,需要讀取以下目錄下的Kconfig文件來生成一個使用make menuconfig時的配置界面。