Linux学习总结(三):Linux系统组件

本文经野火《i.MX Linux开发实战指南》整理而来。

文章目录

    • 1.UBoot
    • 2.Kernel
      • (1)Linux内核
      • (2)linux内核组成
    • 3.dtb
      • (1)设备树简介
      • (2)DTS的加载过程
    • 4.根文件系统

完整的linux系统,通常包含了系统运行需要的4个基础组件:Uboot、Kernel、**.dtb以及根文件系统。

1.UBoot

UBoot,全称 Universal Boot Loader,主要作用是用来启动操作系统内核。
uBoot分为两个阶段,即boot + loader

  • boot阶段:启动系统,初始化硬件设备,建立内存空间映射图,将系统的软硬件带到一个合适的状态
  • loader阶段:将操作系统内核文件加载至内存,之后跳转到内核所在地址运行

通俗的讲,

  • 第一阶段:
    硬件设备初始化。
    加载U-Boot第二阶段代码到RAM空间。
    设置好栈。
    跳转到第二阶段代码入口。
  • 第二阶段:
    初始化本阶段使用的硬件设备。
    检测系统内存映射。
    将内核从存储区域(Flash、SD Card、eMMC)读取到RAM中。
    为内核设置启动参数。
    调用内核。

简单来说BootLoader是一段小程序,它在系统上电时执行,通过这段程序可以将硬件设备进行初始化,如CPU、SDRAM、Flash、串口、网络等,初始化完毕后调用操作系统内核。
UBoot支持下载模式与启动模式,启动模式下会启动默认的系统如linux,下载模式下不会继续启动操作系统内核,而是由开发者去指定BootLoader的工作,如通过串口下载操作系统镜像,通过网络启动镜像等等。

2.Kernel

(1)Linux内核

Kernel即Linux内核,Linux内核采用宏内核架构,即Linux大部分功能都会在内核中实现,如进程管理、内存管理、设备管理、文件管理以及网络管理等功能。与之相对的是微内核架构,仅将内核的基本功能放入内核中,如进程管理、进程调度等,而其他的设备管理、文件管理等功能都放在内核空间之外。
相比之下,宏内核架构没有非常好的扩展性,于是引入了内核模块(动态可加载内核模块),即在内核运行时可以动态加载一组目标代码来实现某些特定的功能而不需要重新编译内核就可以实现动态扩展。模块是具有独立功能的程序,它可以被单独编译,但不能独立运行。它在运行时被链接到内核作为内核 的一部分在内核空间运行,这与运行在用户空间的进程是不同的。

(2)linux内核组成

Linux内核主要由5部分组成,分别为:进程管理,内存管理,文件管理,网络管理,设备管理。整个内核由系统调用层统一管理,应用层通过系统调用层的函数接口与内核进行交互,用户应用程序执行的地方是用户空间,用户空间之下则是 内核空间,Linux 内核正是位于内核空间中。Linux学习总结(三):Linux系统组件_第1张图片

  • 进程管理
    进程管理的核心就是进程调度,进程调度控制系统中的多个进程对CPU的访问。从宏观上看,系统中的进程在CPU中是并发执行的。此外内核通过系统调用层提供了应用程序编程接口,例如:创建新进程(fork,exec),结束进程(kill, exit),并且提供了控制进程、同步进程和进程间通信的接口。
    进程与程序的区别
    程序是一段代码,是静态的;进程是正在执行的程序,是动态的。
    进程的四要素
    ①有一段程序供其执行,这段程序不一定是某个进程所专有,可以与其他进程共用。
    ②有进程专有的系统堆栈空间(也可以称之为内核堆栈空间)。
    ③在内核中有一个task_struct数据结构,即进程控制块,用于内核调度器识别并调度进程,并记录进程占有的各项资源。
    ④独立的用户堆栈空间,就是mm_struct数据结构,该数据结构位于task_struct结构中,字段名称为mm。
    目前linux进程调度器的进程调度算法Completely Fair Scheduler,简称CFS,即完全公平调度算法,会按需分配计算能力。
    进程状态
    每个进程都有状态属性,包括运行态,就绪态,睡眠态或者是深度睡眠态、暂停态或者僵死态等,进程的状态都是动态变化的并且是由进程调度器决定的。
    Linux学习总结(三):Linux系统组件_第2张图片
  • 内存管理
    内存管理的主要作用是保证系统安全访问内存区域,且绝大部分CPU都支持内存管理单元(Memory Management Unit,MMU)。在Linux中,内存管理子系统就负责管理每个进程完成从虚拟内存到物理内存的转换,以及系统可用内存空间。
    内存管理的硬件按照分页方式管理内存,分页就是把系统的物理内存按照相同大小等分,每个内存分片称作内存页,通常内存页大小是4KB。内存管理子系统要管理的不仅是4KB缓冲区,它提供了对4KB缓冲区的抽象,例如slab分配器。这种内存管理模式使用4KB缓冲区为基数,然后从中分配管理结构,并跟踪内存页使用情况 ,系统中哪些内存页是满的,哪些内存页面为空,哪些内存页没有完全使用。这样一来,系统就支持动态调整内存使用情况。除此之外,Linux还支持内存交换,因为Linux中使用的是虚拟内存,当物理内存不足时,内存管理子系统会将内存暂时移到磁盘中,在物理内存充裕时又将内存页从磁盘移到物理内存中,这就是内存交换。
  • 文件管理
    在Linux系统中一切皆文件,包括硬件设备,通常称为设备文件。Linux的文件管理子系统主要实现了虚拟文件系统(Virtual File System,VFS),虚拟文件系统屏蔽了各种硬件上的差异以及具体实现的细节,为所有的硬件设备提供统一的接口,实现了设备无关性,同时文件管理系统还为应用层提供统一的API接口。
    Linux 的文件系统对一个对复杂系统进行了抽象化,通过使用一组通用的 API 函数,Linux 可以在许多种存储设备上支持多种文件系统,如NTFS、EXT2、EXT3、EXT4 、FAT等等;而用户空间包含一些应用程序和 GNU C 库(glibc),它们使用的API接口是由系统调用层提供(如打开、读、写和关闭等),其框架如下图所示:
    Linux学习总结(三):Linux系统组件_第3张图片
  • 网络管理
    在Linux 内核中,与网络相关的代码被Linux独立开,称为网络子系统,分为以下几个层次:
    Socket 层(协议无关层):Linux 采用 BSD Socket API 作为网络相关的 API 接口,Linux 支持的协议族都可以使用 BSD Socket API 作为应用层的编程接口,将Socket层抽象出来屏蔽不同协议族之间的差异,且不会对应用层的使用产生影响。
    协议层:Linux 网络子系统支持 INET(TCP/IP)、INET6、DECnet、ROSE、NETBEUI 等多种协议族,对于INET 、 INET6 协议族来说,又将协议族划分为传输层、网络层以及链路层等。
    网络设备层:即设备驱动层,抽象了网卡数据结构,屏蔽了不同硬件上的差异,提供了一组通用函数供底层网络设备驱动程序使用。
    Linux学习总结(三):Linux系统组件_第4张图片
  • 设备管理
    设备子系统又称为设备驱动,对于Linux来说,不可能去将每个设备都包含到内核,只能抽象去描述某种设备。
    系统调用层是Linux内核与应用程序之间的接口,而设备驱动则是Linux内核与硬件之间的接口。设备驱动程序为应用程序屏蔽了硬件的细节,对于应用程序硬件设备只是一个设备文件,应用程序可以像操作普通文件一样对硬件设备进行操作(打开、读、写和关闭)。设备驱动程序是内核的一 部分,它主要完成以下的功能:
    ①对设备初始化和释放
    ②把数据从内核传送到硬件和从硬件读取数据
    ③读取应用程序传送给设备文件的数据和回送应用程序请求的数据
    ④检测和处理设备出现的错误
    Linux设备分成3大类,分别为:字符设备、块设备、网络设备
    字符设备是以字节为单位传输的IO设备,可以提供连续的数据流,应用程序可以顺序读取,通常不支持随机存取。这种字符传输的效率通常是比较低的,如鼠标、键盘、串口等都是字符设备。
    块设备是以块为单位进行传输的设备,应用程序可以随机访问块设备中的数据,程序可以指定读取数据的位置。磁盘就是一种常见的块设备,应用程序可以寻址磁盘上的任何位置,并在这个位置读取数据。不过需要注意的是,块设备读取的数据只能以块为单位的倍数进行(通常是512Byte的整数倍),而不能与字符设备一样以字节为单位读取,因此通常来说块设备的传输速度是比较高的。
    网络设备就是网络子系统中描述的网络设备层,抽象统一描述了不同的网卡设备,如WIFI、以太网等。因为网络设备涉及了网络层协议,所以Linux将网络设备单独分成一类设备,网络设备的传输速率通常是很高的。
    Linux学习总结(三):Linux系统组件_第5张图片

3.dtb

(1)设备树简介

设备树是描述硬件设备信息的一种脚本语言。设备树包括设备树源码(Device Tree Source,DTS)、设备树编译工具(Device Tree Compiler,DTC)与二进制格式设备树(Device Tree Blob,DTB)。DTS文件是一种人类可以看懂的编码格式,由节点(Node)和属 性(Property)组成,节点中又可能会包含子节点,而属性则是可以简单理解为成对出现的名称与值。
因为Uboot和Linux不能直接识别DTS文件,只能识别二进制文件,所以需要把DTS文件编译成DTB文件,而DTC就是将设备树源码文件(.dts / .dtsi)编译成二进制格式设备树文件(.dtb)的编译工具,位于Linux内 核源码的scripts/dtc目录下。在Linux配置中使能设备树的情况下,内核会自动编译对应的设备树,当然用户也可以单独编译设备树。
DTB可以被内核与BootLoader识别解析,通常在制作NAND Flash、SD Card启动 镜像时,通常会为DTB文件留下一部分存储区域以存储DTB,在BootLoader启动内核时,会先读取DTB到内存(初始化硬件设备)。
Linux的设备树中,可描述的硬件信息包括以下几类:

  • CPU的数量和类别
  • 存基地址和大小
  • 总线和桥
  • 外设连接
  • 中断控制器和中断使用情况
  • GPIO控制器和GPIO使用情况
  • Clock控制器和Clock使用情况

(2)DTS的加载过程

在编译生成DTB文件后,需要将它加载到Linux内核中,让内核来识别这些信息,在系统启动时,BootLoader会将保存在flash中的DTB拷贝到内存,并把DTB在内存中的起始地址传递给内核。

4.根文件系统

根文件系统(rootfs),是linux在初始化时加载的第一个文件系统,包含系统引导和使其他文件系统得以挂载(mount)所必要的文件,还包括许多应用程序如bin目录下的文件等。在linux系统中只有 一个根目录,路径是”/”,其它的分区只是挂载在根目录中的一个文件夹,如”/home”和”/sys”等。
在Linux内核启动的初始阶段,首先内核会初始化一个基于内存的文件系统,如initramfs,initrd等,然后以只读的方式去加载根文件系统(load rootfs),读取并 运行/sbin/init初始化文件,根据/etc/inittab配置文件完成系统的初始化工作(/sbin/init是 一个二进制可执行文件,是系统的初始化程序,而/etc/inittab是初始化文件的配置文件)。在初始化的过程中,还会以读写的方式重新挂载根文件系统,在系统启动后,根文件系统就可用于存储数据了,根文件系统是Linux启动的必要条件。

你可能感兴趣的:(ubuntu)