《linux内核设计与实现》读书笔记第一、二章

第一章 Linux内核简介

1.1 Unix的历史

1971年,Unix被移植到PDP-11型机中。 
1973年,Unix操作系统用C语言改写——为Unix系统的广泛移植铺平了道路。 
1977年,伯克利推出1BSD系统 
1994年,伯克利推出Unix系统的最终官方版——4.4BSD

unix强大的根本原因

(1)简洁:仅提供系统调用并有一个非常明确的设计目的 
(2)抽象:所有东西都被当做文件对待 
(3)可移植性:使用C语言编写,可移植能力强 
(4)进程:创建迅速,独特的fork系统调用 ; 
(5)清晰的层次化结构:一次执行保质保量地完成一个任务,策略和机制分离的理念,简单的进程间通信元语把单一目的的程序方便地组合在一起

1.2 追寻Linux足迹:Linux简介

1991年,Liunx Torvalds开发了Linux

Linux的特点: 
(1)是类Unix系统,但不是Unix 
(2)没有抛弃Unix的设计目标并且保证了应用程序编程接口的一致。 
(3)Linux系统的基础是内核、C库、工具集和系统的基本工具。

1.3 操作系统和内核简介

操作系统

是指整个系统中负责完成最基本功能和系统管理的那些部分。包括

内核、设备驱动程序、启动引导程序、命令行shell或者其他种类的用户界面、基本的文件管理工具和系统工具。

内核

被称作是管理者或者操作系统的核心。其组成包括:

(1)响应中断的中断服务程序 
(2)管理多个进程,分享处理器时间的调度程序 
(3)管理进程地址空间的内存管理程序
(4)网络、进程间通信等系统服务程序

每个处理器在任何指定时间点上的活动必然概括为下列三者之一:

  • 运行于用户空间,执行用户进程
  • 运行于内核空间,处于进程上下文,代表某个特定的进程执行
  • 运行于内核空间,处于中断上下文,与任何进程无关,处理某个特定的中断

1.4 Linux内核和传统Unix内核的比较

单内核和微内核设计之比较

Linux的内核虽然是基于单内核的,也具备微内核的一些特征。 主要有以下特征:

  • 支持动态加载内核模块
  • 支持对称多处理(SMP)
  • 内核可以抢占(preemptive),允许内核运行的任务有优先执行的能力
  • 不区分线程和进程

1.5 Linux内核版本

版本号:2.6.26.1 其中,

2 —— 主版本号 
6 —— 从版本号或副版本号 
26 —— 修订版本号 
1 —— 稳定版本号

副版本号表示这个版本是稳定版(偶数)还是开发版(奇数),上面例子中的版本号是稳定版

1.6 Linux内核开发者社区

可以在http://vegr.kernel.org上订阅邮件。

第二章 从内核出发

2.1 获取内核源码

2.1.1 使用Git

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

有了这两个命令,就可以获取并随时保持与内核官方的代码数一致。

2.1.1 安装内核源代码

内核压缩以GNU zip和bzip2两种

  • 压缩形式为bzip2 
    运行:$ tar xvjf linux-x.y.z.tar.bz2
  • 压缩形式为zip 
    运行:$ tar xvzf linux-x.y.z.tar.gz

注释(xvjf、xvzf):

  • -x 解开;
  • -v 显示详细信息;
  • -j 使用bzip2程序;
  • -z 使用gzip程序;
  • -f 使用归档文件;

内核源码一般安装在/usr/src/linux目录下。

不要以root身份对内核进行修改。

2.1.3 使用补丁

应用增量补丁,从内部代码树开始,只需运行

$ patch -p1 < ../patch-x,y,z

2.2 内核源码树

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

COPYIN:内核许可证; 
CREDITS:内核代码的开发者列表; 
MAINTAINTERS:维护者列表——负责维护内核子系统和驱动程序; 
Makefile:是基本内核的Makefile;

2.3 编译内核

2.3.1 配置内核

1、配置项

(1)二选一:yes/no 
(2)三选一:yes/no/module 
module:选定该配置项但编译的时候以模块形式生成(多用于驱动程序)

2、内核配置工具

$ make config 最简单的一个字符界面下的命令行工具; 
$ make menuconfig 基于ncurse库的图形界面工具; 
$ make gconfig 基于gtk+的图形工具;

3、内核配置命令

make config:遍历所有配置项,并让用户选择 
make deconfig:按默认的配置 
make oldconfig:在修改过配置文件之后,或者在用已有的配置文件配置新的代码树的时候,应该验证和更新配置。 
zcat /proc/config.gz > .config:从/proc下复制出配置文件并且使用它来编译一个内核

  • 配置选项CONFIGIKCONFIGPROC会把完整的压缩过的内核配置文件存放在/proc/config.gz中,再次编译时可以方便地克隆当前的配置。

make:默认的Makefile自动化编译。

2.3.2 减少编译的垃圾信息

  • 不看错误报告和警告信息,对输出重定向 
    $ make > ../detritus
  • 把无用的输出信息重定向到永无返回值的黑洞/dev/null中 $ make > /dev/null

2.3.3 衍生多个编译作业

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

2.3.4 安装新内核

  • 模块的安装,以root身份,运行 
    % make modules_install 
    这样可以把所有已编译的模块安装到正确的主目录/lib/modules下。
  • System.map文件:编译时在内核代码树的根目录下创建的文件;是一个符号对照表;用来将内核符号与它们的起始地址对应起来。

2.4 内核开发的特点

Linux内核编程与用户空间内应用程序开发的差异

  • Linux内核编程时不能访问C库
  • Linux内核编程时必须使用GNU C
  • Linux内核编程时缺乏像用户空间那样的内存保护机制。
  • Linux内核编程时浮点数很难使用。
  • 内核只有一个很小的定长堆栈。
  • 由于内核支持异步中断、抢占式和SMP,因此必须时刻注意同步和并发。
  • 要考虑可移植性的重要性。

2.4.1 无libc库抑或无标准头文件

内核不能使用函数库的原因:速度与大小,这些库对内核来说太大且太低效了。

基本头文件:内核源代码顶级目录下的include中
体系结构相关头文件:内核源代码树的arch//include/asm目录下 
printk()函数:运行指定一个标志来设置优先级,syslogd会根据这个优先级标志来决定在什么地方显示这条系统消息。 
- 优先级标志是预处理程序定义的一个描述性字符串,在编译时优先级标志就与要打印的消息绑在一起处理。

2.4.2 GNU C

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

1、内联函数 
内联函数:对时间要求比较高而本身长度比较短,一般定义在头文件中。

  • 定义一个内联函数,用static作关键字,用inline限定它。 
    static inline void wolf(unsigned long tail_size);

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

2、内联汇编

汇编语言用于偏近底层或对执行时间严格要求的地方。

3、分支声明

对于条件选择语句,在一个条件经常/很少出现时,编译器可通过gcc内建的一条指令对条件分支选择进行优化。 
内核把这条指令封装成了宏。

2.4.3 没有内存保护机制

内核中发生的内存错误会导致oops

内核中的内存不分页:每用掉一个字节,物理内存都减少一个

2.4.4 不要轻易在内核中使用浮点数

与用户空间进程不同,内核不完美支持浮点操作,因为他本身不能陷入

2.4.5 容积小而固定的栈

内核栈的准确大小随体系结构而变 
每个体系结构对应的内核栈的大小时固定的,不能动态增长。

2.4.6 同步和并发

Linux是抢占多任务操作系统。 
Linux内核支持多处理器系统。 
中断是异步到来的,完全不顾及当前正在执行的代码。
Linux内核可以抢占。

2.4.7 可移植性的重要性

能提高移植性的准则

保持字节序 
64位对齐 
不假定字长和页面长度

小结

1、很喜欢作者把章节分的很细,每一章节的内容很短,但又可以把每个部分讲解清楚,读起来不会觉得枯燥不耐烦。 
2、配合这课本的知识讲解,使我对网课的学习有了更多的思考,了解到内核,其实和应用程序一样也是一些代码(可以用C、java或其他语言编写),但唯一的区别就是,他们在物理内存中的组织形式不同,管理方式也不同,内核程序是管理应用程序,并为应用程序服务的。它需要更能加严谨的编码,要求几乎100%的无差错。这是我学习完内核后的一些浅显的理解。

参考资料

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

转载于:https://www.cnblogs.com/java-stx/p/5284917.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/418819.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

取模和取余的区别

其实取模和取余在目标上是一致的&#xff0c;但是因为语言对取余和取模上定义的不同&#xff0c;导致得到的结果不同。 对取余和取模定义不同的语言中&#xff0c;两者的不同点只有一个 取余运算在计算商值向0方向舍弃小数位 取模运算在计算商值向负无穷方向舍弃小数位 从上…

写代码个人体会

主干代码不要写在分支中看看代码是否真的需要判断,不需要判断的就没有必要加判断打分支经量让更多的代码写在分支中 不要写的过于分散if语句最好不要超过两层 &#xff0c;如果if语句超过两层的话就要考虑重新调整逻辑for语句最好不要超过两层&#xff0c;如果for语句超过两层的…

前端学习(1821):前端面试题之封装函数之去重

<!DOCTYPE html> <html><head><meta charset"UTF-8"><title></title></head><body><script type"text/javascript">/** 1.创建一个新数组,把原数组中的第一个元素插入到新数组中* 2.遍历原数组中的…

HandlerInterceptor拦截器的使用

https://blog.csdn.net/sinat_32023305/article/details/81284518

天猫整站SSM-分页-limit(做个人学习笔记整理用)

数据库使用的是mysql 要想在Mybatis中使用分页查询&#xff0c;首先要清楚mysql中limit的用法。 limit a,b a是从第a1条数据开始&#xff0c;b是指读取几条数据 例如&#xff1a;select * from table limit 0,10 这句sql语句是说从表中获取第1条开始的10条记录

spingboot 集成swagger2

https://www.cnblogs.com/jtlgb/p/8532433.html https://blog.csdn.net/qq_41446768/article/details/87936748

天猫整站SSM-分页-herf(做个人学习笔记整理用)

天猫整站SSM-分页-&#xff08;做个人学习笔记整理用&#xff09;<li ><a href"?start${page.start-page.count}" aria-label"Previous" ><span aria-hidden"true">‹</span></a> </li>如&#xff1a;<…

Lab1--关于安装JUnit的简要描述

安装JUnit的过程描述&#xff1a; 下载两个jar包&#xff1a; hamcrest-all-1.3.jar junit-4.12.jar 注意在导入完成jar包之后不要随意改变jar包的路径。 创建java程序&#xff0c;书写如下代码进行测试&#xff1a; triangle.java package triangle; public class triangle { …

天猫整站SSM-分页-总结(做个人学习笔记整理用)

天猫整站SSM-分页-herf&#xff08;做个人学习笔记整理用&#xff09; 先写Page.java package com.how2java.tmall.util;public class Page {private int start; //开始页数private int count; //每页显示个数private int total; //总个数private String param; //参数privat…

Java 图片流和base64互转

https://www.jianshu.com/p/ffb1f7e85530

ParameterizedType应用,利用java反射获取参数化类型的class实例

https://blog.csdn.net/ltaihyy/article/details/78211274 public class TestParameterizedType extends RequestApiParam<UserDispatchMakeInfoDTO1> {public static void main(String[] args) {Class clazz1TestParameterizedType.class;/*** 父类的参数类型不能是泛型…

天猫整站SSM-后台分类管理-增加(做个人学习笔记整理用)

天猫整站SSM-后台分类管理-增加&#xff08;做个人学习笔记整理用&#xff09; CategoryController&#xff1a; request.getSession().getServletContext()// 获取的是page的上下文。 request.getSession().getServletContext().getRealPath(“”); 是获取的的tamcat的路径&a…

Java中的Type接口和Class类有什么区别

https://blog.csdn.net/linghuainian/article/details/86137810

canvas 在线画图

canvas 在线画图 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>Title</title><style type"text/css">/*画图大师来了*/#cans{border:1px solid red;}</style><scrip…

java使用validator进行校验

https://blog.csdn.net/dream_broken/article/details/53584169 public class BeanValidator {// private static Validator validator SpringContextHolder.getBean(Validator.class);/*** 验证某个bean的参数** throws ValidationException 如果参数校验不成功则抛出此异…

Delphi iOS 开启文件共享 UIFileSharingEnabled

Apple 在 iOS 提供了文件共享&#xff08;FileSharing&#xff09;功能&#xff0c;让 App 有一个对外窗口的目录&#xff0c;透过 iTunes 可以任意管理这个目录的文档内容&#xff08;可拖入文档&#xff0c;也能将文档拖出备份&#xff09;。 如果 App 需要文件共享&#xff…

iOS:iOS开发系列–打造自己的“美图秀秀”(中)

来源&#xff1a; KenshinCui 链接&#xff1a;http://www.cnblogs.com/kenshincui/p/3959951.html 其他状态设置 常用的图形上下文状态设置上面基本都用到了&#xff0c;我们不再一一解释&#xff0c;这里着重说一下叠加模式和填充模式&#xff0c;初学者对于这两个状态设置…

Validator 使用总结

https://blog.csdn.net/weixin_37509652/article/details/80676693

ubuntu ifconfig只有lo没有ens33的问题

如果ifconfig只显示了lo&#xff0c; ifconfig -a 却正常显示ens33。那么可以按照如下的操作&#xff1a; service network-manager stop rm /var/lib/NetworkManager/NetworkManager.state service network-manager start 即可恢复网络连接