(九)linux内核中的内存分配

一、内核启动过程中,关于内存的信息

1、内核分区

[    0.000000] Memory: 1024MB = 1024MB total   ---->内存的大小是1GB
[    0.000000] Memory: 810820k/810820k available, 237756k reserved, 272384K highmem
[    0.000000] Virtual kernel memory layout:
[    0.000000]     vector  : 0xffff0000 - 0xffff1000   (   4 kB)    ---->存放中断向量表
[    0.000000]     fixmap  : 0xfff00000 - 0xfffe0000   ( 896 kB)    ---->固定映射区
[    0.000000]     vmalloc : 0xef800000 - 0xfee00000   ( 246 MB)    ---->vmalloc()分配内存的区
[    0.000000]     lowmem  : 0xc0000000 - 0xef600000   ( 758 MB)    ---->低端内存区,属于GFP_KERNEL标志。kmalloc()分配内存的区
[    0.000000]     pkmap   : 0xbfe00000 - 0xc0000000   (   2 MB)    ---->
[    0.000000]     modules : 0xbf000000 - 0xbfe00000   (  14 MB)    ---->#insmod *.ko module存放段
[    0.000000]       .text : 0xc0008000 - 0xc0a51018   (10533 kB)   ---->代码段和只读的数据段
[    0.000000]       .init : 0xc0a52000 - 0xc0a8f100   ( 245 kB)    ---->初始化段,使用__init修饰初始化函数
[    0.000000]       .data : 0xc0a90000 - 0xc0b297d8   ( 614 kB)    ---->可读写的数据段
[    0.000000]        .bss : 0xc0b297fc - 0xc0d09488   (1920 kB)    ---->未初始化的数据段
[    0.000000] SLUB: Genslabs=11, HWalign=64, Order=0-3, MinObjects=0, CPUs=8, Nodes=1
[    4.341000] Freeing init memory: 244K

2、内核中,内存的分配器
slab —>早期的内存分配器
slob —>SLOB的目标是针对嵌入式系统的,主要是适用于那些内存非常有限的系统,比如32MB以下的内存
slub —>SLUB被很认为是Slab和Slob的取代者,大概在2.6.24/2.6.25将会被同志们抛弃。而SLUB将是未来Linux Kernel中的首选。

 

二、内核中如何分配内存

例:

struct teacher *my_teacher;
my_teacher = (struct teacher *)kmalloc(sizeof(struct teacher), GFP_KERNEL)
if(my_teacher == NULL)
	return -1;

1.应用程序分配内存

#include <stdlib.h>  --->标准C库

void *malloc(size_t size);
void free(void *ptr);

2、驱动程序分配内存—kmalloc()
1)malloc()

static __always_inline void *kmalloc(size_t size, gfp_t flags)

参数:
size_t size —>分配内存的大小,字节数
gfp_t flags —>分配内存的标志
返回值:
void * —>指向分配后的内存的指针

2)分配内存的标志
GFP_KERNEL ----> 正常的分配内存,分配的内存在lowmem区
GFP_ATOMIC ----> 分配内存的过程是一个原子过程,该过程是不能被打断的,是一个连续的过程,不会产生阻塞。
在中断服务程序中,需要分配内存,则需要使用GFP_ATOMIC关键字。
GFP_DMA ----> 给DMA控制器分配内存。要求分配的内存,物理地址和虚拟地址都是连续的。
注意:使用kmalloc分配内存的时候,内存的分配大小不能超过128KB。

3)释放内存

void kfree(const void *x)

3、驱动程序分配内存—vmalloc()

void *vmalloc(unsigned long size)
void vfree(const void *addr)

 

三、kmalloc()和vmalloc()的区别

1、分配的大小:kmalloc不超过128kB,而vmalloc没有限制
2、分配的位置:kmalloc在lowmem区,vmalloc在vmalloc
3、原子性:kmalloc(size, GFP_ATOMIC),而vmalloc可能会产生阻塞的。
4、地址的连续性:kmalloc可以保证物理地址和虚拟地址是连续的,而vmalloc不能保证物理地址是连续的。

虚拟地址到物理地址的映射,是以page为单位的。1page = 4kB

 

四、MMU

1、什么是MMU?
MMU — Memory Management Unit ---->内存管理单元
MMU是CPU内核中的一个硬件模块。Cortex-M 没有MMU的 -----> uCOS-III ARM7
Cortex-A 有MMU的 ---->嵌入式linux ARM9、ARM11

2、MMU的作用?
1)MMU实现虚拟地址到物理地址的转换
嵌入式linux、WinCE、VxWorks操作系统只能运行在虚拟地址上,不能直接运行在物理地址上。
物理地址:硬件平台的地址:原理图、CPU的使用手册、…
虚拟地址:操作系统使用的地址:方便内核的保护(用户空间和内核空间)、可以实现不同进程之间的独立地址空间、有利于进程的切换。
2)设置虚拟地址的访问属性
只读、可读写、禁止访问

3、MMU做地址转换的单位
MMU转换地址的时候,不是一个个转换的,而是“一块块”转换的。
1)section(段):1MB
2)large page(大页):64KB
3)little page(小页):4kB ------> linux(page=4kB)
4)tiny page(极小页):1KB

4、MMU的工作原理
简单理解—>查表
1)表
—>page table(页表),页表是在使用MMU之前,就需要现在内存中创建一个页表,页表的首地址叫TTB,该地址要保存到MMU的寄存器中。
当打开MMU后,MMU自动去查找页表,然后得到虚拟地址和物理地址的关系。
2)表的索引
---->表的索引是虚拟地址。

3)表的内容
---->是虚拟地址和物理地址的对应关系,和访问属性。

5、MMU和ioremap之间的关系
虚拟地址 = ioremap(物理地址的开始,物理地址的大小)
ioremap()是一个改写页表的过程,重新定义了物理地址和虚拟地址的对应关系。

6、MMU和cache的关系
在这里插入图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值