热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

内存管理初始化(六)vmalloc_init及ioremap

是不是我错了,本想这个函数会如网上所说将进行非连续内存管理的初始化,但是对于2.6.34的ARM架构而言,该函数实际完成的业务非常少。内存

是不是我错了,本想这个函数会如网上所说将进行非连续内存管理的初始化,但是对于2.6.34的ARM架构而言,该函数实际完成的业务非常少。

内存管理的初始化读到此处,我感觉原有的认识存在很大缺陷:

(1)内核空间的下限是3G吗?永久映射的PKMAP_BASE已在3G下;

(2)低端内存是896M吗?2.6.32的omap4430的VMLLOC_END是1G - 128M,VMALLOC_MIN是1G - 128M -128M;

(3)还存在固定映射吗?FIXADDR_SIZE的空间已被FIX_KMAP_BEGIN ~ FIXK_KMAP_END完全占据;

(4)I/O空间在初始化已固定映射至VMALLOC_END到FIXADDR_START之间的一块虚拟空间区域.

(5)用户态不可以执行3G以上空间代码吗?kuser_cmpxchg_check检测的意义;

(6)引入MODULES_END的意义是什么?

 

对于ARM架构,vmalloc_init中的for循环就没有执行,如有误,望指正.

void vmalloc_init(void)|-->for_each_possible_cpu(i)|--{| struct vmap_block_queue *vbq;| vbq = &per_cpu(vmap_block_queue, i);| spin_lock_init(&vbp->lock);| INIT_LIST_HEAD(&vbq->free);|--}||--for(tmp = vmlist; tmp; tmp = tmp->next)|--{| xxxxxxxx| 对于2.6.34的ARM架构而言,vmlist直到此时仍为0;| 所以该循环不会执行,至于网上的资料大概是针对X86的.|--}||--vmap_area_pcpu_hole = VMALLOC_END;| vmap_initialized = true;

 

 

如下部分是我后期再看init_arch_irq()中看的,主要是因为我们知道:对于ARM架构, vmalloc_init中的for循环没有执行,那么我们自然会想何时对首次修改vmlist以及如何修改.

init_arch_irq中会执行ioremap函数,以下记录该函数的执行流程.

#define ioremap(COOKIE, size) \__arm_ioremap(COOKIE, size, MT_DEVICE)void *__arm_ioremap(unsigned long phys_addr, size_t size,
unsigned int mtype)
|-->__arm_ioremap_caller(phys_addr, size, mtype, NULL)void *__arm_ioremap_caller(unsigned long phys_addr, size_t size,unsigned int mtype, void *caller)|-->unsigned long offset = phys_addr & ~PAGE_MASK;| 对于SOC,例如sep612,每个IP模块的所占空间都是4K的整数倍,所以| 一般情况下offset = 0;||-->unsigned long pfn = __phys_to_pfn(phys_addr);||-->return __arm_ioremap_pfn_caller(pfn, offset, size, mtype, caller);

 

 

void *__arm_ioremap_pfn_caller(unsigned long pfn, unsigned long offset,size_t size, unsigned int mtype, void *caller)|-->const struct mem_type *type = get_mem_type(mtype)| mem_type中存放页表映射属性,及页表的级数||-->size = PAGE_ALIGN(offset + size);||-->struct vm_struct *area = get_vm_area_caller(size, VM_IOREMAP,
| caller);
| 根据size,在VMALLOC_START ~ VMALLOC_END中申请一块size + PAGE_SIZE| 大小的虚拟空间,由于非连续内存区域的管理还利用了红黑树,因此在获得vm_struct| 实例的同时,也将申请vmap_area实例,将申请的虚拟空间,纳入红黑树| vmap_area_root.rb_node的管理.||-->unsigned long addr = (unsigned long)area->addr;||-->remap_area_pages(addr, pfn, size, type);| 前面讲过,申请的虚拟空间是size + PAGE_SIZE,此处我们看到,| 映射的物理空间大小是size.||-->flush_cache_vmap(addr, addr+size);||-->return (void *) (offset + addr);

 

 

struct vm_struct *get_vm_area_caller(unsigned long size,unsigned long flags, void *caller)|-->return __get_vm_area_node(size, 1, flags, VMALLOC_START, VMALLOC_END, -1, GFP_KERNEL, caller);struct vm_struct *__get_vm_area_node(unsigned long size,unsigned long align, unsigned long flags,unsigned long start, unsigned long end,int node, gfp_t gfp_mask, void *caller)|-->struct vmap_area *va &#61; NULL;| struct vm_struct *area &#61; NULL;||-->if(flags & VM_IOREMAP)|--{| int bit &#61; fls(size);| if(bit > IOREMAP_MAX_ORDER) bit &#61; IOREMAP_MAX_ORDER;| else if(bit PAGE_SHIFT;| align &#61; 1 << bit;|--}| 对于IO 映射部分做了对其修正.|||-->size &#61; PAGE_ALIGN(size);||-->area &#61; kzalloc_node(sizeof(*area), gfp_mask & GPF_RECLAIM_MASK,
| node);
| 对于非连续内存区&#xff0c;既使用了vmlist这样的链表管理&#xff0c;也使用了vmap_area_root| 之类的红黑树进行管理&#xff0c;此处即申请需插入到vmlist链表中的vm_struct实例中.||-->size &#43;&#61; PAGE_SIZE;| 为了安全考虑&#xff0c;多申请了一页的虚拟空间&#xff08;注意只是虚拟空间&#xff09;.||-->va &#61; alloc_vmap_area(size, align, start, end, node, gpf_mask);| 从虚拟内存start ~ end中申请一块size大小的虚拟空间&#xff0c;起止地址放在| vmap_area实例中&#xff0c;并将该vmap_area实例插入到以vmap_area_root.rb_node| 为根的红黑树中.||-->insert_vmalloc_vm(area, va, flags, caller);| 将vmap_area实例和vm_struct实例关联起来&#xff0c;并将vm_struct实例插入到| vmlist链表中.

 

 

将vmap_area实例和vm_struct实例关联起来&#xff0c;并将vm_struct实例插入到vmlist链表中.
void insert_vmalloc_vm(struct vm_struct *vm, struct vmap_area *va)|-->struct vm_struct *tmp, **p;||-->vm->flags &#61; flags;| vm->addr &#61; (void *)va->va_start;| vm->size &#61; va->va_end - va->va_start;| vm->caller &#61; caller;| va->private &#61; vm;| va->flags |&#61; VM_VM_AREA;||-->for(p &#61; &vmlist; (tmp &#61; *p) !&#61; NULL; p &#61; &tmp->next)|--{| if(tmp->addr >&#61; vm->addr) break;|--}||--vm->next &#61; *p;| *p &#61; vm;

 



推荐阅读
  • 计算机存储系统的层次结构及其优势
    本文介绍了计算机存储系统的层次结构,包括高速缓存、主存储器和辅助存储器三个层次。通过分层存储数据可以提高程序的执行效率。计算机存储系统的层次结构将各种不同存储容量、存取速度和价格的存储器有机组合成整体,形成可寻址存储空间比主存储器空间大得多的存储整体。由于辅助存储器容量大、价格低,使得整体存储系统的平均价格降低。同时,高速缓存的存取速度可以和CPU的工作速度相匹配,进一步提高程序执行效率。 ... [详细]
  • 本文详细介绍了如何使用MySQL来显示SQL语句的执行时间,并通过MySQL Query Profiler获取CPU和内存使用量以及系统锁和表锁的时间。同时介绍了效能分析的三种方法:瓶颈分析、工作负载分析和基于比率的分析。 ... [详细]
  • 嵌入式处理器的架构与内核发展历程
    本文主要介绍了嵌入式处理器的架构与内核发展历程,包括不同架构的指令集的变化,以及内核的流水线和结构。通过对ARM架构的分析,可以更好地理解嵌入式处理器的架构与内核的关系。 ... [详细]
  • 在2022年,随着信息化时代的发展,手机市场上出现了越来越多的机型选择。如何挑选一部适合自己的手机成为了许多人的困扰。本文提供了一些配置及性价比较高的手机推荐,并总结了选择手机时需要考虑的因素,如性能、屏幕素质、拍照水平、充电续航、颜值质感等。不同人的需求不同,因此在预算范围内找到适合自己的手机才是最重要的。通过本文的指南和技巧,希望能够帮助读者节省选购手机的时间。 ... [详细]
  • 本文介绍了在Android开发中使用软引用和弱引用的应用。如果一个对象只具有软引用,那么只有在内存不够的情况下才会被回收,可以用来实现内存敏感的高速缓存;而如果一个对象只具有弱引用,不管内存是否足够,都会被垃圾回收器回收。软引用和弱引用还可以与引用队列联合使用,当被引用的对象被回收时,会将引用加入到关联的引用队列中。软引用和弱引用的根本区别在于生命周期的长短,弱引用的对象可能随时被回收,而软引用的对象只有在内存不够时才会被回收。 ... [详细]
  • 基于PgpoolII的PostgreSQL集群安装与配置教程
    本文介绍了基于PgpoolII的PostgreSQL集群的安装与配置教程。Pgpool-II是一个位于PostgreSQL服务器和PostgreSQL数据库客户端之间的中间件,提供了连接池、复制、负载均衡、缓存、看门狗、限制链接等功能,可以用于搭建高可用的PostgreSQL集群。文章详细介绍了通过yum安装Pgpool-II的步骤,并提供了相关的官方参考地址。 ... [详细]
  • 在Android开发中,使用Picasso库可以实现对网络图片的等比例缩放。本文介绍了使用Picasso库进行图片缩放的方法,并提供了具体的代码实现。通过获取图片的宽高,计算目标宽度和高度,并创建新图实现等比例缩放。 ... [详细]
  • 本文介绍了C#中生成随机数的三种方法,并分析了其中存在的问题。首先介绍了使用Random类生成随机数的默认方法,但在高并发情况下可能会出现重复的情况。接着通过循环生成了一系列随机数,进一步突显了这个问题。文章指出,随机数生成在任何编程语言中都是必备的功能,但Random类生成的随机数并不可靠。最后,提出了需要寻找其他可靠的随机数生成方法的建议。 ... [详细]
  • 本文介绍了在Linux下安装和配置Kafka的方法,包括安装JDK、下载和解压Kafka、配置Kafka的参数,以及配置Kafka的日志目录、服务器IP和日志存放路径等。同时还提供了单机配置部署的方法和zookeeper地址和端口的配置。通过实操成功的案例,帮助读者快速完成Kafka的安装和配置。 ... [详细]
  • Oracle优化新常态的五大禁止及其性能隐患
    本文介绍了Oracle优化新常态中的五大禁止措施,包括禁止外键、禁止视图、禁止触发器、禁止存储过程和禁止JOB,并分析了这些禁止措施可能带来的性能隐患。文章还讨论了这些禁止措施在C/S架构和B/S架构中的不同应用情况,并提出了解决方案。 ... [详细]
  • MPLS VP恩 后门链路shamlink实验及配置步骤
    本文介绍了MPLS VP恩 后门链路shamlink的实验步骤及配置过程,包括拓扑、CE1、PE1、P1、P2、PE2和CE2的配置。详细讲解了shamlink实验的目的和操作步骤,帮助读者理解和实践该技术。 ... [详细]
  • Android工程师面试准备及设计模式使用场景
    本文介绍了Android工程师面试准备的经验,包括面试流程和重点准备内容。同时,还介绍了建造者模式的使用场景,以及在Android开发中的具体应用。 ... [详细]
  • 网卡工作原理及网络知识分享
    本文介绍了网卡的工作原理,包括CSMA/CD、ARP欺骗等网络知识。网卡是负责整台计算机的网络通信,没有它,计算机将成为信息孤岛。文章通过一个对话的形式,生动形象地讲述了网卡的工作原理,并介绍了集线器Hub时代的网络构成。对于想学习网络知识的读者来说,本文是一篇不错的参考资料。 ... [详细]
  • 本文讨论了微软的STL容器类是否线程安全。根据MSDN的回答,STL容器类包括vector、deque、list、queue、stack、priority_queue、valarray、map、hash_map、multimap、hash_multimap、set、hash_set、multiset、hash_multiset、basic_string和bitset。对于单个对象来说,多个线程同时读取是安全的。但如果一个线程正在写入一个对象,那么所有的读写操作都需要进行同步。 ... [详细]
  • 本文介绍了如何在Azure应用服务实例上获取.NetCore 3.0+的支持。作者分享了自己在将代码升级为使用.NET Core 3.0时遇到的问题,并提供了解决方法。文章还介绍了在部署过程中使用Kudu构建的方法,并指出了可能出现的错误。此外,还介绍了开发者应用服务计划和免费产品应用服务计划在不同地区的运行情况。最后,文章指出了当前的.NET SDK不支持目标为.NET Core 3.0的问题,并提供了解决方案。 ... [详细]
author-avatar
佩刚坤斌冠如_567
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有