嵌入式
返回首页

2026-04-15 来源:EEWorld 论坛

# 内存的虚与实 在学习《计算机操作系统》课时,谈到在操作系统下,各个程序都是认为自己是系统的全部,即独享着系统全部资源。这样的好处十分明显:程序开发的时候并不需要关心其它程序,更不用关心其它程序对硬件资源的占用。与此作对比,在嵌入式系统MCU上进行开发时,则必须要考虑其它进程的情况。否则,要么饿死别人,要么被别人饿死。而两者的区分也非常简单,即看硬件资源有无MMU模块。今天给大家带来的分享是内存管理中的虚与实。也就是MMU与Linux Kernel如何管理内存的策略。 在64位系统中,低地址空间256TB范围为用户空间,高256TB范围为内核空间。Linux操作系统对于不同应用程序分配相同的用户空间地址,而自己的内核空间则独占式管理。 ## **地址空间分布** 上面所说,各个程序分配了相同的地址空间,这也“欺骗”了应用程序,让其认为一直在运行。对于物理内存来说,同一个地址肯定不会存放着两个程序所需要使用的数据。这个很现实,那么前面从应用程序看到的地址就是虚拟内存地址,由MMU提供。真实的内存物理地址则由系统与MMU共同管理,对应用程序无感。换句话说,应用程序0看到的0x20000000的内容与应用程序1看到的0x20000000的内容不同,两者虽然“内存地址”相同,但物理内存地址并不同,其内容不同也就不难理解了。 我们再来看一下ARM64的地址空间分布: 再来细化一下用户空间地址: ## **内存申请函数** 接合实际开发应用,我们再看一下程序中常用的四个内存空间申请接口函数:kmalloc(), vmalloc(), malloc(), mmap()。 先说一下四个函数的相同点:都是用来申请一段内存。而不同点就是申请下来的这段内存所在的地址空间位置,地址是否物理连续了。我们分开来具体说明一下: - kmalloc()函数。kmalloc()用于在内核空间中分配一定数量的物理连续页。注意它分配出来的内存是连续的物理内存,这一点有别于下面要说的vmalloc()。 - vmalloc()函数。其也是在Linux 内核中的分配大块内存,与 kmalloc() 不同,vmalloc() 通常用于需要连续内存但不需要物理连续性的场景。它分配的内存区域是通过页表映射到内核的虚拟地址空间的。这意味着这些区域可以使用内核的任何虚拟地址,包括直接映射的区域和高端内存区域。 - malloc()函数。它是C语言的标准库函数,用于在堆区动态分配内存。注意:它是在用户空间中使用的,而不是内核空间。 - mmap()函数。它是一种内存映射文件的方法。允许一个进程将一个文件或者其他对象映射进内存。一旦一个文件被映射,进程就可以像访问内存一样访问该文件。mmap() 用于实现共享内存,这对于多进程间通信和数据共享非常有用,同时,内核空间对这段区域的修改也直接反映用户空间,从而可以实现不同进程间的文件共享。 下面这和图片展示了mmap()的映射关系。 ## **总结** 内存的知识,内存管理的知识十分宏大。短短几天的阅读,坦白讲,也只是了解了一个皮毛,知道其应用的场景,而要明白其背后的策略,设计的目的,解决的问题则需要更多的时间,结合实际应用来不断的提出问题,不断的理解。 不过,通过本章的总结,我发现,其实malloc()函数调用返回的内存地址已经是对齐了~~ 虚虚实实,各自发挥着各自的作用,在操作系统中相得益彰。充分利用它们各自的优点,让我们的程序性能优异,稳定可靠。

原帖子内容来源:https://bbs.eeworld.com.cn/thread-1270861-1-1.html



进入嵌入式查看更多内容>>
相关视频
  • 【TI MSPM0 应用实战】智能小车+工业角度编码器+血氧仪+烟雾探测器!硬核参考设计详解!

  • FollowMe 第二季:3 - EK_RA6M5 开发板入门

  • FollowMe 第二季: 1 Adafruit Circuit Playground Express及任务讲解

  • Azure RTOS step by step workshop

  • 2022 Digi-Key KOL 系列: 你见过1GHz主频的单片机吗?Teensy 4.1开发板介绍

  • 从0到1:树莓派与物联网教程(英文)

精选电路图
  • TDA2050立体声音频功率放大器

  • 点动计时器

  • 1千赫正弦波发生器

  • 三极管的工作原理详解

  • 可穿戴生物传感器的线性充电器的方案

  • 如何克服汽车前端设计挑战