一、内核启动过程中,关于内存的信息
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的关系