|
|
EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
$ N9 g" v }# ?6 ]+ k2 H% s# {
下面的实验以 debian7.5 64bit 为例.
( g* J. {9 `, g9 q
0 X* ^) [# k: v获取源码
! ?5 | p6 p: R3 n* c获取 debian7.5 本身的源码非常简单:0 ]9 }( y7 S9 V N3 P0 v5 r
6 a$ x" j _! D1 Q
sudo apt-get install linux-source- B: s8 a1 K0 D; C. R! H
https://www.kernel.org/ 的git上提供的源码分支非常多, 刚开始学习源码主要关注下面几个分支:
6 j% i) z G/ k- W
+ h7 A" f* w, p) D& o, S0 Flinus分支: https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/ linux创始人的分支, 不用说肯定最重要, 它是所有分支的根源. 处于 "mainline" 的地位. 这个分支还有个好听的名字 – "vanilla(香草)" 内核.
" h9 I! e7 g; l. S ?* r9 r. flinux-next树: https://git.kernel.org/cgit/linux/kernel/git/next/linux-next.git/ 这个一个为发布将来的版本而积累新代码并进行测试的源码树. 由 Stephen Rothwell 等人进行管理和维护
$ ^( v% G5 n7 b8 E: mstable树: https://git.kernel.org/cgit/linux/kernel/git/stable/linux-stable.git/ 这是一个主要针对过去发布的内核版本进行bug修改, 使其更加稳定的树. 由 Greg Kroah-Hartman, Chris Wright 进行管理和维护. 针对某个Linus树的稳定版维护一般持续6个月左右, 也有更持久的.
* F u5 Z' I) b上面的列出的git树中都可以获取想要的源码.
9 k& D5 K7 b4 e, m: H" R( X
; C! [6 s2 w3 N# M, s编译内核" ]% x8 W8 h- K: S
其实编译内核和编译普通软件也没多大区别, 只是内核编译的参数非常之多. 下面就来先看看如何设置内核编译参数
0 Y, B& c# l$ O/ k# _4 N; {8 f& ?% `$ T6 I
内核编译选项' P! T+ e/ t1 V; v3 u
编译选项个数 内核的编译选项的个数非常多, v2.6.38的内核中就有 12 000 个左右的设置选项(这是包含所有arch的配置选项). 内核编译选项不仅多, 有些编译选项之间还存在依赖关系, 所以手动设置编译选项几乎是不可能的. 值得庆幸的是, 只要知道自己需要设置的那些选项, 就可以使用 make ***config 来进行设置, 它还会自动处理依赖关系.# ?' g6 K. R- v4 d& A8 b1 R2 d
& C" x+ Y+ \3 r N1 E) P. c! o配置编译选项: 设置内核编译选项是通过 kconfig 这个工具来完成的. kconfig 的源码就是内核代码中 script/kconfig 目录下
; B0 `; j7 U9 F' ?' E5 {% O, Y" E9 Y
各个编译选项的选择有3种方式:# t# l5 N+ e' z9 K2 M6 G% y
- G% x0 p! f. T# i5 q# G: ~=y :: 直接编译到内核中
) J5 l5 ]0 [! u% Y9 c* h/ W=m :: 以模块方式编译到内核中
' M6 ^; u8 E& m5 \不设置 :: 不编译, A' q) j4 c. a6 e) P" I! J* U
编译方法:
- d, Y% E8 F' G9 i: e4 ~$ N' ~
: z1 B1 u! V7 a+ O6 smake menuconfig :: 源码根目录下生成 .config (没有会自动生成), .config中就是各个内核编译选项的选择状况.; e/ r, f& n/ @$ n) K4 Q
make defconfig :: 根据当前系统的架构默认 .config 生成内核源码目录下的 .config (每个架构的配置文件: ex. arch/x86/configs/x86_64_defconfig)" E0 N+ \! k' b/ s& Y, a+ w; q, b, m# d
make oldconfig :: 将已有的 .config 放到源码根目录下后执行, 目的是为了复用之前的内核编译选项的配置.
1 }! C+ v! _ Y/ U4 y9 `! _make xconfig :: 图形化配置, 需要qt3, 个人觉得没有必要, 有 make menuconfig 就足够了.6 C* l0 }0 C; g& T; ^
make localmodconfig :: 生成以正在使用的内核模块为对象的 .config* i& P7 M4 ]( W. Z: G: ]
编译1 W' T( p6 V$ o& @1 t
编译很简单, 内核编译选项设置好之后, 只需简单的命令 make, 就可以编译了. 由于内核代码的庞大, 所以和一般应用程序相比, 编译时间会很长. 可以尝试以下方法来加快编译速度:/ Y+ p9 `% r6 y
# O9 p8 d4 h/ t& V
不用的驱动程序都不要设置, 这样就不会编译# L0 S5 j( l; c' u; o3 U. t1 ?, S; G
" m5 F% p* ^3 g
利用make的 -j 选项来并发编译, ex. make -j N (N是并发数). 如果你的机器有2个CPU, 可以用 make -j 2 来提高编译速度
* w) z3 F% f. @/ F6 n$ g1 V! V4 R) r' y! W1 E/ a4 M
使用 make localmodconfig 来生成仅以正在使用的内核模块为对象的 .config (一般这样生成的.config中包含的内核模块最少, 所以编译速度快)
! \# K" k( O6 [) e3 U. _) @# O: e: C, f1 x* F2 ?0 I9 r
编译时间比较: 测试环境 - debian v7.5虚拟机(cpu: 单核, 内存: 512MB)% t7 i- T: d7 t
( p* P) A+ c, a$ X.config生成 make时间 生成的modules 备注
9 @- z/ x6 Q, i/ e9 O3 A+ xmake menuconfig 1小时13分41秒 3052个.ko, 共1.2GB 默认配置, 什么也不选择
/ ]5 o" v0 m" J( e% Dmake localmodconfig 19分36秒 337 个.ko, 共176MB
B6 b" |# l, `* ]# O! x注 modules 是通过 make modules_install 之后, 在 /lib/modules 中根据编译内核版本号来查看的 查看有多少个 .ko 文件的方法:5 @4 m4 R0 l( n/ x
! R( ?- Z9 l" c9 ?0 Fcd /lib/modules/3.2.603 l6 k! X9 D! n' r! B2 F% l) h
find . -name '*.ko' | wc -l
' ^- \2 b' h# m, ?3 E0 d5 t5 `, r分开编译( l$ P' `3 v: w+ z- z
模块和内核不在一起的编译, 就是在现有的内核中追加一些内核模块时, 不需要将内核也重新编译. 模块分开编译的方法很简单, 参考之前的博客: 《Linux内核设计与实现》读书笔记(六)- 内核数据结构 这篇博客中的例子就是和内核分开编译的模块.
L1 R9 [# m$ Q" O( R9 f' p+ |% u X) c
交叉编译; F5 X# V. D( U4 a4 N
交叉编译就是在当前平台上编译其他平台上的内核二进制映像, 比如在 x86_64 平台上编译 ARM 的内核映像. 交叉编译需要目标平台的交叉编译器. 编译时主要是 ARCH 和 CROSS_COMPILE 2个变量的设置.
, {: I. h( ~0 Z8 I" D/ q" o+ q/ P
+ ~" `' V3 r( f6 i0 l' ^. M- |, ?; a下面举个交叉编译 ARM 的例子: 公司用的制作 Cubieboard 板子上的image中的一段编译内核的代码7 _* |3 |: Q* l# @8 [! P/ R
8 y+ C: W. | p. x2 j' t, |$ Z* b1 L
make -C ${CB_KSRC_DIR} O=${CB_KBUILD_DIR} ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- kernel_defconfig
# x8 K8 v, M% ~9 T+ F- r; R7 dmake -C ${CB_KSRC_DIR} O=${CB_KBUILD_DIR} ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- -j4 INSTALL_MOD_PATH=${CB_TARGET_DIR} uImage modules* v" H$ T$ L; F1 v
上述 第一行 是编译内核源码. 第二行 是创建 uImage 格式的内核映像以及创建内核模块 最终在 INSTALL_MOD_PATH 生成的内核模块可以直接拷贝到 arm机器上使用.0 C% q+ V2 u+ f( K
f8 {+ g+ E, a" C, R
生成内核包/ W8 Z% t" \3 W1 g6 M6 Q
debian 系 linux下生成 内核源码包的方法, A( J9 R1 N+ o* q! d
8 ~0 _& K0 S5 f& R& zmake deb-pkg
0 t; l) N3 t( U4 z. i, w( r安装内核
7 B: B: |: s5 [# ]make modules_install (安装内核模块到 /lib/modules 下) make install (安装内核二进制映像, 生成并安装boot初始化文件系统映像文件)! J# g p& f7 V, b
9 ^9 H& u2 i+ Q3 Z6 Y4 z! d卸载内核: X% H; ]7 r, { `
删除/lib/modules/目录下不需要的内核库文件. V B" C }. s8 O
删除/usr/src/kernel/目录下不需要的内核源码0 X. x9 c+ g2 T5 i( [% z5 q
删除/boot目录下启动的核心档案禾内核映像
) ^1 [) t" l: i- x, c更改grub的配置,删除不需要的内核启动列表0 i; ^) s7 y4 [9 E8 U* P2 F* Y- q
内核 Makefile 中一些有用的 target6 d: H! Z: \1 X5 y7 F
make help : 内核Makefile中的各种 target5 J0 U) D& x7 W: s
make cscope : 生成 cscope 文件1 @/ h7 Y9 e4 S( x
make tags/TAGS : tags可用于vim, TAGS可用于emacs |
|