找回密码
 注册
关于网站域名变更的通知
查看: 260|回复: 1
打印 上一主题 下一主题

编译Linux内核

[复制链接]

该用户从未签到

跳转到指定楼层
1#
发表于 2020-9-11 15:25 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式

EDA365欢迎您登录!

您需要 登录 才可以下载或查看,没有帐号?注册

x
8 Z: \8 [. |4 g) k7 B/ R3 ?
下面的实验以 debian7.5 64bit 为例.
- A2 c) v! S+ P3 G7 M2 N& O$ b4 \9 V6 {  l8 X  ~
获取源码
2 A! B" f  X* ]; p2 [% t( k3 V获取 debian7.5 本身的源码非常简单:
6 m7 N; N( Q& B: z; o9 f  {
7 @( m8 x4 e8 ^8 V$ u) C% n$ ksudo apt-get install linux-source
8 G9 x( x: ^5 x' V: w; S% b; Q( whttps://www.kernel.org/ 的git上提供的源码分支非常多, 刚开始学习源码主要关注下面几个分支:( M8 p" ~: T2 {
; O0 t5 l' D3 v$ A) B
linus分支: https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/ linux创始人的分支, 不用说肯定最重要, 它是所有分支的根源. 处于 "mainline" 的地位. 这个分支还有个好听的名字 – "vanilla(香草)" 内核.4 b" P5 l) g, x
linux-next树: https://git.kernel.org/cgit/linux/kernel/git/next/linux-next.git/ 这个一个为发布将来的版本而积累新代码并进行测试的源码树. 由 Stephen Rothwell 等人进行管理和维护+ i3 C" n7 g+ ?, J" F
stable树: https://git.kernel.org/cgit/linux/kernel/git/stable/linux-stable.git/ 这是一个主要针对过去发布的内核版本进行bug修改, 使其更加稳定的树. 由 Greg Kroah-Hartman, Chris Wright 进行管理和维护. 针对某个Linus树的稳定版维护一般持续6个月左右, 也有更持久的.1 l0 _5 P6 v3 o3 N, h0 g2 G. s" q
上面的列出的git树中都可以获取想要的源码.' [4 [7 c: v0 X  B! {7 C  P

' I. }& d- z5 [$ m0 j) k* P6 w$ J编译内核$ j$ V0 T/ I+ N. T
其实编译内核和编译普通软件也没多大区别, 只是内核编译的参数非常之多. 下面就来先看看如何设置内核编译参数
- r* X: I9 s1 V7 N5 ?2 T
& K/ n1 `5 c5 Z3 x内核编译选项
8 q/ f5 ~# }4 G' e' |# O$ p编译选项个数 内核的编译选项的个数非常多, v2.6.38的内核中就有 12 000 个左右的设置选项(这是包含所有arch的配置选项). 内核编译选项不仅多, 有些编译选项之间还存在依赖关系, 所以手动设置编译选项几乎是不可能的. 值得庆幸的是, 只要知道自己需要设置的那些选项, 就可以使用 make ***config 来进行设置, 它还会自动处理依赖关系.
( {; }  M! U4 ^5 R7 C4 c- U! ~1 Y; H' T
配置编译选项: 设置内核编译选项是通过 kconfig 这个工具来完成的. kconfig 的源码就是内核代码中 script/kconfig 目录下! s  z- F# i5 Q

; }. ~; w% M& S3 h; r' B各个编译选项的选择有3种方式:! e9 k. N2 A$ l4 V' k

% W+ F  X3 f' v=y :: 直接编译到内核中) n3 {0 ^8 C, |6 q) M
=m :: 以模块方式编译到内核中
% A: Y( R% I; N不设置 :: 不编译1 c0 e; x. i/ S  m
编译方法:; n. @3 d' z4 m1 L- |

( V" W" j# P* I0 }/ q8 W; Mmake menuconfig :: 源码根目录下生成 .config (没有会自动生成), .config中就是各个内核编译选项的选择状况.
; H& W7 D: l% O; f5 Hmake defconfig :: 根据当前系统的架构默认 .config 生成内核源码目录下的 .config (每个架构的配置文件: ex. arch/x86/configs/x86_64_defconfig)
9 T7 i, ~# Z: Cmake oldconfig :: 将已有的 .config 放到源码根目录下后执行, 目的是为了复用之前的内核编译选项的配置.6 |( j8 m6 z' k( A* e- b
make xconfig :: 图形化配置, 需要qt3, 个人觉得没有必要, 有 make menuconfig 就足够了.2 P4 h3 B" x1 b* b0 [$ V2 A7 \: g
make localmodconfig :: 生成以正在使用的内核模块为对象的 .config% N' p: D+ S' R& T3 @( @, D
编译- C' Z. e3 d/ `1 }6 }7 n
编译很简单, 内核编译选项设置好之后, 只需简单的命令 make, 就可以编译了. 由于内核代码的庞大, 所以和一般应用程序相比, 编译时间会很长. 可以尝试以下方法来加快编译速度:
  a: ]$ V' }% G2 R3 m- K# F) B3 T* P, j
不用的驱动程序都不要设置, 这样就不会编译
- t1 \- _0 [8 D' G+ ~3 t6 g; t/ D# b% x6 A
利用make的 -j 选项来并发编译, ex. make -j N (N是并发数). 如果你的机器有2个CPU, 可以用 make -j 2 来提高编译速度+ B" I; ^( i. E

: e/ ]) B1 l# ^% K$ b使用 make localmodconfig 来生成仅以正在使用的内核模块为对象的 .config (一般这样生成的.config中包含的内核模块最少, 所以编译速度快)5 a+ o* r5 e) D

, @; T0 y+ L- h" B编译时间比较: 测试环境 - debian v7.5虚拟机(cpu: 单核, 内存: 512MB)
* a5 G8 C* D+ ^" W
8 o) }: J; {' H- D8 `.config生成        make时间        生成的modules        备注
% G" I; M/ l" v  v1 E1 cmake menuconfig        1小时13分41秒        3052个.ko, 共1.2GB        默认配置, 什么也不选择7 o$ Y( P: ]" Q/ E/ M
make localmodconfig        19分36秒        337 个.ko, 共176MB         
* F+ [8 v$ t# Q0 l- y注 modules 是通过 make modules_install 之后, 在 /lib/modules 中根据编译内核版本号来查看的 查看有多少个 .ko 文件的方法:
8 c) t/ g# o3 c* k) [; R; j, p' J. Q3 p( }& G
cd /lib/modules/3.2.60+ q$ W' Y# o; L4 y9 @" f6 [
find . -name '*.ko' | wc -l
# I: o. U! L/ z- {- a% c分开编译
2 b, ?8 Y! @8 \* j' c模块和内核不在一起的编译, 就是在现有的内核中追加一些内核模块时, 不需要将内核也重新编译. 模块分开编译的方法很简单, 参考之前的博客: 《Linux内核设计与实现》读书笔记(六)- 内核数据结构 这篇博客中的例子就是和内核分开编译的模块.' ?7 o: @- s. M, w/ ?$ F" c. b% c

6 _3 r) x8 y- g" L交叉编译
2 M! K5 t8 m/ o交叉编译就是在当前平台上编译其他平台上的内核二进制映像, 比如在 x86_64 平台上编译 ARM 的内核映像. 交叉编译需要目标平台的交叉编译器. 编译时主要是 ARCH 和 CROSS_COMPILE 2个变量的设置.
" n& F- b& [7 r
! b0 e" j) m# s! P下面举个交叉编译 ARM 的例子: 公司用的制作 Cubieboard 板子上的image中的一段编译内核的代码7 m/ i4 z* S$ x  C4 }* m
) i1 D- J" u$ Y; I% c
make -C ${CB_KSRC_DIR} O=${CB_KBUILD_DIR} ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- kernel_defconfig
" X6 h$ U' n8 I# t* i' u4 U; f. Hmake -C ${CB_KSRC_DIR} O=${CB_KBUILD_DIR} ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- -j4 INSTALL_MOD_PATH=${CB_TARGET_DIR} uImage modules' C' a* o7 ]& a' s, ]
上述 第一行 是编译内核源码. 第二行 是创建 uImage 格式的内核映像以及创建内核模块 最终在 INSTALL_MOD_PATH 生成的内核模块可以直接拷贝到 arm机器上使用.3 ]. E0 Q: \+ C
+ J- l4 B( g( b  ~2 G9 S2 a1 D7 U
生成内核包3 K5 U) w! M. y: Y. n. N
debian 系 linux下生成 内核源码包的方法% h6 F1 o9 T! K! A8 c8 c9 @) @

8 G& {) {0 i# Dmake deb-pkg% c! |5 ]+ M% e  }8 W: Z% {+ Y8 h
安装内核
) ^' ~/ {+ u2 r1 nmake modules_install (安装内核模块到 /lib/modules 下) make install (安装内核二进制映像, 生成并安装boot初始化文件系统映像文件)
: v; K2 f+ L, K+ C% W8 A) s' w! _% T9 W/ v0 Q$ d
卸载内核9 Q; @/ J/ G$ U+ C+ d
删除/lib/modules/目录下不需要的内核库文件
$ Y% K) X6 j% M7 L/ b3 X% Y删除/usr/src/kernel/目录下不需要的内核源码0 n; f# k1 e  c& f' d
删除/boot目录下启动的核心档案禾内核映像
# s: s$ ~, I1 n, ?- X; n更改grub的配置,删除不需要的内核启动列表& G7 X; ]& K7 w$ ^6 p2 Y5 q" e6 q
内核 Makefile 中一些有用的 target- z  |7 K) B! V$ ~
make help : 内核Makefile中的各种 target3 z4 k) {/ R; q5 m9 q) X
make cscope : 生成 cscope 文件, W7 q' G: \& @
make tags/TAGS : tags可用于vim, TAGS可用于emacs

该用户从未签到

2#
发表于 2020-9-11 16:08 | 只看该作者
编译Linux内核
您需要登录后才可以回帖 登录 | 注册

本版积分规则

关闭

推荐内容上一条 /1 下一条

EDA365公众号

关于我们|手机版|EDA365电子论坛网 ( 粤ICP备18020198号-1 )

GMT+8, 2025-6-27 18:50 , Processed in 0.062500 second(s), 23 queries , Gzip On.

深圳市墨知创新科技有限公司

地址:深圳市南山区科技生态园2栋A座805 电话:19926409050

快速回复 返回顶部 返回列表