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

编译Linux内核

[复制链接]

该用户从未签到

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

EDA365欢迎您登录!

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

x

1 y' Y1 x- S8 E" l: Y下面的实验以 debian7.5 64bit 为例.8 `/ `+ Z7 i" z. e3 q' \1 }
3 z7 K0 }' j: ~4 z3 @9 x# H
获取源码+ I7 n8 D1 p% Y7 |  z6 l5 V+ |+ [5 D
获取 debian7.5 本身的源码非常简单:
3 {- M, H! A8 w- K4 {. W
' R  n& [2 w* h; B- _( Gsudo apt-get install linux-source
+ S" P8 Z$ j$ ]4 Ghttps://www.kernel.org/ 的git上提供的源码分支非常多, 刚开始学习源码主要关注下面几个分支:6 }" _0 A, C4 b4 U2 W. F& \1 j5 C

9 c  X8 K* @8 ]/ Q2 P7 Klinus分支: https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/ linux创始人的分支, 不用说肯定最重要, 它是所有分支的根源. 处于 "mainline" 的地位. 这个分支还有个好听的名字 – "vanilla(香草)" 内核.
$ H6 R' Z: W- z2 z4 Zlinux-next树: https://git.kernel.org/cgit/linux/kernel/git/next/linux-next.git/ 这个一个为发布将来的版本而积累新代码并进行测试的源码树. 由 Stephen Rothwell 等人进行管理和维护# b- t" V# ]& c. d, n3 r
stable树: https://git.kernel.org/cgit/linux/kernel/git/stable/linux-stable.git/ 这是一个主要针对过去发布的内核版本进行bug修改, 使其更加稳定的树. 由 Greg Kroah-Hartman, Chris Wright 进行管理和维护. 针对某个Linus树的稳定版维护一般持续6个月左右, 也有更持久的.9 ^0 o5 L, W7 ~; p* }
上面的列出的git树中都可以获取想要的源码.
4 m7 f7 {  `3 Z; G: B: G1 C
3 ?9 B0 `+ p6 i2 e/ @+ Q编译内核* _; i0 z2 E8 ^; o' ?
其实编译内核和编译普通软件也没多大区别, 只是内核编译的参数非常之多. 下面就来先看看如何设置内核编译参数
. m6 b4 y2 A% x5 }7 @( \' Q# W$ q" C& r" |
内核编译选项0 I5 m% F9 g, m& u4 \
编译选项个数 内核的编译选项的个数非常多, v2.6.38的内核中就有 12 000 个左右的设置选项(这是包含所有arch的配置选项). 内核编译选项不仅多, 有些编译选项之间还存在依赖关系, 所以手动设置编译选项几乎是不可能的. 值得庆幸的是, 只要知道自己需要设置的那些选项, 就可以使用 make ***config 来进行设置, 它还会自动处理依赖关系.
9 g5 E! m  }/ x8 z2 V# W; G* V8 V7 P7 K) D- |- a# E
配置编译选项: 设置内核编译选项是通过 kconfig 这个工具来完成的. kconfig 的源码就是内核代码中 script/kconfig 目录下: W+ i! h; B' |4 p" t. i& f! [  ?: A
. x! R3 o. I; c0 e/ q
各个编译选项的选择有3种方式:
/ W5 k* D9 D* S, N4 n' K# [$ B" E! i0 B3 y
=y :: 直接编译到内核中
4 e& c3 {* O2 }; C=m :: 以模块方式编译到内核中
- n0 h* J4 {, X- Q* N$ b2 i( z8 N; ~不设置 :: 不编译  M% s9 R* S0 {: E6 Z( O; b
编译方法:
+ Q+ y$ `! C' v  d/ W- E. f
& ^4 y% O; R$ V: T; F6 l# b+ A4 y' ~9 zmake menuconfig :: 源码根目录下生成 .config (没有会自动生成), .config中就是各个内核编译选项的选择状况.
0 Z% c7 m2 O! qmake defconfig :: 根据当前系统的架构默认 .config 生成内核源码目录下的 .config (每个架构的配置文件: ex. arch/x86/configs/x86_64_defconfig)! G# ^- B7 @, k* Q( j5 ]$ n
make oldconfig :: 将已有的 .config 放到源码根目录下后执行, 目的是为了复用之前的内核编译选项的配置.
0 ~) k; h; ^5 M7 M& |5 p5 A: E8 Rmake xconfig :: 图形化配置, 需要qt3, 个人觉得没有必要, 有 make menuconfig 就足够了.  O, d4 k8 Q1 e) L0 h+ h
make localmodconfig :: 生成以正在使用的内核模块为对象的 .config  `% r9 |. b4 H3 A
编译5 u& Y1 B; h5 ?7 n
编译很简单, 内核编译选项设置好之后, 只需简单的命令 make, 就可以编译了. 由于内核代码的庞大, 所以和一般应用程序相比, 编译时间会很长. 可以尝试以下方法来加快编译速度:
+ c% O6 F0 w2 }' Z
, g# M2 N2 D) d" u1 ?不用的驱动程序都不要设置, 这样就不会编译, Z6 l+ |" ]. U( Q7 l+ S* e

- _; R  o1 J$ D& u. F+ o利用make的 -j 选项来并发编译, ex. make -j N (N是并发数). 如果你的机器有2个CPU, 可以用 make -j 2 来提高编译速度, F0 h( Q( d8 |0 \
9 b' H! z& U* q& ^$ g
使用 make localmodconfig 来生成仅以正在使用的内核模块为对象的 .config (一般这样生成的.config中包含的内核模块最少, 所以编译速度快)7 _3 f1 P7 c3 ]2 R( h' P9 F
) Q; f$ P; x" ^7 ?$ P
编译时间比较: 测试环境 - debian v7.5虚拟机(cpu: 单核, 内存: 512MB)9 K# x- m5 x7 a, l+ }
" w- n- b: C: l: Y. v
.config生成        make时间        生成的modules        备注
. q9 f2 i, a9 a5 P% T! W2 |+ L( ~make menuconfig        1小时13分41秒        3052个.ko, 共1.2GB        默认配置, 什么也不选择7 Y; a: w- R6 R- V+ E$ c
make localmodconfig        19分36秒        337 个.ko, 共176MB         
( P3 B$ ]& ]: @, E注 modules 是通过 make modules_install 之后, 在 /lib/modules 中根据编译内核版本号来查看的 查看有多少个 .ko 文件的方法:" K7 g# H1 y5 s$ g5 p3 B
8 q; a; ^" U( ^6 l
cd /lib/modules/3.2.60
4 Z9 Q( I* Q! H/ P' H6 l2 qfind . -name '*.ko' | wc -l! h, q2 g* [) K9 c/ c
分开编译
: Z- d6 |: s+ x; h" m- j6 C模块和内核不在一起的编译, 就是在现有的内核中追加一些内核模块时, 不需要将内核也重新编译. 模块分开编译的方法很简单, 参考之前的博客: 《Linux内核设计与实现》读书笔记(六)- 内核数据结构 这篇博客中的例子就是和内核分开编译的模块.
0 D' C- {0 o$ L9 ~, R7 K2 r3 b/ _% c  W% W& V/ Z; h1 }
交叉编译$ @' V1 Y/ \( W
交叉编译就是在当前平台上编译其他平台上的内核二进制映像, 比如在 x86_64 平台上编译 ARM 的内核映像. 交叉编译需要目标平台的交叉编译器. 编译时主要是 ARCH 和 CROSS_COMPILE 2个变量的设置.
+ g7 x1 b5 n2 t
$ r- R# u& G1 {% V下面举个交叉编译 ARM 的例子: 公司用的制作 Cubieboard 板子上的image中的一段编译内核的代码
: c2 k; j+ J* P- P: N3 H6 T/ J& k9 ~# O. O( ^& h/ B  k+ t
make -C ${CB_KSRC_DIR} O=${CB_KBUILD_DIR} ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- kernel_defconfig0 x) w6 \7 [) I7 T" Q; U/ M
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; V6 l# f8 \. F
上述 第一行 是编译内核源码. 第二行 是创建 uImage 格式的内核映像以及创建内核模块 最终在 INSTALL_MOD_PATH 生成的内核模块可以直接拷贝到 arm机器上使用.
$ ]$ O8 h7 `7 ~' o6 N3 Q
2 o9 ^" d4 F( h生成内核包' c- [. z6 K; v, B$ H* z; Q
debian 系 linux下生成 内核源码包的方法
, V: |0 B' W& B/ A1 L, D
! `9 L6 `8 K9 |- q" m/ tmake deb-pkg
) S2 G7 y. j  f3 O3 j8 q: {安装内核  N' k1 |0 c6 C6 U1 M
make modules_install (安装内核模块到 /lib/modules 下) make install (安装内核二进制映像, 生成并安装boot初始化文件系统映像文件); q# m% ~3 k* w* V( l0 r

7 P' b* C" u; E1 l+ W1 i, I0 g3 u卸载内核
- N* z9 P( }  p$ V删除/lib/modules/目录下不需要的内核库文件5 Q( O+ b& D( d' T$ O4 K# M
删除/usr/src/kernel/目录下不需要的内核源码/ m7 u) W6 L# h' L% q9 X% f
删除/boot目录下启动的核心档案禾内核映像
7 K  X: [! p# |4 h3 z$ C8 Y: C更改grub的配置,删除不需要的内核启动列表
/ I) c  d! k3 }5 e/ m内核 Makefile 中一些有用的 target. ]5 C/ ?( C- O7 o" f
make help : 内核Makefile中的各种 target& ~0 U( g# Z: z
make cscope : 生成 cscope 文件& t' t: S) j' P; w, o6 w
make tags/TAGS : tags可用于vim, TAGS可用于emacs

该用户从未签到

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

本版积分规则

关闭

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

EDA365公众号

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

GMT+8, 2025-11-24 22:32 , Processed in 0.156250 second(s), 24 queries , Gzip On.

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

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

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