Linux知识

发布于:2024-04-20 ⋅ 阅读:(27) ⋅ 点赞:(0)

基础

Linux系统的组成

Linux内核、Linux⽂件系统、Linux shell、Linux应⽤程序。

Linux的开机启动过程

u-boot是⼀款常⽤的开源Bootloader,它的启动顺序如下:

  1. CPU上电后,⾸先执⾏boot ROM(引导ROM)代码。
  2. boot ROM会检查系统中的存储设备(如NAND Flash、SD卡等)以确定可以⽤于启动的设备。
  3. boot ROM会从可⽤的存储设备中搜索可引导的bootloader,并将其加载到系统内存中。通常情况下,bootloader的名称为u-boot。
  4. ⼀旦u-boot被加载到内存中,CPU会跳转到u-boot的⼊⼝点,并开始执⾏u-boot的代码。
  5. u-boot会执⾏初始化过程,包括初始化DRAM、设置串⼝、初始化⽹卡、初始化存储设备等。
  6. u-boot会等待⽤户输⼊,以便⽤户可以通过串⼝或⽹⼝控制u-boot的⾏为。在等待⽤户输⼊的同时,u-boot也会⾃动执⾏预设的默认操作,例如⾃动启动内核。
  7. 如果⽤户输⼊了命令,u-boot会执⾏⽤户指定的操作。这些操作可以包括启动内核、烧写Flash、修改环境变量等。
  8. 如果u-boot需要启动内核,它会从存储设备中加载内核镜像,并将其解压缩到DRAM中。然后,u-boot会设置内核启动参数,并跳转到内核⼊⼝点,将控制权移交给内核。

总的来说,u-boot的启动顺序是由boot ROM加载u-boot到内存中,u-boot执⾏初始化过程并等待⽤户输⼊,然后执⾏⽤户指定的操作或启动内核。

什么是 LILO?

LILO 是 Linux 的引导加载程序。它主要⽤于将 Linux 操作系统加载到主内存中,以便它可以开
始运⾏。

Linux为啥不是实时操作系统,如何把Linux改为实时操作系统?

Linux 在设计上并不是⼀个硬实时操作系统,因为它的内核调度算法是基于抢占式的时间⽚轮转调度,⽽不是基于实时性的优先级调度。这意味着在 Linux 中,⽆法保证任务的响应时间和完成时间是可预测的,所以它不能满⾜某些对实时性要求很⾼的应⽤场景。

但是,Linux 内核提供了⼀些实时性增强的选项和扩展,可以将 Linux 改造成为⼀个软实时操作系统。 其中最常⽤的实时性增强扩展是 Real-Time Patch(RT Patch),它是 Linux 内核的⼀个补丁,通过增强内核的实时性和可预测性来提⾼系统的实时性能。RT Patch 改进了内核的调度算法、延迟处理、定时器管理等⽅⾯,从⽽提⾼系统的实时性能。

除了 RT Patch 之外,还有其他⼀些⼯具和技术可以增强 Linux 的实时性能,例如 PREEMPT_RT 补丁、IRQ threads、Control Groups 等。

需要注意的是,将 Linux 改造为实时操作系统需要进⾏相应的配置和编译,⽽且不同的应⽤场景和需求可能需要不同的实时性增强扩展。因此,需要根据具体的应⽤场景和需求来选择合适的实时性增强扩展,并进⾏相应的配置和编译。

linux下的设备

类别

  1. 串⼝设备(/dev/tty*)
    串⼝设备是⽤于串⾏通信的设备,包括RS-232、RS-485等标准。串⼝设备在Linux系统中以/dev/tty*的形式存在。串⼝设备的特点是通信速度较慢,通信距离较短,但是通信稳定可靠。

  2. 并⼝设备(/dev/lp*)
    并⼝设备是⽤于并⾏通信的设备,通常⽤于连接打印机等设备。并⼝设备在Linux系统中以/dev/lp*的形式存在。并⼝设备的特点是通信速度较快,但通信距离较短。

  3. 硬盘设备(/dev/sd*)
    硬盘设备是⽤于存储数据的设备,包括机械硬盘和固态硬盘等。硬盘设备在Linux系统中以/dev/sd*的形式存在。硬盘设备的特点是容量⼤,读写速度较快,但是价格较⾼。

  4. 光驱设备(/dev/cdrom、/dev/dvdrom)
    光驱设备是⽤于读取CD、DVD等光盘数据的设备。光驱设备在Linux系统中以/dev/cdrom和/dev/dvdrom的形式存在。光驱设备的特点是读取速度较慢,但是价格较低。

  5. ⽹络设备(/dev/eth*)
    ⽹络设备是⽤于⽹络通信的设备,包括以太⽹卡等。⽹络设备在Linux系统中以/dev/eth*的形式存在。⽹络设备的特点是通信速度较快,但是需要⽹络基础设施的⽀持。

设备间的区别,靠什么实现

这些设备之间的区别主要在于它们所连接的硬件不同,以及它们的数据传输速度和稳定性等⽅⾯的特点。

这些设备之间的通信都是通过Linux内核提供的设备驱动程序来实现的。设备驱动程序负责向应⽤程序提供接⼝,使得应⽤程序可以通过设备⽂件对设备进⾏读写操作。

CLI和GUI

CLI:命令⾏界⾯(command-line interface,简称 CLI)是在图形⽤户界⾯得到普及之前使⽤最为⼴泛的⽤户界⾯。

GUI:图形⽤户界⾯(Graphical User Interface,简称 GUI,⼜称图形⽤户接⼝)是指采⽤图形⽅式显示的计算机操作⽤户界⾯。

什么是inode

Sector :⽂件储存在硬盘上,硬盘的最⼩存储单位叫做 “扇区”(Sector)。每个扇区储存 512 字节(相当于 0.5KB)。

block :操作系统读取硬盘的时候,不会⼀个个扇区地读取,这样效率太低,⽽是⼀次性连续读取多个扇区,即⼀次性读取⼀个 “块”(block)。这种由多个扇区组成的 “块”,是⽂件存取的最⼩单位。“块” 的⼤⼩,最常⻅的是 4KB,即连续⼋个 sector 组成⼀个 block。

inode :⽂件数据都储存在 “块” 中,那么很显然,我们还必须找到⼀个地⽅储存⽂件的元信
息,⽐如⽂件的创建者、⽂件的创建⽇期、⽂件的⼤⼩等等。这种储存⽂件元信息的区域就叫做
inode,中⽂译名为 “索引节点”。
每⼀个⽂件都有对应的 inode,⾥⾯包含了与该⽂件有关的⼀些信息。

硬链接和软链接

文件属性

在终端执⾏ ls -al 命令显示当前⽬录下的所有⽂件及⽂件夹的详细信息。
在这里插入图片描述
第⼀个字符表示⽂件类型,是⽬录、⽂件或链接⽂件等
在这里插入图片描述
接着9个三个⼀组,第⼀组为⽂件所有者权限;第⼆组为⽤户组权限;第三组为其他⾮本⽤户组的权限 (r:可读,w:可写,x:可执⾏,-:⽆权限)

⽐如“rw-r–r–”表示:⽂件的所有者对该⽂件有读权限、写权限,但是没有执⾏权限;同⼀个⽤户组的其他⽤户对该⽂件只有读权限;其他⽤户对该⽂件也只有读权限。

连接数:表示有多少⽂件名连接到此节点。
⽂件所有者:表示这个⽂件的“所有者的账号”。
⽂件所属⽤户组。
⽂件⼤⼩:表示这个⽂件的⼤⼩,默认单位是 B(字节)。
⽂件最后被修改的时间:这个⽂件的创建⽂件⽇期或者是最近的修改⽇期
⽂件名:对应⽂件的⽂件名。 如果⽂件名之前多了⼀个“.”,则说明这个⽂件为“隐藏⽂件”,执⾏“ls -a”命令可以列出隐藏⽂件。

内核

什么是linux内核

linux内核的组成

在这里插入图片描述
系统调用:提供用户空间程序与内核之间的接口,允许应用程序调用内核提供的功能和服务。
进程管理:负责创建、管理和调度进程,包括进程的创建、销毁和调度等功能。
内存管理:负责管理内存资源,包括物理内存的分配与释放、虚拟内存的映射与管理等。
文件系统:提供对存储设备和文件的访问接口,支持各种文件系统格式。
网络协议栈:实现了各种网络协议,提供网络通信的功能。
设备驱动:提供对硬件设备的抽象和控制接口,支持各种设备驱动程序。

系统调用

系统调用的作用

提供资源访问:应用程序可以通过系统调用请求访问操作系统提供的资源,如文件的读写、网络通信和设备访问等。

实现用户态与内核态切换:应用程序通常运行在用户态,而某些操作需要在内核态执行。通过系统调用,应用程序可以将控制权切换到内核态,让操作系统核心来完成特权操作。

提供操作系统服务:系统调用封装了操作系统提供的各种服务和功能,如进程管理、内存管理、文件系统操作和网络通信等。应用程序可以通过系统调用使用这些服务。

实现进程间通信:系统调用提供了进程间通信的机制,允许不同的应用程序进行数据交换和协作。应用程序可以通过系统调用进行消息传递、共享内存访问等操作。

常用的系统调用函数

read()/write()

调用后的内核执行流程

  1. 用户空间发起read()/write()系统调用,并将参数传递给内核。
  2. 内核根据系统调用号找到相应的内核函数进行处理,如sys_read()/sys_write()。
  3. 内核根据文件描述符找到对应的文件对象,并执行读取或写入操作。
  4. 在读取操作中,内核将数据从文件或设备读取到内核空间,并通过页缓存层进行管理。
  5. 在写入操作中,内核将数据从用户空间拷贝到内核空间,并通过文件系统层将数据写入文件或设备。
  6. 内核可能会通过缓存管理、块设备管理和驱动程序等层次对数据进行处理和传输。
  7. 处理完成后,内核将结果返回给用户空间,并用户空间继续执行下一步操作。

bootloader

文件管理

磁盘相关信息

在这里插入图片描述
磁柱是Cylinder, 磁头是Head, 扇区是Sector, 当我们知道这三个结构的编号, 就能在磁盘中定位到一个指定的扇区

知道磁柱的编号就确定了磁道的编号, 磁头可以确定哪个盘面, 扇区编号可以知道扇区在磁道中的位置, 知道这三个编号, 就能确定到某个盘片上的某条磁道上的某块扇区, 也就知道了当前访问的扇区

这样的地址被称为CHS地址, 用这样的方法, 可以找到磁盘中每个单元的确切位置

文件系统

扇区,块,分区,分组

在这里插入图片描述

操作系统会将分区细分为向上面那样的组, 还会分出一个 Boot Block区域。 Boot Block

组的属性

Data blocks

Data blocks, 其实就是组内存储文件内容的一个区域, 此区域以 块block 为单位, 每块的大小为4KB. 占一个组的绝大部分内容

为什么是单位是4KB? 因为 操作系统与硬件的I/O操作的基本单位就是4KB, 4KB便于操作系统I/O. 其实也就是说明, 文件在操作系统中存储就是以4KB为单位的, 即使文件内容并没有达到4KB的内容, 此文件还是会占用一个4KB的块, 此块独属于此文件, 其他文件不能使用

在文件内容增长的过程中, 文件也会以4KB为单位增大

inode Table

在Linux系统中, 存在一个 inode结构体, 此结构体存储的是磁盘文件的各种属性.

我们使用ll 或者 stat 可以查看多个或单个文件的属性:
在这里插入图片描述

我们使用 stat 查看单个文件的详细属性时, 可以看到 一个文件拥有非常多的属性:
File Size Blocks IO Block Device Inode Links Access Uid Gid 等

这其中有我们很熟悉的file 文件名, 还有Access 权限
但是还有许多不认识的:Blocks IO Block Inode Links 等

这些属性, 其实都存储在 Linux系统的inode结构体中:
在这里插入图片描述
这还只是一部分, 不过我们暂时只需要知道, 在Linux系统中, inode是一个结构体, 存储着文件的所有属性就可以了

在 inode结构体中, 存储着一个叫 inode的属性, 是一个整型值, 此值表示某文件在操作系统中的唯一的一个编号

就是 stat 命令输出的一个叫 Inode 的属性, 也可以通过 ll -i 查看:
在这里插入图片描述
知道了inode 具体是什么东西, 那么再看 inode Table,其实 inode Table 就是组内用来存储 文件inode结构体的一个表格、数组, inode Table的每个单位存储一个inode结构体

inode结构体的大小为 128字节, 那么 inode Table 的单位大小就是 128字节

inode结构体存储着 操作系统层面 文件的所有属性, 但是其中是没有存储文件名的
文件名在Linux操作系统中是属性吗?是的,
但是inode中并没有存储文件名 这其实意味着, 在Linux底层层面, 系统是不认识文件名的, inode结构体中存储的inode编号是操作系统底层对文件的唯一实际标识

inode Table内部的单元格只存在两个状态,存储了文件的inode和没存储文件的inode

位图中每一个bit位代表一个inode id是否空闲,没有被使用。使用过了就不能再使用了。

即, inode Bitmap 就是描述 inode Table 占用情况的位图,可以方便操作系统对此组进行管理。

Block Bitmap

与 inode Bitmap类似, Block Bitmap是用来描述 Data Blocks的占用情况的

Group Descriptor Table

这一部分是描述组中的总览信息的:inode起始编号 inode Table被占用了多少、还剩多少 Data Blocks 中占用了多少、还剩多少 此Group的实际大小是多少 ……

其中有部分信息是可以通过组内的属性计算出来的, 但是总要消耗时间成本, 所以还是直接记录统计存储起来

此部分内容可简称 GDT

Super Block

这以部分内容被称为 Super Block 超级块, 其实并不独属于其所在组

因为此块记录的内容大致是整个分区的相关属性:此分区在磁盘中的实际区域 分区内的分组情况 分区所使用的文件系统格式 ……

此块其实是 操作系统中 文件系统顶层的一个数据结构了

  • 为什么 Super Block 要存储在组内?
    既然, Super Block是一个属于此分区内的数据结构, 那么为什么不像Boot Block一样, 单独存储在组外分区内呢?

其实原因只有一个, 那就是为了提供备份

Super Block是一个描述了分区最重要的属性的数据结构, 并且是需要实时维护的.

当操作系统向某个分区的某个组内写入数据时, Super Block也是处于一个维护状态的. 那么如果此时 写入过程和维护过程意外中断了(比如台式机突然断电). 有没有可能正在维护的Super Block会发生损坏?

如果一个分区只有一个Super Block, 并且已经损坏了, 那么此分区还能使用吗?如果此分区刚好是系统分区, 那系统是不是也就完蛋了

所以 Super Block 需要在一个分区内备份许多份, 以防止单独存储出现损坏无法恢复的情况.

就像Windows中, 如果操作系统正在写入数据的时候突然关机断电, 那么在下次开启的时候很有可能会触发一个询问: 上次系统非正常关机,怎么怎么样, 是否恢复启动? 如果分区中只有一个Super Block这样的结构, 那么是无法恢复的

并不是 所有组内都会存储Super Block, 而是一部分

inode 怎么与 其描述文件的Data Blocks部分 联系起来

Data Blocks 中存储的是文件内容, 是以4KB/块为单位的

inode结构体描述着文件在系统底层的所有属性, 其中一定描述的有指定文件内容在Data Blocks中的存储位置

inode中存储有一个类似block[15]这样的数组结构, 其中:

一部分存储文件内容在 Data Blocks中的存储位置, 比如 [0, 11] 这些位置直接保存文件内容对应的Data Blocks对应的编号,这就是直接块指针

如果文件内容很大, 一部分描述不完时, 还会有另一部分内容. [12, 14] 这部分内容会保存某块 Data Block,但是这块 Data Block中保存的并不是文件内容, 而是像 [0, 11] 那样保存此文件内容在Data Blocks中对应的其他编号。这就需要用到间接块指针,或双重间接块指针,或三重间接块指针。

  • 直接快指针
    直接块指针就是inode中直接记录了block块的号码,直接指向block块,
    假如一个文件的属性与权限数据放置在inode4号,而这个inode记录了档案数据的实际位置放置点位2,7,13,15这四个block号码,此时操作系统可以据此来排列磁盘的阅读顺序,可以直接将四个block的内容读出来,数据的读取如下图所示
    在这里插入图片描述

  • 间接块指针
    间接块指针,其实和直接块指针大同小异,他们都是指针,只是直接块指针式直接指向的block块存储的是文件的数据,而间接块指针是将指向的block块继续当作指针块使用,所以间接指针指向的block块存储的是指针信息,它将继续指向下一个block块中存储的文件数据。

  • 双重间接块指针
    理解了间接指针块,那么双重间接指针块就容易理解了,它是在间接指针块的基础上将第二次指向的block块也当作指针使用,这样就可以指向更的的block块。

  • 三重间接块指针
    三重间接块指针的道理就和双重的道理一样了,只是把第三次指向的block块也当作指针块当作指针使用,这样就可以执行跟过的block块。

前面已经提到使用直接块指针的文件最大不能超过48K,假定一个指针块需要4个字节,一个block块有4K的存储空间,那么一个block块就可以存储1024个指针块,所以间接块指针的文件最大就可以存储10244K=4M的文件,以此类推使用双重间接块指针的文件最大存储空间就有102410244K=4G,使用三重间接块指针的文件最大存储空间就可以达到1024102410244K=4T。

创建和删除文件 的执行流程

文件系统中的目录

我们知道, 在Linux系统中 目录也是文件, 而 文件 = 属性 + 内容

目录的属性我们都知道是什么, 都存储在其inode中, 那么目录文件的内容是什么呢?

我们访问目录、在目录下创建文件、查看目录下的都有什么文件, 都需要什么权限?
访问目录进入目录, 我们需要的是 x执行权限,在目录下创建文件, 我们需要的是 w写权限,查看目录下的文件, 我们需要的是 r读权限
而 文件的w和r权限实际上是对 文件内容的读写权限, 也就是说 目录文件的文件内容 其实就是目录下的文件

更准确一点, 应该说目录文件的文件内容, 其实是 目录下文件的文件名 和 inode编号 之间的映射

即, 目录文件在 Data Blocks 中, 存储的内容是其下文件的文件名与inode编号之间的映射关系
在这里插入图片描述

同一目录下, 是否可以存在多个相同的文件名? 不可以, 同一目录下的文件名是唯一的, 也就是说,
同一目录下一个文件名只对应一个inode编号
在这里插入图片描述

创建文件, 操作系统做了什么?

介绍了这么多 Linux关于inode 的相关信息, 那么创建文件时操作系统都会做什么, 才能正确的创建文件供用户访问呢?

操作系统大致的操作流程应该是:

  • 创建文件的inode, 并将inode和内容分别存储至组的inode Table 和 Data Blocks中, 并修改inode Bitmap 和 Block Bitmap 的相应内容
  • 找到当前用户所处的目录, 再根据当前目录的inode找到目录文件在 Data Blocks中的数据块
  • 将创建的文件的文件名和inode编号, 存储到目录文件在Data Blocks的数据块中, 并修改相关的 Block Bitmap

这样, 我们就可以在指定的目录下找到指定的文件

删除文件, 操作系统又做了什么?

Linux操作系统删除文件会怎么做呢?

一般情况下, 我们对删除文件的第一认知就是 将文件的inode和内容都在 inode Table 和 Data Blocks 中删除, 然后将 inode Bitmap 和 Block Bitmap 对应位置修改为0, 并将存储在目录文件的内容数据块中的映射关系删除. 做完这些, 就是删除文件

但实际上, 操作系统并不是这样做的.

操作系统删除文件, 并不会真的将文件存储在 Data Blocks的内容 和 inode Table的属性 删除, 而是只将 inode Bitmap 和 Block Bitmap 这两个位图中有关删除文件的位置设置为0. 再将目录文件的 Block Bitmap 的相关位置设置为0. 就完成了文件的删除

因为 inode Bitmap 和 Block Bitmap 这两个位图, 描述的是磁盘中实际的存储块的使用情况. 如果这两个位图中相关的位置为0, 那么在操作系统看来, 相应的 inode Table 和 Data Blocks 存储块中就没有存放有效数据, 相应的位置都是可以直接使用的

那么也就是说, 操作系统对文件的删除操作, 从效果来看完成了删除, 因为操作系统可以再次使用那些空间. 但从物理空间上来看, 那些空间内实际上还是存储有相关的文件数据的.
所以, 当删除了一个文件之后, 只要没有再次占用那些空间, 文件是可以被恢复的. 只要知道 文件的inode, 理论上是可以恢复的.
但是, 删除文件之后, 操作系统就可以随意使用那些空间了, 所以实际上也是很有可能无法恢复的

软硬连接

我们了解了Linux文件系统的相关信息之后, 我们知道了, 在操作系统的底层, 是不存在文件名这个概念的.

操作系统底层实际上不是通过文件名来找到 文件的属性和内容的, 而是通过inode编号

所以, 其实inode编号才是操作系统底层的标识符.

那么有没有一种可能, 在磁盘中存在多个文件名映射了同一个inode编号呢?

硬连接

在这里插入图片描述
目录中的文件名 和 inode编号, 以一种映射关系存储在指定的数据块中.

操作系统底层只认识inode编号, 不认识文件名. 所以, 无论是访问文件还是读写文件, 最终其实都是通过inode编号来实现的.

也就是说, 只要文件名可以映射到一个inode编号, 那么就可以通过此文件名访问到指定的文件. 即使存在多个文件名映射到同一个inode编号也是可以的.

而硬连接, 就可以将不同的文件名, 映射到同一个inode编号上
在这里插入图片描述

创建硬连接的命令是:ln 原文件名 新创建的硬链接文件名

可以看到, 不同的文件名映射的inode是相同的. 也就是说, 这两个就是同一个文件, 只是文件名不同, 操作系统没有在磁盘中再创建一个内容相同的文件, 并不会多占用一份磁盘空间. 其实就只是在目录的Data Blocks数据块中, 添加的了一个映射关系, 并没有其他的数据,

在执行了 ln 之后, 此文件inode编号除了被两个不同的文件名映射之外, 还存在另外一个变化:
表示权限一栏的后的数字, 从 1 变为了 2

这是什么意思?
其实, 这个数字是inode结构体记录的此文件的硬连接数, 只要磁盘中存在一个硬连接到此inode的文件, 这个计数就会+1

这样看来, 其实文件在操作系统中只看做是一个 inode结构体 + 文件内容 就可以了, 文件名什么的只是一个供用户查看、记忆的没有什么重要的实际意义的马甲, 而文件名映射的inode编号才是那个最重要的指向一个实际文件的数据. 也就是说, 其实 inode编号 就像是一个 “指针”

那么, 这个硬连接数有什么用呢?
硬连接数, 其实就是一个计数的作用, 只要硬连接数不为0, 就表示此inode所指向的文件 就还在某个地方被映射着甚至使用着呢

相应的, 只要此文件的硬连接数为0了, 那么就表示此文件在操作系统中已经可以不再存在了, 就可以删除了.

也就是说, 只有一个文件的硬连接数为0时, 磁盘中的文件才会被删除. 不为0, 顶多算是解除了某个文件名对其的映射

硬连接有什么用?
要回答这个问题, 先创建一个目录文件和普通文件:
在这里插入图片描述
为什么这样呢?
普通文件被创建出来之后, 就只有一个文件名映射到实际文件对应的inode

而目录文件不同:
在这里插入图片描述
这就是为什么, 当我们执行当前目录下的可执行文件的时候, 需要使用 ./ 作为前缀

软连接

在这里插入图片描述
软连接对比硬连接来说, 就基本没有需要注意的地方.

建立软连接的命令也是 ln, 只不过 需要添加一个选项 -s, 可以看做soft , 即 ln -s 表示建立软连接
在这里插入图片描述

与 硬连接不同的是, 软连接是生成了一个新的文件, 因为映射的inode与原文件不同.

不过, 软连接没有什么其他需要注意的点, 可以把Linux中的软连接看作是Windows中的快捷方式

软连接创建的新文件的内容, 其实是所连接的原文件的所在路径

软硬连接都可以用, unlink 命令来取消连接

进程管理

网络编程

shell

GCC

GDB

启动gdb

gdb filename

设置断点

(gdb) b 行数
(gdb) b 文件名:行数