一、获取内核源码

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.x 实践 第一个例子(Spring 3.x 企业应用开发实战读书笔记第二章)

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

  5. Getting Started With Hazelcast 读书笔记(第二章、第三章)

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

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

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

  7. javascript 数据结构和算法读书笔记 > 第二章 数组

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

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

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

  9. [Effective Java 读书笔记] 第二章 创建和销毁对象 第一条

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

随机推荐

  1. 数论 UVA 11388

    这道题是关于两个数的最大公约数和最小公倍数的题目.给你两个数字g,l,分别表示最大公约数和最小公倍数.要求你找到两个数a,b,要求这两个数的最大公约数和最小公倍数为所给的两个数.如果存在多组数字符合这 ...

  2. Quartus 编译错误

    1.Error (10028): Can't resolve multiple constant drivers for net ** 这种错误一般是由于定义的reg寄存器在多个always中进行赋值 ...

  3. SpringMVC案例1——对User表进行CRUD操作

    ------------------------------------------------------------------web.xml--------------------------- ...

  4. asp.net ajax 调用一例

    <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="WebForm1.aspx. ...

  5. Squid

    事件:由于我们在运维过程中需要升级或安装新的开源软件或组件时,相关的依赖包或基础包非常非常多. 因安全限制,对于没有访问internet权限的服务器,在执行安装或升级过程中就非常容易出错. 所以我们需 ...

  6. Flume1.5.0的安装、部署、简单应用(含伪分布式、与hadoop2.2.0、hbase0.96的案例)

    目录: 一.什么是Flume? 1)flume的特点 2)flume的可靠性 3)flume的可恢复性 4)flume 的 一些核心概念 二.flume的官方网站在哪里? 三.在哪里下载? 四.如何安 ...

  7. Java开发常用Linux命令

    1.查找文件 find / -name filename.txt根据名称查找/目录下的filename.txt文件. find . -name "*.xml"递归查找所有的xml文 ...

  8. JS获取当前日期时间及JS日期格式化

    Js获取当前日期时间: var myDate = new Date(); myDate.getYear(); //获取当前年份(2位) myDate.getFullYear(); //获取完整的年份( ...

  9. [转]解决vista和win7在windows服务中交互桌面权限问题:穿透Session 0 隔离

    服务(Service)对于大家来说一定不会陌生,它是Windows 操作系统重要的组成部分.我们可以把服务想像成一种特殊的应用程序,它随系统的“开启-关闭”而“开始-停止”其工作内容,在这期间无需任何 ...

  10. 【AT91SAM3S】英倍特串口示例工程05-UART中,串口是怎样初始化的

    在这个示例工程的main.c文件中,进入main之后,没有发现串口功能的任何配置.直接使用了printf这个东西进行输出.将软件下载到开发板上之后,在电脑端使用串口软件,可以看板子有数据发来.说明这个 ...