嵌入式Linux开发教程:Linux内核

时间:2022-05-30 08:08:56
摘要:与单纯的硬件开发或软件开发有所不同,嵌入式Linux系统在研发过程中通常都要涉及到硬件和软件两个环节。我们将开始每周连载由周立功编著的《嵌入式Linux开发教程》,供所有开发者阅读。

第1章 Linux操作系统简介

本章导读:本章首先对Linux发展简史进行简要介绍,然后对Linux内核进行了介绍,重点介绍了Linux内核的特点和功能,接着对Linux发行版进行介绍,并列举了一些典型的发行版;最后对嵌入式Linux进行了简要介绍,包括嵌入式Linux的特点和产品形态。

1.1 Linux内核

1.1.1简介

Linux是全球最受欢迎的开源操作系统。它是一个由C语言编写的,符合POSIX标准的类UNIX系统。

词条POSIX

    POSIX是Portable Operating System Interface的缩写,表示可移植操作系统接口,它规定了操作系统应该为应用编程提供的接口标准。

    词条UNIX

      UNIX是一个强大的多用户、多任务分时操作系统,支持多种处理器架构,于1969年在AT&T的贝尔实验室开发。UNIX是商业操作系统,需要收费。

      20世纪九十年代,由于当时UNIX的商业化,Andrew Tannebaum教授开发了Minix操作系统,用于教学和科研,并发布在Internet上,免费给全世界的学生使用。Minix具有UNIX的很多特点,但是不完全兼容。1991年,芬兰大学生Linus Torvalds为了给Minix用户设计一个比较有效的UNIX PC版本,写了一个“类Minix”的操作系统,并发布到了Minix新闻组,在众多支持者的帮助下,Linus推出了Linux第一个稳定版本。1991年11月份,Linux 0.10版本推出,次年12月份,Linux 0.11版本推出,并在发布网上免费供人们使用。Linux 0.13版本发布时,Linux已经非常接近于一种可靠、稳定的操作系统,Linus决定将0.13版本改称为0.95版本,到1994年3月,Linux发布了1.0版本。

      • Linus当时提交到Minix新闻组的原名并不是Linux,而是Freax,取自“Free”和“Unix”两个单词,为“免费的Unix”之意。但当时的管理员并不喜欢“Freax”这个名称,并以“Linus’s Minix”之意,将Freax放到了一个名为“Linux”的目录下,之后便一直用Linux这个名称。

      Linux诞生、发展和壮大于网络,目前依然掌控于Linux社区,遍布全球数以万计的黑客和志愿者参与Linux开发,也有商业公司为Linux贡献代码。Linux内核核心开发队伍的领导者目前是Linus本人。

      Linus其人

      Linus Torvalds(1969.12.28 - ),芬兰赫尔辛基人。在1991年他还是一名大学生的时候,开发了Linux操作系统,在众多黑客的帮助和他的主持下,Linux操作系统蓬勃发展,他本人至今依然是Linux内核项目的核心和*物。他本人获奖无数,主要有:

      • 2014年,Linus获得2014 IEEE计算机先驱奖; 
      • 2012年,芬兰千禧年科技奖; 
      • 2012年,首批入驻“互联网名人堂”; 
      • 2011年,首届ITechLaw成就奖; 
      • 2004年,被评为世界最有影响力的人之一; 
      • 1998年,电子前哨基金会先锋奖。 
      • 除Linux操作系统之外,Linus还创建了目前最流行的版本控制系统Git。

      Linux遵循GPL协议,允许任何人对代码进行修改或发行,包括商业行为。只要其遵守该GPL协议,所有基于Linux的软件也必须以GPL协议的形式发表,并提供源代码。

      词条GPL

      通用公共许可证”。只有GPL英文原版才具有法律效力。

      在软件中采用了使用GPL协议的产品,该软件产品也必须采用GPL协议,即必须开源,这是GPL所谓的“传染性”。

      获取Linux内核源码的网址为:http://www.kernel.org,在这里能够下载各版本的内核源码,包括测试版和最新稳定版。

      Linux的吉祥物是一只名叫Tux的企鹅,看起来像穿了一件晚礼服的企鹅,如下图。

      嵌入式Linux开发教程:Linux内核

      Linux吉祥物创作于1996年,据说Linus被澳大利亚国家动物园的一只小企鹅轻轻咬了一下,于是就有了用企鹅做吉祥物的想法。

      Tux全称tuxedo,但大多数人更倾向于另一种说法,说是Tux名字来源于“Torvalds UniX”。

      Linux发音[’li:nэks],这也是Linus本人的发音,在不同语言里发音有差异,国内很大一部分人发音[’li:njuks]。

      1.1.2 特点

      Linux内核的重要特点

      Linux是一个开放*的操作系统内核,具有一些鲜明的特点:

      1. Linux是一个一体化内核;

      注:“一体化内核”是也称“宏内核”,是相对于“微内核”而言的。几乎所有的嵌入式和实时系统都采用微内核,如VxWorks、uC/OS-II、PSOS等。

      2. 可移植性强。尽管Linus最初只为在X86 PC上实现一个“类UNIX”,后来随着加入者的努力,Linux目前已经成为支持硬件平台最广泛的操作系统;

      注:目前已经在X86、IA64、ARM、MIPS、AVR32、M68K、S390、Blackfin、M32R等众多架构处理器上运行。

      3. 是一个可裁剪操作系统内核。Linux极具伸缩性,内核可以任意裁剪,可以大至几十或者上百兆,可以小至几百K,运行的设备从超级计算机、大型服务器到小型嵌入式系统、掌上移动设备或者嵌入式模块,都可以运行;

      4. 模块化。Linux内核采用模块化设计,很多功能模块都可以编译为模块,可以在内核运行中动态加载/卸载而无需重启系统;

      5. 网络支持完善。Linux内核集成了完整的POSIX网络协议栈,网络功能完善;

      6. 稳定性强。运行Linux的内核的服务器可以做到几年不用复位重启;

      7. 安全性好。Linux源码开放,由众多黑客参与Linux的开发,一旦发现漏洞都能及时修复;

      8. 支持的设备广泛。Linux源码中,设备驱动源码占了很大比例,几乎能支持任何常见设备,无论是很老旧的设备还是最新推出的硬件设备,几乎都能找到Linux下的驱动。

      Linux操作系统的特点

      以Linux内核为核心的操作系统具有如下特点:

      (1)开放性

      遵循世界标准规范,特别是遵循开放系统互连(OSI)国际标准。凡遵循国际标准所开发的硬件和软件,都能彼此兼容,可方便地实现互连。

      词条OSI

      OSI是Open System Interconnection的缩写,意为开放系统互联,该模型由ISO(国际标准化组织)制定。模型把网络通信分为7层:物理层、数据链路层、网络层、传输层、会话层、表示层和应用层。

      词条ISO

      ISO是International Organization for Standardization的缩写,即国际标准化组织,该组织是由国家标准化机构组成的世界范围的联合会,现有140个成员国。ISO*办事机构设在瑞士的日内瓦。

      (2)多用户

      Linux操作系统是一个真正的多用户操作系统;系统资源可以被不同用户各自拥有使用,即每个用户对自己的资源有特定的权限,互不影响。

      经常有初学者将Linux的多用户与Windows的多用户弄混淆,实际上两者的差别是很大的。Windows桌面同一时刻只允许一个用户登录,其余用户必须锁定;而Linux则允许多个用户同时登录。

      (3)多任务

      多任务是现代计算机的最主要的一个特点。它是指计算机同时执行多个程序,而且各个程序的运行互相独立。Linux系统调度每一个进程平等地访问处理器。

      多任务实际上很常见,例如我们在编写文档的时候,还可以一边听歌,甚至还可以从网上下载资料。这至少就有文档处理、音乐播放和网络下载三个任务,相互互不影响,并且是同时运行的。

      (4)良好的用户界面

      Linux向用户提供了两种界面:用户界面和系统调用。

      Linux的传统用户界面是基于文本的命令行界面,即Shell,它既可以联机使用,又可存在文件上脱机使用。Shell有很强的程序设计能力,用户可方便地用它编制程序,从而为用户扩充系统功能提供了更高级的手段。

      Linux还为用户提供了图形用户界面。它利用鼠标、菜单、窗口、滚动条等设施,给用户呈现一个直观、易操作、交互性强的友好的图形化界面。

      系统调用是提供给用户编程时使用的界面。用户可以在编程时直接使用系统提供的系统调用。系统通过这个界面为用户程序提供低级、高效率的服务。

      (5)设备独立性

      Linux操作系统把所有外部设备统一当作成文件来看待,只要安装它们的驱动程序,任何用户都可以像使用文件一样,操纵、使用这些设备,而不必知道它们的具体存在形式。Linux的设备独立性使得它具有高度适应能力,能够适应随时增加支持新设备。

      设备独立性主要是对应用程序开发者来说的。例如,对应用开发者来说,系统自带的串口与USB串口的操作方式是一样的,都是串口设备,而不用关心这个串口设备实际对应的物理硬件是什么。

      现代计算机都实现了设备独立特性。

      (6)完善的网络功能

      Linux内置完整的POSIX网络协议栈,在通信和网络功能方面优于其它操作系统。Linux为用户提供了完善的、强大的网络功能:

      支持Internet。Linux免费提供了大量支持Internet的软件,使得用户能用Linux与世界上的其他人通过Internet网络进行通信。

      网络文件传输。用户能通过一些Linux命令完成内部信息或文件的传输。

      远程访问功能。Linux系统既允许本身通过网络访问远程的系统,也允许远程系统通过网络访问自身。

      (7)可靠的系统安全

      Linux采取了许多安全技术措施,包括对读、写进行权限控制、带保护的子系统、审计跟踪、核心授权等,为网络多用户环境中的用户提供了必要的安全保障。

      (8)模块化

        运行时可以根据系统的需要加载程序而无需重启系统。Linux的模块化极大地提高了Linux的可裁剪性和灵活性。

      (9)良好的可移植性

      Linux是一种可移植的操作系统,能够在从微型计算机到大型计算机的任何环境和任何平台上运行。目前已经成为支持平台最广泛的操作系统。

      Linux内核移植分3个层次:体系结构级别移植、处理器级别移植和板级移植。对大多数开发者而言,只需进行板级移植。


      1.1.3 内核版本号

      Linux内核版本由Linus所领导的内核开发小组控制,版本号有严格规定。

      Linux内核版本号通常由3个数字组成,以2.6.28为例,2为主版本号,6为次版本号,28为修订号。次版本号为偶数则表示这是一个稳定版本,如2.6.17,为奇数则表示是一个开发版本,有可能是不稳定的,如2.5.6。

      另外,还可能见到如2.6.27.8这样的版本号,末尾的.8表示这是2.6.27版本的第8个升级版本,也是可用的稳定版本。

      1.1.4 组成部分

      Linux内核由5个主要子系统组成,分别是:内存管理、进程管理、进程间通信、虚拟文件系统和网络,各子系统之间的关系如图 1.1所示。

      GPL是GNU General Public License的缩写,非正式中文翻译为“GNU 

      嵌入式Linux开发教程:Linux内核

      图1.1 Linux内核组成部分

      1. 进程管理

      进程管理负责控制进程对CPU的访问,如任务的创建、调度和终止等。任务调度是进程管理最核心的工作,由Linux内核调度器来完成。Linux内核调度器根据一定算法来选择最值得运行的进程。

      一个进程的可能状态有如下几种:

      (1)运行态——已经获得了资源,并且进程正在被CPU执行。进程既可运行在内核态,也可运行在用户态。

      内核态,内核和驱动所运行时的状态,程序处于特权阶级,能够访问系统的任何资源,好比社会的统治者。

      用户态,用户程序运行的状态,处于非特权阶级,不能随意访问系统资源,必须通过驱动程序方可访问,用户态程序可通过系统调用进入内核态。用户态程序有如社会的被统治者,处于被管理的非特权阶级,只有通过某种途径才能进入特权阶级。

      (2)就绪态——当系统资源已经可用,但由于前一个进程还没有执行完而释放CPU,准备进入运行状态。

      (3)可中断睡眠状态——当进程处于可中断等待状态时,系统不会调度该程序执行。当系统产生一个中断或者释放了进程正在等待的资源,或者进程收到一个信号,都可以被唤醒进入就绪状态或者运行态。

      (4)不可中断睡眠状态——处于中断等待状态,但是该进程只能被使用wake_up()函数明确唤醒的时候才可进入就绪状态。

      (5)暂停状态——当进程收到SIGSTOP、SIGSTP、SIGTTIN或者SIGTTOU就会进入暂停状态,收到SIGCONT信号即可进入运行态。

      (6)僵死态——进程已经停止运行,但是其父进程还没有询问其状态。

      各状态之间的转换关系和转换条件如图 1.2所示。

      嵌入式Linux开发教程:Linux内核

      图1.2 Linux进程状态和转换

      进程和状态的转换有点抽象,用生活中一个比较接近的例子类比一下,或许能有助于理解。Linux内核调度器好比是生产线的主管,而进程则好比是生产线上的工人。主管24小时不间断的工作,工人的工作时间是朝九晚五,其余时间在等待区排队等候。

      早上工人到达工厂,还没到9点上班时间,工人可以在等待区休息,这个状态可以称之为“就绪态”;但是9点一到,工人则必须上生产线工作,这个工作状态可称之为“运行态”;下午5点一到,到了工人下班时间,工人离开生产线又回到等待区排队等候,处于“就绪态”。

      如果工人上班的时候,收到主管的命令,说是“你暂时不用工作了,到休息室休息等待”,工人此时的这个状态,可以称之为“暂停”状态,过了一段时间,主管通知工人说是“休息结束,要准备工作了”,工人不能直接回生产线岗位,而是必须先到等待区排队等待,轮到后才上生产线工作。

      如果有一天工人精神状态不好,向主管申请要睡觉休息,理由可以是“某种配件不到,我无法工作”,也可以是“我就是困了,想睡觉”,工人最后可能得到两种批准结果:一是主管批准了,但是附加了一个条件说“等我叫醒你,你必须醒来上班”,然后工人就去享受他的安稳觉了,工人进入“不可中断睡眠”状态;另一种是主管也批准了,但是附加了另一个条件,说“在你睡觉的时候,如果配件到了,你就得立马给我起来上班”,工人也去睡觉去了,但此时工人睡得并不安心,因为这不是一个安稳觉,是“可中断睡眠”。无论工人睡得是安稳觉,还是不安稳觉,醒来都不能直接上生产线,而是回到等待区,等待轮值。

      还有一种情况,工人干完活到点下班了,但主管对他不闻不问,也不安排新的工作,这是一种非正常状况,工人进入了“僵死态”。

      2. 内存管理

      内存管理的主要作用是控制和管理多个进程,使之能够安全的共享主内存区域。当CPU提供内存管理单元(MMU)时,内存管理为各进程实现虚拟地址到内存物理地址的转换。在32位系统上,Linux内核将4G空间分为1G内核空间(3~4G)和3G(0~3G)用户空间,通过内存管理,每个进程都可以使用3G的用户空间。

      3. 文件系统

      Linux内核支持众多的逻辑文件系统,如Ext2、Ext3、Ext4、btrfs、NFS、VFAT等。VFS则是Linux基于各种逻辑文件系统抽象出的一种内存中的文件系统,隐藏了各种硬件设备细节,为用户提供统一的操作接口,是用户访问各种不同文件系统和设备时,不用区分具体的逻辑文件系统。例如,Linux下硬盘上使用的文件系统通常是Ext3/4格式,而U盘通常是FAT32格式,但是用户在使用中根本感觉不到差异,也不用区分文件系统的具体差别。

      4. 网络接口

      Linux对网络支持相当完善,网络接口提供了对各种网络标准的存取和各种网络硬件的支持,接口可分为网络协议和网络驱动程序。网络协议部分负责实现每一种可能的网络传输协议。网络设备驱动程序负责与硬件设备通讯,每一种可能的硬件设备都有相应的设备驱动程序。

      5. 进程间通信

      支持进程间各种通信机制,如管道、命名管道、信号、消息队列、内存共享、信号量和套接字等。

      • 管道通常用于具有亲缘关系的父子进程或者兄弟进程间通信,是半双工的,数据只能往一个方向流动,先入先出,与自来水管很相似。如果双方互通时,需要建立两个管道。
      • 命名管道则突破了进程间的亲缘关系限制,即非父子、兄弟进程之间也可相互通信。
      • 信号是软件中断,用于在多个进程之间传递异步信号。日常生活中信号的例子很多了,如一对很亲密的哑巴情侣,在很多时候只需要一个简单的眼神,对方就能知道他(她)需要什么,并做出回应,这个眼神,就是一个“信号”。
      • 信号能传递的信息有限,而消息队列则正好弥补了这点。例如情侣的一个眼神,对方可能能知道情侣的需求,但是如果情侣有一大堆需求,仅仅靠一个眼神就比较费力了。情侣就把自己的需求写在了一张纸条上,递交给对方,对方根据纸条的内容,逐一满足情侣的需求。
      • 共享内存常用于不同进程间进行大量数据传递。Linux下每个进程都有自己的独立空间,各自都不能直接访问其它进程的空间。好比这对情侣都有自己的小金库,有时候需要给对方一部分钱用,但他们不能直接相互转账,必须先将前存到他们俩合开的一个公共账户上面,然后再使用。这个公共账户就是这对情侣的“共享内存”。
      • 信号量用于进程同步。只有获得了信号量的进程才可以运行,没有获得信号量的进程则只能等待。就像十字路口的红绿灯,只有在绿灯亮(获得了绿灯)的时候才能通行,否则只能等待。
      • 套接字(Socket)起源于BSD,也常称“BSD套接字”,用于多个进程间通信,可以基于文件,也可基于网络。Socket本意是“插座”,套接字设计就是通过某些参数设定,然后将一个“插座”与另外一个“插座”连接起来。可能还有点抽象,看一个例子可能就好理解了。把套接字理解为固定电话的插口,现在要打电话出去,必须要知道打给谁,往哪里打;另外电话另一端必须有人在听才可以通话,否则也不能打电话。