写在前面
学习Linux的价值:
- Linux 是现代化应用程序交付的首选平台,无论是部署在裸机、虚拟化还是容器化环境
- 公司内部服务(TCE、FaaS、SCM)统一使用 Debian Linux 系统
- 熟悉 Linux 基础指令,熟练运维前端常用服务(Nginx,Node.js)
- 加深对操作系统概念和实现的理解,夯实基础知识
计算机硬件
首先,我们来了解一下计算机硬件。计算机由五大基本单元组成,分别是控制器、运算器、存储器单元、输入单元和输出单元。
控制器
负责管理和控制计算机系统中的各种设备和组件。控制器通常是一个芯片或电路板,它包含了一些逻辑电路和控制信号,用于控制和管理计算机系统中的各种设备和组件。
在计算机系统中,控制器的作用是将指令和数据从主存储器传输到各种设备和组件中,例如硬盘驱动器、光驱、键盘、鼠标等。控制器还负责将来自这些设备和组件的数据和信号传输回主存储器,以便处理和存储。
在代码中,控制器通常由操作系统或应用程序使用的驱动程序来控制和管理。驱动程序是一种软件程序,它允许操作系统或应用程序与硬件设备进行通信和交互。驱动程序通常包含了一些控制器的指令和数据,用于控制和管理硬件设备。
运算器
负责执行各种算术和逻辑运算。运算器通常是由一些逻辑电路和寄存器组成的,用于执行各种算术和逻辑运算,例如加法、减法、乘法、除法、位运算等。
在计算机系统中,运算器的作用是执行各种算术和逻辑运算,例如将两个数相加、比较两个数的大小、计算两个数的积等等。运算器通常是由中央处理器(CPU)使用的指令集来控制和管理的。
在代码中,运算器通常由编程语言中的算术和逻辑运算符来使用。例如,在Python中,可以使用加号(+)来执行两个数的加法运算,使用减号(-)来执行两个数的减法运算,使用星号()来执行两个数的乘法运算,使用斜杠(/)来执行两个数的除法运算,使用百分号(%)来执行两个数的取模运算等等。
存储器单元
负责存储和检索计算机系统中的数据和指令。存储器单元通常是由一些逻辑电路和存储单元组成的,用于存储和检索计算机系统中的数据和指令。
在计算机系统中,存储器单元的作用是存储和检索计算机系统中的数据和指令。存储器单元通常被划分为两种类型:随机存储器(RAM)和只读存储器(ROM)。RAM用于存储计算机系统中的临时数据和指令,而ROM用于存储计算机系统中的固定数据和指令。在代码中,存储器单元通常由变量和数组来使用。
输入单元
负责将外部设备(例如键盘、鼠标、触摸屏等)输入的数据转换为计算机系统可以理解的格式,并将其传递给其他组件进行处理。输入单元通常是由一些逻辑电路和接口组成的,用于接收和转换外部设备输入的数据。
在计算机系统中,输入单元的作用是将外部设备输入的数据转换为计算机系统可以理解的格式,并将其传递给其他组件进行处理。输入单元通常与输出单元一起使用,以便将计算机系统中的数据和指令传递给外部设备进行显示或输出。在代码中,输入单元通常由编程语言中的输入函数或方法来使用。
输出单元
负责将计算机系统中的数据和指令转换为外部设备(例如显示器、打印机、扬声器等)可以理解的格式,并将其传递给外部设备进行显示或输出。输出单元通常是由一些逻辑电路和接口组成的,用于将计算机系统中的数据和指令转换为外部设备可以理解的格式。
在计算机系统中,输出单元的作用是将计算机系统中的数据和指令转换为外部设备可以理解的格式,并将其传递给外部设备进行显示或输出。输出单元通常与输入单元一起使用,以便将外部设备输入的数据转换为计算机系统可以理解的格式,并将其传递给其他组件进行处理。在代码中,输出单元通常由编程语言中的输出函数或方法来使用。
计算机系统
了解完计算机硬件后,我们来了解一下计算机系统(OS)。计算机系统是由多个硬件和软件组件组成的复杂系统,用于执行各种计算和数据处理任务。其中,输入单元和输出单元是计算机系统中的两个重要组成部分。它管理和控制计算机系统中硬件和软件资源,用于在用户与系统硬件之间传递信息。
输入单元负责将外部设备输入的数据转换为计算机系统可以理解的格式,并将其传递给其他组件进行处理。在代码中,输入单元通常由编程语言中的输入函数或方法来使用。输出单元负责将计算机系统中的数据和指令转换为外部设备可以理解的格式,并将其传递给外部设备进行显示或输出。在代码中,输出单元通常由编程语言中的输出函数或方法来使用。
小思考:程序启动必须有操作系统来执行,那操作系统本身也是一个程序,那是如何在开机时被执行的呢?
我们来了解一下系统的启动流程
启动流程
操作系统的启动流程是计算机系统中的一个重要过程。在启动过程中,计算机硬件和软件组件将被初始化和配置,以便它们可以正常运行并提供所需的功能。
在上图,我们发现计算系统的启动流程由两种:分别是BIOS和UEFI两种方法引导系统启动。
BIOS
BIOS的启动流程通常包括以下步骤:
加载BIOS:计算机开机时,首先会加载基本输入/输出系统(BIOS),它是计算机系统中的一个固件,负责初始化硬件设备并启动操作系统。启动引导程序:BIOS将启动引导程序加载到计算机内存中,该程序负责查找并加载操作系统内核。加载内核:启动引导程序将操作系统内核加载到计算机内存中,并将控制权转移到内核代码。初始化内核:内核代码将初始化计算机系统中的各种硬件和软件组件,例如处理器、内存、文件系统等。启动用户空间:内核代码将启动用户空间,使用户可以开始使用计算机系统。
在代码中,操作系统的启动过程通常由操作系统内核代码实现。例如,在Linux操作系统中,内核代码位于"/boot"目录下的"vmlinuz"文件中。可以使用bootloader程序(例如GRUB)来加载内核代码并启动操作系统。
UEFI
UEFI的启动流程通常包括以下步骤:
加载UEFI固件:计算机开机时,首先会加载UEFI固件,它是计算机系统中的一个固件,负责初始化硬件设备并启动操作系统。启动引导程序:UEFI将启动引导程序加载到计算机内存中,该程序负责查找并加载操作系统内核。加载内核:启动引导程序将操作系统内核加载到计算机内存中,并将控制权转移到内核代码。初始化内核:内核代码将初始化计算机系统中的各种硬件和软件组件,例如处理器、内存、文件系统等。启动用户空间:内核代码将启动用户空间,使用户可以开始使用计算机系统
在代码中,UEFI的启动流程通常由UEFI固件和操作系统内核代码实现。例如,在Windows操作系统中,UEFI固件位于计算机的固件芯片中,而操作系统内核代码位于计算机硬盘的某个分区中。可以使用UEFI固件中的启动管理器来加载操作系统内核代码并启动操作系统。
小思考:通过以上的了解,我们发现BIOS以及UEFI在启动流程步骤上类似,那么它们有什么区别呢?
UEFI(统一的可扩展固件接口)是一种
新型的固件接口,它正在逐渐取代BIOS作为计算机系统的启动程序。UEFI的启动流程与BIOS的启动流程类似,但UEFI具有更多的功能和灵活性。例如,UEFI支持更大的硬盘容量和更快的启动速度,还支持网络启动和安全启动等功能。
Linux系统概要
Linux操作系统是一种开源的、免费的操作系统,它的内核是由Linus Torvalds和其他贡献者开发的。Linux操作系统广泛用于服务器、超级计算机、移动设备和嵌入式系统等领域。Linux操作系统的优点包括高度的可定制性、稳定性和安全性。我们来了解一下Linux。
发展简史
- 1969年,Unix诞生于贝尔实验室
- 1984年,贝尔实验室将Unix商业化
- 1984年,Tanenbaum开发Minix操作系统用于教学并开放源码
- 1984年,Richard M.Stallman发起自由软件(FSF)与GNU项目,起草GPL(通用公共许可)协议 5.1991年,Linus Torvalds受Minix影响实现初版的Linux内核6.1992年,Linux内核以GPL协议发行V1.0
Linux版本
Linux的版本分为内核版本以及发行版本。
小思考:内核版本和发行版本有什么区别?
Linux内核是操作系统的核心组件,它提供了操作系统的基本功能,例如进程管理、内存管理和设备驱动程序。
发行版本是基于Linux内核的操作系统的完整实现,它包括内核、系统工具、库和应用程序等组件。发行版本通常由Linux社区或其他组织开发和维护,并提供不同的功能和特性。
我们怎么查看Linux的系统内核版本呢?
uname -acat /proc/version
同样的,我们怎么查看Linux系统的发行版本呢?
cat /etc/os-release
Linux的应用领域
- IT服务器、操作系统、虚拟化和云计算
- 嵌入式和智能设备
- 个人办公桌面
- 学术研究和软件研发
Linux系统结构
在认识完Linux的系统概要后,我们来了解一下Linux的系统结构。
基本组成
Linux系统一般由四个部分组成,即内核、Shell、文件系统和应用程序。
- 内核:
Linux内核是操作系统的核心,它是操作系统的主要组成部分之一。它是一个开源项目,由Linus Torvalds创建并维护。Linux内核是一个模块化的内核,它允许用户在运行时添加或删除内核模块,以便根据需要定制内核。 - Shell:Shell是一种命令行解释器,它允许用户与操作系统进行交互。在Linux系统中,有许多不同的Shell可供选择,其中最常用的是Bash(Bourne-Again SHell)。
Bash是Linux系统中默认的Shell,它是一个功能强大的Shell,具有许多有用的功能和命令。 - 文件系统:文件系统是操作系统用于管理文件和目录的一种机制。在Linux系统中,有许多不同的文件系统可供选择,每种文件系统都有其自己的特点和用途。Linux系统中最常用的文件系统是
Ext4(第四扩展文件系统)。Ext4是Linux系统中默认的文件系统,它是一个成熟的、稳定的文件系统,具有许多有用的功能和优点。例如,它支持文件和目录的权限控制、日志记录、快速恢复等。 除了Ext4之外,Linux系统还支持许多其他文件系统,例如Btrfs、XFS、NTFS等。 - 应用程序:应用程序是一种计算机程序,它旨在
执行特定的任务或功能。在Linux系统中,有许多不同的应用程序可供选择,每种应用程序都有其自己的特点和用途。
Linux体系结构
Linux的体系结构大致可以分为用户空间以及内核空间。
用户空间包括用户进程和应用程序,它提供了许多有用的功能和服务,例如文件系统、网络通信、进程管理等。用户空间中的应用程序可以使用许多不同的编程语言和框架进行编写。其中一些最常用的编程语言包括C、C++、Python和Java。用户可以使用任何文本编辑器或集成开发环境(IDE)编写Linux应用程序。在编写应用程序时,请确保使用正确的文件扩展名,并设置正确的文件权限。
内核空间包括操作系统内核和驱动程序等核心组件,内核空间和用户空间之间有一个重要的区别,即它们的访问权限不同。内核空间具有更高的访问权限,可以直接访问系统硬件和资源。用户空间则具有较低的访问权限,只能通过系统调用等方式访问内核空间提供的服务和资源。
由上图我们可以看到:
- 内核是硬件与软件之间的
中间层 - 内核是一个
资源管理程序 - 内核提供一组面向系统的命令
进程管理
Linux用户空间中的进程是指正在运行的程序实例。每个进程都有自己的内存空间、状态和优先级等属性。Linux系统使用进程来管理和执行各种任务,例如运行应用程序、处理网络请求和执行系统服务等。在Linux系统中,用户可以使用许多不同的命令和工具来管理和监视进程。一个 CPU 核同一时间只能运行一个进程,进程由它的进程 ID(PID)和它父进程的进程 ID(PPID)唯一识别。
我们怎么查看进程信息呢?
# 查看启动的 nginx 进程
ps -ef | grep 进程名
# 查看某个进程
top -p 进程ID
# 关闭指定的进程
kill 进程ID
# 全部进程动态实时视图
top
小思考:系统中运行的程序远远大于CPU的核数,那Linux系统是如何实现同时运行这么多程序的?
Linux系统可以通过
多任务和时间片轮转等技术来实现同时运行多个程序。具体来说,Linux系统将CPU时间划分为多个时间片,并将每个时间片分配给不同的程序。当一个程序的时间片用完后,Linux系统将暂停该程序的执行,并将CPU时间片分配给下一个程序。这种方式可以让多个程序同时运行,从而提高系统的利用率和响应能力。
进程调度
Linux系统使用了进程调度算法来决定哪些程序应该获得CPU时间片。Linux系统中有多种进程调度算法可供选择,例如CFS(完全公平调度器)和实时调度器等。这些算法可以根据程序的优先级、资源需求和运行时间等因素来决定程序的执行顺序,从而实现更加公平和高效的进程调度。
由上图可以知道,进程有多个状态:
- R (TASK_RUNNING):可执行状态
- S (TASK_INTERRUPTIBLE):可中断的睡眠状态
- D (TASK_UNINTERRUPTIBLE):不可中断的睡眠状态
- T (TASK_STOPPED or TASK_TRACED):暂停状态或跟踪状态
- Z (TASK_DEAD - EXIT_ZOMBIE):退出状态,进程成为僵尸进程
- X (TASK_DEAD - EXIT_DEAD),退出状态,进程即将被销毁
进程调度的原则有:
- 一个 CPU 核同一时间只能运行一个进程
- 每个进程有近乎
相等的执行时间 - 对于逻辑 CPU 而言进程调度使用轮询的方式执行,当轮询完成则回到第一个进程反复
- 进程
执行消耗时间和进程量成正比
进程的系统调用
在Linux系统中,内核空间和用户空间是通过虚拟内存技术来实现的。具体来说,Linux系统将物理内存划分为多个页面,并将每个页面映射到不同的虚拟地址空间中。内核空间和用户空间各自拥有自己的虚拟地址空间,它们之间通过系统调用和中断等机制进行通信和交互。
由上图我们可以知道,程序的运行让程序在用户态以及内核态之间来回切换。
文件系统
Linux 中一切皆文件。Linux系统中的文件系统是指用于管理和组织文件和目录的一组数据结构和算法。Linux系统支持多种文件系统,包括ext4、NTFS、FAT32等。其中,ext4是Linux系统默认的文件系统,它具有高性能、高可靠性和高扩展性等优点,适用于大多数Linux系统的应用场景。文件系统负责管理持久化数据的子系统,负责把用户的文件存到磁盘硬件中。
Linux文件系统是采用树状的目录结构,最顶层的是根目录即/目录。
小思考:Linux 有这么多不同的文件系统,如何实现对用户提供统一调用接口的?
通过虚拟文件系统VFS进行对用户提供统一调用接口。
虚拟文件系统VFS
VFS定义了一组通用的文件系统接口和数据结构,使得应用程序可以通过相同的方式来访问不同类型的文件系统,而不必关心底层文件系统的具体实现。它对应用层提供一个标准的文件操作接口同时对文件系统提供一个标准的文件接入接口。
我们可以查看文件系统类型,通过如下命令:
# df 命令报告文件系统磁盘空间利用率
df -T
# mount 命令是挂载文件系统用的,不带任何参数运行,会打印包含文件系统类型在内的磁盘分区的信息
mount
当然,在Linux中,我们有一系列的文件操作命令,如下所示
# 查看文件夹下内容
ls
# 创建文件夹
mkdir demo
# 移动 demo 文件夹到 /home
mv demo /home
# 删除 demo 文件夹
rm -r demo
# 创建空文件
touch file.txt
# 复制文件
cp file.txt file_bak.txt
用户和权限
在Linux中,用户身份用来区别某些命令或者文件的执行相关动作的权限,这增强了Linux的安全性。用户身份分为用户账户和用户组。其中,用户账户分为:
- 普通用户账户:在系统中进行普通作业
- 超级用户账户:在系统中对普通用户和整个系统进行管理
而用户组又可以分为:
- 标准组:可以容纳多个用户
- 私有组:只有用户自己
在Linux中,我们可以使用命令来查看用户信息,具体命令如下:
# 查看当前登录用户信息
w
# 查看当前用户所属的组
groups
# 查看用户的 uid 信息
id
文件权限
文件权限三个概念,分别是:
所有者:文件的所有者所在组:文件的所有者所在的组其他人:除文件所有者及所在组外的其他人
其中,每个用户对于文件都有不同权限,包括读(R)、写(W)、执行(X)。文件权限的格式如下:
在Linux中,我们可以使用命令来进行文件权限操作,命令如下所示:
# 在根目录创建一个文件夹,查看当前用户拥有文件夹的权限
cd / && mkdir demo && ls -ld demo
# 创建一个用户,并赋予可写操作
sudo useradd ceshi
# 设置用户密码
sudo passwd ceshi
# 切换 ceshi 用户登录
su ceshi
# 进入 demo 文件夹
cd demo
# 创建 index.js 文件,提示无权限,需要给 ceshi 用户 demo 文件夹的权限
touch index.js
# demo 文件夹写权限赋予其他人
sudo chmod o+r ./demo
# 切换 ceshi 用户登录
su ceshi
# 进入 demo 文件夹
cd demo
# 创建 index.js 文件成功
touch index.js
Linux的软件包管理
什么是软件包?软件包通常指的是一个应用程序,它可以是一个GUI应用程序、命令行工具或(其他软件程序需要的)软件库。
软件包管理用于管理和安装软件包。在Linux系统中,常见的软件包管理工具有dpkg、rpm、yum、apt-get等,它们可以自动解决软件包之间的依赖关系,并提供了更加友好的命令行界面。它分为:
- 底层工具:主要用来处理安装和删除软件包文件等任务,DPKG,RPM
- 上层工具:主要用于数据的搜索任务和依赖解析任务,APT,YUM,DNF
扩展:
- RPM(Red Hat Package Manager),为Red hat操作系统的包管理系统
- DPKG(Debian package),为 Debian 操作系统的包管理系统
Debian 配置软件源
通常Debian系的Linux软件源配置文件:/etc/apt/sources.list。
镜像地址:mirrors.aliyun.com/
- /dists:查看系统代号
- /pool:查看软件分支