《Linux内核设计与实现》读书笔记 第二章 从内核出发

时间:2022-09-28 17:37:45

一、获取内核源码

1. Git

  • git实际上是一种开源的分布式版本控制工具。

  • Linux作为一个开源的内核,其源代码也可以用git下载和管理

      - 获取最新提交到版本树的一个副本
    - $ git clone git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6.git
    - 下载代码后,更新自己的分支到最新分支
    - $ git pull

2.安装内核源代码

  • 压缩形式为bzip2:$ tar xvjf linux-x.y.z.tar.bz2

  • 压缩形式为zip:$ tar xvzf linux-x.y.z.tar.gz

      关于参数:
    -x 解开.tar格式的文件
    -v 显示详细信息
    -j 使用bzip2程序
    -z 使用gzip程序
    -f 使用归档文件

3. 使用补丁

从内部源码树开始,运行$ patch -p1 < ../patch-x,y,z

二、内核源码结构

详见LINUX内核分析第三周学习总结:构造一个简单的LINUX系统MENUOS中第一部分:“Linux内核源码简介”。

目 录 描 述
arch 特定体系结构的代码
block 块设备I/O层
crypo 加密API
Documentation 内核源码文档
drivers 设备驱动程序
firmware 使用某些驱动程序而需要的设备固件
fs VFS和各种文件系统
include 内核头文件
init 内核引导和初始化
ipc 进程间通信代码
kernel 像调度程序这样的核心子系统
lib 同样内核函数
mm 内存管理子系统和VM
net 网络子系统
samples 示例,示范代码
scripts 编译内核所用的脚本
security Linux 安全模块
sound 语音子系统
usr 早期用户空间代码(所谓的initramfs)
tools 在Linux开发中有用的工具
virt 虚拟化基础结构
  • COPYIN:内核许可证
  • CREDITS:开发者列表
  • MAINTAINTERS:维护者列表(维护内核子系统和驱动程序)

三、编译内核

1. 配置内核(关于make与config)

(1)相关

  • Makefile:根据配置的情况,构造出需要编译的源文件列表,然后分别编译,并把目标代码链接到一起,最终形成 Linux 内核二进制文件。
  • config.in:内核配置文件,给用户提供配置选择的功能。
  • 配置工具:包括配置命令解释器(make config)和配置用户界面(例如:make menuconfig:基于ncurse库的图形界面工具;make gconfig:基于gtk+的图形工具...)。
  • .config:用户用来存放内核配置后结果的文件。
  • 可以配置的各种选项:用CONFIG_FEATURE形式表示,其前缀为CONFIG。

(2)命令

  • make config:遍历所有配置项,并让用户选择
  • make deconfig:按默认的配置
  • make oldconfig:先将/boot目录下的配置文件写进.config文件中,采用的是注释的形式写进新增加的功能。
  • zcat /proc/config.gz > .config:配置选项CONFIG_IKCONFIG_PROC会把完整的压缩过的内核配置文件存放在/proc/config.gz中,再次编译时可以方便地克隆当前的配置。
  • make:默认的Makefile自动化编译。

2. 其它事项

  • 减少垃圾信息

      $ make > ../detritus
    #将错误报告和警告信息重定向到文件中
    $ make > /dev/null
    #将无用的输出信息重定向到/dev/null中 - /dev/null:空设备,输入的信息直接丢弃
  • 衍生多个编译作业:make程序能把编译过程拆分成多个并行的作业。其中每个作业独立并发地运行,有助于加快多处理器系统上的编译过程,也有利于改善处理器的利用率。默认情况下,make只衍生一个作业。

      $ make -jn
    #以多个作业编译内核 - j:指定同时执行多任务
    - n:要衍生出的作业数

3. 安装新内核

make modules_install
#把所有已编译的模块安装到正确的主目录/lib/modules下
  • System.map文件:编译时在内核代码树的根目录下创建的符号对照表。用来将内核符号与它们的起始地址对应起来。

四、内核开发特点

1. 无libc库/标准头文件

  • 原因:(速度与大小)保证内核高效和简练。

  • 内核源代码文件不能包含外部头文件。

    • 基本头文件:内核源代码*目录下的include
    • 体系结构相关头文件:内核源代码树的arch/<architecture>/include/asm目录下
  • printk()函数:把格式化好的字符串拷贝到内核日志缓冲区上,syslog程序可以通过读取该缓冲区来获取内核信息。

2. 必须使用GNU C

什么是GNU?GNU是一种操作系统,GNU提供的C编译器就是我们之前使用的gcc。

(1)内联函数

static inline void wolf(unsigned long tail_size);
- static:关键字
- inline:用于限定关键字
  • 内联函数:编译时在它被调用的地方展开。

    • 优点:减少了函数调用的开销,性能较好。
    • 缺点:频繁的使用内联函数也会使代码变长,从而在运行时占用更多的内存。
  • 定义内联函数特点:时间要求高,本身长度较短的函数。

  • 使用之前就要定义好内联函数,一般在头文件中定义。

  • 为了类型安全和易读性,优先使用内联函数而不是复杂的宏。

(2)内联汇编

unsigned int low, high;
asm volatile("rdtsc" : "=a" (low), "=d" (high));
/* low 和 high 分别包含64位时间戳的低32位和高32位 */
- asm:嵌入汇编代码
- volatile:不优化
  • 汇编语言用于偏近底层或对执行时间严格要求的地方。

(3)分支声明

/* 如果error在绝大多数情况下为0(假) */
if (unlikely(error)) {
/* ... */
} /* 如果success在绝大多数情况下不为0(真) */
if (likely(success)) {
/* ... */
}
  • 对于条件选择语句,在一个条件经常/很少出现时,编译器可通过gcc内建的一条指令对条件分支选择进行优化。
  • 内核把这条指令封装成了宏。

3. 没有内存保护机制

  • 内核自己非法访问内存的风险
  • 内核中的内存都不分页:每用掉一个字节,物理内存都减少一个

4. 难以执行浮点运算

  • 使用浮点数时,需要人工保存和恢复浮点寄存器及其他一些繁琐的操作。
  • 不建议使用

5. 每个进程只有一个很小的定长堆栈

  • 内核栈的大小是编译内核时决定的,对于不用的体系结构,内核栈的大小不一样,但都是固定的。(不像用户空间的栈可以动态增长)

6. 必须时刻注意同步和并发

  • 原因:

    • Linux是抢占多任务操作系统
    • 内核支持对称多处理器系统(SMP)
    • 中断异步到来
    • 内核可以抢占
  • 常用解决方法:自旋锁和信号量

7. 考虑可移植性的重要性

  • 需要保持的特点:大部分C语言代码与体系结构无关。

五、总结:关于Linux内核的结构与特点

1. 版本控制

  • 我最早接触git是刚开始使用实验楼的时候,实验楼中的代码保存需要用到其中“我的代码库”功能,实际上就是最简单的git。
  • Linux内核这种开源的代码以及很多项目使用git进行版本控制与协作都是挺方便的。
  • 网上有很多教程可以参考,感觉这个比较全面:Git教程,可以在一些网站上创建自己的代码库,比如:git.oschina,操作过就会发现还是比较简单的。

2. 依据结构和特点的开发

  • 通读本章之后感觉Linux内核的很多要求与一般的项目其实是差不多的,它的这些基本结构、开发的特点,对于理解它各个部分的工作过程是很有帮助的。

参考资料1:《Linux内核设计与实现》(原书第三版)

参考资料2:make config 解惑

《Linux内核设计与实现》读书笔记 第二章 从内核出发的更多相关文章

  1. Linux内核设计与实现 读书笔记 转

    Linux内核设计与实现  读书笔记: http://www.cnblogs.com/wang_yb/tag/linux-kernel/ <深入理解LINUX内存管理> http://bl ...

  2. Linux内核设计与实现 读书笔记

    第三章 进程管理 1. fork系统调用从内核返回两次: 一次返回到子进程,一次返回到父进程 2. task_struct结构是用slab分配器分配的,2.6以前的是放在内核栈的栈底的:所有进程的ta ...

  3. STL源码分析读书笔记--第二章--空间配置器(allocator)

    声明:侯捷先生的STL源码剖析第二章个人感觉讲得蛮乱的,而且跟第三章有关,建议看完第三章再看第二章,网上有人上传了一篇读书笔记,觉得这个读书笔记的内容和编排还不错,我的这篇总结基本就延续了该读书笔记的 ...

  4. Spring 3&period;x 实践 第一个例子(Spring 3&period;x 企业应用开发实战读书笔记第二章)

    前言:工作之后一直在搞android,现在需要更多和后台的人员交涉,技术栈不一样,难免鸡同鸭讲,所以稍稍学习下. 这个例子取自于<Spring 3.x 企业应用开发实战>一书中的第二章,I ...

  5. Getting Started With Hazelcast 读书笔记&lpar;第二章、第三章&rpar;

    第二章 起步 本章就相当简单粗暴了,用一个个例子说明hazelcast怎么用. 1.map,set,list这些集合类都是开箱即用的,只要从Hazelcast的实例中获取一份就行. 2.增加了Mult ...

  6. Java Concurrency in Practice 读书笔记 第二章

    第二章的思维导图(代码迟点补上):

  7. javascript 数据结构和算法读书笔记 &gt&semi; 第二章 数组

    这章主要讲解了数组的工作原理和其适用场景. 定义: 一个存储元素的线性集合,元素可以通过索引来任意存取,索引通常是数字,用来计算元素之间存储位置的偏移量. javascript数组的特殊之处: jav ...

  8. 《C&plus;&plus; Primer》读书笔记—第二章 变量和基本类型

    声明: 文中内容收集整理自<C++ Primer 中文版 (第5版)>,版权归原书所有. 学习一门程序设计语言最好的方法就是练习编程. 1.8比特的char类型计算机表示的实际范围是-12 ...

  9. &lbrack;Effective Java 读书笔记&rsqb; 第二章 创建和销毁对象 第一条

    第二章  创建和销毁对象 第一条 使用静态工厂方法替代构造器,原因: 静态工厂方法可以有不同的名字,也就是说,构造器只能通过参数的不同来区分不同的目的,静态工厂在名字上就能表达不同的目的 静态工厂方法 ...

随机推荐

  1. &lbrack;Java coding&rsqb; leetcode notes

    1, 如何不排序而找到最大,次大或者最小值? var int max1, max2, min1; iterate array once: update max1, max2, min1, for ex ...

  2. 使用Xcode6和IOS8SDK以后遇到的问题

    定位.苹果在IOS8里面修改了定位授权协议,也就意味着你原来的app在ios8上很可能无法定位.目前最好的办法就是在app启动的时候调用IOS8的定位授权API来获取用户的授权,这样就不要在其他地方做 ...

  3. android19以上和以下uri转路径的方法

    android 19以上 /** * 专为Android4.4以上设计的从Uri获取文件路径 */ public static String getPath(final Context context ...

  4. Android 高仿腾讯旗下app的 皮肤加载技术

    http://www.cnblogs.com/punkisnotdead/p/4968851.html 以前写的这篇文章 可以高仿出 知乎 新浪微博等 绝大多数app的换肤技术,但是遗漏了腾讯的效果, ...

  5. uva 10910

    简单dp /************************************************************************* > Author: xlc2845 ...

  6. &equals;&equals; 和 equal

    ==比较是地址 equal比较的是值 Integer r1 = new Integer(900);//定义r1整型对象 Integer r2 = new Integer(900);//定义r2整型对象 ...

  7. No matching authentication protocol

    java 连接oracle数据库: 之前连接公司的oracle数据库没有问题,但客户提供的是oracle12C版本的,连接就报 :No matching authentication protocol ...

  8. SpringBoot 使用validation数据校验

    后端对数据进行验证 添加包 hibernate-validator <!-- https://mvnrepository.com/artifact/org.hibernate.validator ...

  9. 2019-03-27-day020-单继承与多继承

    昨日回顾 类的加载顺序 类内部的代码什么时候执行? 除了方法里面的代码 其余的所有内容都是在执行这个文件的时候就从上到下依次执行的 不需要调用 如果有同名的方法.属性,总是写在后面的会生 class ...

  10. Codeforces Round &num;313 D&period; Equivalent Strings(DFS)

    D. Equivalent Strings time limit per test 2 seconds memory limit per test 256 megabytes input standa ...