tag 标签: MMU

相关帖子
相关博文
  • 热度 4
    2023-10-12 08:22
    1695 次阅读|
    0 个评论
    Linux内存管理 | 二、虚拟地址空间布局 上一章,我们了解了内存管理的由来以及核心思想,下面我们按照顺序,先来介绍一下Linux虚拟内存空间的管理。 同样,我们知道Linux内核抽象出来虚拟内存空间,主要是为了让每个进程都独享该空间,那虚拟内存空间是如何布局的呢? 前提 :针对于不同位数的CPU,寻址能力不同,抽象出来的虚拟内存空间大小也不同,我们以常见的32位的CPU为例。 1、虚拟内存空间布局 对于32位的CPU,寻址范围为0~2^32,也就是0x00000000-0xFFFFFFFF,即最多抽象出来4G的虚拟内存空间。 这4GB的内存空间,在Linux中,又分为 用户空间和内核空间 ,其中0x0000000-0xBFFFFFFF,共3G为用户空间,0xC00000000-0xFFFFFFFF,共1G为内核空间,如下: image-20230924173124939 无论内核空间还是用户空间,其仍然是在虚拟内存空间基础之上进行划分的,其直接访问的依旧都是虚拟地址,而非物理地址! 我们编写代码后,所生成的可执行程序,运行之后就成为一个系统进程,我们在"虚"的角度来看,每个进程都是独享这4G虚拟地址空间的, 2、用户态空间布局 如上所述,用户空间在虚拟内存中分布在0x0000000-0xBFFFFFFF,大小为3G。 每一个用户进程,按照 访问属性一致的地址空间存放在一起 的原则,划分成5个不同的内存区域(访问属性一致指的是:可读,可写,可执行): 代码段 :Text Segment,也就是我们的二进制程序,代码段需要防止在运行时被非法修改, 所以该段为只读 。 数据段 :Data Segment,主要存放初始化了的变量,主要包括:静态变量和全局变量, 该段为读写 。 BSS段 :BSS Segment,主要存放未初始化的全局变量,在内存中 bss 段全部置零, 该段为读写 。 堆段 :Heap Segment,主要存放进程运行过程中动态分配的内存段,大小不固定,可动态扩张和缩减,通常使用malloc和free来分配释放,并且堆的增长方向是向上的。 文件映射和匿名映射段 :Memory Mapping Segment,主要存放进程使用到的文件或者依赖的动态库,从低地址向上增长。 栈段 :Stack Segment,主要存放进程临时创建的局部变量,函数调用上下文信息等,栈向下增长。 image-20231005160139650 一个可执行程序,可以通过size命令,查看编译出来的可执行文件大小,其中包括了代码段,数据段等数据信息,如下: donge@Donge:$sizeDonge-Demo textdatabssdechexfilename 1253819164363258086e2e6Donge-Demo text:代码段大小 data:数据段大小 bss:bss段大小 dec:十进制表示的可执行文件大小 hex:十六进制表示的可执行文件大小 运行该程序后,可以通过cat /proc/PID/maps命令,或者pmap PID命令,来查看该进程在虚拟内存空间中的分配情况,其中PID为进程的PID号,如下: donge@Donge:$cat/proc/16508/maps 55976ff9e000-55976ffa0000r--p0000000008:10184922/home/donge/WorkSpace/Program/Donge_Programs/Donge_Demo/build/Donge-Demo 55976ffa0000-55976ffa2000r-xp0000200008:10184922/home/donge/WorkSpace/Program/Donge_Programs/Donge_Demo/build/Donge-Demo 55976ffa2000-55976ffa3000r--p0000400008:10184922/home/donge/WorkSpace/Program/Donge_Programs/Donge_Demo/build/Donge-Demo 55976ffa3000-55976ffa4000r--p0000400008:10184922/home/donge/WorkSpace/Program/Donge_Programs/Donge_Demo/build/Donge-Demo 55976ffa4000-55976ffa5000rw-p0000500008:10184922/home/donge/WorkSpace/Program/Donge_Programs/Donge_Demo/build/Donge-Demo 55976ffa5000-55976ffaf000rw-p0000000000:000 559771d91000-559771db2000rw-p0000000000:000 7fec1ad84000-7fec1ad87000rw-p0000000000:000 7fec1ad87000-7fec1adaf000r--p0000000008:1022282/usr/lib/x86_64-linux-gnu/libc.so.6 7fec1adaf000-7fec1af44000r-xp0002800008:1022282/usr/lib/x86_64-linux-gnu/libc.so.6 7fec1af44000-7fec1af9c000r--p001bd00008:1022282/usr/lib/x86_64-linux-gnu/libc.so.6 7fec1af9c000-7fec1afa0000r--p0021400008:1022282/usr/lib/x86_64-linux-gnu/libc.so.6 7fec1afa0000-7fec1afa2000rw-p0021800008:1022282/usr/lib/x86_64-linux-gnu/libc.so.6 7fec1afa2000-7fec1afaf000rw-p0000000000:000 7fec1afb5000-7fec1afb7000rw-p0000000000:000 7fec1afb7000-7fec1afb9000r--p0000000008:1022068/usr/lib/x86_64-linux-gnu/ld-linux-x86-64.so.2 7fec1afb9000-7fec1afe3000r-xp0000200008:1022068/usr/lib/x86_64-linux-gnu/ld-linux-x86-64.so.2 7fec1afe3000-7fec1afee000r--p0002c00008:1022068/usr/lib/x86_64-linux-gnu/ld-linux-x86-64.so.2 7fec1afef000-7fec1aff1000r--p0003700008:1022068/usr/lib/x86_64-linux-gnu/ld-linux-x86-64.so.2 7fec1aff1000-7fec1aff3000rw-p0003900008:1022068/usr/lib/x86_64-linux-gnu/ld-linux-x86-64.so.2 7ffce385d000-7ffce387e000rw-p0000000000:000 7ffce394e000-7ffce3952000r--p0000000000:000 7ffce3952000-7ffce3953000r-xp0000000000:000 上面能大致看出该进程的代码段、堆、文件映射段,栈的内存分布等情况,以上就是我们的可执行程序被加载进入内存之后,在用户态虚拟内存空间的布局情况。 顺便介绍一下 我的圈子: 高级工程师聚集地 ,期待大家的加入。 3、内核态空间布局 下面我们来看一下内核态的虚拟空间布局,首先我们要知道: 在Linux系统中,用户进程通常只能访问用户空间的虚拟地址,只有在执行内陷操作或系统调用时才能访问内核空间。 所有的进程通过系统调用进入内核态之后,看到的虚拟地址空间都是一样的,他们是共享内核态虚拟内存空间的。 32位的内核态虚拟空间在虚拟内存中分布在0xC00000000-0xFFFFFFFF上,大小为1G,其要分为以下几个区 : 直接映射区(Direct Memory Region) :顾名思义,直接映射区就是直接与物理内存建立一一映射关系。从内核空间起始地址开始,到896M的内核空间地址区间,为直接内存映射区,该区域线性地址和分配的物理地址都是连续的。 896M以上的内核地址空间,又称为高端内存区域。 安全保护区 :也成为内存空洞,大小为8M,其主要目的是为了避免 非连续区的非法访问, 动态映射区 :也就是vmalloc Region,该区域由Vmalloc函数分配,特点是:虚拟地址空间连续,但是物理地址空间不一定连续。 永久映射区(Persistent Kernel Mapping Region) :该区域主要用于访问高端内存,通过alloc_page (_GFP_HIGHMEM)接口分配高端内存页,可以使用kmap函数将分配到的高端内存映射到该区域。 固定映射区(Fixing kernel Mapping Region) :该区域虚拟内存地址可以自由映射到物理内存的高端地址上,“固定”表现在“虚拟内存空间地址是固定的”,被映射的物理地址是可变的。 为什么会有固定映射这个概念呢 ? 比如:在内核的启动过程中,有些模块需要使用虚拟内存并映射到指定的物理地址上,而且这些模块也没有办法等待完整的内存管理模块初始化之后再进行地址映射。因此,内核固定分配了一些虚拟地址,这些地址有固定的用途,使用该地址的模块在初始化的时候,将这些固定分配的虚拟地址映射到指定的物理地址上去。 image-20231005155942462 4、总结 以上就是整个虚拟地址空间的划分,总结如下: image-20231005160802093
  • 热度 13
    2014-11-23 21:52
    2152 次阅读|
    0 个评论
    Software is strange stuff. If a newly-constructed bridge is fine with heavily-loaded trucks going across, odds are pretty good that little Sally on her bicycle won’t cause it to collapse. If the bridge were made of code it might be fine with a dozen 18-wheelers but fail when six of them try to cross. Or even at some random time when completely unloaded. Most firmware is tremendously fragile. A single failure – a null pointer dereference, a divide by zero – can cause the entire system to crash. Before a bridge fails, generally cracks will start near where the loads are highest. Not so with code; that ‘divide by zero’ might be followed by millions of instructions before the system locks up or exhibits some other unwanted behavior. There are good reasons for this. Computation is inherently fragile. Think of how many things have to go right for any decent-sized program to run! The hardware has to be almost perfect, as one bad fetch, one out of millions of bits of memory getting dropped, any of billions of logic operations per second going wrong, will cause a crash. Software is the same: millions of instructions and data values per second must sequence perfectly. The code itself must be perfect as well, yet it is comprised of millions of bits of information that interact in complex ways. In the embedded world we usually deal with failure by going to a safe, but dead, state. A watchdog timer might reset the system. Interlocks might shut the system down but park dangerous mechanical components in a safety zone. These responses are hardly what anyone wants, but most of the time that’s the only sort of response we know how to implement. How do you respond to a divide by zero that could occur in any of a thousand divide operations? Some languages, like C++ and Eiffel, provide mechanisms to respond to these unwanted events, but it is still hard to recover and continue computing. An FMEA (Failure Mode Effects Analysis) followed by a strategy to mitigate the risks is helpful, but often incredibly expensive. Some systems use a supervisor, a separate processor and code base, which watches the primary system’s outputs and takes corrective actions if something goes wrong. This might be a limp-home mode in a car, or, like in the Space Shuttle, a simpler set of software that does little more than get the craft safely back to Earth. These are great approaches. But they simply mask the deeper truth: that when a program fails, it does so catastrophically. There are no easy answers, but in some cases it’s possible to contain failure. A memory management unit (MMU) can detect component failures and restart the component. Old-timers remember segmented addressing on the 8086. Four segment registers let 16-bit address registers handle 1 MB of memory. They drove developers mad. At the very first Embedded Systems Conference a (in my opinion rude) member of the audience asked keynoter Andy Groves when they would move beyond that addressing scheme. Intel did. They came out with the 386 with a 32-bit address space, but, to the horror of almost everyone, used thousands of segment registers to get to all of that memory. These were embodied in the on-chip MMU. The entire software world revolted. Nearly everyone programmed the MMU to give each program a flat 32-bit address space. That was a mistake. The MMU offered a new way to make programs run safely. Sure, an individual application might crash as programs remain fragile. But if properly constrained into its own MMU-protected sandbox it wouldn’t damage other programs. The system itself could keep running despite the failure of one part. By and large microcontrollers were not outfitted with memory management units. That was sensible since most MCUs ran small programs doing a single thing. Even today it’s not unusual to see, say, a PIC running a program that’s just a couple of hundred bytes of code. But more modern MCUs often sport large address spaces and run complex applications. Why don’t silicon vendors provide an MMU to permit more graceful degradation of a complex application? Divide the code into a number of individual components – e.g., tasks – and put each in a protected chunk of memory. A supervisor would look for access violations and attempt to restart or recover from one component’s failure. Transistors are essentially free. Vendors should give us a hardware resource like this to help us build more robust programs. Recently ARM introduced the Cortex-M7, a sort of super-core for MCUs that gives around 5 Coremarks/MHz, not far from some of Intel’s older speed demons. ST is the first company to offer M7 silicon, and their STM32F756xx comes with a memory protection unit (MPU), which is sort of a poor-person’s MMU. It allows eight memory regions that are hardware-protected from interfering with each other. Access to each region can be finely controlled to permit, for instance, fetches only, or read-only, or read/write access. The MPU is available on some other ARM cores as well. That’s a nice start. ARM often cackles with delight about how Cortex M0 parts can be made in just 0.01mm**2 of silicon using a 45 nm node. That’s pretty impressive. How about adding 0.001mm**2 for an MMU? The cost is tiny, the benefits can be huge. Developers who don’t need it can just leave it off. Put it in its own power domain so it consumes nothing when idle. Many RTOSes include code to manage the MMU; the incremental firmware cost is not large. What’s your take? Would you use an MMU if one were offered?
相关资源
  • 所需E币: 0
    时间: 2023-2-12 22:09
    大小: 377.33KB
    上传者: ZHUANG
    ARMDSP系统MMU在射频一致性测试仪表的实现
  • 所需E币: 0
    时间: 2020-12-22 23:01
    大小: 362.1KB
    上传者: czd886
    ARM+DSP系统MMU在射频一致性测试仪表的实现
  • 所需E币: 3
    时间: 2019-12-26 12:31
    大小: 1.57MB
    上传者: 978461154_qq
    嵌入式系统的构建……
  • 所需E币: 4
    时间: 2019-12-26 12:31
    大小: 1.52MB
    上传者: 978461154_qq
    嵌入式系统的构建(清华大学教材)……
  • 所需E币: 3
    时间: 2019-12-26 12:29
    大小: 2.96MB
    上传者: 二不过三
    基于ARM的嵌入式系统教学与科研应用……
  • 所需E币: 3
    时间: 2019-12-26 12:29
    大小: 2.96MB
    上传者: wsu_w_hotmail.com
    基于ARM的嵌入式系统教学与科研应用(魏洪兴博士)……
  • 所需E币: 3
    时间: 2019-12-26 12:19
    大小: 2.32MB
    上传者: 2iot
    ARM应用与开发资料……
  • 所需E币: 3
    时间: 2019-12-26 12:19
    大小: 5.69MB
    上传者: rdg1993
    Arm相关资料,包括常用ARM指令集与汇编……
  • 所需E币: 4
    时间: 2019-12-26 12:18
    大小: 1.26MB
    上传者: 二不过三
    ARM公司ARM710A手册……
  • 所需E币: 3
    时间: 2019-12-26 12:18
    大小: 139.8KB
    上传者: quw431979_163.com
    ARM初学者指南……
  • 所需E币: 5
    时间: 2019-12-26 10:26
    大小: 42.38KB
    上传者: 978461154_qq
    Linux设备驱动编程之内存与IO操作……
  • 所需E币: 3
    时间: 2019-12-26 10:20
    大小: 745.08KB
    上传者: rdg1993
    ARM芯片的应用和选型[芯片类]……
  • 所需E币: 3
    时间: 2019-12-26 00:24
    大小: 65.72KB
    上传者: 二不过三
    ARMMMU详细图解……
  • 所需E币: 5
    时间: 2019-12-25 16:52
    大小: 154.25KB
    上传者: 微风DS
    嵌入式系统关键技术分析与开发应用嵌入式系统关键技术分析与开发应用(发布日期:2005-7-109:20:29)浏览人数:2鼠标双击自动滚屏摘要:基于嵌入式系统的概念,阐述嵌入式系统的关键技术、嵌入式开发以及广泛的应用。首先,分析嵌入式系统的技术特点,分别从嵌入式处理器和嵌入式操作系统两方面介绍,着重说明它不同于其它操作系统的一些处理方法和过程;在此基础上阐述嵌入式软件的开发过程,并结合作者嵌入式软件开发的实践,着重阐述嵌入式软件的一些开发技巧。接着,介绍目前嵌入式系统一些流行的应用,以及南京东大移动互联技术有限公司自行研制的基于蓝牙技术的嵌入式产品。最后,给出作者的体会,展望嵌入式系统的前景。关键词:嵌入式系统嵌入式处理器微内核内存管理单元蓝牙系统引言在当前数字信息技术和网络技术高速发展的后PC(Post-PC)时代,嵌入式系统已经广泛地渗透到科学研究、工程设计、军事技术、各类产业和商业文化艺术以及人们的日常生活等方方面面中。随着国内外各种嵌入式产品的进一步开发和推广,嵌入式技术越来越和人们的生活紧密结合。……
  • 所需E币: 5
    时间: 2019-12-25 14:59
    大小: 69.09KB
    上传者: 二不过三
    存储器管理IIEB+HM>AN202RabbitMemoryManagementInaNutshellIntroductionTheRabbitCPUhasaMemoryManagementUnit(MMU)thatcontrolshowlogicalmem-oryaddressesmapintophysicaladdresses,andaMemoryInterfaceUnitthatcontrolshowphysicaladdressesmapintoactualhardware.TheDynamicCcompilerandlibrariesgenerallyhandlememorymappingdetailssothatmostDynamicCusersdon’thavetoconcernthemselveswithit,butsomeadvancedappli-cationsmayneedtomanipulatetheMMUand/ortheMIU.ForfurtherdetailsontheRabbitmemorymanagement,seetheRabbit2000Microproces-sorUser’sManualDefinitionsPhysical(orLinear)Addresses-20-bitaddressesrepresentingthe1Maddressspacethatlogicaladdre……
  • 所需E币: 3
    时间: 2019-12-25 12:42
    大小: 5.95KB
    上传者: 238112554_qq
    ARM7在嵌入式应用中启动程序的实现……
  • 所需E币: 5
    时间: 2019-12-25 10:35
    大小: 372.62KB
    上传者: 二不过三
    ARM存储系统……
  • 所需E币: 5
    时间: 2020-1-6 12:28
    大小: 294.97KB
    上传者: 16245458_qq.com
       Combinationofaworld-classRISCprocessorsystemwithindustryleadingprogrammablelogiconasingledevice……
  • 所需E币: 3
    时间: 2019-12-25 16:10
    大小: 102.92KB
    上传者: 16245458_qq.com
    32位RISCCPUARM芯片的应用和选型中国电子网www.ec66.com转载中国电子论坛www.ecbbs.com欢迎光临我们的网站32位RISCCPUARM芯片的应用和选型上海交通大学周洁杨心怀摘要:ARM公司以及ARM芯片的现状和发展,从应用的角度介绍了ARM芯片的选择方法,并介绍了具有多芯核结构的ARM芯片。列举了目前的主要ARM芯片供应商,其产品以及应用领域。举例说明了几种嵌入式产品最佳ARM芯片选择方案。关键词:ARMMMUSOCRISCCPUARM公司自1990年正式成立以来,在32位RISC(ReducedInstructionSetComputer)CPU开发领域不断取得突破,其结构已经从V3发展到V6。由于ARM公司自成立以来,直以IP(IntelligenceProperty)提供者的身份向各大半导体制造商出售知识产权,而自己从不介入芯片的生产销售,加上其设计的芯核具有功耗低、成本低等显著优点,因此获得众多的半导体厂家和整机厂商的大力支持,在32位嵌入式应用领域获得了巨大的成功,目前已经占有75%以上32位RISC嵌入式产品市场。在低功耗、低成本的嵌入式应用领域确立了市场领导地位。现在设计、生产ARM芯片的国际大公司已经超过50多家,国中兴通讯和华为通讯等公司已经购买ARM公司芯核用于通讯专用芯片的设计。目前非常流行的ARM芯核有ARM7TDMI,StrongARM,ARM720T,ARM9TDMI……
  • 所需E币: 3
    时间: 2019-12-25 11:22
    大小: 60KB
    上传者: 二不过三
    ARM公司以及ARM芯片的现状和发展,从应用的角度介绍了ARM芯片的选择方法,并介绍了具有多芯核结构的ARM芯片。列举了目前的主要ARM芯片供应商,其产品以及应用领域。举例说明了几种嵌入式产品最佳ARM芯片选择方案。32位RISCCPUARM芯片的应用和选型摘要:ARM公司以及ARM芯片的现状和发展,从应用的角度介绍了ARM芯片的选择方法,并介绍了具有多芯核结构的ARM芯片。列举了目前的主要ARM芯片供应商,其产品以及应用领域。举例说明了几种嵌入式产品最佳ARM芯片选择方案。   关键词:ARMMMUSOCRISCCPUARM公司自1990年正式成立以来,在32位RISC(ReducedInstructionSetComputer)CPU开发领域不断取得突破,其结构已经从V3发展到V6。由于ARM公司自成立以来,直以IP(IntelligenceProperty)提供者的身份向各大半导体制造商出售知识产权,而自己从不介入芯片的生产销售,加上其设计的芯核具有功耗低、成本低等显著优点,因此获得众多的半导体厂家和整机厂商的大力支持,在32位嵌入式应用领域获得了巨大的成功,目前已经占有75%以上32位RISC嵌入式产品市场。在低功耗、低成本的嵌入式应用领域确立了市场领导地位。现在设计、生产ARM芯片的国际大公司已经超过50多家,国中兴通讯和华为通讯等公司已经购买ARM公司芯核用于通讯专用芯片的设计。目前非常流行的ARM芯核有ARM7TDMI,StrongARM,ARM720T,ARM9TDMI,ARM922T,ARM940T,RM946T,ARM966T,ARM10TDMI等。自V5以且,ARM公司提供PiccoloDSP的芯核给芯片设计得,用于设计ARMDSP的SOC(SystemOnChip)结构芯片。此外,ARM芯片还获得了许多实时操作系统(RealTimeOperatingSystem)供应商的支持,比较知名的有:WindowsCE、Linux、pSOS、VxWo……