下面的实验以 debian7.5 64bit 为例.

获取源码

获取 debian7.5 本身的源码非常简单:

sudo apt-get install linux-source

https://www.kernel.org/ 的git上提供的源码分支非常多, 刚开始学习源码主要关注下面几个分支:

  1. linus分支: https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/

    linux创始人的分支, 不用说肯定最重要, 它是所有分支的根源. 处于 "mainline" 的地位.

    这个分支还有个好听的名字 – "vanilla(香草)" 内核.
  2. linux-next树: https://git.kernel.org/cgit/linux/kernel/git/next/linux-next.git/

    这个一个为发布将来的版本而积累新代码并进行测试的源码树.

    由 Stephen Rothwell 等人进行管理和维护
  3. stable树: https://git.kernel.org/cgit/linux/kernel/git/stable/linux-stable.git/

    这是一个主要针对过去发布的内核版本进行bug修改, 使其更加稳定的树.

    由 Greg Kroah-Hartman, Chris Wright 进行管理和维护.

    针对某个Linus树的稳定版维护一般持续6个月左右, 也有更持久的.

上面的列出的git树中都可以获取想要的源码.

编译内核

其实编译内核和编译普通软件也没多大区别, 只是内核编译的参数非常之多.

下面就来先看看如何设置内核编译参数

内核编译选项

  1. 编译选项个数

    内核的编译选项的个数非常多, v2.6.38的内核中就有 12 000 个左右的设置选项(这是包含所有arch的配置选项).

    内核编译选项不仅多, 有些编译选项之间还存在依赖关系, 所以手动设置编译选项几乎是不可能的.

    值得庆幸的是, 只要知道自己需要设置的那些选项, 就可以使用 make ***config 来进行设置, 它还会自动处理依赖关系.

  2. 配置编译选项:

    设置内核编译选项是通过 kconfig 这个工具来完成的.

    kconfig 的源码就是内核代码中 script/kconfig 目录下

    各个编译选项的选择有3种方式:

    1. =y :: 直接编译到内核中
    2. =m :: 以模块方式编译到内核中
    3. 不设置 :: 不编译

    编译方法:

    1. make menuconfig :: 源码根目录下生成 .config (没有会自动生成), .config中就是各个内核编译选项的选择状况.
    2. make defconfig :: 根据当前系统的架构默认 .config 生成内核源码目录下的 .config (每个架构的配置文件: ex. arch/x86/configs/x86_64_defconfig)
    3. make oldconfig :: 将已有的 .config 放到源码根目录下后执行, 目的是为了复用之前的内核编译选项的配置.
    4. make xconfig :: 图形化配置, 需要qt3, 个人觉得没有必要, 有 make menuconfig 就足够了.
    5. make localmodconfig :: 生成以正在使用的内核模块为对象的 .config

编译

编译很简单, 内核编译选项设置好之后, 只需简单的命令 make, 就可以编译了.

由于内核代码的庞大, 所以和一般应用程序相比, 编译时间会很长. 可以尝试以下方法来加快编译速度:

  1. 不用的驱动程序都不要设置, 这样就不会编译

  2. 利用make的 -j 选项来并发编译, ex. make -j N (N是并发数). 如果你的机器有2个CPU, 可以用 make -j 2 来提高编译速度

  3. 使用 make localmodconfig 来生成仅以正在使用的内核模块为对象的 .config (一般这样生成的.config中包含的内核模块最少, 所以编译速度快)

  4. 编译时间比较: 测试环境 - 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初始化文件系统映像文件)

卸载内核

  1. 删除/lib/modules/目录下不需要的内核库文件
  2. 删除/usr/src/kernel/目录下不需要的内核源码
  3. 删除/boot目录下启动的核心档案禾内核映像
  4. 更改grub的配置,删除不需要的内核启动列表

内核 Makefile 中一些有用的 target

  1. make help : 内核Makefile中的各种 target
  2. make cscope : 生成 cscope 文件
  3. make tags/TAGS : tags可用于vim, TAGS可用于emacs

编译Linux内核的更多相关文章

  1. 如何解决编译linux内核(解决声卡问题),遭遇fatal error: linux/limits.h: 没有那个文件或目录

    最近帮一位上海的朋友搞一块小板,在ubuntu15.04 vivid上已经加载了对应了.ko驱动包 但关键是系统根本就枚举不到该声卡ALC5640,试了OpenSUSE也是一样的结果,看来是内核漏加载 ...

  2. Centos下编译Linux内核

    Linux内核编译是一件简单却费事的事.但是独立的编译linux内核会帮助你很好的理解Linux内核的工作机理. 首先编译linux内核我们需要在当前linux操作系统下安装gcc编译器,因为我是Ce ...

  3. 编译linux内核时出错

    在编译linux内核的时候使用make menuconfig 可能出现下面的错误 *** Unable to find the ncurses libraries or the*** required ...

  4. Mac下重新编译Linux内核

    Mac下重新编译Linux内核 操作系统实验,要求添加系统调用并重新编译内核,这里记录一下编译内核的过程 0.下载VirtualBox 博主一直用parallel desk,但因为驱动等问题,在PD上 ...

  5. 为什么要编译Linux内核?

    新的内核修订了旧内核的bug,并增加了许多新的特性.如果用户想要使用这些新特性,或想根据自己的系统度身定制一个更高效,更稳定的内核,就需要重新编译Linux内核. 通常,更新的内核会支持更多的硬件,具 ...

  6. 编译Linux内核(Mac OS平台)

    操作系统第一次实验需要编译Linux内核,我之前在Mac上一直使用的都是Parallels Desktop这个软件,所以这次也将课程网站上提供的Ubuntu安装在了PD上,但是编译完内核后无法进入Ub ...

  7. 自定义配置编译linux内核

    1 编译linux内核原因一般情况下,我们是不需要重新去编译linux内核的,但如果你发现你需要修改内核的某个部分或者说你需要的某个模块并没有编译进内核,那里你可以通过重新编译内核来满足你的需求,比如 ...

  8. 《Linux内核精髓:精通Linux内核必会的75个绝技》一HACK #2 如何编译Linux内核

    HACK #2 如何编译Linux内核 本节介绍编译Linux内核的方法.当发现bug而修改源代码或者添加新功能时,就需要对内核进行重新编译,生成二进制映像文件.另外,如果想要使用发布版内核中无效的功 ...

  9. make 编译 linux 内核是单线程的任务 才用-j4命令使用4 线程加速

    今天使用 make 编译 linux 内核,发现CPU只用了30%多一点,而我的电脑是4核的,所以如果没有意外的话,make 编译 linux 内核的任务是用单线程做的. 又了解到,使用-j4参数可以 ...

  10. 35、在编译Linux内核中增加程序需要完成以下3项工作

    在编译Linux内核中增加程序需要完成以下3项工作: 将编写的源代码拷入Linux内核源代码的相应目录. 在目录的Kconfig文件中增加关于新源代码对应项目的编译配置选项 在目录的Makefile文 ...

随机推荐

  1. mysql5.7 代价模型浅析

    代价模型 mysql 5.7.10代价计算相对之前的版本有5.7 代价模型浅析较大的改进.例如 代价模型参数可以动态配置,可以适应不同的硬件 区分考虑数据在内存和在磁盘中的代价 代价精度提升为浮点型 ...

  2. 手Q兴趣号的价值在哪里

    拥有5.21亿月活跃用户,如果不做点什么东西出来,实在是浪费至极.如此庞大的用户量,如果能够将内容贡献出来,那将是恐怖的,QQ空间产品就是很好的佐证. QQ群让个体用户能够连接在一起,单个的用户关系链 ...

  3. MongoDB3.0新版本几点介绍

    2015年3月3号,MongoDB新版本3.0发布了,和以前版本相比,这次改动较大,主要有以下几个方面: 1. 引入了插件式的存储引擎架构,允许第三方根据实际项目的需要开发存储引擎,类似于MySql中 ...

  4. 开始VS 2012 中LightSwitch系列的第1部分:表中有什么?描述你的数据

    [原文发表地址]  Beginning LightSwitch in VS 2012 Part 1: What’s in a Table? Describing Your Data [原文发表时间]  ...

  5. 第1讲 Redis部署与基本操作

    目录 一.简介 二.安装 1.默认安装位置 2.指定安装位置 3.安装的可执行文件的作用 三.启动与关闭 四.配置文件 五.Redis的数据类型 1. 共计5种类型 2. String(子串类型) 3 ...

  6. Dubbo的使用及原理浅析.

    前面几个博文中关于SSM 框架已经搭建完成, 这里来讲下项目中使用到的Dubbo以及自己了解到的关于Dubbo的一些知识. Dubbo是什么? Dubbo是阿里巴巴SOA服务化治理方案的核心框架,每天 ...

  7. Atititi tesseract使用总结

    Atititi tesseract使用总结 消除bug,优化,重新发布.当前版本为3.02 项目下载地址为:http://code.google.com/p/tesseract-ocr. Window ...

  8. SSH框架详解

    1.什么是ssh? SSH对应 struts spring hibernate struts 采用MVC模式,主要是作用于用户交互 spring 采用IOC和AOP~作用比较抽象,是用于项目的松耦合 ...

  9. ngResource提交json数据如何带参数

    ngResource提交json数据如何带参数 直接使用ngResource和REST服务接口交互可以让程序显得简洁,前提是配置好跨域和OPTIONS请求的支持,与此同时,如果需要带些额外的参数,有两 ...

  10. XML学习笔记7——XSD实例

    在前面的XSD笔记中,基本上是以数据类型为主线来写的,而在我的实际开发过程中,是先设计好了XML的结构(元素.属性),并写好了一份示例,然后再反过来写XSD文件(在工具生成的基础上修改),也就是说,是 ...