|
|
EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
2 v- @) c8 |0 P8 c+ a3 ]/ k$ \+ X( n下面的实验以 debian7.5 64bit 为例.3 o* \! ~5 k1 T
1 ?) k( @6 d$ V4 R获取源码
. H& i3 |+ [! D获取 debian7.5 本身的源码非常简单:' B. {; O4 n5 @* J2 {
" ]6 E! A% K8 A, G% e: esudo apt-get install linux-source$ Q: U1 M( B( z& y$ W
https://www.kernel.org/ 的git上提供的源码分支非常多, 刚开始学习源码主要关注下面几个分支:
5 W" _3 R1 O6 T, O
% _, \2 M: L5 y! blinus分支: https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/ linux创始人的分支, 不用说肯定最重要, 它是所有分支的根源. 处于 "mainline" 的地位. 这个分支还有个好听的名字 – "vanilla(香草)" 内核.
" Y! `& T5 G; a* glinux-next树: https://git.kernel.org/cgit/linux/kernel/git/next/linux-next.git/ 这个一个为发布将来的版本而积累新代码并进行测试的源码树. 由 Stephen Rothwell 等人进行管理和维护
* ~5 @" f( W$ V% Z: ustable树: https://git.kernel.org/cgit/linux/kernel/git/stable/linux-stable.git/ 这是一个主要针对过去发布的内核版本进行bug修改, 使其更加稳定的树. 由 Greg Kroah-Hartman, Chris Wright 进行管理和维护. 针对某个Linus树的稳定版维护一般持续6个月左右, 也有更持久的.: J$ Q! \- @: R0 r% O5 a3 x
上面的列出的git树中都可以获取想要的源码.
5 X% u3 R, H$ P, h3 A8 ?
. n: ~- M9 `5 N编译内核" u: N' c$ d" @3 F# z! Y7 ?" L" C1 {
其实编译内核和编译普通软件也没多大区别, 只是内核编译的参数非常之多. 下面就来先看看如何设置内核编译参数
. D* \' a6 w+ }4 u4 h
5 D H7 S/ P7 D4 ^8 @内核编译选项
+ L) q( W( [ m5 m* r! u# U5 l) Y编译选项个数 内核的编译选项的个数非常多, v2.6.38的内核中就有 12 000 个左右的设置选项(这是包含所有arch的配置选项). 内核编译选项不仅多, 有些编译选项之间还存在依赖关系, 所以手动设置编译选项几乎是不可能的. 值得庆幸的是, 只要知道自己需要设置的那些选项, 就可以使用 make ***config 来进行设置, 它还会自动处理依赖关系.% W; o# ]! u; o5 j
6 z5 D& G6 w6 q9 O6 o
配置编译选项: 设置内核编译选项是通过 kconfig 这个工具来完成的. kconfig 的源码就是内核代码中 script/kconfig 目录下
9 i3 @! X6 `3 s! @+ J0 X/ h/ |, i) m, K. P! m& n
各个编译选项的选择有3种方式:4 y" R0 i/ @2 \4 m6 J) P9 n. w' F
! _% Z9 y& S9 v* m) s- p=y :: 直接编译到内核中
5 ?% g) O/ q4 R X8 ?4 U=m :: 以模块方式编译到内核中
6 U4 ?- d9 j T. |: B不设置 :: 不编译
) F8 k; l- o I H( P) f7 f0 k编译方法:( w X- S }& I( n1 T
( n* w; g% `3 ?# Umake menuconfig :: 源码根目录下生成 .config (没有会自动生成), .config中就是各个内核编译选项的选择状况.
9 n- D; r# N0 x% }: ~7 kmake defconfig :: 根据当前系统的架构默认 .config 生成内核源码目录下的 .config (每个架构的配置文件: ex. arch/x86/configs/x86_64_defconfig): e$ Q! d: a% y( _9 o$ {+ b- ?; k8 `
make oldconfig :: 将已有的 .config 放到源码根目录下后执行, 目的是为了复用之前的内核编译选项的配置.' y, c; a) z) _ u" K
make xconfig :: 图形化配置, 需要qt3, 个人觉得没有必要, 有 make menuconfig 就足够了.% t, a+ Z. s, b$ I
make localmodconfig :: 生成以正在使用的内核模块为对象的 .config
# _+ ?/ P9 Q" P* t0 x编译4 C7 o$ }9 N" Z: X
编译很简单, 内核编译选项设置好之后, 只需简单的命令 make, 就可以编译了. 由于内核代码的庞大, 所以和一般应用程序相比, 编译时间会很长. 可以尝试以下方法来加快编译速度:
4 P+ r# M/ G7 U1 K2 [3 c! \0 A$ {# g- I' c! Z
不用的驱动程序都不要设置, 这样就不会编译& E0 \2 G" k9 s& J
6 m- Q! f5 [* v0 f1 Y- ^0 h) Y2 Z, i
利用make的 -j 选项来并发编译, ex. make -j N (N是并发数). 如果你的机器有2个CPU, 可以用 make -j 2 来提高编译速度7 k# F: `+ d9 I( O: Z! Z( G
K% C1 o% l8 c& L使用 make localmodconfig 来生成仅以正在使用的内核模块为对象的 .config (一般这样生成的.config中包含的内核模块最少, 所以编译速度快)
8 ]9 _4 D8 f5 `
, S, J$ U+ }4 ]6 ~1 { ~8 D: I编译时间比较: 测试环境 - debian v7.5虚拟机(cpu: 单核, 内存: 512MB)
4 I( t& {9 H+ U5 }! N% e, `$ H4 b E/ r C( k' g, P
.config生成 make时间 生成的modules 备注
8 _: \; s R- \( f: d) bmake menuconfig 1小时13分41秒 3052个.ko, 共1.2GB 默认配置, 什么也不选择6 B' L2 j/ x, `; P7 \
make localmodconfig 19分36秒 337 个.ko, 共176MB
9 x* E) f; H9 R1 x8 o# _3 ]% T注 modules 是通过 make modules_install 之后, 在 /lib/modules 中根据编译内核版本号来查看的 查看有多少个 .ko 文件的方法:
% a( v8 w, g' f7 J# \* H9 v5 w! i: K& h7 W( n+ N9 ~
cd /lib/modules/3.2.60
+ k( C# T$ z- S& t+ Zfind . -name '*.ko' | wc -l; _& }4 h3 D" k& |# V
分开编译: Y3 c) n3 A) a
模块和内核不在一起的编译, 就是在现有的内核中追加一些内核模块时, 不需要将内核也重新编译. 模块分开编译的方法很简单, 参考之前的博客: 《Linux内核设计与实现》读书笔记(六)- 内核数据结构 这篇博客中的例子就是和内核分开编译的模块.) I9 e* Y9 v. o) C2 Q% w& r
% g) t. c1 b' T/ i' ?& D
交叉编译
; p( d' h* c) O/ Y) f交叉编译就是在当前平台上编译其他平台上的内核二进制映像, 比如在 x86_64 平台上编译 ARM 的内核映像. 交叉编译需要目标平台的交叉编译器. 编译时主要是 ARCH 和 CROSS_COMPILE 2个变量的设置.
: x3 b1 w3 X. I$ W! ]( ~) n: N4 U& j
下面举个交叉编译 ARM 的例子: 公司用的制作 Cubieboard 板子上的image中的一段编译内核的代码6 N$ m# z( b, a9 n
$ A. D7 a1 S# N1 S. }make -C ${CB_KSRC_DIR} O=${CB_KBUILD_DIR} ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- kernel_defconfig, ~ t0 o" d7 n) s# F" @
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( o& m/ k* I P+ O* r1 @
上述 第一行 是编译内核源码. 第二行 是创建 uImage 格式的内核映像以及创建内核模块 最终在 INSTALL_MOD_PATH 生成的内核模块可以直接拷贝到 arm机器上使用.5 U4 H; t1 i1 W) j5 e% x/ w
& N: Z7 C0 u- H. f5 {( R- K( E
生成内核包
( K; o. y' S: \9 W) b9 {debian 系 linux下生成 内核源码包的方法
2 ?: m3 H6 x. @& L& @ n
5 f- }; ]! r4 q" k( imake deb-pkg# P+ w) y: w2 p$ S( d: C3 L
安装内核
9 t- K+ Y# T# A0 {$ kmake modules_install (安装内核模块到 /lib/modules 下) make install (安装内核二进制映像, 生成并安装boot初始化文件系统映像文件)2 D2 k* ^# R" l. m+ W* b0 f5 Z
+ y; t, d6 R" L- ^
卸载内核9 W3 @' X) ]! [3 `
删除/lib/modules/目录下不需要的内核库文件
/ v( r( V/ \0 W" t; P) S% ? M删除/usr/src/kernel/目录下不需要的内核源码! L5 q" u+ n& w! l# i- Z7 g- ~" \' U
删除/boot目录下启动的核心档案禾内核映像
" s+ W! P, v4 J! C" r* Y D9 s( `1 R更改grub的配置,删除不需要的内核启动列表
& j' k+ y& i6 X7 ~内核 Makefile 中一些有用的 target8 Z- S& h1 w: G N1 @- m
make help : 内核Makefile中的各种 target
" Y- u. R/ f* gmake cscope : 生成 cscope 文件: `1 H3 E' W* M+ E& l
make tags/TAGS : tags可用于vim, TAGS可用于emacs |
|