內核源碼樹
驅動開發環境
要進行linux驅動開發我們首先要有linux內核的源碼樹,並且這個linux內核的源碼樹要和開發板中的內核源碼樹要一直;
比如說我們開發板中用的是linux kernel內核版本為2.6.35.7,在我們ubuntu虛擬機上必須要有同樣版本的源碼樹,
我們再編譯好驅動的的時候,使用modinfo XXX命令會列印出一個版本號,這個版本號是與使用的源碼樹版本有關,如果開發板中源碼樹中版本與
modinfo的版本信息不一致使無法安裝驅動的;
我們開發板必須設置好nfs掛載;這些在根文件系統一章有詳細的介紹;
『貳』 如何通過linux源碼樹製作linux kernel headers用於內核模塊開發
先查看自己OS使用的內核版本
shana@shana:~$ uname -r
2.6.22-14-generic
如果安裝系統時,自動安裝了源碼。在 /usr/src 目錄下有對應的使用的版本目錄。例如下(我是自己下的)
shana@shana:/usr/src$ ls
linux-headers-2.6.22-14
linux-headers-2.6.22-14-generic
linux-source-2.6.22
linux-source-2.6.22.tar.bz2
shana@shana:/usr/src$
如果沒有源碼。(一般ubuntu 都沒有吧)
查看一下可一下載的源碼包(切記不要使用超級用戶使用此命令否則……會提示沒有此命令)
shana@shana:/usr/src$ apt-cache search linux-source
linux-source - Linux kernel source with Ubuntu patches
xen-source-2.6.16 - Linux kernel source for version 2.6.17 with Ubuntu patches
linux-source-2.6.22 - Linux kernel source for version 2.6.22 with Ubuntu patches
shana@shana:/usr/src$
我選擇了 linux-source-2.6.22 - Linux kernel source for version 2.6.22 with Ubuntu patches 這個~
然後 install 之
shana@shana:/usr/src$ sudo apt-get install linux-source-2.6.22
下載完成後,在/usr/src下,文件名為:linux-source-2.6.22.tar.bz2,是一個壓縮包,解壓縮既可以得到整個內核的源代碼:
注意 已經切換到超級用戶模式
root@shana:/usr/src#tar jxvf linux-source-2.6.20.tar.bz2
解壓後生成一個新的目錄/usr/src/linux-source-2.6.22,所有的源代碼都在該目錄下。
進入該目錄
開始配置內核 選擇最快的原版的配置(默認)方式 (我是如此)
root@shana:/usr/src/linux-source-2.6.22# make oldconfig
當然你也可以使用 自知前己喜歡的配置方式 如 menuconfig , xconfig(必須有GTK環境吧)。反正不用剪裁什麼,所以不管那種方式能配置它就行了。
完成後,開始make 吧拆模 這兒比較久 一般有1一個小時吧。(保證空間足夠 我編譯完成後 使用了1.8G) 我分區時分給/目錄30G的空間,我沒遇到這問題。倒是我朋友遇到了。
shana@shana:/usr/src/linux-source-2.6.22$ make
shana@shana:/usr/src/linux-source-2.6.22$ make bzImage
當然,第一個make也可以不執行,直接make bzImage。執行結束後,可以看到在當前目錄下生成了一個新的文件: vmlinux, 其屬性為-rwxr-xr-x。
然後 :
root@shana:/usr/src/linux-source-2.6.22#make moles
root@shana:/usr/src/linux-source-2.6.22#make moles_install
執行結束之後,會在/lib/moles下生成新的目錄/lib/moles/2.6.22-14-generic/
。 在隨後的編譯模塊文件時,要用到這個路徑下的build目錄。至此,搭御清內核編譯完成。可以重啟一下系統。
至此 內核樹就建立啦
『叄』 如何在Android 內核源碼樹中添加app應用
1. 不帶jni本地代碼
首先,在Android內核源碼中選擇一個目錄來存放HelloWorld應用的源碼,比如放到/packages/apps目錄下。和陪
(1) 在HelloWorld目錄下新建Android.mk文件,示例如下:
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE_TAGS := eng
LOCAL_SRC_FILES := $(call all-subdir-java-files)
LOCAL_PACKAGE_NAME := HelloWorld
include $(BUILD_PACKAGE)
註:LOCAL_MODULE_TAGS的備選值有user,eng,tests,optional,這里使用的TAGS值為eng,因此,毀前僅當用戶指定的編譯纖棚清選項為eng時才會編譯該工程。
『肆』 如何構造內核源代碼樹
Linux內核的配置系統由三個部分組成,分別是:
Makefile:分布在 Linux 內核源代碼中的 Makefile,定義 Linux 內核的編譯規則;
配置文件(config.in):給用戶提供配置選擇的功能;
配置工具:包括配置命令解釋器(對配置腳本中使用的配置命令進行解釋)和配置用戶界面(提供基於字元界面、基於 Ncurses 圖形界面以及基於 Xwindows 圖形界面的用戶配置界面,各自對應於 Make config、Make menuconfig 和 make xconfig)。
這些配置工具都是使用腳本語言,如 Tcl/TK、Perl 編寫的(也包含一些用 C 編寫的代碼)。本文並不是對配置系統本身進行分析,而是介紹如何使用配置系統。所以,除非是配置系統的維護者,一般的內核開發者無須了解它們的原理,只需要知道如何編寫 Makefile 和配置文件就可以。所以,在本文中,我們只對 Makefile 和配置文件進行討論。另外,凡是涉及到與具體 CPU 體系結構相關的內容,我們都以 ARM 為例,這樣不僅可以將討論的問題明確化,而且對內容本身不產生影響。
2. Makefile
2.1 Makefile 概述
Makefile 的作用是根據配置的情況,構造出需要編譯的源文件列表,然後分別編譯,並把目標代碼鏈接到一起,最終形成 Linux 內核二進制文件。
由於 Linux 內核源代碼是按照樹形結構組織的,所以 Makefile 也被分布在目錄樹中。Linux 內核中的 Makefile 以及與 Makefile 直接相關的文件有:
Makefile:頂層 Makefile,是整個內核配置、編譯的總體控制文件。
.config:內核配置文件,包含由用戶選擇的配置選項,用來存放內核配置後的結果(如 make config)。
arch/*/Makefile:位於各種 CPU 體系目錄下的 Makefile,如 arch/arm/Makefile,是針對特定平台的 Makefile。
各個子目錄下的 Makefile:比如 drivers/Makefile,負責所在子目錄下源代碼的管理。
Rules.make:規則文件,被所有的 Makefile 使用。
用戶通過 make config 配置後,產生了 .config。頂層 Makefile 讀入 .config 中的配置選擇。頂層 Makefile 有兩個主要的任務:產生 vmlinux 文件和內核模塊(mole)。為了達到此目的,頂層 Makefile 遞歸的進入到內核的各個子目錄中,分別調用位於這些子目錄中的 Makefile。至於到底進入哪些子目錄,取決於內核的配置。在頂層 Makefile 中,有一句:include arch/$(ARCH)/Makefile,包含了特定 CPU 體系結構下的 Makefile,這個 Makefile 中包含了平台相關的信息。
位於各個子目錄下的 Makefile 同樣也根據 .config 給出的配置信息,構造出當前配置下需要的源文件列表,並在文件的最後有 include $(TOPDIR)/Rules.make。
Rules.make 文件起著非常重要的作用,它定義了所有 Makefile 共用的編譯規則。比如,如果需要將本目錄下所有的 c 程序編譯成匯編代碼,需要在 Makefile 中有以下的編譯規則:
%.s: %.c
$(CC) $(CFLAGS) -S $< -o $@
有很多子目錄下都有同樣的要求,就需要在各自的 Makefile 中包含此編譯規則,這會比較麻煩。而 Linux 內核中則把此類的編譯規則統一放置到 Rules.make 中,並在各自的 Makefile 中包含進了 Rules.make(include Rules.make),這樣就避免了在多個 Makefile 中重復同樣的規則。對於上面的例子,在 Rules.make 中對應的規則為:
%.s: %.c
$(CC) $(CFLAGS) $(EXTRA_CFLAGS) $(CFLAGS_$(*F)) $(CFLAGS_$@) -S $< -o $@
2.2 Makefile 中的變數
頂層 Makefile 定義並向環境中輸出了許多變數,為各個子目錄下的 Makefile 傳遞一些信息。有些變數,比如 SUBDIRS,不僅在頂層 Makefile 中定義並且賦初值,而且在 arch/*/Makefile 還作了擴充。
常用的變數有以下幾類:
1) 版本信息
版本信息有:VERSION,PATCHLEVEL, SUBLEVEL, EXTRAVERSION,KERNELRELEASE。版本信息定義了當前內核的版本,比如 VERSION=2,PATCHLEVEL=4,SUBLEVEL=18,EXATAVERSION=-rmk7,它們共同構成內核的發行版本KERNELRELEASE:2.4.18-rmk7
2) CPU 體系結構:ARCH
在頂層 Makefile 的開頭,用 ARCH 定義目標 CPU 的體系結構,比如 ARCH:=arm 等。許多子目錄的 Makefile 中,要根據 ARCH 的定義選擇編譯源文件的列表。
3) 路徑信息:TOPDIR, SUBDIRS
TOPDIR 定義了 Linux 內核源代碼所在的根目錄。例如,各個子目錄下的 Makefile 通過 $(TOPDIR)/Rules.make 就可以找到 Rules.make 的位置。
SUBDIRS 定義了一個目錄列表,在編譯內核或模塊時,頂層 Makefile 就是根據 SUBDIRS 來決定進入哪些子目錄。SUBDIRS 的值取決於內核的配置,在頂層 Makefile 中 SUBDIRS 賦值為 kernel drivers mm fs net ipc lib;根據內核的配置情況,在 arch/*/Makefile 中擴充了 SUBDIRS 的值,參見4)中的例子。
4) 內核組成信息:HEAD, CORE_FILES, NETWORKS, DRIVERS, LIBS
Linux 內核文件 vmlinux 是由以下規則產生的:
vmlinux: $(CONFIGURATION) init/main.o init/version.o linuxsubdirs
$(LD) $(LINKFLAGS) $(HEAD) init/main.o init/version.o
--start-group
$(CORE_FILES)
$(DRIVERS)
$(NETWORKS)
$(LIBS)
--end-group
-o vmlinux
可以看出,vmlinux 是由 HEAD、main.o、version.o、CORE_FILES、DRIVERS、NETWORKS 和 LIBS 組成的。這些變數(如 HEAD)都是用來定義連接生成 vmlinux 的目標文件和庫文件列表。其中,HEAD在arch/*/Makefile 中定義,用來確定被最先鏈接進 vmlinux 的文件列表。比如,對於 ARM 系列的 CPU,HEAD 定義為:
HEAD := arch/arm/kernel/head-$(PROCESSOR).o
arch/arm/kernel/init_task.o
表明 head-$(PROCESSOR).o 和 init_task.o 需要最先被鏈接到 vmlinux 中。PROCESSOR 為 armv 或 armo,取決於目標 CPU。 CORE_FILES,NETWORK,DRIVERS 和 LIBS 在頂層 Makefile 中定義,並且由 arch/*/Makefile 根據需要進行擴充。 CORE_FILES 對應著內核的核心文件,有 kernel/kernel.o,mm/mm.o,fs/fs.o,ipc/ipc.o,可以看出,這些是組成內核最為重要的文件。同時,arch/arm/Makefile 對 CORE_FILES 進行了擴充:
# arch/arm/Makefile
# If we have a machine-specific directory, then include it in the build.
MACHDIR := arch/arm/mach-$(MACHINE)
ifeq ($(MACHDIR),$(wildcard $(MACHDIR)))
SUBDIRS += $(MACHDIR)
CORE_FILES := $(MACHDIR)/$(MACHINE).o $(CORE_FILES)
endif
HEAD := arch/arm/kernel/head-$(PROCESSOR).o
arch/arm/kernel/init_task.o
SUBDIRS += arch/arm/kernel arch/arm/mm arch/arm/lib arch/arm/nwfpe
CORE_FILES := arch/arm/kernel/kernel.o arch/arm/mm/mm.o $(CORE_FILES)
LIBS := arch/arm/lib/lib.a $(LIBS)
5) 編譯信息:CPP, CC, AS, LD, AR,CFLAGS,LINKFLAGS
在 Rules.make 中定義的是編譯的通用規則,具體到特定的場合,需要明確給出編譯環境,編譯環境就是在以上的變數中定義的。針對交叉編譯的要求,定義了 CROSS_COMPILE。比如:
CROSS_COMPILE = arm-linux-
CC = $(CROSS_COMPILE)gcc
LD = $(CROSS_COMPILE)ld
......
CROSS_COMPILE 定義了交叉編譯器前綴 arm-linux-,表明所有的交叉編譯工具都是以 arm-linux- 開頭的,所以在各個交叉編譯器工具之前,都加入了 $(CROSS_COMPILE),以組成一個完整的交叉編譯工具文件名,比如 arm-linux-gcc。
CFLAGS 定義了傳遞給 C 編譯器的參數。
LINKFLAGS 是鏈接生成 vmlinux 時,由鏈接器使用的參數。LINKFLAGS 在 arm/*/Makefile 中定義,比如:
# arch/arm/Makefile
LINKFLAGS :=-p -X -T arch/arm/vmlinux.lds
6) 配置變數CONFIG_*
.config 文件中有許多的配置變數等式,用來說明用戶配置的結果。例如 CONFIG_MODULES=y 表明用戶選擇了 Linux 內核的模塊功能。
.config 被頂層 Makefile 包含後,就形成許多的配置變數,每個配置變數具有確定的值:y 表示本編譯選項對應的內核代碼被靜態編譯進 Linux 內核;m 表示本編譯選項對應的內核代碼被編譯成模塊;n 表示不選擇此編譯選項;如果根本就沒有選擇,那麼配置變數的值為空。
2.3 Rules.make 變數
前面講過,Rules.make 是編譯規則文件,所有的 Makefile 中都會包括 Rules.make。Rules.make 文件定義了許多變數,最為重要是那些編譯、鏈接列表變數。
O_OBJS,L_OBJS,OX_OBJS,LX_OBJS:本目錄下需要編譯進 Linux 內核 vmlinux 的目標文件列表,其中 OX_OBJS 和 LX_OBJS 中的 "X" 表明目標文件使用了 EXPORT_SYMBOL 輸出符號。
M_OBJS,MX_OBJS:本目錄下需要被編譯成可裝載模塊的目標文件列表。同樣,MX_OBJS 中的 "X" 表明目標文件使用了 EXPORT_SYMBOL 輸出符號。
O_TARGET,L_TARGET:每個子目錄下都有一個 O_TARGET 或 L_TARGET,Rules.make 首先從源代碼編譯生成 O_OBJS 和 OX_OBJS 中所有的目標文件,然後使用 $(LD) -r 把它們鏈接成一個 O_TARGET 或 L_TARGET。O_TARGET 以 .o 結尾,而 L_TARGET 以 .a 結尾。
『伍』 linux 模塊編程為什麼要編譯內核源碼樹
當然需要。。。
第一點,就是源碼樹中有相應的頭文件和函數的實現,沒有源碼樹,你哪調用去呢?(PC上編譯的時候內核有導出符號,系統中有頭文件,這樣就可以引用內核給你的介面了,但是只能編譯你PC上版本的內核可載入的模塊)。
第二個,內核模塊中會記錄版本號的部分,需要記錄版本號的原因是不同的內核版本之間,那些介面和調用可能會有比較大的差異,因此必須要保證你的代碼和某個特定的內核對應,這樣編譯出來的模塊就可以(也是只能)在運行這個內核版本的Linux系統中載入,否則一個很簡單的異常就會導致內核崩潰,或者你的代碼根本無法編譯通過(介面名變了)。
我上面說的是編譯模塊的情況,當然如果是把模塊直接編譯到內核當中去的話,那就不用說了,沒有內核源碼,你無法編譯內核。
『陸』 linux驅動中內核源碼樹和載入模塊的問題
恩? 理解不全,要重新編譯一個內核來使用,要注意兩點:
a,安裝 LKMs 到 /lib/moles 的子目錄下;
b,將新的內核映像拷貝到 /boot 分區中,並配置 grub/lilo;
centos/redhat 發行版中的內核版本有自己很多的補丁修改,不同於主流的
從 kernel.org 中下載下來的內核。你只是簡單的修改版本名稱那是不行的,
mod version 內部還是會被認為是兩個不同的內核(實際上也是不同的)。
在 centos/redhat 上為本機運行著的內核開發驅動,實際上可以不用去下載
任何版本的內核代碼樹,你只需要安裝 相對應的 kernel-devel rpm 包即可。
當然,為了更方便,你可以直接從 centos 官網下載合適的源碼包來重新編
譯後再開發你的驅動程序。
更多問題,可以上巨立安郵件列表中進行交流。
巨立安技術是你在arm/x86下學習 linux 開發的上佳指導。
『柒』 Linux內核源碼樹是什麼是Linux源碼經過編譯之後得到的嗎
內核源碼樹就是內核源碼,只不過源碼的組織形式是從根目錄開始,包含各種文件夾,形象稱之為樹
『捌』 linux 驅動程序開發,為什麼要編譯內核源碼樹
您好,這樣的情況建議您下載最新版本的驅動精靈,或是直接在線升級一下驅動精靈。希望可以幫到您。