嵌入式学习-驱动开发前奏-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

相关文章

Spring Boot集成/输出/日志级别控制/持久化开发实践

《SpringBoot集成/输出/日志级别控制/持久化开发实践》SpringBoot默认集成Logback,支持灵活日志级别配置(INFO/DEBUG等),输出包含时间戳、级别、类名等信息,并可通过... 目录一、日志概述1.1、Spring Boot日志简介1.2、日志框架与默认配置1.3、日志的核心作用

MySQL 内存使用率常用分析语句

《MySQL内存使用率常用分析语句》用户整理了MySQL内存占用过高的分析方法,涵盖操作系统层确认及数据库层bufferpool、内存模块差值、线程状态、performance_schema性能数据... 目录一、 OS层二、 DB层1. 全局情况2. 内存占js用详情最近连续遇到mysql内存占用过高导致

最新Spring Security的基于内存用户认证方式

《最新SpringSecurity的基于内存用户认证方式》本文讲解SpringSecurity内存认证配置,适用于开发、测试等场景,通过代码创建用户及权限管理,支持密码加密,虽简单但不持久化,生产环... 目录1. 前言2. 因何选择内存认证?3. 基础配置实战❶ 创建Spring Security配置文件

PyQt5 GUI 开发的基础知识

《PyQt5GUI开发的基础知识》Qt是一个跨平台的C++图形用户界面开发框架,支持GUI和非GUI程序开发,本文介绍了使用PyQt5进行界面开发的基础知识,包括创建简单窗口、常用控件、窗口属性设... 目录简介第一个PyQt程序最常用的三个功能模块控件QPushButton(按钮)控件QLable(纯文本

在macOS上安装jenv管理JDK版本的详细步骤

《在macOS上安装jenv管理JDK版本的详细步骤》jEnv是一个命令行工具,正如它的官网所宣称的那样,它是来让你忘记怎么配置JAVA_HOME环境变量的神队友,:本文主要介绍在macOS上安装... 目录前言安装 jenv添加 JDK 版本到 jenv切换 JDK 版本总结前言China编程在开发 Java

Spring Boot Actuator应用监控与管理的详细步骤

《SpringBootActuator应用监控与管理的详细步骤》SpringBootActuator是SpringBoot的监控工具,提供健康检查、性能指标、日志管理等核心功能,支持自定义和扩展端... 目录一、 Spring Boot Actuator 概述二、 集成 Spring Boot Actuat

MySQL多实例管理如何在一台主机上运行多个mysql

《MySQL多实例管理如何在一台主机上运行多个mysql》文章详解了在Linux主机上通过二进制方式安装MySQL多实例的步骤,涵盖端口配置、数据目录准备、初始化与启动流程,以及排错方法,适用于构建读... 目录一、什么是mysql多实例二、二进制方式安装MySQL1.获取二进制代码包2.安装基础依赖3.清

java内存泄漏排查过程及解决

《java内存泄漏排查过程及解决》公司某服务内存持续增长,疑似内存泄漏,未触发OOM,排查方法包括检查JVM配置、分析GC执行状态、导出堆内存快照并用IDEAProfiler工具定位大对象及代码... 目录内存泄漏内存问题排查1.查看JVM内存配置2.分析gc是否正常执行3.导出 dump 各种工具分析4.

Linux之platform平台设备驱动详解

《Linux之platform平台设备驱动详解》Linux设备驱动模型中,Platform总线作为虚拟总线统一管理无物理总线依赖的嵌入式设备,通过platform_driver和platform_de... 目录platform驱动注册platform设备注册设备树Platform驱动和设备的关系总结在 l

一文解密Python进行监控进程的黑科技

《一文解密Python进行监控进程的黑科技》在计算机系统管理和应用性能优化中,监控进程的CPU、内存和IO使用率是非常重要的任务,下面我们就来讲讲如何Python写一个简单使用的监控进程的工具吧... 目录准备工作监控CPU使用率监控内存使用率监控IO使用率小工具代码整合在计算机系统管理和应用性能优化中,监