提交 98ca59c5 编写于 作者: O openeuler-ci-bot 提交者: Gitee

!243 新增罗宇哲系列博客2/3/4/5/6

Merge pull request !243 from liuxuelan/master
+++
title="第二期Linux内核发展史-3"
date="2020-08-06"
tags=["Linux","内核","发展史"]
archives="2020-08"
author="罗宇哲"
summary="Linux内核发展史-3"
+++
_作者:罗宇哲,中国科学院软件研究所智能软件研究中心_
这一小节我们主要介绍Linux系统应用程序的主要来源——GNU。
### 一、GNU
Linux包含系统内核和提供系统服务和工具的应用程序两个部分。Linux所使用的应用程序是由许多程序元编写并自由发布的。Linux支持自由软件的概念,即软件本身不应受限,它们应遵守GNU(GNU是GNU's Not UNIX的递归缩写)通用公共许可证(GPL)[1]。软件通常是以源代码的形式发布的,但也可能需要支付一定的费用。这里提到的GNU项目最初是由自由软件基金会(Free Software Foundation)发起的,这个基金会的创始人是Richard Stallman。GNU项目的宗旨是:试图创建一个与UNIX系统兼容,但并不受UNIX名字和源代码私有权限制的操作系统和开发环境。[1]因此GNU为软件社区贡献了许多UNIX系统上应用程序的仿制品,这些应用程序都遵循GPL许可证。
下面是在GPL条款下发布的一些主要的GNU项目软件[1]:
- GCC: GNU编译器集,它包括GNU C编译器。
- G++: C++编译器,是GCC的一部分。
- GDB:源代码级的调试器。
- GNU make: UNIX make命令的免费版本。
- Bison:与UNIX yacc兼容的语法分析程序生成器。
- bash:命令解释器(shell)。
- GNU Emacs:文本编辑器及环境。
许多其他的软件包也是在遵守自由软件的原则和GPL条款的情况下开发和发行的,包括电子表格、源代码控制工具、编译器和解释器、因特网工具、图形图像处理工具(如Gimp),以及两个完整的基于对象的环境(GNOME和KDE)。
### 二、常见开源协议简介
木兰协议:木兰协议是我国首个开源协议,这一开源协议共有五个主要方面,涉及授予版权许可、授予专利许可、无商标许可、分发限制和免责申明与责任限制。在版权许可方面,木兰协议允许“每个‘贡献者’根据’本许可证‘授予您永久性的、全球性的、免费的、非独占的、不可撤销的版权许可,您可以复制、使用、修改、分发其‘贡献’,不论修改与否。”木兰协议比Apache License更友好一些,Apache License要求列出每个修改文件,其实很多项目做不到这一点,所以MulanPSL直接取消了这项要求[2]。
GPL协议:GPL协议采取两种措施来保护程序员的权利:(1)给软件以版权保护;(2)给程序员提供许可证。它给程序员复制,发布和修改这些软件的法律许可。在复制和发布方面,GPL协议规定“只要你在每一副本上明显和恰当地出版版权声明和不承担担保声明,保持此许可证的声明和没有担保的声明完整无损,并和程序一起给每个其他的程序接受者一份许可证的副本,你就可以用任何媒体复制和发布你收到的原始的程序的源代码。你可以为转让副本的实际行动收取一定费用。你也有权选择提供担保以换取一定的费用。”[3]GPL的出发点是代码的开源/免费使用和引用/修改/衍生代码的开源/免费使用,但**不允许**修改后和衍生的代码做为**闭源的商业软件发布和销售**。GPL协议的主要内容是只要在一个软件中使用(“使用”指**类库**引用,修改后的**代码**或者**衍生代码**)GPL协议的产品,则该软件产品必须也采用**GPL协议**,既必须也是**开源和免费**[4]。
LGPL协议:LGPL是一个为主要为**类库使用**设计的开源协议。和GPL要求任何使用/修改/衍生之GPL类库的的软件必须采用GPL协议**不同**。LGPL允许**商业软件**通过类库**引用(link)方式**使用LGPL类库而**不需要**开源商业软件的代码。这使得采用**LGPL协议**的开源代码可以被**商业软件**作为类库引用并发布和销售。但是如果**修改LGPL协议的代码**或者**衍生**,则所有修改的代码,涉及修改部分的额外代码和衍生的代码都**必须采用LGPL协议**[4]。
BSD协议:BSD开源协议是一个给于使用者很大自由的协议。可以自由的使用,修改源代码,也可以将修改后的代码作为开源或者专有软件再发布。当你发布使用了BSD协议的代码,或者以BSD协议代码为基础做二次开发自己的产品时,需要满足三个条件:
1.如果再发布的产品中包含源代码,则在源代码中必须带有原来代码中的BSD协议。
2.如果再发布的只是二进制类库/软件,则需要在类库/软件的文档和版权声明中包含原来代码中的BSD协议。
3.不可以用开源代码的作者/机构名字和原来产品的名字做市场推广。
BSD代码鼓励代码共享,但需要尊重代码作者的著作权。BSD由于允许使用者修改和重新发布代码,也允许使用或在BSD代码上开发商业软件发布和销售,因此是对商业集成很友好的协议[5]。
### 三、总结
本小节中我们简要介绍了有关Linux应用程序的一个重要来源——GNU。从下一小节开始我们将介绍Linux内核源码结构。
参考文献
[1] 《Linux程序设计(第四版)》
[2] https://iot.ofweek.com/2019-08/ART-132216-8120-30401877.html
[3] https://baike.baidu.com/item/GPL/2357903?fromtitle=GPL%E5%8D%8F%E8%AE%AE&fromid=8274607&fr=aladdin
[4] https://blog.csdn.net/xiaoxiao133/article/details/83049959
[5] https://www.runoob.com/note/13176
\ No newline at end of file
+++
title="第三期Linux内核发展史-2"
date="2020-08-06"
tags=["Linur","内核","发展史"]
archives="2020-08"
author="罗宇哲"
summary="Linux内核发展史-2"
+++
_作者:罗宇哲,中国科学院软件研究所智能软件研究中心_
Linux是由赫尔辛基大学的Linus Torvalds开发的,在系统开发期间得到了因特网上广大UNIX程序员的帮助。它最初只是受Andy Tanenbaum教授的Minix(—个小型的类UNIX系统)启发而开发的一个程序,纯属个人爱好,但后来它逐步发展成为一个完整的系统。Linux的成功来源于其之前操作系统和应用软件的已有工作,主要是UNIX和GNU。本小结我们将介绍一下UNIX的发展简史。
### 一、UNIX操作系统发展历史
UNIX操作系统最初是由贝尔实验室开发的,当时的贝尔实验室是电信业巨头AT&T(美国电报电话公司)旗下的一员。UNIX是在20世纪70年代为DEC(数字设备公司)的PDP系列计算机设计的,它现在已成为一种非常流行的多用户、多任务操作系统。UNIX操作系统可以运行在大量不同种类的硬件平台上,其适用范围从PC工作站一直到多处理器服务器和超级计算机。
UNIX系统的主要特点有[1]:
1.简单性:许多很有用的UNIX工具是非常简单的,因此也是很小并易于理解的。
2.集中性:在UNIX中,当用户出现新的需求时,我们通常是把小工具组合起来以完成更复杂的任务,而不是试图将一个用户期望的所有功能放在一个大程序里。
3.可重用组件:将应用程序的核心实现为库。具有简单而灵活的编程接口、文档齐备的库可以常助其他人开发出同类程序,或者把这些技术应用到新的应用领域。
4.过滤器:许多UNIX应用程序可用作过滤器。也就是说,它们对输入进行转换并产生输出。
5.开放的文件格式:比较成功并流行的UNIX程序都使用纯ASCII码的文本文件或XML文件作为配置文件和数据文件。
6.灵活性:你不能期待用户都能非常正确地使用你的程序。所以,你在編程时应尽景考虑到灵活性,尽量避免随意限制字段长度或记录数目。
最初的Unix是用汇编语言编写的,一些应用是由叫做B语言的解释型语言和汇编语言混合编写的。B语言在进行系统编程时不够强大,所以汤普逊和里奇对其进行了改造,并与1971年共同发明了C语言。1973年汤普逊和里奇用C语言重写了Unix。在当时,为了实现最高效率,系统程序都是由汇编语言编写,所以汤普逊和里奇此举是极具大胆创新和革命意义的。用C语言编写的UNIX代码简洁紧凑、易移植、易读、易修改,为此后UNIX的发展奠定了坚实基础。
1974年,汤普逊和里奇合作在ACM通信上发表了一篇关于UNIX的文章,这是UNIX第一次出现在贝尔实验室以外。此后UNIX被政府机关,研究机构,企业和大学注意到,并逐渐流行开来。
1975年,UNIX发布了4、5、6三个版本。1978年,已经有大约600台计算机在运行UNIX。1979年,版本7发布,这是最后一个广泛发布的研究型UNIX版本。20世纪80年代相继发布的8、9、10版本只授权给了少数大学。此后这个方向上的研究导致了九号计划的出现,这是一个新的分布式操作系统。
1982年,AT&T基于版本7开发了UNIX System Ⅲ的第一个版本,这是一个商业版本仅供出售。为了解决混乱的UNIX版本情况,AT&T综合了其他大学和公司开发的各种UNIX,开发了UNIX System V Release 1。
这个新的UNIX商业发布版本不再包含源代码,所以加州大学柏克莱分校继续开发BSD UNIX,作为UNIX System III和V的替代选择。BSD对UNIX最重要的贡献之一是TCP/IP。BSD有8个主要的发行版中包含了TCP/IP:4.1c、4.2、4.3、4.3-Tahoe、4.3-Reno、Net2、4.4以及4.4-lite。这些发布版中的TCP/IP代码几乎是现在所有系统中TCP/IP实现的前辈,包括AT&T System V UNIX和Microsoft Windows。其他一些公司也开始为其自己的小型机或工作站提供商业版本的UNIX系统,有些选择System V作为基础版本,有些则选择了BSD。BSD的一名主要开发者,比尔·乔伊,在BSD基础上开发了SunOS,并最终创办了太阳计算机系统公司。
1991年,一群BSD开发者(Donn Seeley、Mike Karels、Bill Jolitz和Trent Hein)离开了加州大学,创办了Berkeley Software Design, Inc (BSDI)。BSDI是第一家在便宜常见的Intel平台上提供全功能商业BSD UNIX的厂商。后来Bill Jolitz离开了BSDI,开始了386BSD的工作。386BSD被认为是FreeBSD、OpenBSD和NetBSD、DragonFlyBSD的先辈。AT&T继续为UNIX System V增加了文件锁定,系统管理,作业控制,流和远程文件系统。1987到1989年,AT&T决定将Xenix(微软开发的一个x86-pc上的UNIX版本),BSD,SunOS和System V融合为System V Release 4(**SVR4**)。这个新发布版将多种特性融为一体,结束了混乱的竞争局面。
1993年以后,大多数商业UNIX发行商都基于SVR4开发自己的UNIX变体了。
UNIX System V Release 4发布后不久,AT&T就将其所有UNIX权利出售给了Novell。Novell期望以此来对抗微软的Windows NT,但其核心市场受到了严重伤害,最终Novell将SVR4的权利出售给了X/OPEN Consortium,后者是定义UNIX标准的产业团体。最后X/OPEN和OSF/1合并,创建了Open Group。Open Group定义的多个标准定义着什么是以及什么不是UNIX。实际的UNIX代码则辗转到了Santa Cruz Operation,这家公司后来出售给了Caldera Systems。Caldera原来也出售Linux系统,交易完成后,新公司又被重命名为SCO Group。
下图以树状图的形式展示了从UNIX系统衍生出的各种操作系统[2]:
<img src="/zh/blog/luoyuzhe/003History-of-Linux-kernel-2/ Derivate-OS-of-NUIX.gif">
### 二、总结
本小节中我们简要介绍了有关Linux内核的一个重要基础——UNIX操作系统。下一小节我们将介绍Linux应用程序的一个重要来源——GNU。
参考文献
[1]《Linux程序设计(第四版)》
[2] https://www.cnblogs.com/alantu2018/p/8991158.html
\ No newline at end of file
+++
title="第五期Linux内核源码结构-1"
date="2020-08-06"
tags=["Linux","内核","源码"]
archives="2020-08"
author="罗宇哲"
summary="Linux内核源码结构-1"
+++
_作者:罗宇哲,中国科学院软件研究所智能软件研究中心_
在上一期中,我们介绍了Linux内核发展的历史,也介绍了与其相关的UNIX和GNU的相关知识。从这一期开始,我们将介绍Linux内核的源码结构。我们将先根据Linux源码的目录结构进行分析,到本文章发布前,Linux 4.19的最新版本为Linux 4.19.94,我们将依据openEuler开源社区源码并参考Linux 4.19.94版内核源码进行分析。
### 一、Linux内核源码的目录结构分析
下图列出了截至文章发表前openEuler开源社区kernel目录下的目录结构[5]:
<img src="/zh/blog/luoyuzhe/005Linux-kernel-source-structure-1/Directory-structure-1.png">
<img src="/zh/blog/luoyuzhe/005Linux-kernel-source-structure-1/Directory-structure-2.png">
<img src="/zh/blog/luoyuzhe/005Linux-kernel-source-structure-1/Directory-structure-3.png">
其中各个文件夹中**源代码的功能**如下表所示[1][3]
| **目录/文件名** | **源码功能简介** |
| ---------------- | ------------------------------------------------------------ |
| `/Documentation` | 说明文档,对每个目录的具体作用进行说明。 |
| `/arch` | 不同CPU架构下的核心代码。其中的每一个子目录都代表Linux支持的CPU架构。 |
| `/block` | 块设备通用函数。 |
| `/certs` | 与证书相关。 |
| `/crypto` | 常见的加密算法的C语言实现代码,譬如crc32、md5、sha1等。 |
| `/drivers` | 内核中所有设备的驱动程序,其中的每一个子目录对应一种设备驱动。 |
| `/include` | 内核编译通用的头文件。 |
| `/init` | 内核初始化的核心代码。 |
| `/ipc` | 内核中进程间的通信代码。 |
| `/kernel` | 内核的核心代码,此目录下实现了大多数Linux系统的内核函数。与处理器架构相关的内核代码在`/kernel/$ARCH/kernel`。 |
| `/lib` | 内核共用的函数库,与处理器架构相关的库在`/kernel/$ARCH/lib`。 |
| `/mm` | 内存管理代码,譬如页式存储管理内存的分配和释放等。与具体处理器架构相关的内存管理代码位于`/arch/$ARCH/mm`目录下。 |
| `/net` | 网络通信相关代码。 |
| `/samples` | 示例代码。 |
| `/scripts` | 用于内核配置的脚本文件,用于实现内核配置的图形界面。 |
| `/security` | 安全性相关的代码。 |
| `/sound` | 与音频有关的代码,包括与音频有关的驱动程序[2]。 |
| `/tools` | Linux中的常用工具。 |
| `/usr` | 该目录中的代码为内核尚未完全启动时执行用户空间代码提供了支持。 |
| `/virt` | 此文件夹包含了虚拟化代码,它允许用户一次运行多个操作系统。 |
| `COPYING` | 许可和授权信息。 |
| `CREDITS` | 贡献者列表。 |
| `Kbuild` | 内核设定脚本,可以对内核中的变量进行设定。 |
| `Kconfig` | 配置哪些文件编译,那些文件不用编译[4]。 |
| `Makefile` | 该文件将编译参数、编译所需的文件和必要的信息传给编译器。 |
### 二、结语
本期我们根据openEuler的目录,并参考Linux目录结构简要介绍了openEuler kernel中各个子目录的功能,下一期我们将结合Linux 内核的Kernel Map介绍**Linux内核的基本功能和抽象层级**
参考文献
[1] https://www.cnblogs.com/CaesarTao/p/10600462.html
[2] http://blog.chinaunix.net/uid-30374564-id-5571674.html
[3] https://blog.csdn.net/wangyachao0803/article/details/81380882
[4] https://blog.csdn.net/jianwen_hi/article/details/53398141
[5] https://gitee.com/openeuler/kernel
\ No newline at end of file
+++
title="第六期Linux内核源码结构-2"
date="2020-08-06"
tags=["Linux","内核","源码"]
archives="2020-08"
author="罗宇哲"
summary="Linux内核源码结构-2"
+++
_作者:罗宇哲,中国科学院软件研究所智能软件研究中心_
在上一期中,我们按照openEuler内核的目录结构简要介绍了openEuler内核目录中各个子目录的功能,这一期我们将简要介绍**Linux内核的基本功能和抽象层级。**
### 一、Linux内核Kernel Map简介
Linux内核的Kernel Map从功能上将Linux内核划分为不同功能的区域,并展示了不同区域中函数互相之间的调用关系。下图展示了Linux 2.6.36版内核的Kernel Map[1]:
<img src="/zh/blog/luoyuzhe/006Linux-kernel-source-structure-2/Kernel-6-1.png">
从Kernel Map中我们可以看出,操作系统事实上提供了硬件资源的抽象,供用户程序调用,例如在图中操作系统管理的硬件资源有用户外设(如键盘、摄像头和图形卡等)、IO端口(如USB、PCI接口等)、CPU、内存、磁盘和网络设备等。
针对所有硬件资源的使用,在用户态程序看来都是一系列的系统调用,这些系统调用展示在user space interface层,例如对于进程来说有fork、execve等系统调用,分别用于创建新的进程和运行可执行文件等;而对于文件系统则有read和write等系统调用,用于读写文件等。Linux系统可以通过执行软中断将系统控制权交给内核,内核可以执行不同的系统调用再将结果返回[2]。下表列出了**Linux内核各系统调用的基本功能**[2]:
<img src="/zh/blog/luoyuzhe/006Linux-kernel-source-structure-2/Kernel-6-2.png">
硬件设备之上是设备驱动程序,驱动程序能控制硬件设备上的微控制器,如磁盘的磁盘控制器,来达到控制硬件设备的目的。然而,在高层的系统调用和设备驱动程序之间有着很大的鸿沟,需要用不同级别的软件抽象来实现。以用于管理磁盘的文件系统为例,对用户程序来说,只需要关注一般的读写功能统一函数接口就可以了,而不需要关注具体使用的是什么样的文件系统,例如是Ext2还是Ext4文件系统,这是因为虚拟文件系统(VFS)对这些不同的文件系统进行了统一的抽象。虚**拟文件系统与具体的文件系统的关系**如下图所示[3]:
<img src="/zh/blog/luoyuzhe/006Linux-kernel-source-structure-2/Kernel-6-3.png">
以Ext2文件系统的写数据为例,在调用用户态的write()接口的时候,需要传入文件描述符。内核根据文件描述符找到file,然后调用函数接口(file-\>fop-\>write)将数据写入文件。其中file结构体的fop指针就是在打开文件的时候通过inode初始化的[3]。这个过程如下图所示:
<img src="/zh/blog/luoyuzhe/006Linux-kernel-source-structure-2/Kernel-6-4.png">
此外,从Kernel Map中可以看出,有一些对系统资源抽象的重要功能,如进程/线程的调度,也在Kernel Map的中间层实现。注意在Linux中,进程和线程都是由task_struct数据结构来管理的,它们的区别在于线程间共享虚拟地址空间而进程的内存资源互相独立[4]。内核从靠近硬件的底层到靠近用户程序的高层,抽象程度逐渐提升,实现了提供给用户程序的各种硬件资源抽象和使用它们所需要的公共功能,最终抽象为系统调用供用户程序使用。内核程序一般运行在CPU的特权级别,可以访问系统的所有资源,而用户态程序运行在CPU的用户级别下,只能访问其进程的资源,这种设计增加了系统的稳定性。
### 二、结语
本期我们结合Linux内核Kernel Map简要介绍了Linux内核的基本功能和抽象层级,从下一期开始我们将介绍Linux内核编程环境。
参考文献
[1] https://makelinux.github.io/kernel/map/
[2] https://baijiahao.baidu.com/s?id=1604601045858159778&wfr=spider&for=pc
[3] https://baijiahao.baidu.com/s?id=1621555464151870974&wfr=spider&for=pc
[4] https://blog.csdn.net/u012218309/article/details/81912074
\ No newline at end of file
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册