从内核出发


  版权声明本文参考了《Linux 内核设计与艺术》。 未经作者允许,严禁用于商业出版,否则追究法律责任。网络转载请注明出处,这是对原创者的起码的尊重!!!


1 编译内核与内核补丁

  • 获取内核源码:内核是开源的, 可以从http://www.kernel.org下载或者用git从git.kernel.org克隆。
  • 内核源码路径:内核源码一般安装在/usr/src/linux目录下。但不要用于开发,也不要用root身份修改,而应当建立自己的主目录,仅以root身份安装

  • 配置内核

    • 每个选项要么是二选一yes或no,要么是三选一yes、no、module。yes表示把代码编译进内核映像,module表示以模块方式编译。
    • $ make config——逐一遍历每个选项
    • $ make menuconfig——使用ncurse图形界面
    • $ make gconfig——使用图形界面工具
    • $ make defconfig——默认配置
    • 内核配置好后,配置项存放在源代码内核源码根目录的.config文件中,可以直接修改该文件,但修改后应该更新用$ make oldconfig更新配置。
    • 选项CONFIG_IKCONFIG_PROC把压缩过的内核配置文件放在/proc/config.gz中,如果当前内核启用了该选项,则可以直接克隆该配置。
  • 编译内核
    • $ make,2.6版本之前每次编译需要运行$make dep
    • 减少编译时的垃圾信息
      • $make > 文件名 : 把编译细节、警告、错误输出到指定文件。
      • $make > /dev/null:不记录任何编译信息
    • 衍生多个编译作业:$make -jn,n为作业数目,每个CPU核心一个或两个作业。
  • 删除内核:是如何安装的就选择相应的删除方法:
    • rpm 删除法
      rpm -qa | grep kernel* (查找所有linux内核版本)
      rpm -e kernel-(想要删除的版本)
    • yum 删除法
      yum remove kernel-(要删除的版本)
    • 手动删除
      删除/lib/modules/目录下不需要的内核库文件
      删除/usr/src/kernel/目录下不需要的内核源码
      删除/boot目录下启动的核心档案和内核映像
      更改grub的配置,删除不需要的内核启动列表
  • 安装内核补丁$patch -pl < 补丁路径

  • 内核源码的结构

目录说明
arch特定体系结构相关的代码
arch//mach-xxxx具体机器或主板相关的代码
arch//include/asm体系结构相关的头文件
arch//boot/dts设备数从3.0以后才有
block块设备I/O层次
crypo加、解密库
COPYING版权声明。
CREDITSLinux主要贡献者名单
Documentation,README内核源码文档及帮助文件
drivers设备驱动程序
firmware使用某些驱动程序而需要的设备固件
fsVFS和各种文件系统
include内核头文件,需要提供给外部模块使用。
init内核引导和初始化
ipc进程间通信代码
kernel像调度程序这样的核心子系统
Kconfig, Kbuild, Makefile, scripts用于内核编译癿配置文件、脚本等。
lib内核函数库
mm内存管理子系统和VM
MAINTAINERS维护者名单。
net网络子系统
samples示例,示范代码
scripts编译内核所用的脚本
securityLinux 安全模块 SElinux
sound音频子系统
tools在Linux开发中用于性能测试、自测试等常用工具
usr早期用户空间代码(所谓的initramfs)
virt虚拟化基础结构

2 内核开发的特点

  • 无标准C库:不能使用标准C库和标准头文件。基本内核头文件位于源码顶级目录下的include目录,体系结构头文件位于源码顶级目录下的arch/体系结构/include目录。

  • 使用GNU C,推荐用gcc 4.4或以后的版本来编译内核。

    • 内联函数:内联函数在编译时会在它被调用的地方展开,减少了函数调用的开销,性能较好。但是,频繁的使用内联函数也会使代码变长,从而在运行时占用更多的内存。所以内联函数使用时最好要满足以下几点:函数较小,会被反复调用,对程序的时间要求比较严格。如:内联函数示例:static inline void sample();
    • 分支声明:用unlikely标记绝少发生的分支和likely标记常发生的分支。如:if (unlikely(error)) {};if (likely(success)) {};
    • 内联汇编:内联汇编用于偏近底层或对执行时间严格要求的地方。如:unsigned int low, high; asm volatile("rdtsc" : "=a" (low), "=d" (high));
  • 没有内存保护:因为内核是最低层的程序,所以如果内核访问的非法内存,那么整个系统都会挂掉!!所以内核开发的风险比用户程序开发的风险要大。而且,内核中的内存是不分页的,每用一个字节的内存,物理内存就少一个字节。所以内核中使用内存一定要谨慎。

  • 不使用浮点数:内核不能完美的支持浮点操作,使用浮点数时,需要人工保存和恢复浮点寄存器及其他一些繁琐的操作。

  • 内核栈容积小且固定:内核栈的大小有编译内核时决定的,对于不用的体系结构,内核栈的大小虽然不一样,但都是固定的。查看内核栈大小的方法:$ ulimit -a | grep "stack size"

  • 同步和并发:Linux是多用户的操作系统,所以必须处理好同步和并发操作,防止因竞争而出现死锁。

  • 可移植性:Linux内核可用于不用的体现结构,支持多种硬件。所以开发时要时刻注意可移植性,尽量使用体系结构无关的代码。


  版权声明本文参考了《Linux 内核设计与艺术》。 未经作者允许,严禁用于商业出版,否则追究法律责任。网络转载请注明出处,这是对原创者的起码的尊重!!!


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

蓝月心语

你的鼓励是我最大的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值