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

Linux内核设计与实现之内核开发的准备

[复制链接]

该用户从未签到

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

EDA365欢迎您登录!

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

x
) m% m0 x: w6 b8 h0 ]6 H: p: U
在尝试内核开发之前,需要对内核有个整体的了解。
3 w5 w1 M% _- ?/ x  z  u
( B! z8 H% \) K5 N主要内容:% W  z. x( l8 H2 P

! L  x8 ]1 P# y! X' y获取内核源码
4 ^; T2 V6 E% I* w# ~内核源码的结构% r8 A$ d  A) C# F4 l  d- A4 U
编译内核的方法
! S! ]& K7 z/ j. R" R内核开发的特点
1 U1 b8 y& f; ^; Z' T! q * c: o# M6 s9 e  L& s+ d
' d* ~4 ^4 b$ a6 T' r& N) @
1. 获取内核源码
* a% n3 \$ s4 s" n+ ]内核是开源的,所有获取源码特别方便,参照以下的网址,可以通过git或者直接下载压缩好的源码包。. W7 n- R! s# D2 G
9 `9 {3 r& A$ D' u5 U" M6 n  z
http://www.kernel.org
0 |) r! i( A: y& l' t* I, w$ l+ o4 T/ h# \

' E/ {( V, B5 q& g+ y
, }' D) \3 ?1 B. E0 O3 ?2. 内核源码的结构( ~- ~% R( J) a- E

, L$ z% V7 q0 B
8 a$ Q/ i% B6 ~; |) z. Y/ p. h目录        说明! i6 D8 Z& Q5 I
arch        特定体系结构的代码3 |) I) z) ^% o* C
block        块设备I/O层1 m# {! J) Y( u1 [( y4 U. b
crypo        加密API- @% M1 G$ n( a. c& a5 Y
Documentation        内核源码文档
4 T8 Y( V3 J; [, G6 @9 Cdrivers        设备驱动程序
% P, z# E' `3 T6 Ofirmware        使用某些驱动程序而需要的设备固件- \5 R1 {0 x) L. Z4 B5 K
fs        VFS和各种文件系统: H3 Z' A! l5 k; S8 M6 L% e; l# M
include        内核头文件$ R" x& g+ s- R3 ^8 G4 p
init        内核引导和初始化
% ?3 _2 ]7 E& ]; a) O/ cipc        进程间通信代码
% E* _- Z: h3 Gkernel        像调度程序这样的核心子系统
2 a, \$ o$ g& y: u* Z4 _lib        同样内核函数) C, x, S/ ]2 S3 {. V/ g$ U8 z
mm        内存管理子系统和VM
$ K/ O0 }! G6 P5 D8 X  c' ~net        网络子系统
( |) F' F( `8 p9 R# _8 u# ysamples        示例,示范代码
7 o3 x" U% O9 k) O# |scripts        编译内核所用的脚本
9 D2 ?* g. S- I, ~! Y: ^! G' esecurity        Linux 安全模块
6 r! r) {# y- Y7 x4 osound        语音子系统
1 Q3 Z1 _  ]8 V5 t9 y  cusr        早期用户空间代码(所谓的initramfs)
: B' }2 N' a: f5 V3 f0 Itools        在Linux开发中有用的工具
9 `, Y& D6 s4 v+ [* O& fvirt        虚拟化基础结构3 |2 X& U" p% j

3 K# r6 w- f0 l- U: P$ [! H$ M* g0 n! W, H) b
3. 编译内核的方法
, j# W! N  n+ K. _! x还未实际尝试过手动编译内核,只是用yum更新过内核。这部分等以后手动编译过再补上。' R% y  ~6 Z# U. S+ k

% j3 T! r' B/ D. i7 U安装新的内核后,重启时会提示进入哪个内核。当多次安装新的内核后,启动列表会很长(因为有很多版本的内核),显得不是很方便。5 e9 i% |2 G0 I; B/ C3 T, E2 K

- S# n! x0 l; ]& l下面介绍3种删除那些不用的内核的方法:(是如何安装的就选择相应的删除方法)
) _2 A1 w% t/ e- {9 B# W9 f- a% n  G
3.1 rpm 删除法; d( g8 V" L1 f
   rpm -qa | grep kernel*  (查找所有linux内核版本)6 U& I0 w; O- V) c0 b( P4 |3 w8 L
   rpm -e kernel-(想要删除的版本)
3 k9 i" m- m& Y
9 b$ \/ V0 S) {3 d! p; J* o3.2 yum 删除法
+ m  l# ?! ^3 `6 v* `   yum remove kernel-(要删除的版本)
# T+ r/ A! F0 o
1 S% H, r. j8 C* {' D3.3 手动删除
4 S( B! `4 N' [8 J  t2 z, i   删除/lib/modules/目录下不需要的内核库文件& Q5 Q8 b) G' ?% i; U
   删除/usr/src/kernel/目录下不需要的内核源码' h: f1 S9 a* x7 J! W8 Q
   删除/boot目录下启动的核心档案禾内核映像
& o  Q( N* r1 }6 s+ [+ U2 h   更改grub的配置,删除不需要的内核启动列表- h  [( {5 f- T
( R8 T7 w) g* d) k' [( B# Q) i! P( R( u

! U: F: f' a  P: o) }% [& |# l+ x2 B0 V4 ?! i* }
4. 内核开发的特点
6 r. b/ V# @7 r/ l+ A: L0 v4.1  无标准C库
9 T$ ~/ i. ^/ L" S6 U为了保证内核的小和高效,内核开发中不能使用C标准库,所以连最常用的printf函数也没有,但是还好有个printk函数来代替。
& c7 i0 \, o. ?2 d9 b7 Z
0 h8 Q. f+ Z7 e/ c4.2 使用GNU C,推荐用gcc 4.4或以后的版本来编译内核
/ L8 w  Q* g) x3 m( D! ^因为使用GNU C,所有内核中常使用GNU C中的一些扩展:+ ?# \" B/ k1 B1 E# }  w5 E/ |: D1 c
# U7 K# S& L( b) N
4.2.1 内联函数$ q( ?) @+ W! H+ r% g/ h2 k1 W
内联函数在编译时会在它被调用的地方展开,减少了函数调用的开销,性能较好。但是,频繁的使用内联函数也会使代码变长,从而在运行时占用更多的内存。( S# {2 u* @% L) q# @

, {$ r' V- m+ A& r5 H) F所以内联函数使用时最好要满足以下几点:函数较小,会被反复调用,对程序的时间要求比较严格。
  A/ `" c- S1 A! N2 r( {" ]
: ~4 g3 ^9 D4 @, v5 h. s内联函数示例:static inline void sample();6 D3 o! k. R3 X: V
: j4 R/ [0 G6 @1 T% B$ L
4.2.2 内联汇编0 w  @9 Q$ l+ M4 q+ S1 b$ \
内联汇编用于偏近底层或对执行时间严格要求的地方。示例如下:
: y% u2 S0 X% G! ~. L; `: b! c% r8 F5 O
unsigned int low, high;* b, D3 o* Z+ d% i
asm volatile("rdtsc" : "=a" (low), "=d" (high));3 J( S3 `$ k5 E% Z" A+ {1 I: }. o
/* low 和 high 分别包含64位时间戳的低32位和高32位 */( f: o" d) H( s1 h
4.2.3 分支声明
- ?" y. a. t  [/ ~+ W3 @5 I如果能事先判断一个if语句时经常为真还是经常为假,那么可以用unlikely和likely来优化这段判断的代码。
: y$ Z) ^8 C7 ^8 s3 g8 l, M/ X! s, X. ]1 M  Q% h
复制代码; F: m, ^; D- R; x
/* 如果error在绝大多数情况下为0(假) */
* l+ m3 @4 E) l* b$ X7 i: oif (unlikely(error)) {
1 m8 L+ u/ y5 v- [4 k9 {1 g$ P4 u    /* ... */
5 ^0 t5 k& _6 l+ U- r}
' `4 `& X& g0 M) H8 i* Z! P0 o/ N" Y% `9 y; S2 {9 ~
/* 如果success在绝大多数情况下不为0(真) */9 y+ p2 F0 V. a4 I
if (likely(success)) {
7 d. Y' Y4 p, p/ @$ }    /* ... */4 D0 @5 n/ F& h2 V& {2 R. q9 a
}
1 G- V( x7 R" [, }4 O! a复制代码
1 V9 u) i: P7 _& O) r/ }4.3 没有内存保护
9 ?, q) c9 k5 P$ r; p3 X8 P因为内核是最低层的程序,所以如果内核访问的非法内存,那么整个系统都会挂掉!!所以内核开发的风险比用户程序开发的风险要大。$ n' M" ^% E  p; K% d4 Z

, F! ]1 l  w. M+ I, P" p" L, A而且,内核中的内存是不分页的,每用一个字节的内存,物理内存就少一个字节。所以内核中使用内存一定要谨慎。
' V/ S! |0 w' a+ @, \' a- Y% e) V& _8 _, ]4 I  |2 Y$ @
4.4 不使用浮点数/ H6 R- K, J, ?, x2 }1 r
内核不能完美的支持浮点操作,使用浮点数时,需要人工保存和恢复浮点寄存器及其他一些繁琐的操作。
; o) s. g! T6 B+ I  c
+ h1 T1 i' h. z4 |+ s" `" t+ G4.5 内核栈容积小且固定5 H9 c) \; t. g
内核栈的大小有编译内核时决定的,对于不用的体系结构,内核栈的大小虽然不一样,但都是固定的。: R! V" [, [( ?/ i
1 _5 i) s& v  ^0 I8 O( g
查看内核栈大小的方法:
2 v6 u& j7 C2 H4 s* p, M$ s& ]
- y+ Q7 K4 n; I4 q- `  `ulimit -a | grep "stack size"
5 _: W+ k3 w( V4.6 同步和并发* y+ J) V8 I# S1 l* `; F9 q7 T! B
Linux是多用户的操作系统,所以必须处理好同步和并发操作,防止因竞争而出现死锁。
3 i5 `# \* R8 A9 N
! \" B6 e1 u& b) @, L4.7 可移植性7 c- a, p3 u( C/ @5 d3 d
Linux内核可用于不用的体现结构,支持多种硬件。所以开发时要时刻注意可移植性,尽量使用体系结构无关的代码。

该用户从未签到

2#
发表于 2020-9-24 16:05 | 只看该作者
Linux内核设计与实现之内核开发的准备
您需要登录后才可以回帖 登录 | 注册

本版积分规则

关闭

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

EDA365公众号

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

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

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

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

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