嵌入式学习-驱动开发前奏-lesson2-内存管理与进程管理子系统

本文主要是介绍嵌入式学习-驱动开发前奏-lesson2-内存管理与进程管理子系统,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

内存管理子系统

在内核相关一课中,已经介绍过,linux内核一共有7个子系统:
1.SCI
2.Pm
3.MM
4.Arch
5.Vfs
6.Network stack
7.DD

在以后的驱动学习章节中,主要是与 MM PM VFS 这三个相关。
在本章节中则主要讲解MM(内存管理子系统)

1)内存管理模型

这里写图片描述
根据上面的图,可以得知,内存的管理主要是做两个方面的工作:
1:物理内存分配
2:虚拟地址与物理地址的映射

2)地址的映射

这里写图片描述
上面这幅图是地址空间映射图,将其分为三个部分:
1:虚拟地址空间分布
2:虚拟地址转化为物理地址
3:物理内存分配

1.虚拟地址空间分布

根据上图可知,4G的虚拟地址空间又可分为3G的用户空间和1G的内核空间。

1G的内核空间又可分为4部分:
①、直接映射区,最大空间为896MB (896MB以下的内存称之为低端内存,以上则称之为高端内存) 然后减去3G 就可以直接得到物理地址
②、vmalloc区(既可以访问低端区域,也可以访问高端区域)
③、永久内核映射(固定访问高端内存)
④、固定映射的线性地址(和一些特殊的寄存器有关)

2.虚拟地址向物理地址转化

主要是上图第二部分完成的,将其简化为下图
这里写图片描述

具体过程:
1.cr3基地址加上虚拟地址的22–32位指向页目录的某一个地址(cr3指向页目录的基地址)
2.指向页目录的那个地址又指向页表的基地址,然后该地址加上虚拟地址的12–21位指向页表的某一个地址,也就是物理页的基地址
3.物理页的基地址加上虚拟地址的0–11,就得到物理存储单元的地址

3.物理内存的分配

这里写图片描述
linux使用虚拟地址管理方式,只有真正访问物理地址,才分配物理内存

上图,当使用malloc或者vmalloc时,会分配一个虚拟地址,并没有真正访问到物理内存,当需要使用物理内存的时候,会产生一个 请页异常 然后从 空闲页框 中 ,查看是否有空闲的物理内存,当有空闲的时候,机会分配一个物理内存,从而建立起访问关系。
但是当使用kmalloc的时候,slab管理器会直接将虚拟地址和物理地址建立关系。

进程管理子系统

一、进程相关概念

1)进程与程序

程序
存放在磁盘上的一系列代码和数据的可执行映像,是一个静止的实体
进程
是一个执行中的程序,它是动态的实体

2)进程四要素

  1. 有一段程序供其执行。这段程序不一定是某个进程所专有,可以与其他进程共用。
  2. 有进程专用的内核空间堆栈。
  3. 在内核中有一个task_struct数据结构,即通常所说的“进程控制块(pcb)”。有了这个数据结构,进程才能成为内核调度的一个基本单位接受内核的调度。
  4. 有独立的用户空间。
    这里写图片描述

3) Linux进程状态

这里写图片描述

linux进程的状态可以将其范围上面三个部分,就绪、执行、阻塞。这是一种典型的三态图,将其进一步细分,
这里写图片描述

1.TASK_RUNNING(就绪、执行)
进程正在被CPU执行,或者已经准备就绪,随时可以执行。当一个进程刚被创建时,就处于TASK_RUNNING状态。
2.TASK_INTERRUPTIBLE(属于三态中的阻塞态)
处于等待中的进程,待等待条件为真时被唤醒,也可以被信号或者中断唤醒。
3. TASK_UNINTERRUPTIBLE
处于等待中的进程,待资源有效时唤醒,但不可以由其它进程通过信号(signal)或中断唤醒。
4. TASK_KILLABLE
Linux2.6.25新引入的进程睡眠状态,原理类似于TASK_UNINTERRUPTIBLE,但是可以被致命信号(SIGKILL)唤醒。
5. TASK_TRACED
正处于被调试状态的进程。
6. TASK_DEAD
进程退出时(调用do_exit),所处的状态。

4) Linux进程描述

在Linux内核代码中,线程、进程都使用结构task_struct(sched.h)来表示,它包含了大量描述进程/线程的信息,其中比较重要的有:
pid_t pid; //进程号
long state; //进程状态
int prio; //进程优先级

在内核源代码sched.h中有关于此结构体的详细描述

二、进程调度

所谓的进程调度就是从就绪的进程中选出最适合的一个来执行。
主要分为:
1、调度策略
2、调度时机
3、调度步骤

1) 调度策略

SCHED_NORMAL(SCHED_OTHER):普通的分时进程
SCHED_FIFO :先入先出的实时进程
SCHED_RR:时间片轮转的实时进程(间隔一定时间,不管是否执行完,换下一个进程运行同样的时间)
SCHED_BATCH:批处理进程
SCHED_IDLE: 只在系统空闲时才能够被调度执行的进程

2 )调度时机

什么时候发生调度?
即schedule()函数什么时候被调用?
schedule()函数在linux内核中完成调度过程

1主动式调度

在内核中直接调用schedule()。当进程需要等待资源等而暂时停止运行时,会把自己的状态置于挂起(睡眠),并主动请求调度,让出CPU。
范例:
1. current->state = TASK_INTERRUPTIBLE; (处于阻塞态)
2. schedule();

2被动式调度

被动式调度又名:抢占式调度。分为:用户态抢占(Linux2.4、Linux2.6)和内核态抢占(Linux2.6)。

2.1用户态抢占
用户抢占发生在:
从系统调用返回用户空间。
从中断处理程序返回用户空间。
内核即将返回用户空间的时候,如果need_resched标志被设置,会导致schedule()被调用,即发生用户抢占。
**当某个进程耗尽它的时间片时,会设置need_resched标志
**当一个优先级更高的进程进入可执行状态的时候,也会设置need_resched标志。

2.2内核态抢占
用户态抢占缺陷
进程/线程一旦运行到内核态,就可以一直执行,直到它主动放弃或时间片耗尽为止。这样会导致一些非常紧急的进程或线程将长时间得不到运行,降低整个系统的实时性。

改进方式
允许系统在内核态也支持抢占,更高优先级的进程/线程可以抢占正在内核态运行的低优先级进程/线程。

内核抢占可能发生在:
**中断处理程序完成,返回内核空间之前。
**当内核代码再一次具有可抢占性的时候,如解锁及使能软中断等。

在支持内核抢占的系统中,某些特例下是不允许抢占的:
** 内核正在运行中断处理。
** 内核正在进行中断上下文的Bottom Half(中断的底半部)处理。硬件中断返回前会执行软中断,此时仍然处于中断上下文中。
** 进程正持有spinlock自旋锁、writelock/readlock读写锁等,当持有这些锁时,不应该被抢占,否则由于抢占将可能导致其他进程长期得不到锁,而让系统处于死锁状态。
** 内核正在执行调度程序Scheduler。抢占的原因就是为了进行新的调度,没有理由将调度程序抢占掉再运行调度程序。

2.3 抢占计数
为保证Linux内核在以上情况下不会被抢占,抢占式内核使用了一个变量preempt_count,称为内核抢占计数。这一变量被设置在进程的thread_info结构中。每当内核要进入以上几种状态时,变量preempt_count就加1,指示内核不允许抢占。每当内核从以上几种状态退出时,变量preempt_count就减1,同时进行可抢占的判断与调度。

3) 调度步骤

Schedule函数工作流程如下:
1. 清理当前运行中的进程;
2. 选择下一个要运行的进程;
3. 设置新进程的运行环境;
4. 进程上下文切换 。

菜鸟一枚,如有错误,多多指教。。。

这篇关于嵌入式学习-驱动开发前奏-lesson2-内存管理与进程管理子系统的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1007134

相关文章

Java内存泄漏问题的排查、优化与最佳实践

《Java内存泄漏问题的排查、优化与最佳实践》在Java开发中,内存泄漏是一个常见且令人头疼的问题,内存泄漏指的是程序在运行过程中,已经不再使用的对象没有被及时释放,从而导致内存占用不断增加,最终... 目录引言1. 什么是内存泄漏?常见的内存泄漏情况2. 如何排查 Java 中的内存泄漏?2.1 使用 J

基于Python开发电脑定时关机工具

《基于Python开发电脑定时关机工具》这篇文章主要为大家详细介绍了如何基于Python开发一个电脑定时关机工具,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录1. 简介2. 运行效果3. 相关源码1. 简介这个程序就像一个“忠实的管家”,帮你按时关掉电脑,而且全程不需要你多做

高效管理你的Linux系统: Debian操作系统常用命令指南

《高效管理你的Linux系统:Debian操作系统常用命令指南》在Debian操作系统中,了解和掌握常用命令对于提高工作效率和系统管理至关重要,本文将详细介绍Debian的常用命令,帮助读者更好地使... Debian是一个流行的linux发行版,它以其稳定性、强大的软件包管理和丰富的社区资源而闻名。在使用

Java中的Opencv简介与开发环境部署方法

《Java中的Opencv简介与开发环境部署方法》OpenCV是一个开源的计算机视觉和图像处理库,提供了丰富的图像处理算法和工具,它支持多种图像处理和计算机视觉算法,可以用于物体识别与跟踪、图像分割与... 目录1.Opencv简介Opencv的应用2.Java使用OpenCV进行图像操作opencv安装j

python多进程实现数据共享的示例代码

《python多进程实现数据共享的示例代码》本文介绍了Python中多进程实现数据共享的方法,包括使用multiprocessing模块和manager模块这两种方法,具有一定的参考价值,感兴趣的可以... 目录背景进程、进程创建进程间通信 进程间共享数据共享list实践背景 安卓ui自动化框架,使用的是

基于Qt开发一个简单的OFD阅读器

《基于Qt开发一个简单的OFD阅读器》这篇文章主要为大家详细介绍了如何使用Qt框架开发一个功能强大且性能优异的OFD阅读器,文中的示例代码讲解详细,有需要的小伙伴可以参考一下... 目录摘要引言一、OFD文件格式解析二、文档结构解析三、页面渲染四、用户交互五、性能优化六、示例代码七、未来发展方向八、结论摘要

关于Java内存访问重排序的研究

《关于Java内存访问重排序的研究》文章主要介绍了重排序现象及其在多线程编程中的影响,包括内存可见性问题和Java内存模型中对重排序的规则... 目录什么是重排序重排序图解重排序实验as-if-serial语义内存访问重排序与内存可见性内存访问重排序与Java内存模型重排序示意表内存屏障内存屏障示意表Int

SpringBoot使用minio进行文件管理的流程步骤

《SpringBoot使用minio进行文件管理的流程步骤》MinIO是一个高性能的对象存储系统,兼容AmazonS3API,该软件设计用于处理非结构化数据,如图片、视频、日志文件以及备份数据等,本文... 目录一、拉取minio镜像二、创建配置文件和上传文件的目录三、启动容器四、浏览器登录 minio五、

如何测试计算机的内存是否存在问题? 判断电脑内存故障的多种方法

《如何测试计算机的内存是否存在问题?判断电脑内存故障的多种方法》内存是电脑中非常重要的组件之一,如果内存出现故障,可能会导致电脑出现各种问题,如蓝屏、死机、程序崩溃等,如何判断内存是否出现故障呢?下... 如果你的电脑是崩溃、冻结还是不稳定,那么它的内存可能有问题。要进行检查,你可以使用Windows 11

在 VSCode 中配置 C++ 开发环境的详细教程

《在VSCode中配置C++开发环境的详细教程》本文详细介绍了如何在VisualStudioCode(VSCode)中配置C++开发环境,包括安装必要的工具、配置编译器、设置调试环境等步骤,通... 目录如何在 VSCode 中配置 C++ 开发环境:详细教程1. 什么是 VSCode?2. 安装 VSCo