内存测量

系统占用内存 free 旧版本free $ free total used free shared buffers cached Mem: 65960636 63933576 2027060 73392 1602076 32628548 -/+ buffers/cache: 29702952 36257684 Swap: 0 0 0 (1)第一行Mem:内存的使用情况,默认单位是Kb。 - tot

进程虚拟内存

进程虚拟地址空间 Executable and Linkable Format(ELF)   上图是可执行文件的内容结构图,由ELF header、program headers、各section、sections headers组成。 - ELF header:描述整个文件的基本属性,如文件版本号、目标机器型号、程序入口地址等。 - program headers:描述ELF文件该如何被操作系统

DMA与cache一致性

无DMA时:设备与内存之间数据搬运需要依靠CPU来完成。 有DMA时:DMA可以直接完成设备与内存直接的数据搬运,不需要cpu介入。 DMA的引入,优点是数据在内存和设备之间的搬运不需要CPU参与,这极大降低了CPU的负荷。但是也引入了新的问题,即cpu读取到的数据不一定是最新的,是因为中间cache的存在(如上图有DMA的情况),具体表现为当DMA修改从Device读取数据写入到memory后,

连续内存分配器CMA

CMA,contiguous memory allocator是内存管理子系统的一个模块,其主要为了解决分配连续的物理内存。尽管有了伙伴系统、slab分配器以及相关的内存回收机制,但是对于一些驱动如camera、display等模块一下需要分配比较大的一块连续物理内存,随着系统运行久之后,碎片化严重,分配较大的连续内存会变得困难,而同时又不能直接预留一块大的连续内存只用于连续物理内存分配,因为当模

slub分配器

伙伴系统内存分配是以物理页面4KB为单位,但是实际使用的时候不会一下使用到4KB。实际使用中很多情况会以字节为单位。因此为了更精确的划分使用内存,linux内核在伙伴系统之上使用slab分配器来进行管理。截止目前linux内核中从最初slab发展到现在,衍生了slub,slob三种方式。Linux内核通过配置,选择其中一种。本章节主要围绕slub分配器进行说明。 乒乓球的管理 某公司的组织架构如上

伙伴系统

相关结构体 核心结构体 struct pglist_data: 节点的描述,arm64 UMA架构中,只有一个节点。 struct zone node_zone:是一个数组,每个元素表示一个内存区域所对应的 struct zone 结构体。从名字可以看出,此数组的长度为 MAX_NR_ZONES,即它最多可以包含 MAX_NR_ZONES 个元素,因此,此数组通常用于描述系统所能支持的所有内存

内存初始化之物理内存初始化

恒等映射与内核镜像映射__create_page_tables preserve_boot_args:保持启动参数到boot_args数组 set_cpu_boot_maode_flag:设置关于cpu boot相关的全局变量 __create_page_tables:创建恒等映射页表,内核映像映射页表 __cpu_setup:为打开mmu做一些cpu相关的初始化 __primary_swit

内存初始化之页表基本操作

页表级数 如何确定page table level?确定了VABITS和PAGES size之后,页表级数也可确定,根据内核的配置如下: config PGTABLE_LEVELS int default 2 if ARM64_16K_PAGES && ARM64_VA_BITS_36 default 2 if ARM64_64K_PAGES && ARM64_VA

内存初始化基本概念

三级结构Node、Zone、Page Node与内存架构UMA、NUMA UMA架构(uniform memory acces) 一致内存访问,所有CPU访问内存都需要过总线,距离都是一样的,所以每个处理器访问各个内存块都是同样快。如上图4个CPU都通过系统总线来访问物理内存DDR。目前大部分嵌入式系统或台式机系统采用UMA架构。 NUMA架构(Non-uniform memory acces)

文件系统缓存

#To free pagecache echo 1 > /proc/sys/vm/drop_caches #To free dentry and inode cache echo 2 > /proc/sys/vm/drop_caches #To free pagecache,dentry cache,inode cache echo 3 > /proc/sys/vm/drop_c

内存管理概述

地址空间   虚拟地址:程序使用的内存地址;物理地址:硬件的地址空间。虚拟地址通过MMU转化为物理地址,虚拟地址的长度与实际的物理内存容量没有关系,从系统中每个进程的角度看,地址空间的进程无法感知其他进程的存在。   32位cpu处理的地址空间为2^32=4G,所以虚拟地址空间为4G,分为用户空间和内核空间。用户空间的范围0~TASK_SIZE(可配置)通常为0x00000000~0xBFFFFF

一切皆文件之块设备驱动(五)

实验环境 准备 kernel version: linux 5.15 kernel module: 块设备:simpleblk.ko 文件系统:simplefs.ko application: 制作文件系统:mkfs.simplefs 步骤 1.加载块设备驱动:insmod simpleblk.ko 2.加载文件系统:insmod simplefs.ko 3.查看文件系统类型:cat /proc/

一切皆文件之块设备驱动(四)

实验环境 kernel version: linux 5.15 kernel module: simpleblk.ko 参考上一章节 application:app_test 参考上一章节 块设备无文件系统方式读写 写数据 存储设备没有格式化挂载文件系统,那么对磁盘设备的操作会经过/dev/xxx tmpfs文件系统和bdev伪文件系统组合的方式读写磁盘。 Write系统调用经过VFS调用到def

一切皆文件之块设备驱动(二)

打开块设备 mknod 块设备同样要使用mknod创建设备节点,这与字符设备一样。会调用到init_special_inode填充inode的file_operations,只不过块设备注册的是def_blk_fops。 void init_special_inode(struct inode *inode, umode_t mode, dev_t rdev) { inode->i_mode

一切皆文件之块设备驱动(一)

块设备驱动简介 在linux系统中,有3大驱动类型,分别是:字符设备驱动、块设备驱动、网络设备驱动。块设备驱动与文件系统有着密不可分的关系,块设备是文件系统实际的数据传输单位,通常存储设备有eMMC,Nand/Nor flash,机械硬盘,固态硬盘等,这里所说的块设备驱动,实际就是这些存储设备驱动。块设备驱动与字符设备驱动有较大差异,块设备驱动是以块位单位进行读写,而字符设备驱动以字节为单位进行传

一切皆文件之字符设备

#include <linux/module.h> #include <linux/fs.h> #include <linux/uaccess.h> #define DEVICE_NAME \"mychardev\" #define BUFFER_SIZE 1024 static char device_buffer; static int

文件系统常见系统调用

上一章节中,我们编写了没有带磁盘设备的文件系统,了解了文件系统操作的大致流程,本章节我们继续在上一章节的基础上完善文件系统,并梳理从用户空间到内核空间大致的调用流程。实验的代码我们使用开源的示例https://github.com/sysprog21/simplefs/tree/master,在启动本章节之前建议先搭建好试验环境,将simplefs挂载起来,当然有余力的也可以在上一节示例代码的基础

实现简单文件系统

文件系统注册与挂载 static struct file_system_type simplefs_fs_type = { .owner = THIS_MODULE, .name = \"simplefs\", .mount = simplefs_mount, .kill_sb = simplefs_kill_sb, }; static int __init init_simplefs(void) {

虚拟文件系统

  Linux系统中支持多种不同的文件系统,为了是用户可以通过一个文件系统操作界面,对各种不同的文件系统进行操作,在具体的文件系统(ext2/ext4等)之上增加了一层抽象一个统一的虚拟文件系统界面,向上提供归一化的文件操作,这个抽象层就称为虚拟文件系统。 为了实现抽象层,Linux内核定义了4个重要的数据结构对象。 supper block: 管理文件系统的相关描述信息。 Inode:一个文件对