嵌入式,linux内存管理

简介: 所有段的基地址均为0,由此可以得出,每个段的逻辑地址空间范围为0-4GB。因为每个段的基地址为0,因此,逻辑地址与线性地址保持一致 linux页式管理有四级: 1. 页全局目录 (Page Global Directory):即pgd,是多级页表的抽象最高层。
所有段的基地址均为0,由此可以得出,每个段的逻辑地址空间范围为0-4GB。因为每个段的基地址为0,因此,逻辑地址与线性地址保持一致
linux页式管理有四级:
1. 页全局目录 (Page Global Directory):即pgd,是多级页表的抽象最高层。
2. 页上级目录(Page Upper Directory):即pud。
3. 页中间目录(Page Middle Directory):即pmd,是页表的中间层。
4. 页表(Page Table Entry):即 pte。
Linux操作系统采用 虚拟内存管理技术,使得每个进程都有独 立的进程地址空间,该空间是大小为3G,用户看到和接触的都是虚拟地址,无法看到实际的物理地址。利用这种虚拟地址不但能起到保护操作系统的作用,而且更重要的是用户程序可使用比实际物理内存更大的地址空间。
Linux将4G的虚拟地址空间划分为两个部分—— 用户空间与内核空间。用户空间从0到0xbfffffff,内核空间从3G到4G。用户进程通常情况下只能访问用户空间的虚拟地址,不能访问内核空间。例外情况是用户进程通过系统调用访问内核空间。
用户空间对应进程,所以每当进程切换,用户空间就会跟着变化。
每个进程的用户空间都是 完全独立、互不相干的。把同一个程序同时运行10次(为了能同时运行,让它们在返回前睡眠100秒),会看到10个进程使用的线性地址一模一样。cat /proc//maps
创建进程fork()、程序载入execve()、动态内存分配malloc()等进程相关操作都需要分配内存给进程。这时进程申请和获得的不是物理地址,仅仅是虚拟地址。
实际的物理内存只有当进程真的去访问新获取的虚拟地址时,才会由“请页机制” 产生“缺页”异常,从而进入分配实际页框的程序。该异常是虚拟内存机制赖以存在的基本保证—它会告诉内核去为进程分配物理页,并建立对应的页表,这之后虚拟地址才实实在在地映射到了物理地址上。

在应用程序中,常使用malloc函数进行动态内存分配,而在Linux内核中,通常使用kmalloc来动态分配内存。kmalloc
原型是:
           #include
           void *kmalloc(size_t size, int flags)
           参数:
                           size:要分配的内存大小。
                           flags:分配标志, 它控制 kmalloc 的行为。
           分配标志
                           GFP_ATOMIC         用来在进程上下文之外的代码(包括中断处理)中分配内存,从不睡眠。
                           GFP_KERNEL         进程上下文中的分配。可能睡眠。(16M-896M)
                           __GFP_DMA           这个标志要求分配能够 DMA 的内存区(物理地址在16M以下的页帧 )
                           __GFP_HIGHMEM   这个标志表示分配的内存位于高端内存。(896M以上)
最常用的标志是 GFP_KERNEL,它的意思是该内存分配是由运行在内核态的进程调用的。也就是说,调用它的函数属于某个进程的,
当空闲内存太少时,kmalloc函数会使当前进程进入睡眠,等待空闲页的出现。
如果kmalloc是在进程上下文之外调用,比如在 中断处理,任务队列处理和内核定时器处理中。这些情况属于中断上下文,不能进入睡眠,这时应该使用优先权GFP_ATOMIC。

如果模块需要分配大块的内存,那使用面向页的分配技术会更好
get_zeroed_page(unsigned int flags)                 返回指向新页面的指针,并将页面清零。
 __get_free_page(unsigned int flags)                 和get_free_page类似,但不清零页面。
 __get_free_pages(unsigned int flags,unsigned int order )分配若干个连续的页面,返回指向该内存区域的指针,但也不清零这段内存区域。
当程序用完这些页, 可以使用下列函数之一来释放它们:
void free_page(unsigned long addr)
void free_pages(unsigned long addr, unsigned long order)

内核空间是由内核负责映射,它并不会跟着进程改变,是固定的。
物理内存896MB以上的部分称之
高端内存。
从3G开始,最大896M的线性地址区间,我们称作直接
内存映射区,这是因为该区域的线性地址和物理地址之
间存在线性转换关系
                  线性地址=3G + 物理地址
动态内存映射区
(Vmalloc Region)
该区域的地址由内核函数vmalloc来进行分
配,其特点是线性空间连续,但对应的物理空
间不一定连续。vmalloc分配的线性地址所对
应的物理页可能处于低端内存,也可能处于高
端内存。

对于896MB以上的高端内存,可使用该区域来访
问,访问方法:
      1. 使用alloc_page(__GFP_HIGHMEM)分配高端
内存页
      2. 使用kmap函数将分配到的高端内存映射到该区
固定映射区
(Fixing Mapping Region)
PKMap区上面,有4M的线性空间,被称
作固定映射区,它和4G顶端只有4K的隔
离带。固定映射区中每个地址项都服务
于特定的用途,如ACPI_BASE等
相关文章
|
24天前
|
监控 Linux
如何检查 Linux 内存使用量是否耗尽?这 5 个命令堪称绝了!
本文介绍了在Linux系统中检查内存使用情况的5个常用命令:`free`、`top`、`vmstat`、`pidstat` 和 `/proc/meminfo` 文件,帮助用户准确监控内存状态,确保系统稳定运行。
150 6
|
3月前
|
安全 Linux Shell
Linux上执行内存中的脚本和程序
【9月更文挑战第3天】在 Linux 系统中,可以通过多种方式执行内存中的脚本和程序:一是使用 `eval` 命令直接执行内存中的脚本内容;二是利用管道将脚本内容传递给 `bash` 解释器执行;三是将编译好的程序复制到 `/dev/shm` 并执行。这些方法虽便捷,但也需谨慎操作以避免安全风险。
202 6
|
22天前
|
缓存 Java Linux
如何解决 Linux 系统中内存使用量耗尽的问题?
如何解决 Linux 系统中内存使用量耗尽的问题?
107 48
|
6天前
|
算法 Linux
深入探索Linux内核的内存管理机制
本文旨在为读者提供对Linux操作系统内核中内存管理机制的深入理解。通过探讨Linux内核如何高效地分配、回收和优化内存资源,我们揭示了这一复杂系统背后的原理及其对系统性能的影响。不同于常规的摘要,本文将直接进入主题,不包含背景信息或研究目的等标准部分,而是专注于技术细节和实际操作。
|
19天前
|
缓存 Ubuntu Linux
Linux环境下测试服务器的DDR5内存性能
通过使用 `memtester`和 `sysbench`等工具,可以有效地测试Linux环境下服务器的DDR5内存性能。这些工具不仅可以评估内存的读写速度,还可以检测内存中的潜在问题,帮助确保系统的稳定性和性能。通过合理配置和使用这些工具,系统管理员可以深入了解服务器内存的性能状况,为系统优化提供数据支持。
27 4
|
22天前
|
Linux
如何在 Linux 系统中查看进程占用的内存?
如何在 Linux 系统中查看进程占用的内存?
|
22天前
|
缓存 Linux
如何检查 Linux 内存使用量是否耗尽?
何检查 Linux 内存使用量是否耗尽?
|
1月前
|
算法 Linux 开发者
深入探究Linux内核中的内存管理机制
本文旨在对Linux操作系统的内存管理机制进行深入分析,探讨其如何通过高效的内存分配和回收策略来优化系统性能。文章将详细介绍Linux内核中内存管理的关键技术点,包括物理内存与虚拟内存的映射、页面置换算法、以及内存碎片的处理方法等。通过对这些技术点的解析,本文旨在为读者提供一个清晰的Linux内存管理框架,帮助理解其在现代计算环境中的重要性和应用。
|
14天前
|
存储 算法 安全
深入理解Linux内核的内存管理机制
本文旨在深入探讨Linux操作系统内核的内存管理机制,包括其设计理念、实现方式以及优化策略。通过详细分析Linux内核如何处理物理内存和虚拟内存,揭示了其在高效利用系统资源方面的卓越性能。文章还讨论了内存管理中的关键概念如分页、交换空间和内存映射等,并解释了这些机制如何协同工作以提供稳定可靠的内存服务。此外,本文也探讨了最新的Linux版本中引入的一些内存管理改进,以及它们对系统性能的影响。
|
1月前
|
存储 缓存 监控