下面的实验以 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. linux安装oracle 11g rac

    安装oracle 11gR2 RAC 一.网络规划及安装虚拟主机 主机名 主机版本 Ip rac1.localdomain Redhat 6.5 RAC节点1 192.168.100.11 rac2. ...

  2. Ubuntu 初始化Root账户密码

    昨晚新装的Ubuntu12(电脑太烂了),每次都记不住初始化root密码的命令,既然决定开始写自己的园子了,那就在自己的园子里面记一下,方便自己稳固之心 好了,不废话了了 draenei@ubuntu ...

  3. JQuery源码解析(一)

    写在前面:本<JQuery源码解析>系列是基于一些前辈们的文章进行进一步的分析.细化.修改而写出来的,在这边感谢那些慷慨提供科普文档的技术大拿们. 要查阅JQ的源文件请下载开发版的JQ.j ...

  4. 说说WeakReference弱引用

    WeakReference弱引用概述 http://www.cnblogs.com/xrq730/p/4836700.html,关于Java的四种引用状态具体请参看此文 Java里一个对象obj被创建 ...

  5. Wix 安装部署教程(十三) -- 多语言安装包

    这几天摸索WIX的多语言安装包(这里是Wix的setup 工程,不是Bundle),终于走通了,感谢网友uni的指点.WIX的多语言安装包能够根据系统环境自动切换界面语言,你也可以通过命令指定语言.下 ...

  6. 简介Gulp, Grunt, Bower, 和 Npm 对Visual Studio的支持

    [原文发表地址]Introducing Gulp, Grunt, Bower, and npm support for Visual Studio Web 开发,特别是前端 Web 开发,正迅速变得像 ...

  7. C# 版 flvmerge:快速合并多个flv文件

    网上的视频很多都是分片的flv文件,怎么把他们合为一体呢?GUI工具就不考虑了,不适合批量执行,不适合在后台运行.有没有命令行工具或库可以实现呢? ffmpeg 提供了一个方法: (1)先把flv文件 ...

  8. fsfds

    ccc fs -fsd fsdfsfs

  9. 让我欲罢不能的node.js

    从我大一接触第一门编程语言C开始,到现在工作三年陆续接触到了C.汇编.C++.C#.Java.JavaScript.PHP,还有一些HTML.CSS神马的,从来没有一门语言让我像对node.js一样的 ...

  10. git rm–r folder fatal:pathspec "" did not match any files

    问题描述: 某年某月某日,在查看git库的时候,发现文件的分布和文件夹的名字是极其不合理的,所以移动和重命名了某些文件. 在删除(git rm –r folder)一个空文件夹的时候,出现错误:fat ...