linux源碼樹結構
參考 http://www.360doc.com/content/13/0410/17/7044580_277403053.shtml
目錄 | 描述 |
---|---|
arch | 目錄包括了所有和體系結構相關的核心代碼。它下面的每一個子目錄都代表一種Linux支持的體系結構,例如i386就是Intel CPU及與之相兼容體系結構的子目錄。PC機一般都基於此目錄。 |
block | 塊設備I/O層 |
crypto | 加密API |
documentation | 目錄下是一些文檔,是對每個目錄作用的具體說明。 |
drivers | 目錄中是系統中所有的設備驅動程序。它又進一步划分成幾類設備驅動,每一種有對應的子目錄 |
firmware | 使用某些驅動程序而需要的設備固件 |
fs | VFS和各種文件系統,存放Linux支持的文件系統代碼。不同的文件系統有不同的子目錄對應,如ext3文件系統對應的就是ext3子目錄。 |
include | 目錄包括編譯核心所需要的大部分頭文件,例如與平台無關的頭文件在include/linux子目錄下。 |
init | 目錄包含核心的初始化代碼(不是系統的引導代碼),有main.c和Version.c兩個文件。這是研究核心如何工作的好起點。 |
ipc | 核心進程間的通信代碼 |
kernel | 內核管理的核心代碼放在這里。同時與處理器結構相關代碼都放在arch/*/kernel目錄下 |
lib | 通用的核心庫的代碼,不過與處理器結構相關的庫代碼被放在arch/*/lib/目錄下 |
mm | 內存管理子系統和VM。與具體硬件體系結構相關的內存管理代碼位於arch/*/mm目錄下。 |
net | 目錄里是核心的網絡部分代碼,其每個子目錄對應於網絡的一個方面。 |
samples | 示例,示范代碼 |
scripts | 配置和編譯內核所用的腳本文件 |
security | linux安全模塊 |
sound | 語音子系統 |
usr | 早期的用戶空間代碼,所謂的initramfs |
tools | 在linux開發中有用的工具 |
virt | 虛擬化基礎結構 |
獲取源碼包的方式
為什么要活取源碼包?
在筆者到官網下載源碼時,源碼下面有如下說明:
If you are simply trying to build third-party modules for your kernel, you do not want this package. Install the appropriate linux-headers package instead. 意思是,如果你只是想為內核編譯第三方的模塊,那么,你不需下載此源碼包。安裝內核頭文件包或 許會更適合你。
如果你的ubuntu是保持更新的(比如您經常執行sudo apt-get update和dist-upgrade),
那么您的系統是安裝有內核頭文件包的,不信您到/usr/src目錄下查看,是不是有linux-headers-[版本號]-generic的文件夾呢,呵呵。我現在可以說,你可以在此開發你的驅動程序了。
但是為什么我們還要活取源碼呢?
前面已經提到如果你只是想為內核編譯第三方的模塊,那么,你不需下載此源碼包。安裝內核頭文件包或許會更適合你。
但是很多時候我們做嵌入式開發或者驅動開發,一個基本的Linux設備驅動開發環境由宿主機和目標機組成,宿主機就是用來做驅動開發工作的主機,目標機就是用來運行和測試設備驅動的主機,在宿 主機上需要有開發工具(gcc,gdb,make等)和linux源碼(版本要對應目標機上的linux內核),而目標機上只要運行linux即可。由於 步驟有所不同,下面分為普通Linux設備驅動開發和嵌入式Linux設備驅動開發兩種情況來講述環境的搭建和驅動程序的編譯:
普通Linux設備驅動開發
普通Linux主要是區別於於嵌入式Linux(一般指uClinux),在這種開發中宿主機和目標機可以是一台主機,
即在本機上開發編譯然后在本機 上加載運行(Linux設備驅動也可以直接編譯進內核,但為了開發工作方便,一般采用動態加載的方式),
當然也可以是兩台主機,
如果是兩台主機的話,要保證宿主機上的linux源碼的版本號與目標機中的linux內核版本一致。
普通Linux設備驅動開發的步驟如下:
①在宿主機上安裝開發工具和下載linux源碼(要求版本號和目標機上的linux內核版本一致)。開發工具主要有gcc、gdb、make等,
②編寫Linux驅動程序
是需要修改內核源代碼的。那么這就需要我們在本地主機上安裝一份源碼,在編譯成庫后,在進行驅動開發。
③編寫Makefile文件
④編譯出驅動文件
⑤加載並測試以及卸載:加載使用insmod或modprobe命令來實現,使用rmmod命令卸載驅動模塊
嵌入式Linux設備驅動開發
這種開發中一般目標機為帶有嵌入式處理器的開發板,而宿主機為PC,開發環境需要在宿主機上搭建,嵌入式Linux設備驅動開發的步驟如下:
①在宿主機上下載嵌入式Linux的源碼,並安裝嵌入式Linux開發工具(針對於不同的嵌入式處理器,工具也有所不同,如對應於Arm的arm-gcc系列,針對nios2處理器的nios2-cc系列)
②編寫Linux設備驅動驅動程序,將該文件復制到(linux 源碼目錄)/drivers/(目標文件夾)/中
③配置以及修改內核源碼的信息以及makefile文件,在此步配置中可以選擇將我們編寫的驅動編譯進內核還是不選擇編譯,但是不能選擇編譯成模塊
④配置並且編譯內核
⑤將內核燒寫在開發版上進行測試:將生成的zImage文件下載到開發板,開發板上的嵌入式Linux啟動后可以用insmod或modprobe加載驅動模塊,測試完畢后可以通過rmmod命令卸載驅動模塊
總結
因此在開發驅動的時候如果你只是想為內核編譯第三方的模塊,那么,你不需下載此源碼包。安裝內核頭文件包或許會更適合我們,但是多數情況下,我們可能時需要修改內核源代碼信息的,這就需要我們在宿主機維護一份與目標機上相同的內核信息,否則我們怎么保證我們編寫的驅動可以在目標機器上運行呢。。。。
源碼包活取的方法
linux源碼可以通過以下幾種途徑獲得:
①直接去www.kernel.org下載
https://www.kernel.org/pub/linux/kernel/
②通過包管理工具下載源碼,在debian和Ubuntu中可以通過下面這個命令下載,apt-get install linux-source-(版本號) ,下載后的文件在/usr/src目錄中,解壓到該目錄即可
獲取源碼包
注意:
如果您只是為了簡單的學習下驅動的開發,而不期望深層次的探究Linux內核的機制,那么您完全可以跳過此步驟,單使用頭文件您是完全可以進行簡單的第三方驅動開發的。
直接從內核官網上下載
使用發行版自帶的源碼包
Ubunto14.04
安裝編譯內核所需要的軟件build-essential、autoconf、automake、cvs、subversion
sudo apt-get install build-essential kernel-package libncurses5-dev
注意:libncurses5這個軟件包在使用menuconfig配置內核的時候會用到。
ls一下/usr/src首先看下我們的系統中有沒有源碼包,僅僅有內核頭文件包
進入/usr/src ,在這里構建源碼樹,我們用下面指令查看可用的源碼包
sudo apt-cache search linux-source
可以看到得到如下信息
linux-source - Linux kernel source with Ubuntu patches linux-source-3.13.0 - Linux kernel source for version 3.13.0 with Ubuntu patches
那么就讓我們來下載3.13.0版的kernel,通過使用命令下載內核
sudo apt-get install linux-source-3.13.0
下載完成后,會自動的存放在/usr/src下,
在/usr/src/下ls以下
解壓縮源碼包
sudo tar jxvf linux-source-3.13.0.tar.bz2
這樣我們就已經獲取到了一份完整的源碼包,
CentOS構建源碼樹
獲取內核頭文件
構建的之前,最好先
yum update
把內核升級到最新版本。至於具體安裝哪一份源碼樹,要看你用的哪一種內核,用uname -a可以看到。
先檢查看看有哪些源碼包
yum list | grep kernel
如果用的普通內核,就
yum install kernel-headers kernel-devel
如果用的PAE內核,就
yum install kernel-headers kernel-PAE-devel
如果用的xen內核,就
yum install kernel-headers kernel-xen-devel
centos安裝內核源代碼
但是上面的方式只會為我們安裝內核的頭文件目錄以及庫信息,如果我們期望獲取到源碼需要下面的操作
參照
下面我們的方式是使用構建本地組內搭建內部yum源的方式安裝linux內核的源碼包
目前我們實驗室的服務器系統是centos5.11,地址 http://vault.centos.org/5.11/os/SRPMS/kernel-2.6.18-398.el5.src.rpm
不同的版本,下載地址更改一下即可
其他下載地址http://rpm.pbone.net/index.php3
- 1.安裝 rpmbuild
rpmbuild是用來制作rpm包的工具
yum install rpm-build redhat-rpm-config unifdef
- 2.下載源碼包
wget http://vault.centos.org/5.11/os/SRPMS/kernel-2.6.18-398.el5.src.rpm
- 3.安裝內核源碼
rpm -ivh kernel-2.6.18-274.el5.src.rpm
這樣我們的源碼就已經下載好了,在/usr/src/redhat目錄下有我們需要的所有東西。
但是到現在我們只是安裝了環境目錄,以及源碼的壓縮包,但是並沒有安裝
我們可以看到我們已經有了源碼的壓縮包,但是並沒有解壓縮,因此我們下面執行的操作其實就是用工具對其進行解壓縮。
* 4.安裝源碼包
cd /usr/src/redhat/SPECS
rpmbuild -bp --target=`uname -m` kernel.spec 2> prep-err.log | tee prep-out.log
以上步驟完成以后,查看prep-err.log錯誤日志,
如果沒有錯誤,則成功解出的內核源碼位置在 /usr/src/redhat/BUILD 目錄下
編譯內核
按原來的kernel配置,配置kernel.
sudo make oldconfig
make(相當耗時),開始編譯內核
sudo make
編譯內核鏡像
sudo make bzImage
安裝內核模塊
make modules_install
執行結束之后,會在/lib/modules下生成新的目錄/lib/modules/3.13.0-48-generic/, 下面的build文件就是編譯模塊的要用到的文件。至此內核編譯完成。
卸載無用的內核相關文件
我們為不同的目標機配置不同的內核模塊,這樣一段時間后,我們的系統中會有多份內核信息,再加上我們的系統由於自動升級,系統里也會安裝了很多內核。這樣始終用不到的舊內核或者無用內核有必要清理一下,以節省啟動時間和硬盤空間。
然后通過查看本機上所有內核的列表來決定哪些需要刪除掉:
運行命令:
dpkg --get-selections|grep linux
例如我本機顯示為:
注意:
不要刪除當前使用的版本.后面的install表示已安裝,deinstall表示曾經安裝過,現在已被刪除(已不占空間).
首先可查看當前用的內核是哪個,可通過命令:uname -a 來獲得信息。
其中帶有image的就是內核文件,因此可看出我的機器上共五個內核鏡像版本。但是其實只安裝了2個鏡像,這個卸載的時候我們就會發現,我當前使用的是3.13.0-49,所以決定將其它沒用的內核刪除。
刪除內核鏡像的命令
刪除的命令為:sudo apt-get remove linux-image-XXXX
例如我要卸載3.13.0-48的舊內核鏡像,那么運行命令
sudo apt-get purge linux-image-3.13.0-48-generic
或者
sudo apt-get remove linux-image-3.13.0-48-generic
我們會發現linux-image-extra-3.13.0-48-generic也會跟着被卸載,
這時候我們ls /lib/modules/3.13.0-48-generic/會發現,安裝的內核鏡像文件已經沒有了
卸載內核頭文件
sudo apt-get purge linux-headers-3.13.0-48
或者
sudo apt-get remove linux-headers-3.13.0-48
這條命令會自動把linux-headers-3.13.0-48-generic刪除,如果未刪除我們同樣可以使用命令刪除即可。
最后再次運行命令,查看安裝的內核文件,查看是否卸載成功
dpkg --get-selections|grep linux
最后最好刷新一個啟動菜單
sudo update-grub