1、Linux内存管理
linux内存最小管理单位为页(page),通常一页为4kb。
linux系统中,在初始化时,内核为每个物理内存页建立一个page的管理结构,操作物理内存时实际上就是操作page页。
物理地址:出现在cpu地址总线上的寻址物理内存的地址信号,是地址变换的最终结果。
线性地址(虚拟地址):在32位cpu架构上,可以表示4G的地址空间,也就是0x00000000-0xFFFFFFFF。
逻辑地址:实际上是一个相对地址,是程序代码经过编译之后在汇编程序中出现的地址。
linux内核地址转换:出现在机器语言指令(程序编译后得到的二进制机器码序列)中的内存地址都是逻辑地址,逻辑地址必须被转换为线性地址,MMU将线性地址转换成物理地址,最终实现对应物理内存的访问。在linux系统中,逻辑地址和线性地址(虚拟地址)是一致的。
2、实例代码
/** *Copyright (c) 2013.TianYuan *All rights reserved. * *文件名称: kernelspace.c *文件标识: 内核空间中内存的申请与释放 * *当前版本:1.0 *作者:wuyq * *取代版本:xxx *原作者:xxx *完成日期:2013-11-18 */ #include <linux/init.h> #include <linux/module.h> #include <linux/fs.h> #include <linux/slab.h> #include <linux/vmalloc.h> MODULE_LICENSE("GPL"); #define PAGE_NUM 4/*编码幻数*/ unsigned char *kernelkmalloc = NULL; unsigned char *kernelpagemem = NULL; unsigned char *kernelvmalloc = NULL; static int __init kernelspace_init(void) { int ret = -ENOMEM; /* *GFP_KERNEL:分配内存,分配过程中可能导致睡眠。 *GFP_ATOMIC:分配过程中不会导致睡眠。 *GFP_DMA:申请到的内存通常情况下,位于0~16M之间 *__GFP_HIGNMEM:申请高端内存(物理地址896M以上的) */ kernelkmalloc = (unsigned char *)kmalloc(100, GFP_KERNEL); if(IS_ERR(kernelkmalloc)){ printk("kmalloc failed!\n"); ret = PTR_ERR(kernelkmalloc); goto failure_kmalloc; } printk("kmalloc space :0x%lx!\n",(unsigned long)kernelkmalloc); kernelpagemem = (unsigned char *)__get_free_pages(GFP_KERNEL, PAGE_NUM);/*请求或释放的页数的2的幂*/ if(IS_ERR(kernelpagemem)){ printk("get_free_pages failed!\n"); ret = PTR_ERR(kernelpagemem); goto failure_get_free_pages; } printk("get_free_pages address:0x%lx\n",(unsigned long)kernelpagemem); kernelvmalloc = (unsigned char *)vmalloc(1024*1024); if(IS_ERR(kernelvmalloc)){ printk("vmalloc failed!\n"); ret = PTR_ERR(kernelvmalloc); goto failure_vmalloc; } printk("vmalloc address: 0x%lx\n",(unsigned long)kernelvmalloc); return 0; failure_vmalloc: free_pages((unsigned long)kernelpagemem, PAGE_NUM); failure_get_free_pages: kfree(kernelkmalloc); failure_kmalloc: return ret; } static void __exit kernelspace_exit(void) { vfree(kernelvmalloc); free_pages((unsigned long)kernelpagemem, PAGE_NUM); kfree(kernelkmalloc); } module_init(kernelspace_init); module_exit(kernelspace_exit);
KERNELDIR ?=/root/Desktop/work/ldd3/linux-2.6.31_TX2440A PWD := $(shell pwd) obj-m += kernelspace.o default: $(MAKE) -C $(KERNELDIR) M=$(PWD) modules clean: @rm -f *.o *.ord* *.sy* *.mod.* *.ko
时间: 2024-10-02 05:45:34