【Linux】Linux内核结构基础

news2024/12/28 6:51:37

Linux内核结构基础

  • 一、Linux内核结构介绍
  • 二、Linux内核结构
    • ☆ Linux内核结构框图
    • Linux系统架构
  • 三、认识驱动
    • 为什么学驱动
    • 文件名与设备号
    • open函数过程实例详解
  • 四、shell
    • shell脚本

参考博文:

  • 【Linux】内核结构(全)
  • linux内核结构介绍(简)
  • 图解Linux系统的系统架构
  • Linux驱动(驱动程序开发、驱动框架代码编译和测试)

一、Linux内核结构介绍

  Linux 内核是操作系统的核心部分,它负责管理系统的资源、进程调度、设备驱动程序等核心功能。以下是 Linux 内核的主要组成部分和结构:

1. 进程管理:

  • 调度器(Scheduler): 决定在多任务系统中那个进程获得CPU时间
  • 进程控制块(Process Control Block,PCB) 存储有关进程的信息,如寄存器状态、进程状态等。

2. 内层管理:

  • 虚拟内存管理: 管理进程的虚拟地址空间,包括分页机制、页面置换机制等。
  • 物理存储管理: 负责跟踪系统中的物理内存,包括内存分配、释放等。

3. 文件系统:

  • 虚拟文件系统(VFS): 提供文件系统的抽象接口,使得不同类型的文件系统可以共享相同的API
  • 文件描述符表: 管理打开的文件信息,每个进程都有一个文件描述符表

4. 设备驱动程序:

  • 字符设备和块设备驱动: 用于管理字符设备(如终端)和块设备(如硬盘)
  • 网络设备驱动: 处理网络设备和协议栈

5. 网络协议栈:

  • TCP/IP 协议栈: 包括网络层、传输层等,用于实现网络通信
  • 套接字层: 提供应用程序与网络协议直接的接口

6. 系统调用接口:

  • 系统调用: 提供用户空间程序与内核直接的接口,允许用户程序请求内核执行特权操作。

7. 中断和异常处理:

  • 中断处理程序: 处理硬件中断,允许外部设备向CPU发生信号
  • 异常处理程序: 处理由于错误或异常情况而引发的事件

8. 定时器和时钟管理:

  • 内核定时器: 用于实现记时和时间管理
  • 实时时钟(RTC): 处理硬件时钟

9. 同步和互斥机制:

  • 信号量、自旋锁、互斥量等: 用于确保多个进程或线程之间的同步与互斥

10. 系统初始化和启动:

  • 引导加载程序(Bootloader): 负责记载内核镜像到内存中
  • 启动过程: 初始化硬件、文件系统等,最终执行第一个用户空间进程。

这些组件一起构成了 Linux 内核的核心结构。内核的源代码是 modulized 的,允许添加或删除特定功能的模块,以适应不同的需求。整个内核的结构和实现细节非常庞大,具体的功能和特性取决于具体的内核版本和配置。

linux系统将设备分为3类:字符设备、块设备、网络设备

  • 字符设备: 指只能一个字节一个字节读写的设备,不能随机读取设备内存中的某一数据,读取数据需要按照先后顺序。字符设备是面向流的设备,常见的字符设备有鼠标、键盘、串口、控制台和LED设备等。
  • 块设备: 指可以从设备的任意位置读取一定长度数据的设备。块设备包括硬盘、磁盘、U盘和SD卡等。
  • 网络设备: 网络设备可以是一个硬件设备,如网卡; 但也可以是一个纯粹的软件设备, 比如回环接口(lo).一个网络接口负责发送和接收数据报文。

二、Linux内核结构

☆ Linux内核结构框图

这一部分内容十分重要,在后续的open函数实例讲解中会有大量的重复,主要是为了突出重要性和强化记忆过程

重点在于理解图的流程


用户态:

  • 是指用户编写程序、运行程序的层面,用户态在开发时需要C的基础和C库,C库讲到文件,进程,进程间通信,线程,网络。C库是linux标准库一定有,提供了程序支配内核干活的接口,C库中的各种API调用的是内核态,支配内核干活。

内核态:

  • 用户要使用某个硬件设备时,需要内核态的设备驱动程序,进而驱动硬件干活。

  • 在linux中一切皆文件,各种的文件和设备(比如:鼠标、键盘、屏幕)都是文件,那既然是文件了,就可以使用文件操作函数来操作这些设备。文件操作函数是如何知道打开的文件是哪一种硬件设备呢?

  • Linux的设备管理是和文件系统紧密结合的,各种设备都以文件的形式存放在/dev目录下,称为设备文件。为了管理这些设备,系统为设备编了号,每个设备号又分为主设备号和次设备号

  • 主设备号用来区分不同种类的设备,而次设备号用来区分同一类型的多个设备。 一个字符设备或者块设备都有一个主设备号和次设备号。主设备号和次设备号统称为设备号。主设备号用来表示一个特定的驱动程序。次设备号用来表示使用该驱动程序的各设备。


  • 驱动链表: 管理所有设备的驱动,添加或查找, 添加是发生在我们编写完驱动程序,加载到内核。查找是在调用驱动程序,由应用层用户空间去查找使用open函数。驱动插入链表的顺序由设备号检索,就是说主设备号和次设备号除了能区分不同种类的设备和不同类型的设备,主次设备号还能起到将驱动程序加载到链表的某个位置

综上所述:如果想要打开dev下面的pin4引脚,过程是:

  • 用户态调用open(“/de/pin4”,O_RDWR);

  • 对于内核来说,上层调用open函数会触发一个软中断(系统调用专用,中断号是0x80,0x80代表发生了一个系统调用),系统进入内核态,并走到system_call,可以认为这个就是此软中断的中断服务程序入口,然后通过传递过来的系统调用号来决定调用相应的系统调用服务程序(在这里是调用VFS中的sys_open

  • sys_open会在内核的驱动链表里面根据设备名和设备号查找到相关的驱动函数(每一个驱动函数是一个节点),驱动函数里面有通过寄存器操控IO口的代码,进而可以控制IO口实现相关功能。

  • 补充: system_call函数是怎么找到详细的系统调用服务例程的呢? 通过系统调用号查找系统调用表sys_call_table!软中断指令INT 0x80运行时,系统调用号会被放入 eax 寄存器中,system_call函数能够读取eax寄存器获取,然后将其乘以4,生成偏移地址,然后以sys_call_table为基址。基址加上偏移地址,就能够得到详细的系统调用服务例程的地址了!然后就到了系统调用服务例程了。

额外补充:

  1. 每个系统调用都对应一个系统调用号,而系统调用号就对应内核中的相应处理函数。

  2. 所有系统调用都是通过中断0x80来触发的。

  3. 使用系统调用时,通过eax 寄存器将系统调用号传递到内核,系统调用的入参通过ebx、ecx……依次传递到内核

  4. 和函数一样,系统调用的返回值保存在eax中,所有要从eax中取出

Linux系统架构

  • 最内层是硬件,最外层是用户应用,比如浏览器等等。硬件是物质基础,而应用提供服务。
  • 为了方便调用内核,Linux将内核的功能接口制作成系统调用(system call)。用户不需要了解内核的复杂结构,就可以使用内核。系统调用是操作系统的最小功能单位。一个操作系统,以及基于操作系统的应用,都不可能实现超越系统调用的功能。
  • 系统调用提供的功能非常基础,所以使用起来很麻烦。一个简单的给变量分配内存空间的操作,就需要动用多个系统调用。Linux定义一些库函数(library routine)来将系统调用组合成某些常用的功能。上面的分配内存的操作,可以定义成一个库函数,比如常用的malloc。

三、认识驱动

为什么学驱动

  • 以前树莓派开发使用厂家提供的wiringPi库,开发简单。
  • 但未来做开发时,不一定都是用树莓派,没有wiringPi库可以用。但只要能运行Linux,linux的标准C库一定有。
  • 学会根据标准C库编写驱动,只要能拿到linux内核源码,拿到芯片手册,电路图…就能做开发。

文件名与设备号

  nux一切皆为文件,其设备管理同样是和文件系统紧密结合。在目录/dev下都能看到鼠标,键盘,屏幕,串口等设备文件,硬件要有相对应的驱动,那么open怎样区分这些硬件呢?

依靠文件名与设备号

依靠文件名与设备号。在/devls -l可以看到


设备号又分为:

  • 主设备号用于区别不同种类的设备;
  • 次设备号区别同种类型的多个设备。
  • 驱动插入到链表的位置(顺序)由设备号检索

内核中存在一个内核驱动链表,管理所有设备的驱动。 驱动开发无非以下两件事:

  • 编写完驱动程序,加载到内核
  • 用户空间open后,调用驱动程序(驱动程序就是操作寄存器来驱动IO口,单片机51,32就是这种操作)

open函数过程实例详解

  open 函数是用户空间应用程序通过系统调用访问文件的入口。打通上层到底层硬件的过程涉及几个步骤,主要包括:

1. 用户空间调用: 应用程序在用户空间通过标准库函数 open 调用打开文件。该调用提供了文件路径和一些标志位参数。

int fd = open("/dev/video0", O_RDWR);

2. 系统调用: open 函数触发系统调用,导致应用程序从用户空间切换到内核空间(发生软中断)。在内核空间,调用处理程序开始执行。

3. 查找文件: 内核通过文件系统层次结构查找指定的文件。在这个例子中,是查找 /dev/video0 这个设备文件。

4. 获取文件对象: 找到文件后,内核会创建一个文件对象(file structure)来代表该文件。这个文件对象包含了一系列与文件相关的信息,例如文件的位置、访问模式、设备号等。

5. 权限检查: 内核会检查应用程序对文件的访问权限。如果应用程序没有足够的权限,open 将失败。

6. 分配文件描述符: 成功后,内核为应用程序分配一个文件描述符,这个描述符是一个整数,用于标识文件对象。应用程序将使用这个描述符进行后续的文件操作。

7. 调用文件操作函数: 对于设备文件,内核会调用相应的设备驱动程序中的文件操作函数。例如,open 操作可能触发设备驱动程序的 open 函数。

8. 设备操作: 设备驱动程序中的 open 函数执行与设备相关的初始化或其他必要的操作。这可能包括分配设备资源、配置硬件等。

9. 返回文件描述符: 如果所有步骤成功,open 系统调用返回文件描述符给应用程序,表示文件打开成功。

通过这个过程,open 函数从用户空间向内核发起请求,内核负责管理文件系统和与设备相关的硬件,最终建立起用户空间应用程序与底层硬件的连接。

用户空间调用open:

  • 用户空间调用open(比如open(“/dev/pin4”,O_RDWR))产生一个软中断(中断号是0x80),进入内核空间调用sys_call,这个sys_call在内核里面是汇编的,用Source Insight搜索不到。

  • sys_calll真正调用的是sys_open(属于VFS层虚拟文件系统,因为磁盘的分区和引脚分区不一样,为了实现上层统一化),根据你的设备名比如pin4去到内核的驱动链表根据其主设备号与次设备号找到相关驱动函数

  • 调用驱动函数里面的open,这个open就是对寄存器的操作,从而设置IO口引脚电平。这件事对于单片机来说特变容易,就两句话搞定

    sbit pin4 = P1^4;
    pin4 = 1;
    

    (对应下图的粉色笔迹)

四、shell

shell(壳)是一个特殊的应用,也经常被称为命 令行 。可以理解为是一个命令解释器

例如:当我们输入“ ls -l ”的时候,它将此字符串解释为:

  1. 在默认路径找到该文件(/bin/ls),
  2. 执行该文件,并附带参数"-l"。

一个shell对应一个终端 (terminal)。曾经来说,终端是一个硬件设备,用来输入并显示输出。如今,由于图形化界面的普及,终端往往就像下图一样,是一个图形化的窗口。


可以通过这个窗口输入或者输出文本,这个文本直接传递给shell进行分析解释,然后执行,本质就是提供和内核交互的程序。

shell脚本

  在没有图形界面之前,shell充当了用户的界面,当用户要运行某些应用时,通过shell输入命令,来运行程序。shell是可编程的,它可以执行符合shell语法的文本,这样的文本叫做shell脚本(script)

以下是一些关于 Shell 脚本的基本信息:

1. 脚本文件格式: Shell 脚本通常以 .sh 为扩展名,但这不是必须的。脚本文件的第一行通常包含指定 Shell 解释器的路径,例如 #!/bin/bash 表示使用 Bash 解释器执行脚本。

2. 权限设置: 在执行 Shell 脚本之前,需要为脚本文件添加执行权限。可以使用 chmod +x script.sh 命令为脚本添加执行权限。

3. 语法: Shell 脚本遵循 Shell 的语法规则,包括变量、条件语句、循环、函数等。常见的 Shell 脚本语言包括 Bash、sh、zsh 等。

4. 变量: 定义和使用变量,例如:

# 定义变量
name="xiaoming"

# 使用变量
echo "Hello $name!"

5. 选择语句:

# 定义变量
name="xiaoming"

# 条件语句
if [ "$name" == "xiaoming" ]; then
    echo "It's xiaoming"
else
    echo "It's not xiaoming"
fi

6. 循环:

# 循环
for i in {1..5}; do
    echo "Count: $i"
done

7. 函数:

# 定义函数
func(){
    echo "Hello from the function"
}

#调用函数
func

8. 命令替换: Shell 脚本支持使用反引号 或 $() 将命令的输出嵌入到脚本中。

# 命令替换
pwd_cmd=`pwd`
echo "current location: $pwd_cmd"

9. 输入输出重定向: 可以使用 <、>、>> 等运算符实现输入和输出的重定向。

# 输出重定向
echo "Hello, World!" > output.txt

# 输入重定向
cat < input.txt

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

理解Python闭包概念

闭包并不只是一个python中的概念&#xff0c;在函数式编程语言中应用较为广泛。理解python中的闭包一方面是能够正确的使用闭包&#xff0c;另一方面可以好好体会和思考闭包的设计思想。 1.概念介绍 首先看一下维基上对闭包的解释&#xff1a; 在计算机科学中&#xff0c;闭包…

【动态规划-分组背包】【hard】力扣2218. 从栈中取出 K 个硬币的最大面值和

一张桌子上总共有 n 个硬币 栈 。每个栈有 正整数 个带面值的硬币。 每一次操作中&#xff0c;你可以从任意一个栈的 顶部 取出 1 个硬币&#xff0c;从栈中移除它&#xff0c;并放入你的钱包里。 给你一个列表 piles &#xff0c;其中 piles[i] 是一个整数数组&#xff0c;分…

OpenEuler虚拟机安装保姆级教程 | 附可视化界面

0x00 系统介绍 在 2019 年 7 月 19 日&#xff0c;华为宣布要在年底正式开源 openEuler 操作系统&#xff1b;在半年后的 12 月 31 日&#xff0c;华为正式开源了 openEuler 操作系统&#xff0c;邀请社区开发者共同来贡献。 一年后&#xff0c;截止到 2020 年12 月 25日&…

注册中心Eureka

Eureka 文章目录 前言一、Eureka是什么&#xff1f;二、使用步骤1.搭建一个SpringCloud项目2.启动类上增加注解 EnableEurekaServer3.启动项目 访问 配置文件里定义的端口号4.启动成功访问 localhost:70005.以同样的方式创建子项目 eureka-client-xx 作为 服务客户端 然后向eur…

实用SQL小总结

WHERE 条件 column 为纯英文字符 或 不包含任何字符 语法&#xff1a; SELECT * FROM your_table WHERE REGEXP(your_column,^[A-Za-z]$); SELECT * FROM your_table WHERE NOT REGEXP(your_column,^[A-Za-z]$);例&#xff1a; SELECT DISTINCT t.pldlibho FROM kibb_pldlyw…

gRPC基础讲解

一、gRPC原理 1、什么是RPC RPC 即远程过程调用协议&#xff08;Remote Procedure Call Protocol&#xff09;&#xff0c;可以让我们像调用本地函数一样发起远程调用。RPC 凭借其强大的治理功能&#xff0c;成为解决分布式系统通信问题的一大利器。 gRPC是一个现代的、高性能…

电路学习——反激电源(2024.09.29)

参考链接1: XXX 在此感谢各位前辈大佬的总结&#xff0c;写这个只是为了记录学习大佬资料的过程&#xff0c;内容基本都是搬运的大佬博客&#xff0c;觉着有用自己搞过来自己记一下&#xff0c;如果有大佬觉着我搬过来不好&#xff0c;联系我删。 电路学习——反激电源&#xf…

基于大数据的高校新生数据可视化分析系统

作者&#xff1a;计算机学姐 开发技术&#xff1a;SpringBoot、SSM、Vue、MySQL、JSP、ElementUI、Python、小程序等&#xff0c;“文末源码”。 专栏推荐&#xff1a;前后端分离项目源码、SpringBoot项目源码、Vue项目源码、SSM项目源码、微信小程序源码 精品专栏&#xff1a;…

生信科研,教授(优青)团队一站式指导:高通量测序技术--农业植物基因组分析、组蛋白甲基化修饰、DNA亲和纯化测序、赖氨酸甲基化

组蛋白甲基化修饰工具(H3K4me3 ChIP-seq) 组蛋白甲基化类型也有很多种&#xff0c;包括赖氨酸甲基化位点H3K4、H3K9、H3K27、H3K36、H3K79和H4K20等。组蛋白H3第4位赖氨酸的甲基化修饰(H3K4)在进化上高度保守&#xff0c;是被研究最多的组蛋白修饰之一。 DNA亲和纯化测序 DNA亲…

QT设计中文输入法软键盘DLL给到C#开发步骤

开发目的&#xff1a;本文提供解决触摸屏C#程序中无法输入中文问题&#xff0c;中文拼音采用开源的谷歌输入法程序、使用QT编译中文输入法界面和中文输入法接口给到C#使用。 开发步骤&#xff1a; 1、QT中设计字母和字符输入界面 2、QT中设计数字输入界面 3、QT中封装调用谷歌…

神秘“蓝莓“模型横空出世:AI文生图界的新霸主还是营销噱头?

Ai 智能办公利器 - Ai-321.com AI文生图领域近日风起云涌&#xff0c;“蓝莓”模型横空出世&#xff0c;迅速占领行业制高点&#xff0c;成为万众瞩目的焦点。这个神秘而强大的模型&#xff0c;在众多AI竞技高手中脱颖而出&#xff0c;一举超越了OpenAI的“草莓”、Flux.1等强…

基于springboot+小程序的儿童预防接种预约管理系统(疫苗1)(源码+sql脚本+视频导入教程+文档)

&#x1f449;文末查看项目功能视频演示获取源码sql脚本视频导入教程视频 1、项目介绍 本儿童预防接种预约微信小程序可以实现管理员和用户。 1、管理员功能有个人中心&#xff0c;用户管理&#xff0c;儿童信息管理&#xff0c;疫苗信息管理&#xff0c;儿童接种管理&#x…

C++中的多态(详细讲解)

目录 一、多态的概念 1、多态的概念 二、多态的定义以及实现 1、多态的构成条件 2、虚函数 3、虚函数的重写 1&#xff09; 虚函数重写的理解 2&#xff09;虚函数重写的两个例外 1. 协变(基类与派生类虚函数返回值类型不同) 2. 析构函数的重写(基类与派生类析构函数的…

个人获取Wiley 、ScienceDirect、SpringerLink三个数据库文献的方法

在同学们的求助文献中经常出现Wiley 、ScienceDirect、SpringerLink这三个数据库文献。本文下面就讲解一下个人如何不用求助他人自己搞定这三个数据库文献下载的方法。 个人下载文献首先要先获取数据库资源&#xff0c;小编平时下载文献是通过科研工具——文献党下载器获取的数…

情感短视频素材上哪里找?推荐几个热门情感视频素材资源网站

抖音上热门的情感短视频都是怎么做的&#xff1f;情感视频素材都在哪里可以下载呢&#xff1f;作为一名资深的视频剪辑师&#xff0c;今天就跟大家聊聊那些可以下载情感素材高清无水印的网站&#xff0c;如果你也在苦苦找寻情感素材&#xff0c;快来看看吧&#xff5e; 1. 稻虎…

AI预测福彩3D采取888=3策略+和值012路或胆码测试9月28日新模型预测第101弹

经过100多期的测试&#xff0c;当然有很多彩友也一直在观察我每天发的预测结果&#xff0c;得到了一个非常有价值的信息&#xff0c;那就是9码定位的命中率非常高&#xff0c;100多期一共只错了12次&#xff0c;这给喜欢打私房菜的朋友提供了极高价值的预测结果~当然了&#xf…

黑神话热潮,能引发GPU狂欢的才是杀手级应用

黑神话与GPU技术的共舞&#xff1a;游戏推动硬件创新的新时代 ©作者|Steven 来源|神州问学 黑神话掀起游戏风暴 《黑神话&#xff1a;悟空》自上线以来&#xff0c;可谓是在游戏界掀起了一场前所未有的风暴。上线后就蝉联 Steam 热销榜首&#xff0c;晚间同时在线人数超…

打造自己的解析大模型:模型的安装与推理

RAG系统中要快速构建AI助理&#xff0c;首先要高效、准确地建立知识库&#xff0c;而实现这一点的关键便是具备一个功能强大的文档解析器。在上一篇中&#xff0c;我们介绍了PdfParser&#xff0c;本篇将深入讨论该解析器所依赖的模型&#xff0c;以及如何在Windows环境中安装并…

深度学习新手必备:Easy-PyTorch 助你轻松入门 PyTorch

深度学习初学者必备工具&#xff0c;简化代码编写&#xff0c;提升学习效率&#xff01; 对于刚入门深度学习的小伙伴&#xff0c;PyTorch 是一个强大的工具&#xff0c;但同时也伴随着大量复杂的代码和不小的学习曲线。你是否曾因为不知道如何快速实现模型而感到困惑&#xff…

4. 将pycharm本地项目同步到(Linux)服务器上——深度学习·科研实践·从0到1

目录 前序工作 1. 服务器项目名和本地一致 2. pycharm连接服务器 3. 本地项目对应到服务器项目 4. 简单测试一下同步效果 同步成功 前序工作 在同步到服务器之前&#xff0c;得确保已经完成以下几个前置步骤&#xff1a; 1. 租一个云服务器&#xff0c;可参考&#xff1a…