|
|
EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
2 t6 Z5 F! o/ M下面的实验以 debian7.5 64bit 为例.
/ T; i- ^, C& L+ b0 F
( ?( f. Y9 j0 z( l获取源码0 n! X+ {) V# y6 h( `
获取 debian7.5 本身的源码非常简单:% \* ~) j$ w/ y [1 Z. k) H# c0 W
K4 u" Q1 y7 Y: g3 A; }8 |# r% T
sudo apt-get install linux-source
% b' I# h3 x. Ihttps://www.kernel.org/ 的git上提供的源码分支非常多, 刚开始学习源码主要关注下面几个分支:
8 q9 ?+ b1 x' `& G) J- @) ^
+ c* T' a0 M7 v$ d# @% ?/ L5 {& {linus分支: https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/ linux创始人的分支, 不用说肯定最重要, 它是所有分支的根源. 处于 "mainline" 的地位. 这个分支还有个好听的名字 – "vanilla(香草)" 内核.) n# C7 q$ R: f8 R8 I
linux-next树: https://git.kernel.org/cgit/linux/kernel/git/next/linux-next.git/ 这个一个为发布将来的版本而积累新代码并进行测试的源码树. 由 Stephen Rothwell 等人进行管理和维护$ X: x4 j+ \2 J& Z1 \
stable树: https://git.kernel.org/cgit/linux/kernel/git/stable/linux-stable.git/ 这是一个主要针对过去发布的内核版本进行bug修改, 使其更加稳定的树. 由 Greg Kroah-Hartman, Chris Wright 进行管理和维护. 针对某个Linus树的稳定版维护一般持续6个月左右, 也有更持久的.
; W$ _: N1 N K$ U上面的列出的git树中都可以获取想要的源码.
, b. k' b) [+ r, d. _
. ~7 A7 v8 X+ x2 @' T! y编译内核
: F, w$ s8 g0 S* x" C, E/ z6 {其实编译内核和编译普通软件也没多大区别, 只是内核编译的参数非常之多. 下面就来先看看如何设置内核编译参数
3 s* A$ Y* p1 K5 F9 o4 g; N$ s! ?6 k7 q9 K
内核编译选项' q6 f4 S& {! |5 S; d, @- i4 j
编译选项个数 内核的编译选项的个数非常多, v2.6.38的内核中就有 12 000 个左右的设置选项(这是包含所有arch的配置选项). 内核编译选项不仅多, 有些编译选项之间还存在依赖关系, 所以手动设置编译选项几乎是不可能的. 值得庆幸的是, 只要知道自己需要设置的那些选项, 就可以使用 make ***config 来进行设置, 它还会自动处理依赖关系.
4 F' ^6 v5 V7 _* g |! I7 e+ q% V+ N
( D7 H1 B* _6 L9 D配置编译选项: 设置内核编译选项是通过 kconfig 这个工具来完成的. kconfig 的源码就是内核代码中 script/kconfig 目录下* D+ ^& h3 M5 a5 p$ O' S& B1 K
" q% d. s, [& ^) a, z! Q9 q# C各个编译选项的选择有3种方式:( L0 Q( t0 r: t# C, g% b
' x' N4 H/ o; r4 l' Q=y :: 直接编译到内核中) |( Q& c. o# v7 q
=m :: 以模块方式编译到内核中- |2 h6 N3 Y1 C/ b; x
不设置 :: 不编译
7 `# {" L( S& t6 P( K$ Y编译方法:* C( {. x: O6 M
7 i% s1 I" w. n7 y/ t# I$ Vmake menuconfig :: 源码根目录下生成 .config (没有会自动生成), .config中就是各个内核编译选项的选择状况.; Q. ]- B% a$ g c. R0 ~
make defconfig :: 根据当前系统的架构默认 .config 生成内核源码目录下的 .config (每个架构的配置文件: ex. arch/x86/configs/x86_64_defconfig)/ W; u' i+ i# k$ Y
make oldconfig :: 将已有的 .config 放到源码根目录下后执行, 目的是为了复用之前的内核编译选项的配置.' J" u- R8 C' |( [. S
make xconfig :: 图形化配置, 需要qt3, 个人觉得没有必要, 有 make menuconfig 就足够了.
6 o1 p6 U# `: [) b6 ~* umake localmodconfig :: 生成以正在使用的内核模块为对象的 .config, p/ y4 p) l4 [, _- f! A7 P/ o# _( {$ o
编译
) V) P* k! d% k/ }* d* u K( C编译很简单, 内核编译选项设置好之后, 只需简单的命令 make, 就可以编译了. 由于内核代码的庞大, 所以和一般应用程序相比, 编译时间会很长. 可以尝试以下方法来加快编译速度:) {. I. k! }2 x! Q' f- @
/ ~; j$ j! o+ A; E8 x; }4 \. x* F
不用的驱动程序都不要设置, 这样就不会编译
7 k. w4 m* N5 b( z% z- L. e* a; i8 Q) `
利用make的 -j 选项来并发编译, ex. make -j N (N是并发数). 如果你的机器有2个CPU, 可以用 make -j 2 来提高编译速度+ [! R$ K" \$ e
9 A. U! z1 g: o, T3 l
使用 make localmodconfig 来生成仅以正在使用的内核模块为对象的 .config (一般这样生成的.config中包含的内核模块最少, 所以编译速度快)
3 d% Q7 m1 u+ b, h0 ~- Q! F. Z; F
, A, W8 G/ V! K7 n编译时间比较: 测试环境 - debian v7.5虚拟机(cpu: 单核, 内存: 512MB)" i, X8 }+ r6 Q0 D
" z# G0 h( Z Q H6 g
.config生成 make时间 生成的modules 备注+ H! A" P8 W1 ^. B. G
make menuconfig 1小时13分41秒 3052个.ko, 共1.2GB 默认配置, 什么也不选择
9 V' H8 m& R6 v/ K2 rmake localmodconfig 19分36秒 337 个.ko, 共176MB
0 G8 _# H: }: ?& Y$ G" x6 q: Q注 modules 是通过 make modules_install 之后, 在 /lib/modules 中根据编译内核版本号来查看的 查看有多少个 .ko 文件的方法:+ w( F1 \4 A% q! E% H X
/ j+ C7 w7 ]5 G- Z( v0 V& o: w
cd /lib/modules/3.2.603 G. H7 w+ u; T4 q& k- h
find . -name '*.ko' | wc -l4 X# ?' `* I- n! c9 V
分开编译
& k* V @, |, e模块和内核不在一起的编译, 就是在现有的内核中追加一些内核模块时, 不需要将内核也重新编译. 模块分开编译的方法很简单, 参考之前的博客: 《Linux内核设计与实现》读书笔记(六)- 内核数据结构 这篇博客中的例子就是和内核分开编译的模块.
! o) ^" u C6 \7 a& s8 F1 c
, b1 D! S3 j+ L交叉编译
^' \( ~. I; p+ [1 B# l/ N: R+ l交叉编译就是在当前平台上编译其他平台上的内核二进制映像, 比如在 x86_64 平台上编译 ARM 的内核映像. 交叉编译需要目标平台的交叉编译器. 编译时主要是 ARCH 和 CROSS_COMPILE 2个变量的设置.# Y* _& x9 n/ [* A0 n6 q; N( b/ P
" p' G- J) a4 D$ ?( k* [% P7 u
下面举个交叉编译 ARM 的例子: 公司用的制作 Cubieboard 板子上的image中的一段编译内核的代码
) W. M; K% L6 q: h5 W. k. `( n# k' U- o2 G ^4 x' ?
make -C ${CB_KSRC_DIR} O=${CB_KBUILD_DIR} ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- kernel_defconfig
( y6 c# f+ E* t, l0 _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- R b+ \8 S) j5 @* {+ @7 d
上述 第一行 是编译内核源码. 第二行 是创建 uImage 格式的内核映像以及创建内核模块 最终在 INSTALL_MOD_PATH 生成的内核模块可以直接拷贝到 arm机器上使用.
# A! y, r; H& X9 u" R7 J0 }( i* l' B8 s( e% s, c# H% f. d6 E
生成内核包/ H d* U. g7 A8 C& ^
debian 系 linux下生成 内核源码包的方法9 g* L8 R4 J( u4 H( T' F
4 O0 P6 _. Z8 v2 E V2 Dmake deb-pkg
; {0 i) n7 C) I% c安装内核& ^) q1 c. X; r9 t
make modules_install (安装内核模块到 /lib/modules 下) make install (安装内核二进制映像, 生成并安装boot初始化文件系统映像文件)
, s5 c+ c6 V. t& v. k9 I5 N. u% O0 [' I7 v3 g( Q: \( E
卸载内核; j, `: l% U6 P2 w& L
删除/lib/modules/目录下不需要的内核库文件
( I( |+ G3 q& C删除/usr/src/kernel/目录下不需要的内核源码5 Y, ?" T# }. }5 D
删除/boot目录下启动的核心档案禾内核映像5 X, r- y. ^ K5 `; i
更改grub的配置,删除不需要的内核启动列表
" ~! {! e5 w: r- e内核 Makefile 中一些有用的 target& c3 @0 R) X1 P" K' K6 G7 }
make help : 内核Makefile中的各种 target! K2 r [8 Z! |& Q; F# w8 [
make cscope : 生成 cscope 文件: j+ _; I( F! z( I
make tags/TAGS : tags可用于vim, TAGS可用于emacs |
|