linux kernel 内存相关记录

本篇文章是学习了《linux内核设计与实现》和《linux设备驱动开发详解》关于linux 内存部分的记录。

 

MMU

内存管理单元,提供虚拟地址和物理地址映射、内存访问权限、cache缓存控制

TLB

缓存部分虚拟地址和物理地址的映射关系。

TTW

当TLB没有的时候,经过TTW转换后报错到TLB中;

页:

内核把物理页作为内存管理的基本单位,MMC通常都是以页为单位进行虚拟地址和物理地址的转换的;页的大小根据不同的体系结构而不同;32bit的为4K,64bit的为8k;使用struct page表示。

 

区:

对具有相似功能的页进行分组;一下会根据不同的体系结构有差异

ZONE_DMA 执行DMA操作

ZONE_NORMAL 证访问映射的页

ZONE_HIGHEM 高端内存 不能永久映射到内核地址空间

 

Linux的内存管理

通过MMU管理,每个进程的地址空间可以达到4GB,其中0-3GB为用户空间使用;3-4GB为kernel空间使用;用于空间不能访问ernel空间数据 只能通过系统调用进行访问;

1G的kernel空间又被划分为物理内存映射区、vmalloc虚拟内存映射区、高端页面映射区、专用页面映射区、系统保留区

 

内核接口

页操作:

字节操作

Kmalloc 分配指定的内存字节大小,在物理地址上是连续的;

Kmallco(size_t size,gfp_t flags);kfree 释放分配的空间

Size 申请的字节数

Flags 通常使用

GFP_KERNEL 这个会引起睡眠,再分配不出来的时候回等待,因此不能在中断上下文中使用

GFP_ATOMIC 不会睡眠,分配不到立即返回,可以在中断中使用;

 

Vmalloc 分配指定内存字节大小,在虚拟地址上是连续的 物理地址上是不连续的;需要对物理地址和虚拟地址进行映射,因此效率不高;

会引起睡眠,不能在中断上下文中使用

Vmallc(unsigned long size) vfree

 

栈上的静态分配

用户空间栈—空间大 可以动态增长

内核空间栈—空间小而且固定 通常是2个页或者2个页 可以通过配置设定;如果设置为1个页,中断栈就会有独立栈空间

 

局部变量总空间不能超过几百字节;

栈溢出会造成系统自己火星莫名破坏其他数据,导致异常问题;

 

Malloc

Malloc 并不一定每次都进行系统调用;比如在执行free前执行mallopt,free就不会把内存还给kernel,地址由C库保存。

Malloc返回成功后,实际上并没有申请空间只有开始写入后才开始分配;

 

I/O端口和I/O内存

I/O端口是在X86上的概念这里并不描述

I/O内存 就是UART USB等控制器地址;访问这个地址通过ioremap函数映射成虚拟地址访问;通过ioumap释放;devm_ioremap不需要释放

 

访问由2种方式

C指针直接操作寄存器

Kernel提供的接口:readb readw readl writeb writew writel

 

设备地址映射到用户空间

1、显示设备的kernel地址空间数据直接映射到用户空间,防止在copy一次;

2、应用程序直接访问某段地址;

 两者都是通过应用空间的mmap函数和驱动中对应的实现函数完成;mmap函数必须已页为单位进行映射

 

比如直接访问地址

Mmap的fd是打开的/dev/mem节点

static int drv_mmap(struct file*file, struct vm_area_struct *vma){

    struct drv_test *devp = file->private_data; /*获得设备结构体指针*/

    vma->vm_flags |= VM_IO;

    vma->vm_flags |= VM_RESERVED;

    if (remap_pfn_range(vma,vma->vm_start,virt_to_phys(devp->mem)>>PAGE_SHIFT, vma->vm_end - vma->vm_start, vma->vm_page_prot))

          return  -EAGAIN;

                                                                                                                                                                                                                                                                                                                                                                                                                              

      return 0;

}

 

剩余补充:

如果频繁申请和释放内存,可以考虑如下方式

Slab 如果需要频繁申请和释放,并且希望前后2次申请在同一块内存;

 

内存池

分配大量小对象 后备缓存技术

Mempool_create

Mempoll_alloc

Mempoll_free

Mempoll_destroy

 

DMA

DMA编程待补充

DMA 和cache

注意dma的目的地址和cache对应的ddr地址是否有重叠;方式dma把ddr地址修改但是cache没有更新的问题;

 

 

每个CPU接口

内核提供接口为每个cpu提供需要的内存

申请内存Alloc_percpu

操作内存 get_cpu_var put_cpu_var

 

 

 

 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值