与牢霍沟通——Linux操作系统原理


硬件层

计算机由何组成?

我们现在手中的计算机,无论配置如何,是笔记本还是台式,都由三部分构成:

  1. 输入设备:键盘,鼠标...
  2. 中央处理器:cpu,显卡,磁盘...
  3. 输出设备:显示器... 

在这三个设备里,已经有两个设备是我们天天看到使用的,输入设备和输出设备,但是我们了解甚少的,也就是中央处理器,是我们今天的主要话题:计算机是怎么通过这些中央处理器,操控我们的电脑的? 

冯诺依曼体系

为了方便大家理解,我们用三体中的冯诺依曼来作为例子:三体中的冯诺依曼-CSDN博客icon-default.png?t=N7T8https://blog.csdn.net/qq_74260823/article/details/139362105?spm=1001.2014.3001.5501 (一个关于三体冯诺依曼的扩写,详细讲了冯诺依曼体系的原理和构成,有兴趣可以看看帮助理解)

  •  记录方阵,用来记录数据,我们把他叫做内存。
  • 计算方阵,用来计算数据,我们把他叫做运算器。
  • 皇帝,用来翻译指令,然后转化成机器指令,告诉内存和cpu应该干什么,cpu应该从内存的哪里拿什么数据,我们把他叫做控制器。

这些,便构成了现代的冯诺依曼体系:

但是我们很容易发现,所有的人干的事情,输入和输出,都只能和内存相互交流,没办法去直接和cpu交流,因为cpu听不懂你的话,你也看不懂cpu说的啥,就算你们直接交流了,也是语无伦次不了了之。 

就像,你想和霍金说说话,直接找他是没办法的,你必须要通过其他渠道:

并且,这也是出于对cpu的一种保护机制,如果我们直接操作cpu里的数据,一会就给cpu干烧了

比如我们的数组越界,或者是野指针等问题,都是因为操作系统只允许我们操作安全范围内的内存。我们访问内存,实际上是操作系统在帮我们找内存,而非直接访问到cpu内的真实内存。当操作系统发现这个内存在安全范围内,我们便把数据首先交给操作系统,然后操作系统再把数据交给cpu,从而保护cpu内的数据不是被乱修改的。 


软件层 

什么是操作系统 

操作系统是一款软件,要钱的。

我们为什么要选择Linux?因为Linux免费的。

但是,不同的操作系统,价格不同,其实现的基本准则是相同的。操作系统的任务和目标都只有一个:管理好所有的软硬件,只要能完成这个任务,无论这个操作系统是谁做的要多少钱,他都是一个好操作系统。

除了要钱以外,操作系统是一款专门负责管理的软件,他负责管理两件事:

  1. 与硬件交互,管理所有的软硬件资源
  2. 与用户交互,为用户的程序提供运行环境。

但是光凭这两句话,操作系统还是不知道要干什么。我们再把软硬件交互和用户交互细分,慢慢看看操作系统的管理原理:

硬件交互

键鼠硬盘

一个优秀的计算机,自然要有这几个熟知的硬件:

  • 键盘
  • 鼠标
  • 网卡
  • 硬盘
  • ...

但是,计算机怎么知道,这些硬件被安装在了哪里,又怎么知道,这些硬件分别是干什么的?
cpu是没有办法直接读取这些信息值的,这些硬件也没有办法把内存里的二进制数01翻译成给人能看的懂的东西。所以,这个时候就必须要有一个翻译官:操作系统。
操作系统负责切换机械语言和偏人类语言:

当你在键盘敲下d的时候,由操作系统把d翻译成机器二进制码01放在内存的某个安全的位置,然后告诉显示器,从内存的哪个位置(具体的指针地址)拿到这个d,用哪种方式哪种语言打印在显示器的哪个位置,这便是操作系统对底层的任务。

不过,总有些神经病,喜欢改键位。R是放大招,可他偏不,他就喜欢A放大招,R改成平A,享受那种边走边R的快感。这个时候,键位发生了变化,如果直接去操作系统里改文件,

比如把#define R 大招   改成   #define A 大招

首先要找到键位对应的代码文件,然后找到某个键位对应的那一行,最后看看改了这些之后会不会对其他的代码产生影响,那也太麻烦了。

就算改了,对操作系统的负担也是相当大:

“原本我都写死了,现在你说要可修改,那我又要新加一堆功能,新写一堆接口,这个钱谁给我补呢?”

所以,为了避免这些麻烦,操作系统和硬件之间还有一层软件:驱动

驱动

驱动是介于操作系统和硬件之间的一个软件。有了驱动,操作系统就不再直接去硬件上读然后翻译了,他直接读取驱动已经翻译好了的东西,然后直接拿给内存。

比如还是放大招的问题。

按照原先的逻辑,操作系统首先看输入的是什么,是R,然后看R对应的是什么,是大招于是就知道,我要放大招了。这用了两步翻译。

而有了驱动,驱动直接告诉操作系统,现在有一个大招的输入,操作系统就不再去看用户输入了哪个键,而是直接拿驱动告诉他的大招信息,然后知道,我要放大招了。只用了一步翻译。

但是,驱动什么时候向操作系统发出大招信息呢?这个就是驱动的实现,和操作系统没有关系了,操作系统只负责写出函数声明,然后让每家硬件公司在生产硬件的时候,必须配套一个驱动,驱动里要补充完整这些函数接口,让操作系统直接调用。至此,操作系统只负责接受各种已被驱动处理过的信息,而这些信息怎么来,怎么和用户进行交互,那就变成了驱动的事情。

但是,有人就要问了:

话是这个话,但是,驱动不是我操作系统写的,我只负责写好我的逻辑,当你一个公司产生一个产品的时候,你就把对应的驱动给写好给我,我直接用你的驱动,这样我的锅就变成了你的锅,岂不是完美? 

用户交互

我们最直观的用户交互,便是我给钱,你给我发个安装包
太有交互了,我的Windows!

除此之外,我们按下CTRL+ALT+.,会蹦出来个任务管理器,这便是我们第二直观可以看到操作系统的交互:告诉我们每个进程的详细信息,杀掉一个进程,或是创造一个进程。

可是,我们有没有想过,为什么我们可以杀掉这些进程?为什么我们可以创建这些进程? 

我们告诉操作系统这些任务,然后操作系统权量这些任务是否合理,合理的操作系统就帮我们完成,不合理的操作系统就会给我们警告,并不会实施这些操作。我们可能很疑惑,难道还有什么任务,是对操作系统不合理的吗? 

 要不你去直接修改cpu的数据试试?
 要不你去直接修改操作系统的数据试试?

操作系统,同样对着底层和自身有着保护机制。我们能用操作系统去完成一些操作,完全是因为,操作系统给了我们一些操作指令,告诉我们那些是可以帮我们做的,这些指令叫做系统调用。比如printf,比如scanf,便是被封装起来的系统调用,我们可以用这些指令去访问底层,但是却无法直接访问底层的数据,因为他们都是被操作系统保护起来的。 

所以,整个计算机的管理结构,可以用一张图来概括起来:


怎么管理?

对操作系统来说,所有的管理只遵从一句话: 

先描述,再组织。 

先描述,再组织。 

先描述,再组织。 

啥意思?

湖人球队

就比如你想管理湖人球队,此时来了一位年轻的球员,叫做科比,你对他并不熟悉,第一步应该干什么?把他的特点描述出来: 

然后第二步,根据你的描述,把被描述的对象组织起来

 而对所有球员,我们都这样安排,最后用一个册子把他们包含在内:

我们就完成了对一个球队的管理,需要的时候,我们从名单中一个个分析,一个个拿取,而球队中坠机了某位之后,我们只要把球员的信息表从册子里抽出来就可以了。

操作链表 

而操作系统对任何东西的管理,也是通过此完成的。我们接下来要讲进程,就以进程举例,我们首先去描述一个进程,而在C语言中,描述一个进程最好的方法自然是结构体: 

struct task//进程
{
	char* name;//进程名
	int pid;//进程id
	...
}

 而组织,便是把所有的进程串起来。完成这一操作,最简单的方法,自然也是链表

struct task_listnode//进程链表
{
	task* task;//指向的进程
	task_listnode* next_task;//下一个进程
}

对一个进程的增删查改,就变成了对链表结点的增删查改,进程相当于球队的球员,而链表就相当于球队的名单,我们利用先描述再组织这一准则,完美把所有进程管理了起来。

当一个进程被创建的时候,我们把他放在链表的尾部;当一个进程退出的时候,我们直接用O(1)的时间把他删除掉。而在链表中的所有进程,便是正在运行的进程,我们想查看和管理进程的时候,直接遍历链表就可以找到这个进程。

而对文件,对内存,也都是先用结构体描述起每一个对象的特征,然后用链表把所有对象串起来,整个计算机也就通过这种巧妙的方法,完美地用几张链表管理了起来。 


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/666743.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

在鲲鹏服务器上安装nginx

华为鲲鹏服务器采用华为自研cpu ARMv8架构,提供 Windows 和多个Linux 系统 常使用 CentOS 7.6 64bit with ARM Nginx 和 Apache 一样都是一种 Web 服务器。是基于 REST 架构风格,以统一资源描述符URI 或者统一资源定位符URL 作为沟通依据,通过 HTTP 协议…

Flink系列二:DataStream API中的Source,Transformation,Sink详解(^_^)

在上面篇文章中已经对flink进行了简单的介绍以及了解了Flink API 层级划分,这一章内容我们主要介绍DataStream API 流程图解: 一、DataStream API Source Flink 在流处理和批处理上的 source 大概有 4 类: (1)基于本…

【深度学习】安全帽检测,目标检测,yolov10算法,yolov10训练

文章目录 一、数据集二、yolov10介绍三、数据voc转换为yolo四、训练五、验证六、数据、模型、训练后的所有文件 寻求帮助请看这里: https://docs.qq.com/sheet/DUEdqZ2lmbmR6UVdU?tabBB08J2一、数据集 安全帽佩戴检测 数据集:https://github.com/njvi…

匿名函数(lambda)

自学python如何成为大佬(目录):https://blog.csdn.net/weixin_67859959/article/details/139049996?spm1001.2014.3001.5501 匿名函数是指没有名字的函数,应用在需要一个函数,但是又不想费神去命名这个函数的场合。通常情况下,这样的函数只…

VRTK4.0学习——(二)

手柄绑定以及显示 1.导入CameraRigs.UnityXRPluginFramework 和 CameraRigs.TrackedAlias 预设,将CameraRigs.UnityXRPluginFramework拖入CameraRigs.TrackedAlias的Elements中即可,运行软件后即可看到手柄了 注:如果无法看到手柄&#xff…

鹤城杯 2021 流量分析

看分组也知道考http流量 是布尔盲注 过滤器筛选http流量 将流量包过滤分离 http tshark -r timu.pcapng -Y "http" -T json > 1.json这个时候取 http.request.uri 进一步分离 http.request.uri字段是我们需要的数据 tshark -r timu.pcapng -Y "http&quo…

fmql之CAN调试

刚刚把zynq的CAN调成功。那么现在就要把程序移植到fmql了。 老规矩,Procise导入vivado的.bd和.xci文件。 Procise下create block也可以,但是不能自动约束引脚,只能手动写代码。 PeripheralTest CanExample中用到了CAN0和CAN1:…

重生之 SpringBoot3 入门保姆级学习(11、日志的进阶使用)

重生之 SpringBoot3 入门保姆级学习(11、日志的进阶使用) 3.2.4 文件输出3.2.5 日志文档的归档与切割 3.2.4 文件输出 配置 application.properties # 日志文件名 如果不写路径默认就是在项目根路径建立 demo.log 文件 推荐写法 D:\\demo.log 路径 文…

虚拟机Ubuntu 22.04上搭建GitLab操作步骤

GitLab是仓库管理系统,使用Git作为代码管理工具。GitLab提供了多个版本,包括社区版(Community Edition)和企业版(Enterprise Edition)。实际应用场景中要求CPU最小4核、内存最小8GB,非虚拟环境。 以下是在虚拟机中安装社区版步骤:…

R语言ggplot2包绘制高端堆积柱状图

数据和代码获取:请查看主页个人信息!!! 关键词“高端堆积柱状图” 大家好,今天我将介绍如何使用ggplot2包绘制高端堆积柱状图。 本次绘图灵感来源于下面这篇文章,之所以复现这张图,有这么几个原…

查看docker中各个容器所占的资源

要查看Docker中的每个容器占用的资源,可以使用docker stats命令。这个命令提供了容器的实时资源使用统计,包括内存使用情况。以下是如何使用docker stats命令的示例: docker stats --format "table {{.Name}}\t{{.CPUPerc}}\t{{.MemUsa…

Nginx企业级负载均衡:技术详解系列(14)—— 账户认证功能

你好,我是赵兴晨,97年文科程序员。 你有没有听说过Nginx的账户认证功能?这可不只是一个技术问题,它关系到我们上网时的安全和便利。就像家里需要一把钥匙才能进们一样,Nginx的账户认证功能就是确保有只有授权的人才能…

Linux-在centos7中为普通用户配置sudo认证

目录 前言一、sudo是什么?二、配置sudo三、测试 前言 本篇文章介绍如何在centos7中为普通用户配置sudo认证 一、sudo是什么? sudo是一个命令,其作用是为普通用户以临时管理员(root)的身份去执行一条命令。 例如&…

ConvNeXt(CVPR 2022)论文解读

paper:A ConvNet for the 2020s official implementation:https://github.com/facebookresearch/ConvNeXt third-party implementation:https://github.com/huggingface/pytorch-image-models/blob/main/timm/models/convnext.py 背景 在…

面试杂谈k8s

其实看我之前的博客,k8s刚有点苗头的时候我就研究过,然后工作的时候间接接触 也自己玩过 但是用的不多就忘记了,正苦于不知道写什么,水一篇 用来面试应该是够了 支持云应用开发、运行与运维一体化的云应用平台软件应运而生 k8s核…

JVM 指针压缩

运用java内存对齐填充,对java内存进行8字节划分,java对象指针映射到每个划分区域上,使得4个字节(32位)表示2^32个地址,从而使4个字节指针映射32G内存空间。 1.为什么进行指针压缩: jvm从32位变…

【DSP】xDAIS算法标准

1. 简介 在安装DSP开发支持包时,有名为 “xdais_7_21_01_07”文件夹。xDAIS全称: TMS320 DSP Algorithm Standard(算法标准)。39条规则,15条指南。参考文档。参考文章。 2. 三个层次 3.接口 XDAIS Digital Media。编解码引擎。VISA(Video&…

18.Redis之哨兵

1.哨兵机制的介绍 通过自动化的手段,来解决主节点挂了的问题~~ 哨兵机制, 是通过独立的 进程 来体现的.和之前 redis-server 是不同的进程!! redis-sentine| 不负责存储数据,只是对其他的 redis-server 进程起到监控的效果~~ 通常哨兵节点,也会搞一个集合~~(多个哨兵节点构成的…

汽车MCU虚拟化--对中断虚拟化的思考(2)

目录 1.引入 2.TC4xx如何实现中断虚拟化 3.小结 1.引入 其实不管内核怎么变,针对中断虚拟化无非就是上面两种,要么透传给VM,要么由Hypervisor统一分发。汽车MCU虚拟化--对中断虚拟化的思考(1)-CSDN博客 那么,作为车规MCU龙头…

基于ES安装IK分词插件

前言 IK分词器插件是为Elasticsearch设计的中文分词插件,由Elasticsearch的官方团队之外的开发者medcl开发。它主要针对中文文本的分词需求,提供了较为准确的中文分词能力。以下是IK分词器插件的一些特点: 智能分词:IK分词器采用基…