编译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文 ...
随机推荐
- 工具mark
http://zh.snipaste.com/ 截图工具 https://brookhong.github.io/2014/04/28/keycast-on-windows-cn.html 按键显示 ...
- VS2008 Pocket PC 2003 SE仿真程序上网设置
设置大体分为3个步骤:Microsoft ActiveSync安装配置.Pocket PC 2003 SE仿真程序配置.Pocket PC 2003连接到Microsoft ActiveSync. 1 ...
- Backbone源码解析(五):Route和History(路由)模块
今天是四月十二号,距离上次写博已经将近二十天了.一直忙于工作,回家被看书的时间占用了.连续两个礼拜被频繁的足球篮球以及各种体育运动弄的精疲力竭,所以很少抽时间来写技术博客.今天抽出时间把backbon ...
- Sensor(PROXIMITY)
package com.example.sensor01; import android.hardware.Sensor; import android.hardware.SensorEvent; i ...
- UWP的一种下拉刷新实现
简介 我们最近实现了一个在UWP中使用的下拉刷新功能,以满足用户的需求,因为这是下拉刷新是一种常见的操作方式,而UWP本身并不提供这一机制. 通过下拉刷新这一机制,可以让移动端的界面设计变得更加简单, ...
- 译文---C#堆VS栈(Part Four)
前言 在本系列的第一篇文章<C#堆栈对比(Part Three)>中,介绍了值类型和引用类型在Copy上的区别以及如何实现引用类型的克隆以及使用ICloneable接口等内容. 本文为文章 ...
- 赴美工作常识(Part 5 - 绿卡优先级)
这个系列的第一篇<赴美工作常识(Part 1 - 签证)>是三年前写的,过了这么久这个系列终于要继续下去了.接下来当然时讨论绿卡的事情了.跟讨论签证一样,这里必须要有免责声名.因为我不是移 ...
- [nRF51822] 3、 新年也来个总结——图解nRF51 SDK中的Button handling library和FIFO library
:本篇是我翻译并加入自己理解的nRF51 SDK中按钮相关操作的库和先进先出队列库.虽然是nRF51的SDK,但是通过此文你将更多地了解到在BSP(板级支持)上层嵌入式程序或OS的构建方法. 1.按钮 ...
- Android手动签名
在生成release build时可实现自动签名,所谓手动签名,就是在命令行下完成签名,落实到Android Studio里面,就是在terminal里面做. 下面是三个命令,第一个签名,第二个验证, ...
- 翻译-Salt与Ansible全方位比较
原文链接:http://jensrantil.github.io/salt-vs-ansible.html 作者: Jens Rantil 之前某些时候我需要评估配置管理系统.结合从他人得到的意见,我 ...