编译Linux内核
下面的实验以 debian7.5 64bit 为例.
获取源码
获取 debian7.5 本身的源码非常简单:
sudo apt-get install linux-source
https://www.kernel.org/ 的git上提供的源码分支非常多, 刚开始学习源码主要关注下面几个分支:
- linus分支: https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/
linux创始人的分支, 不用说肯定最重要, 它是所有分支的根源. 处于 "mainline" 的地位.
这个分支还有个好听的名字 – "vanilla(香草)" 内核. - linux-next树: https://git.kernel.org/cgit/linux/kernel/git/next/linux-next.git/
这个一个为发布将来的版本而积累新代码并进行测试的源码树.
由 Stephen Rothwell 等人进行管理和维护 - stable树: https://git.kernel.org/cgit/linux/kernel/git/stable/linux-stable.git/
这是一个主要针对过去发布的内核版本进行bug修改, 使其更加稳定的树.
由 Greg Kroah-Hartman, Chris Wright 进行管理和维护.
针对某个Linus树的稳定版维护一般持续6个月左右, 也有更持久的.
上面的列出的git树中都可以获取想要的源码.
编译内核
其实编译内核和编译普通软件也没多大区别, 只是内核编译的参数非常之多.
下面就来先看看如何设置内核编译参数
内核编译选项
编译选项个数
内核的编译选项的个数非常多, v2.6.38的内核中就有 12 000 个左右的设置选项(这是包含所有arch的配置选项).
内核编译选项不仅多, 有些编译选项之间还存在依赖关系, 所以手动设置编译选项几乎是不可能的.
值得庆幸的是, 只要知道自己需要设置的那些选项, 就可以使用 make ***config 来进行设置, 它还会自动处理依赖关系.配置编译选项:
设置内核编译选项是通过 kconfig 这个工具来完成的.
kconfig 的源码就是内核代码中 script/kconfig 目录下各个编译选项的选择有3种方式:
- =y :: 直接编译到内核中
- =m :: 以模块方式编译到内核中
- 不设置 :: 不编译
编译方法:
- make menuconfig :: 源码根目录下生成 .config (没有会自动生成), .config中就是各个内核编译选项的选择状况.
- make defconfig :: 根据当前系统的架构默认 .config 生成内核源码目录下的 .config (每个架构的配置文件: ex. arch/x86/configs/x86_64_defconfig)
- make oldconfig :: 将已有的 .config 放到源码根目录下后执行, 目的是为了复用之前的内核编译选项的配置.
- make xconfig :: 图形化配置, 需要qt3, 个人觉得没有必要, 有 make menuconfig 就足够了.
- make localmodconfig :: 生成以正在使用的内核模块为对象的 .config
编译
编译很简单, 内核编译选项设置好之后, 只需简单的命令 make, 就可以编译了.
由于内核代码的庞大, 所以和一般应用程序相比, 编译时间会很长. 可以尝试以下方法来加快编译速度:
不用的驱动程序都不要设置, 这样就不会编译
利用make的 -j 选项来并发编译, ex. make -j N (N是并发数). 如果你的机器有2个CPU, 可以用 make -j 2 来提高编译速度
使用 make localmodconfig 来生成仅以正在使用的内核模块为对象的 .config (一般这样生成的.config中包含的内核模块最少, 所以编译速度快)
编译时间比较: 测试环境 - debian v7.5虚拟机(cpu: 单核, 内存: 512MB)
| .config生成 | make时间 | 生成的modules | 备注 |
|---|---|---|---|
| make menuconfig | 1小时13分41秒 | 3052个.ko, 共1.2GB | 默认配置, 什么也不选择 |
| make localmodconfig | 19分36秒 | 337 个.ko, 共176MB |
注 modules 是通过 make modules_install 之后, 在 /lib/modules 中根据编译内核版本号来查看的
查看有多少个 .ko 文件的方法:
cd /lib/modules/3.2.60
find . -name '*.ko' | wc -l
分开编译
模块和内核不在一起的编译, 就是在现有的内核中追加一些内核模块时, 不需要将内核也重新编译.
模块分开编译的方法很简单, 参考之前的博客: 《Linux内核设计与实现》读书笔记(六)- 内核数据结构 这篇博客中的例子就是和内核分开编译的模块.
交叉编译
交叉编译就是在当前平台上编译其他平台上的内核二进制映像, 比如在 x86_64 平台上编译 arm 的内核映像.
交叉编译需要目标平台的交叉编译器. 编译时主要是 ARCH 和 CROSS_COMPILE 2个变量的设置.
下面举个交叉编译 ARM 的例子: 公司用的制作 Cubieboard 板子上的image中的一段编译内核的代码
make -C ${CB_KSRC_DIR} O=${CB_KBUILD_DIR} ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- kernel_defconfig
make -C ${CB_KSRC_DIR} O=${CB_KBUILD_DIR} ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- -j4 INSTALL_MOD_PATH=${CB_TARGET_DIR} uImage modules
上述 第一行 是编译内核源码. 第二行 是创建 uImage 格式的内核映像以及创建内核模块
最终在 INSTALL_MOD_PATH 生成的内核模块可以直接拷贝到 arm机器上使用.
生成内核包
debian 系 linux下生成 内核源码包的方法
make deb-pkg
安装内核
make modules_install (安装内核模块到 /lib/modules 下)
make install (安装内核二进制映像, 生成并安装boot初始化文件系统映像文件)
卸载内核
- 删除/lib/modules/目录下不需要的内核库文件
- 删除/usr/src/kernel/目录下不需要的内核源码
- 删除/boot目录下启动的核心档案禾内核映像
- 更改grub的配置,删除不需要的内核启动列表
内核 Makefile 中一些有用的 target
- make help : 内核Makefile中的各种 target
- make cscope : 生成 cscope 文件
- make tags/TAGS : tags可用于vim, TAGS可用于emacs
编译Linux内核的更多相关文章
- 如何解决编译linux内核(解决声卡问题),遭遇fatal error: linux/limits.h: 没有那个文件或目录
最近帮一位上海的朋友搞一块小板,在ubuntu15.04 vivid上已经加载了对应了.ko驱动包 但关键是系统根本就枚举不到该声卡ALC5640,试了OpenSUSE也是一样的结果,看来是内核漏加载 ...
- Centos下编译Linux内核
Linux内核编译是一件简单却费事的事.但是独立的编译linux内核会帮助你很好的理解Linux内核的工作机理. 首先编译linux内核我们需要在当前linux操作系统下安装gcc编译器,因为我是Ce ...
- 编译linux内核时出错
在编译linux内核的时候使用make menuconfig 可能出现下面的错误 *** Unable to find the ncurses libraries or the*** required ...
- Mac下重新编译Linux内核
Mac下重新编译Linux内核 操作系统实验,要求添加系统调用并重新编译内核,这里记录一下编译内核的过程 0.下载VirtualBox 博主一直用parallel desk,但因为驱动等问题,在PD上 ...
- 为什么要编译Linux内核?
新的内核修订了旧内核的bug,并增加了许多新的特性.如果用户想要使用这些新特性,或想根据自己的系统度身定制一个更高效,更稳定的内核,就需要重新编译Linux内核. 通常,更新的内核会支持更多的硬件,具 ...
- 编译Linux内核(Mac OS平台)
操作系统第一次实验需要编译Linux内核,我之前在Mac上一直使用的都是Parallels Desktop这个软件,所以这次也将课程网站上提供的Ubuntu安装在了PD上,但是编译完内核后无法进入Ub ...
- 自定义配置编译linux内核
1 编译linux内核原因一般情况下,我们是不需要重新去编译linux内核的,但如果你发现你需要修改内核的某个部分或者说你需要的某个模块并没有编译进内核,那里你可以通过重新编译内核来满足你的需求,比如 ...
- 《Linux内核精髓:精通Linux内核必会的75个绝技》一HACK #2 如何编译Linux内核
HACK #2 如何编译Linux内核 本节介绍编译Linux内核的方法.当发现bug而修改源代码或者添加新功能时,就需要对内核进行重新编译,生成二进制映像文件.另外,如果想要使用发布版内核中无效的功 ...
- make 编译 linux 内核是单线程的任务 才用-j4命令使用4 线程加速
今天使用 make 编译 linux 内核,发现CPU只用了30%多一点,而我的电脑是4核的,所以如果没有意外的话,make 编译 linux 内核的任务是用单线程做的. 又了解到,使用-j4参数可以 ...
- 35、在编译Linux内核中增加程序需要完成以下3项工作
在编译Linux内核中增加程序需要完成以下3项工作: 将编写的源代码拷入Linux内核源代码的相应目录. 在目录的Kconfig文件中增加关于新源代码对应项目的编译配置选项 在目录的Makefile文 ...
随机推荐
- linux安装oracle 11g rac
安装oracle 11gR2 RAC 一.网络规划及安装虚拟主机 主机名 主机版本 Ip rac1.localdomain Redhat 6.5 RAC节点1 192.168.100.11 rac2. ...
- PDF2
itex生成PDF文档示例 package dao.other; import java.awt.Color; import java.io.File; import java.io.FileInpu ...
- PDF
源代码请从这里下载: http://download.csdn.net/source/2984395 使用的是JSP编程 这是导出后的效果 这是数据库中的内容 部分代码: <%@ p ...
- 分享一个批量导出当前实例下的所有linkedserver脚本
分享一个批量导出当前实例下的所有linkedserver脚本 很多时候,我们都需要导出实例下面的登录用户,job,linkedserver等等 导出job比较复杂,下午写了一个脚本把所有的linked ...
- Eclipse引入外部Jar在发布时没有自动带入,导致出现ClassNoFound错误
今天换了一台电脑重新配置环境调试老程序的时候出现链接数据库错误java.lang.ClassNotFoundException: oracle.jdbc.driver.OracleDriver提示. ...
- kernel 内核安装
1.kernel 下载 https://cdn.kernel.org/pub/linux/kernel/ 2.解压源码 tar -zxvf linux-*.tar.gz 3.进入目录 cd linux ...
- java 多线程(wait/notify/notifyall)
package com.example; public class App { /* wait\notify\notifyAll 都属于object的内置方法 * wait: 持有该对象的线程把该对象 ...
- 《C#图解教程》读书笔记之三:方法
本篇已收录至<C#图解教程>读书笔记目录贴,点击访问该目录可获取更多内容. 一.方法那些事儿 (1)方法的结构:方法头—指定方法的特征,方法体—可执行代码的语句序列: (2)方法的调用:参 ...
- 数据库优化实践【MS SQL优化开篇】
数据库定义: 数据库是依照某种数据模型组织起来并存在二级存储器中的数据集合,此集合具有尽可能不重复,以最优方式为特定组织提供多种应用服务,其数据结构独立于应用程序,对数据的CRUD操作进行统一管理和控 ...
- L# ForUnity Helloworld的更新方法
Forunity目录结构 进入plugins 删除这三个目录 从Github代码位置copy 然后删除里面 bin obj property 项目文件等,仅留代码即可. 在editor运行test项目 ...