一、linux内核启动过程中,关于内存信息
1、内核的内存的分区
[ 0.000000] Memory: 1024MB = 1024MB total ---> 1G
[ 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) ---->低端内存
[ 0.000000] pkmap : 0xbfe00000 - 0xc0000000 ( 2 MB) ---->高端内存区
[ 0.000000] modules : 0xbf000000 - 0xbfe00000 ( 14 MB) ----> 执行insmod ***.ko存放段
[ 0.000000] .text : 0xc0008000 - 0xc0a51044 (10533 kB) ----->代码段和只读数据段
[ 0.000000] .init : 0xc0a52000 - 0xc0a8f100 ( 245 kB) ----->由__init修饰的函数存放段
[ 0.000000] .data : 0xc0a90000 - 0xc0b29f18 ( 616 kB) ----->可读写数据段
[ 0.000000] .bss : 0xc0b29f3c - 0xc0d09c48 (1920 kB) ---->未初始化数据段
[ 0.000000] SLUB: Genslabs=11, HWalign=64, Order=0-3, MinObjects=0, CPUs=8, Nodes=1 ---->linux内核内存分配器
由__init修饰的函数存放段,该函数只会执行一次,之后所对应的内存会被释放:
[ 4.475000] devtmpfs: mounted
[ 4.478000] Freeing init memory: 244K
2、linux内存的分配器(SLUB,SLOB,SLAB)
kernel\mm ---->关于SLUB、SLOB、SLAB对于源码位置
SLUB,SLOB,SLAB区别:
1) SLOB是针对嵌入式系统的,并且内存在32M以下.
2) SLAB是最早期的内存分配器.
3) SLUB是SLOB和SLAB的内存分配器的取代者.
3、在内核中如何分配内存---申请内存
1)申请内存:kmalloc
#include <linux/slab.h>
static __always_inline void *kmalloc(size_t size, gfp_t flags)
size_t size size_t ---> unsigned int 申请内存的大小
gfp_t flags ---->分配内存的标志
typedef enum {
GFP_KERNEL,--->正常分配内存,内存分配在lowmem区
GFP_ATOMIC,---->分配内存的过程是一个原子操作,该过程不能被打断,如果在申请内存的程序中,是一个原子过程
则使用该标志,比如:中断服务程序中,申请内存
} gfp_t;
返回值:void *
成功:返回该内存对应的基址,该申请的内存大小为:2 * PAGE_SIZE
失败:返回NULL
2)释放内存
static inline void kfree(void *p)
3)申请内存:vmalloc()
#include <linux/vmalloc.h>
void *vmalloc(unsigned long size)
4)释放内存:vfree
void vfree(const void *addr)
malloc、kmalloc与vmalloc的区别:
1)kmalloc和vmalloc是分配的是内核的内存,malloc分配的是用户的内存
2)kmalloc保证分配的内存在物理上是连续的,vmalloc保证的是在虚拟地址空间上的连续
3)kmalloc能分配的大小有限,vmalloc和malloc能分配的大小相对较大
4)内存只有在要被DMA访问的时候才需要物理上连续
5)vmalloc比kmalloc要慢
二、MMU
1、什么是MMU
MMU,即Memory Manmager Unit(内存管理单元),是cpu核中的一个硬件模块,不是所有的CPU都有该模块。MMU的模块会使得CPU的处理速度加快。
2、MMU作用
1) MMU实现虚拟地址与物理地址的转换。嵌入式linux,WINCE,VxWorks操作系统只能运行在虚拟地址上,不能直接运行在物理地址上。
物理地址:硬件平台上寄存器的地址,来自于原理图,cpu手册;
虚拟地址:操作系统的地址,方便内核保护(内核空间和用户空间),可以实现不同进程之间的切换,有利于进行的通信。
2)设置虚拟地址空间访问属性:只读,只写,禁止访问。
3、MMU做地址转换的单位
MMU做地址转换的时候,不是一个一个转换,而是一块一块转换的。
所对应的单位:
1) section(段):1MB
2) larger page(大页):64KB
3) little page(小页):4KB ----->(linux page = 4KB)
4) tiny page(极小页):1KB
GPIO口每组大小为:4KB
4、MMU工作原理
简单的来讲--->查表
1) 表(page table),页表是在使用MMU之前,就需要在内存中创建一个页表,页表的首地址叫TTB,该地址要保存到MMU中,当打开 MMU后,MMU会自动去查表,得到虚拟地址和物理地址的关系。
2) 表的索引--->虚拟地址的索引
3) 表的内容--->是虚拟地址与物理地址的转换关系和访问属性
5、MMU与ioremap的关系
虚拟地址 = ioremap(物理地址,物理地址的大小)。ioremap()实质上是一个改写页表的过程,重新定义了虚拟地址与物理地址的这种关系。
觉得有帮助的话,打赏一下呗。。