linux内存学习笔记(一)

 

一、内存管理单元MMU

该单元辅助操作系统进行内存管理,提供虚拟地址和物理地址的映射、内存访问权限保护和Cache缓存控制等硬件支持。

(1)       TLB:它缓存少量的虚拟地址与物理地址的转换关系。“快表”

(2)       TTW:包含所有虚拟地址与物理地址的转换关系。TTW成功后,结果写入TLB

二、arm平台linux内存映射(来自《解析基于ARM9 的Linux 内存映射》)

arm中的地址转换表不是一下子就建立的,分为三个阶段

(1)       第一阶段是发生在内核解压缩,自引导时,也就内核镜像zimage 的文件头部分。在/arch/arm/boot/compressed/head.S中实现,这个映射表是临时的,是为了提高内核解压缩时的速度而实现的。在解压缩结束之后,进入内核代码之前,MMU 功能就被关闭了,随之的映射表也被废弃不用。

(2)       第二阶段是的页表创建是非常关键的。同样也是使用汇编语言来实现,具体文件路径为:/arch/arm/kernel/head.S。在代码,有个函数__create_page_tables,这就是创建MMU 映射表,开启MMU 做准备的重要动作

(3)       第三阶段是创建更高级别的映射关系和映射方法,主要和架构相关。不同的架构有不同的映射方法,比如ARM 就是二级映射的方法实现地址映射,但是必须按照LINUX 的三级映射模型PGD、PMD、PTE 来实现。从内核代码上来看,内核启动的过程中主要有两个函数比较重要:(1)start_kernel->setup_arch->paging_init->bootmem_init->bootmem_init_node->create_mapping(2)start_kernel->setup_arch->paging_init->devicemaps_init(3)start_kernel->trap_init函数一:重新建立了一级映射表,添加了对内存空间的二级映射,同时建立了bootmem 这个内存管理器。函数二:在再bootmem 的帮助下实现了平台部分设备IO 地址的映射。函数三:则是完成了中断矢量的映射。

三、用户空间内动态申请

#include <stdlib.h>

void *malloc(size_t size);

void free(void *ptr_to memory);

四、内核空间内存动态申请

void * kmalloc(size_t size,int flags);

kmalloc()的底层依赖__get_free_pages()实现。最常用的分配标志GFP_KERNEL,其含义为在内核空间的进程中申请内存。该函数标志可引起进程阻塞。

GFP_ATOMIC,不会引起阻塞。

GFP_USER,为用户空间分配内存。

GFP_HIGHUSER,类似GFP_USER,但是从高端分配内存。

GFP_NOIO,不允许I/O初始化

GFP_NOFS,不允许进行任何文件系统调用。

__GFP_DMA,要求分配在能够DMA的内存区。

__GFP_HIGHMEM,指示分配的内存可以位于高端内存。

__GFP_COLD,请求一个较长时间不访问的页。

__GFP_NOWARN,分配无法满足时,阻止内核发出警告。

__GFP_HIGH,高优先级请求,允许获得被内核保留给紧急状态使用的最后的内存页。

__GFP_REPEAT,分配失败则尽力重复尝试。

__GFP_NOFAIL,标志只允许申请成功,不推荐。

__GFP_NORETRY,若申请不成功,则放弃。

 

__get_free_pages()系列函数

get_zeroed_page(unsigned int flags);

返回一个指向新页的指针,并将该页清零。

__get_free_page(unsigned int flags);

返回一个指向新页的指针,不清零。

__get_free_pages(unsigned int flags,unsigned int order);

返回可分配多个页并返回分配内存的首地址,分配的页数为2的order次方。

void free_page(unsigned long addr);

void free_pages(unsigned long addr,unsigned long order);

flags的参数说明与kmalloc()的flags一致。

 

 

void *vmalloc(unsigned long size);

void vfree(void *addr);

此函数一般用于分配较大的缓冲区,分配少量的内存是不合理的

 

 

slab与内存池

slab在底层每次申请1页或多页,之后再分隔这些页为更小的单元,从而节省了内存。内存池和slab设计目的相仿。

创建slab

struct kmem_cache *kmem_cache_create(const char *name,

size_t size,size_t align,unsigned long flags,

void (*ctor)(void *,struct kmem_cache *,unsigned long),

void (*dtor)(void *,struct kmem_cache *,unsigned long));

 

              flags,SLAB_NO_REAP,即使内存紧缺时也不自动收缩这块缓存。

                     SLAB_HWCACHE_ALIGN,每个数据对象被对齐到一人缓存行。

                     SLAB_CACHE_DMA,要求数据对象在DMA内存区分配。

       分配slab缓存

              void *kmem_cache_alloc(struct kmem_cache *cachep,gfp_t flags);

       释放

              void kmem_cache_free(struct kmem_cache *cachep,void *objp);

       回收

              int kmem_cache_destroy(struct kmem_cache *cachep);

slab使用模板

              static kmem_cache_t *xxx_cachep;

              xxx_cachep=kmem_cache_create(“xxx”,sizeof(struct xxx),0,

                                                 SLAB_HWCACHE_ALIGN|SLAB_PANIC,NULL,NULL);

              struct xxx *ctx;

              ctx=kmem_cache_alloc(xxx_cachep,GFP_KERNEL);

              kmem_cache_free(xxx_cachep,ctx);

              kmem_cache_destroy(xxx_cachep);

       在/proc/slabinfo节点中可以获知当前slab的分配和使用情况。

创建内存池

       mempoo_t *mempool_create(int min_nr,mempool_alloc_t *alloc_fn,

                            mempool_free_t *free_fn,void *pool_data);

min_nr,预分配对象的数目

alloc_fn的free_fn,内存池对象分配和回收函数的指针。

pool_data,是分配和回收函数要用到的指针。

       分配和回收对象

       void *mempool_alloc(mempool_t *pool,int gfp_mask);

       void *mempool_free(void *element,mempool_t *pool);

gfp_mask,分配标记,只有当__GFP_WAIT标记被指定时,分配函数才会休眠。

       回收内存池

       void mempool_destroy(mempool_t *pool);

 

五、I/O内存

动态映射

void *ioremap(unsigned long offset,unsigned long size);

void inunmap(void *addr);

访问

unsigned int ioread8(void *addr);

unsigned int ioread16(void *addr);

unsigned int ioread32(void *addr);

 

void iowrite8(u8 value,void *addr);

void iowrite16(u16 value,void *addr);

void iowrite32(u32 value,void *addr);

 

void ioread8_rep(void *addr,void *buf,unsigned long count);

void ioread16_rep(void *addr,void *buf,unsigned long count);

void ioread32_rep(void *addr,void *buf,unsigned long count);

 

void iowrite8_rep(void *addr,void *buf,unsigned long count);

void iowrite16_rep(void *addr,void *buf,unsigned long count);

void iowrite32_rep(void *addr,void *buf,unsigned long count);

 

void memcpy_fromio(void *dest,void *source,unsigned int count);

void memcpy_toio(void *dest,void *source,unsigned int count);

 

I/O内存申请

struct resource *request_mem_region(unsigned long start,unsigned long len,char *name);

void release_mem_region(unsigned long start,unsigned long len);

上面两个函数是检查申请的资源是否可用,如果可用再进行ioremap()申请,这样会访问会相对安全一些。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Linux 学习笔记整理 一、Linux 简介 Linux,全称 GNU/Linux,是一种自由和开放源代码的类 Unix 操作系统,它主要是由 Linus Torvalds 在 1991 年创建的。Linux 操作系统具有多用户、多任务、多线程、支持多种文件系统、网络功能强大等优点。 二、Linux 基础命令 1. 基本操作命令 cd:切换目录,例如:cd /usr/local ls:查看目录下文件,例如:ls /usr/local mkdir:创建目录,例如:mkdir test rmdir:删除目录,例如:rmdir test cp:复制文件,例如:cp a.txt b.txt rm:删除文件,例如:rm a.txt mv:移动文件或修改文件名,例如:mv a.txt b.txt 或 mv a.txt /usr/local 2. 文件操作命令 cat:查看文件内容,例如:cat a.txt more:分页显示文件内容,例如:more a.txt less:分页显示文件内容,例如:less a.txt head:显示文件头部内容,例如:head a.txt tail:显示文件尾部内容,例如:tail a.txt grep:查找文件中的关键字,例如:grep "hello" a.txt 3. 权限相关命令 chmod:修改文件权限,例如:chmod 755 a.txt chown:修改文件所属用户和组,例如:chown user:group a.txt su:切换用户,例如:su root sudo:以管理员权限执行命令,例如:sudo apt-get install nginx 4. 网络相关命令 ping:测试网络连通性,例如:ping www.baidu.com ifconfig:查看网络接口信息,例如:ifconfig netstat:查看网络连接状态,例如:netstat -an nslookup:解析域名,例如:nslookup www.baidu.com 5. 系统管理命令 ps:查看进程状态,例如:ps -ef top:实时查看系统资源占用情况,例如:top kill:终止进程,例如:kill 1234 free:查看系统内存使用情况,例如:free -m df:查看磁盘使用情况,例如:df -h 三、常用 Linux 发行版 1. CentOS CentOS(Community Enterprise Operating System)是一款基于 Red Hat Enterprise Linux(RHEL)源代码的 Linux 发行版,它是一个稳定、可靠且高性能的服务器操作系统,广泛用于企业服务器领域。 2. Ubuntu Ubuntu 是一款基于 Debian 的 Linux 发行版,它以易用性、稳定性和安全性著称,适合用于桌面和服务器领域。 3. Debian Debian 是一个由志愿者组成的开源社区开发的 Linux 发行版,以稳定性和安全性著称,适合用于服务器和桌面领域。 4. Fedora Fedora 是由 Red Hat 公司赞助的一个社区项目,它是一个面向桌面用户的 Linux 发行版,以最新的软件包和技术为特点。 四、Linux 常用软件 1. Apache Apache 是世界上最流行的 Web 服务器软件之一,它是一款免费、开源的软件,支持多种操作系统和编程语言,适用于企业和个人网站搭建。 2. MySQL MySQL 是一款流行的关系型数据库管理系统,它是免费、开源的软件,支持多种操作系统和编程语言,适用于企业和个人网站数据存储。 3. Nginx Nginx 是一款高性能的 Web 服务器软件,它是免费、开源的软件,支持多种操作系统和编程语言,适用于企业和个人网站搭建。 4. Git Git 是一款流行的分布式版本控制系统,它是免费、开源的软件,支持多种操作系统和编程语言,适用于团队协作和代码管理。 五、Linux 学习资源推荐 1. Linux 命令大全 2. Linux 教程 3. Linux 学习路径 4. Linux 知识库 5. Linux 命令在线手册 六、总结 本文介绍了 Linux 的基础知识、常用命令、常用发行版、常用软件和学习资源,希望能够帮助读者快速了解 Linux 并入门。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值