linux源码树结构
参考 http://www.360doc.com/content/13/0410/17/7044580_277403053.shtmlphp
目录 | 描述 |
---|---|
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 | 虚拟化基础结构 |
获取源码包的方式
为何要活取源码包?
在笔者到官网下载源码时,源码下面有以下说明:html
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
可是为何咱们还要活取源码呢?
前面已经提到若是你只是想为内核编译第三方的模块,那么,你不需下载此源码包。安装内核头文件包或许会更适合你。
可是不少时候咱们作嵌入式开发或者驱动开发,一个基本的Linux设备驱动开发环境由宿主机和目标机组成,宿主机就是用来作驱动开发工做的主机,目标机就是用来运行和测试设备驱动的主机,在宿 主机上须要有开发工具(gcc,gdb,make等)和linux源码(版本要对应目标机上的linux内核),而目标机上只要运行linux便可。因为 步骤有所不一样,下面分为普通Linux设备驱动开发和嵌入式Linux设备驱动开发两种状况来说述环境的搭建和驱动程序的编译:ios
普通Linux设备驱动开发
普通Linux主要是区别于于嵌入式Linux(通常指uClinux),在这种开发中宿主机和目标机能够是一台主机,
即在本机上开发编译而后在本机 上加载运行(Linux设备驱动也能够直接编译进内核,但为了开发工做方便,通常采用动态加载的方式),
固然也能够是两台主机,
若是是两台主机的话,要保证宿主机上的linux源码的版本号与目标机中的linux内核版本一致。
普通Linux设备驱动开发的步骤以下:
①在宿主机上安装开发工具和下载linux源码(要求版本号和目标机上的linux内核版本一致)。开发工具主要有gcc、gdb、make等,
②编写Linux驱动程序
是须要修改内核源代码的。那么这就须要咱们在本地主机上安装一份源码,在编译成库后,在进行驱动开发。
③编写Makefile文件
④编译出驱动文件
⑤加载并测试以及卸载:加载使用insmod或modprobe命令来实现,使用rmmod命令卸载驱动模块sql
嵌入式Linux设备驱动开发
这种开发中通常目标机为带有嵌入式处理器的开发板,而宿主机为PC,开发环境须要在宿主机上搭建,嵌入式Linux设备驱动开发的步骤以下:
①在宿主机上下载嵌入式Linux的源码,并安装嵌入式Linux开发工具(针对于不一样的嵌入式处理器,工具也有所不一样,如对应于Arm的arm-gcc系列,针对nios2处理器的nios2-cc系列)
②编写Linux设备驱动驱动程序,将该文件复制到(linux 源码目录)/drivers/(目标文件夹)/中
③配置以及修改内核源码的信息以及makefile文件,在此步配置中能够选择将咱们编写的驱动编译进内核仍是不选择编译,可是不能选择编译成模块
④配置而且编译内核
⑤将内核烧写在开发版上进行测试:将生成的zImage文件下载到开发板,开发板上的嵌入式Linux启动后能够用insmod或modprobe加载驱动模块,测试完毕后能够经过rmmod命令卸载驱动模块shell
总结
所以在开发驱动的时候若是你只是想为内核编译第三方的模块,那么,你不需下载此源码包。安装内核头文件包或许会更适合咱们,可是多数状况下,咱们可能时须要修改内核源代码信息的,这就须要咱们在宿主机维护一份与目标机上相同的内核信息,不然咱们怎么保证咱们编写的驱动能够在目标机器上运行呢。。。。ubuntu
源码包活取的方法
linux源码能够经过如下几种途径得到:
①直接去www.kernel.org下载
https://www.kernel.org/pub/linux/kernel/centos
②经过包管理工具下载源码,在debian和Ubuntu中能够经过下面这个命令下载,apt-get install linux-source-(版本号) ,下载后的文件在/usr/src目录中,解压到该目录便可安全
获取源码包
注意:
若是您只是为了简单的学习下驱动的开发,而不指望深层次的探究Linux内核的机制,那么您彻底能够跳过此步骤,单使用头文件您是彻底能够进行简单的第三方驱动开发的。bash
直接从内核官网上下载
使用发行版自带的源码包
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