linux内存分配注释及小结

本文深入解析了内核初始化过程、内存申请、使用、释放等关键步骤,详细阐述了虚拟地址与物理地址的转换机制及内存管理的核心原理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1. 内核初始化: 

    * 内核建立好内核页目录页表数据库,假设物理内存大小为len,则建立了[3G--3G+len]::[0--len]这样的虚地址vaddr和物理地址paddr的线性对应关系; 
    * 内核建立一个page数组,page数组和物理页面系列完全是线性对应,page用来管理该物理页面状态,每个物理页面的虚地址保存在page->virtual中; 
    * 内核建立好一个free_list,将没有使用的物理页面对应的page放入其中,已经使用的就不用放入了; 

2. 内核模块申请内存vaddr = get_free_pages(mask,order): 

    * 内存管理模块从free_list找到一个page,将page->virtual作为返回值,该返回值就是对应物理页面的虚地址; 
    * 将page从free_list中脱离; 
    * 模块使用该虚拟地址操作对应的物理内存; 

3. 内核模块使用vaddr,例如执行指令mov(eax, vaddr): 

    * CPU获得vaddr这个虚地址,利用建立好的页目录页表数据库,找到其对应的物理内存地址; 
    * 将eax的内容写入vaddr对应的物理内存地址内; 

4. 内核模块释放内存free_pages(vaddr,order): 

    * 依据vaddr找到对应的page; 
    * 将该page加入到free_list中; 

5. 用户进程申请内存vaddr = malloc(size): 

    * 内存管理模块从用户进程内存空间(0--3G)中找到一块还没使用的空间vm_area_struct(start--end); 
    * 随后将其插入到task->mm->mmap链表中; 

6. 用户进程写入vaddr(0-3G),例如执行指令mov(eax, vaddr): 

    * CPU获得vaddr这个虚地址,该虚地址应该已经由glibc库设置好了,一定在3G一下的某个区域,根据CR3寄存器指向的current->pgd查当前进程的页目录页表数据库,发现该vaddr对应的页目录表项为0,故产生异常; 
    * 在异常处理中,发现该vaddr对应的vm_area_struct已经存在,为vaddr对应的页目录表项分配一个页表; 
    * 随后从free_list找到一个page,将该page对应的物理页面物理首地址赋给vaddr对应的页表表项,很明显,此时的vaddr和paddr不是线性对应关系了; 
    * 将page从free_list中脱离; 
    * 异常处理返回; 
    * CPU重新执行刚刚发生异常的指令mov(eax, vaddr); 
    * CPU获得vaddr这个虚地址,根据CR3寄存器指向的current->pgd,利用建立好的页目录页表数据库,找到其对应的物理内存地址; 
    * 将eax的内容写入vaddr对应的物理内存地址内;   

7. 用户进程释放内存vaddr,free(vaddr): 

    * 找到该vaddr所在的vm_area_struct; 
    * 找到vm_area_struct:start--end对应的所有页目录页表项,清空对应的所有页表项; 
    * 释放这些页表项指向物理页面所对应的page,并将这些page加入到free_list队列中; 
    * 有必要还会清空一些页目录表项,并释放这些页目录表项指向的页表; 
    * 从task->mm->mmap链中删除该vm_area_struct并释放掉; 

综合说明: 

    * 可用物理内存就是free_list中各page对应的物理内存; 
    * 页目录页表数据库的主要目的是为CPU访问物理内存时转换vaddr-->paddr使用,分配以及释放内存时不会用到,但是需要内核内存管理系统在合适时机为CPU建立好该库; 
    * 对于用户进程在6中获得的物理页面,有两个页表项对应,一个就是内核页目录页表数据库的某个pte[i ],一个就是当前进程内核页目录页表数据库的某个 pte[j],但是只有一个page和其对应。如果此时调度到其他进程,其他进程申请并访问某个内存,则不会涉及到该物理页面,因为其分配时首先要从 free_list中找一个page,而该物理页面对应的page已经从free_list中脱离出来了,因此不存在该物理页面被其他进程改写操作的情况。内核中通过get_free_pages等方式获取内存时,也不会涉及到该物理页面,原理同前所述。
要成功地进行Xilinx Zynq-7000 SoC的集成开发,你将需要熟悉TLZ7xH-EVM开发板的硬件特性以及相应的软件编程。在此,我们推荐参考以下资源《创龙TLZ7xH-EVM开发板:Xilinx Zynq-7000双核Cortex-A9+Kintex-7》,这将为你的项目提供详尽的支持。 参考资源链接:[创龙TLZ7xH-EVM开发板:Xilinx Zynq-7000双核Cortex-A9+Kintex-7](https://wenku.youkuaiyun.com/doc/80nyorov3y) 首先,在硬件编程方面,你需要了解开发板的硬件架构和资源。TLZ7xH-EVM开发板集成了双核ARM Cortex-A9处理器和Kintex-7 FPGA。你应该首先阅读Zynq-7000开发板规格书,了解各个硬件接口和信号引脚的详细信息。根据你的项目需求,进行硬件资源配置,包括配置处理器的时钟频率、电源管理、存储接口以及外设接口等。 其次,在软件编程方面,Xilinx提供了Vivado和SDK套件,用于硬件逻辑设计和软件应用开发。在Vivado中,你需要完成硬件平台的设计和生成,包括创建项目、综合、实现和生成比特流文件。完成硬件设计后,你可以通过Xilinx SDK进行软件编程,创建应用程序和驱动,以与硬件平台交互。编写代码时,你需要参考开发板提供的Demo程序,这些示例程序展示了如何加载和运行用户代码。 确保你具备相关的硬件编程经验,以及掌握至少一种用于嵌入式开发的编程语言,如C/C++。在软件开发过程中,你还需要了解操作系统的选择和配置,比如使用PetaLinux等。 集成开发成功的关键在于硬件和软件的紧密配合,这通常需要进行多次迭代和调试。使用TLZ7xH-EVM开发板上的调试接口,比如JTAG和串口,进行代码调试和性能分析。 在开发过程中,不妨利用创龙科技提供的技术支持和服务,及时解决开发中遇到的问题。此外,你可以利用公司提供的增值服务平台,如定制化开发、培训等,进一步提升开发效率和产品品。 综上所述,通过阅读相关规格书,使用Vivado和SDK进行硬件设计和软件编程,结合创龙科技的技术支持,你将能够高效地完成Zynq-7000 SoC的集成开发任务。对于那些希望深入学习和探索更多高级功能和技巧的读者,我们再次推荐《创龙TLZ7xH-EVM开发板:Xilinx Zynq-7000双核Cortex-A9+Kintex-7》,这份资料不仅帮助你入门,还将引导你掌握更深层次的知识。 参考资源链接:[创龙TLZ7xH-EVM开发板:Xilinx Zynq-7000双核Cortex-A9+Kintex-7](https://wenku.youkuaiyun.com/doc/80nyorov3y)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值