| |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
-> 嵌入式 -> 内存基础小知识(arm) -> 正文阅读 |
|
[嵌入式]内存基础小知识(arm) |
? ? ? 处理器的cr0寄存器Pcd标志用来启用或者禁用高速缓存电路。 pcd标志是访问叶匡中的数据时高速缓存是否开启,pwt表示将数据写到叶匡的时候采用的回写策略是通写还是回写。 TLB用于缓存刚刚被访问的物理地址。每个cpu都有一个TLB。 常用宏功能: PAGE_SHIFT:指定offset字段的位数,页框大小。 PMD_SHIFT指定线性地址的offset字段与table字段的总位数。32位当PAE被禁用的时候是22位offset(12)+table(10),PMD_MASK为0xffe00000。 PUD_SHIFT:页上级目录项所映射的区域大小的对数。32位的环境上由于是两级页表所以总是等于PMD_SHIF。 PGDIR_SHIFT:页全局目录项所能映射的区域大小的对数。PGDIR_MASK宏用于屏蔽offset、table、middle、upper字段的所有位。 PTRS_PER_PTE、OTRS_PED_PMD、PTRS_PER_PUD、PTRS_PER_PGD用于计算页表、页中间目录、页上级目录和页全局目录表中的表项个数。 pte_t、pmd_t、pud_t、pgd_t分别描述页表项、页中间目录项、页上级目录和页全局目录定义。 __pte\__pmd\__pud\__pgd\__pgprot和pte_val\pmd_val\pud_val\pgd_val\pgprot_val是将相应表项和无符号整数相互转换。 pte_none\pmd_none\pud_none\pgd_none表示相应的表项值为0则返回1否则返回0。 pte_clear\pmd_clear\pud_clear\pgd_clear清除相应的表项,set_pte\set_pmd\set_pud\set_pgd向一页表中写入指定的值。 pte_same表示两个页表项指向相同的页且有相同的访问优先级则返回1否则返回0。 pmd_large(e)当e指向大型页则返回1。 pmd_bad用于检查传入的页中间目录参数,如果页中间所指向的页表满足下列之一返回1。 a页不存在(present标志被清除)b页只允许读访问(read\write标志被清除) c access或者 dirty标志被清除。pud_bad和pgd_bad总是返回0,没有定义pte_bad。 pte_user\pte_read读取user/supervisor标志 pte_write\pte_exec读取read/write标志 pte_dirty 读取dirty标志 pte_young 读取accessed标志 pte_file读取dirty标志 设置页标志函数: mk_pte_huge设置页表中的page size和present标志 pte_wrprotect 清除read/write标志 pte_rdprotect/pte_exprotect 清除user/supervisor标志 pte_mkwrite 设置read/write标志 pte_mkread/pte_mkexec ?设置user/supervisor标志 pte_mkclean 清除dirty标志 pte_mkdirty 设置dirty标志 pte_mkold/pte_mkyoung ?清除/清除accessd标志 pte_modify(p,v) 把页表p所有访问权限设置为v ptep_set_wrprotect 与pet_protect类似但是只是针对页表项。 petp_set_access_flags 如果dirty为1则将页的存取权限设置为指定的值,并且调用flush_tlb_page函数刷新tlb。 ptep_test_and_clear_dirty 只是针对页表项 petp_test_and_clear_young 只是针对页表项 页表操作宏: pgd_index(addr) 找到现行地址addr对应的目录项在页全局目录中的索引。 pgd_offset(mm,addr)根据addr找到页全局目录内的相应页目录项的线性地址。 pgd_offset_k(addr) 产生内核页全局目录包含addr的目录项。 pgd_page(pgd) 产生页上级目录所在页框的页描述符地址。 pud_offset(pgd,addr) 页上级目录中目录项addr对应的线性地址 pud_page(pud) 通过页上级目录pud产生相应的页中间目录的线性地址。 pmd_index(addr) 产生线性地址addr在页中间目录的目录项的索引 pmd_page(pmd) 页中间目录项pmd产生的页表描述符地址。 mk_pte(p,prot) 接收页描述符地址p和存取权限prot作为参数 pte_index(addr) 产生线性地址addr对应的表项在页表中的索引 pte_offdset_kernel(dir,addr),dir是页中间目录,线性地址addr在页中间目录dir中的对应的项即页表的线性地址。 pte_offset_map(dir,addr)接收指向一个页中间目录项的指针dir和线性地址addr作为参数,产生与线性地址addr相对应的页表项的线性地址。 pte_page(x) 返回页表项x所引用的描述符地址 pte_to_pgoff(pte) 从一个页表项的pte字段中提取文件偏移量,这个文件偏移量对应着一个非线性文件内存映射所在的页。 pgoff_to_pte(offset)为非线性文件内存所映射的页创建对应的页表项的内容 pgd_alloc(mm) \pgd_free分配一个新的页全局目录 pud_alloc(mm,pgd,addr)/pud_free分配pud pmd_alloc(mm,pud,addr)/pmd_free,为addr分配个新的页中间目录 pte_alloc_(mm,pmd,addr) 如果页中间目录为空则分配个新的页表,addr对应的项目被创建且user/supervisor标志被设置为1。如果页表在高端内存则建立一个临时映射 pte_alloc_kernel(mm,pmd,addr)分配一个新的页表然后返回与addr相关的线性地址。 pte_free(pte)释放与页描述符指针相关的页表 pte_free_kernel(pte) 内核主页表使用类似与pte_free clear_page_range(mmu,start,end)从线性地址start到end通过反复释放页表和清除页中间目录项来清除进程页表内容。 set_fixmap(idx,phyaddr)将idx指定的页表设置为phyaddr指定的物理地址 set_fixmap_nocache(idx,phyaddr)类似set_fixmap 只是多设置了pcd标志表示不使用cache缓存。 L1_CACHE_BYTES?表示高速缓存行的L1的大小以字节为单位 flush_tlb_all ??刷新所有的TLB表项。 flush_tlb_kernel_range刷新给定范围内的所有的TLB表 flush_tlb 刷新当前进程拥有的非全局页相关的所有TLB flush_tlb_mm 刷新指定进程拥有的TLB非页全局相关的所有TLB flush_tlb_range 刷新指定进程的线性地址间隔对应的TLB表项 flush_tlb_pgtables 刷新指定进程中特定的相邻页表集相关的TLB flush_tlb_page 刷新指定进程中单个页表项相关的TLB表项 任何进程切换都会更新活动页表集,本地tlb必须刷新 _count 页的引用计数 ?page_count()函数返回_count+1后的值 flags ?页框状态的标志 使用GFP_KERNEL的标志分配内存页面即使没有足够的页面也不会被阻塞,仅仅是分配失败而已,,一般情况下内核会保留一个页框池,在内存不足时供GFP_KERNEL使用,保留内存数量存放在min_free_kbytes(KB); 请求页框标志:? ? 组合标志: ? ? page_address(mm/highmem.c):返回页框对应的线性地址 1 根据PG_highmem标志判断页框是否在高端地址,不在则直接根据页框下标转换成物理地址再转换成线性地址。 2 是高端地址,则到page_address_htable散列表查找,找到对应的页框则返回线性地址否则返回NULL; 永久映射: 高端内存映射函数(arm arch/arm/mm/highmem.c): kamp 1 首先判断页框是否是高端地址通过PG_highmem标志。不是则通过page_address直接返回对应的线性地址。 2 是高端地址调用kmap_high
?map_new_virtual:
pkmap_count表示已经使用。 对应的函数kunmap ??1 如果不是高端地址页框则直接返回,因为永远线性映射区不需要释放 2 调用 kunmap_high去释放 kunmap_high:
struct vm_struct { ????struct vm_struct ???*next;//指向下一个vm,链表第一个元素被vmlist变量指向 ????void ???????????*addr;//内存区的第一个内存单元线性地址 ????unsigned long ??????size;//内存区大小+4096 ????unsigned long ??????flags;//非连续内存区映射的内存类型 ????struct page ????**pages;//指向nr_pages数组指针,该数组由指向页描述符的指针组成 ????unsigned int ???????nr_pages;//内存区填充的页面的个数 ????phys_addr_t ????phys_addr;//该字段为0,除非内存已经被创建来映射一个硬件设备的io共享内存 ????const void ?????*caller; }; flags: VM_ALLOC表示vmalloc得到的页 VM_MAP 使用vmap映射的已经被分配的页 IO_IOREMAP 表示使用ioremap映射的硬件设备的板上内存 get_vm_area如果flags没有指定VM_NO_GUARD则添加vmalloc的间隙。 vmalloc函数的解析: { return __vmalloc_node_flags(size, NUMA_NO_NODE,GFP_KERNEL); } return __vmalloc_node(size, 1, flags, PAGE_KERNEL,node, __builtin_return_address(0)); ??1 ???获取vm且设置va(首先查找全局free_vmap_cache红黑树找到开始地址最小的va,然后从此vm开始遍历查找两个va之间最小的且合适的间隙如果没有找到则在va末尾添加一个,然后将va信息填充到vm里) 2 ???调用__vmalloc_area_node去获取物理页面并且设置页表。 临时映射:可以用在中断或者可延迟函数内部不会阻塞上下文。注意是在kmap_atomic关抢占在__kunmap_atomic才会打开抢占。pagefault也一样。 kmap_atomic:建立临时映射 1 判断是否是高端地址,如果不是直接调用page_address返回线性地址 2 对于高端地址则设置pte页表为page构造的pte。 __kunmap_atomic:解除临时映射 ????1 刷新dcache 。 2 清除对应的页表。 __zone_watermark_ok:检查水位是否符合指定的值 1 首先判断是否设置了ALLOC_HARDER或者ALLOC_OOM值,如果设置了则认为是alloc_harder申请。如果没有指定则将free_pages减去nr_reserved_highatomic,去掉高端保留内存 2 指定了则继续判断是否指定了ALLOC_OOM,如果指定了则设置min减半否则min减少1/4。 3 判断free_pages是否小于min+z->lowmem_reserve,如果小于则返回false 4 判断传入参数order为0 则立即返回真 5 从order开始遍历存在非空的则返回true,如果是alloc_harder,则MIGRATE_HIGHATOMIC不空则也返回true。 总结就是判断在mark和保留内存水位之上且存在一个大于等于order的连续内存。 ? ? ? |
|
嵌入式 最新文章 |
基于高精度单片机开发红外测温仪方案 |
89C51单片机与DAC0832 |
基于51单片机宠物自动投料喂食器控制系统仿 |
《痞子衡嵌入式半月刊》 第 68 期 |
多思计组实验实验七 简单模型机实验 |
CSC7720 |
启明智显分享| ESP32学习笔记参考--PWM(脉冲 |
STM32初探 |
STM32 总结 |
【STM32】CubeMX例程四---定时器中断(附工 |
|
上一篇文章 下一篇文章 查看所有文章 |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 | -2024/11/19 20:15:28- |
|
网站联系: qq:121756557 email:121756557@qq.com IT数码 |