tag 标签: linux内核

相关帖子
相关博文
  • 热度 3
    2023-10-18 08:33
    1206 次阅读|
    0 个评论
    Linux内存管理 | 三、虚拟地址空间管理 上一节,我们主要了解了虚拟内存空间的布局情况,趁热打铁,我们直接从源代码的视角,来看一下Linux内核是如何管理虚拟内存空间的。 废话不多说,直接开始! 1、用户态空间管理 读完上一节我们知道,用户态的布局情况如下: image-20231005160139650 我们运行的可执行程序,被加载进内存后,会作为一个进程存在,这个进程Linux内核会将其抽象成一个结构体。没错,它就是task_struct。 1.1 task_struct结构体 task_struct结构体是进程的抽象,进程所涉及到的内容非常多,下面只列举出一些重要的数据结构,方面理解。 //include/linux/sched.h struct task_struct { ... pid_t pid; //进程PID pid_t tgid; //线程PID struct files_struct * files ; //进程打开的文件信息 struct mm_struct * mm ; //进程虚拟内存空间的内存描述符 ... } 如上,进程抽象为task_struct结构体,通过mm_struct结构体来管理虚拟内存空间。 1.2 mm_struct结构体 每个进程都有唯一的 mm_struct 结构体,也就是前边提到的每个进程的虚拟地址空间都是独立,互不干扰的。 mm_struct的结构体如下: //include/linux/mm_types.h struct mm_struct { ... struct { ... unsigned long task_size; /*sizeoftaskvmspace*/ ... unsigned long mmap_base; /*baseofmmaparea*/ unsigned long total_vm; /*Totalpagesmapped*/ unsigned long locked_vm; /*PagesthathavePG_mlockedset*/ unsigned long pinned_vm; /*Refcountpermanentlyincreased*/ unsigned long data_vm; /*VM_WRITE&~VM_SHARED&~VM_STACK*/ unsigned long exec_vm; /*VM_EXEC&~VM_WRITE&~VM_STACK*/ unsigned long stack_vm; /*VM_STACK*/ unsigned long start_code,end_code,start_data,end_data; unsigned long start_brk,brk,start_stack; unsigned long arg_start,arg_end,env_start,env_end; ... struct vm_area_struct * mmap ; /*listofVMAs*/ struct rb_root mm_rb ; ... }__randomize_layout; ... } 1.3 内核态和用户态的划分 mm_struct里面定义的task_size变量,就是用来划分虚拟内存的用户空间和内核空间的。 unsigned long task_size; task_size也就是两者的分界线,下面我们看下task_size是如何被赋值的。 当我们执行一个新的进程的时候,Linux内核会执行load_elf_binary的API接口,进而调用setup_new_exec函数来实现新进程的创建。 在setup_new_exec函数中,会执行 task_size=TASK_SIZE; 这个TASK_SIZE就是我们设置的内核空间地址和用户空间地址的分界线,由我们自定义配置。 # ifdef CONFIG_X86_32 /* *Userspaceprocesssize:3GB(default). */ # define TASK_SIZEPAGE_OFFSET # define TASK_SIZE_MAXTASK_SIZE /* configPAGE_OFFSET hex default0xC0000000 dependsonX86_32 */ # else /* *Userspaceprocesssize.47bitsminusoneguardpage. */ # define TASK_SIZE_MAX((1UL<<47)-PAGE_SIZE) # define TASK_SIZE(test_thread_flag(TIF_ADDR32)?\ IA32_PAGE_OFFSET:TASK_SIZE_MAX) ...... 这里我们只需要知道TASK_SIZE默认值3为PAGE_OFFSET,并且默认为0xC0000000为分界线的,即用户空间3GB,内核空间1GB;当然这个可以由我们动态配置,可以配置PAGE_OFFSET为0x80000000,即用户空间和内核空间均为2GB,取决于我们的应用场合,当你看到与我们讲解不同时,也不用大惊小怪。 以上,表达的概念很简单,如下图: image.png 1.4 位置信息描述 我们知道用户态内存空间分为几个区域:代码段、数据段、BSS段、堆、文件映射和匿名映射区、栈等几个部分,同样在mm_struct中,定义了这些区域的统计信息和位置。 unsigned long mmap_base; /*baseofmmaparea*/ unsigned long total_vm; /*Totalpagesmapped*/ unsigned long locked_vm; /*PagesthathavePG_mlockedset*/ unsigned long pinned_vm; /*Refcountpermanentlyincreased*/ unsigned long data_vm; /*VM_WRITE&~VM_SHARED&~VM_STACK*/ unsigned long exec_vm; /*VM_EXEC&~VM_WRITE&~VM_STACK*/ unsigned long stack_vm; /*VM_STACK*/ unsigned long start_code,end_code,start_data,end_data; unsigned long start_brk,brk,start_stack; unsigned long arg_start,arg_end,env_start,env_end; total_vm:总映射页面的数目。(这么大的虚拟内存空间,不可能全部映射到真实的物理内存,都是按需映射的,这里表示当前映射的页面总数目) 由于物理内存比较小,当内存吃紧的时候,就会发生 换入换出 的操作,即将暂时不用的页面换出到硬盘上,有的页面比较重要,不能换出。 locked_vm:被锁定不能换出的页面 pinned_vm :不能换出、也不能移动的页面 data_vm:存放数据页的页的数目 exec_vm:存放可执行文件的页的数目 stack_vm:存放堆栈信息页的数目 start_code、end_code:表示可执行代码开始和结束的位置 start_data、end_data:表示已初始化数据的开始位置和结束位置 start_brk、brk:堆的起始地址,结束地址 start_stack:是栈的起始位置,在 RBP 寄存器中存储,栈的结束位置也就是栈顶指针,在 RSP 寄存器中存储。在栈中内存地址的增长方向也是由高地址向低地址增长。 arg_start、arg_end:参数列表的起始位置和结束位置 env_start、env_end:环境变量的起始位置和结束位置 整体的布局情况如下 : image.png 1.5 区域属性描述 尽管已经有了一些变量来描述每一个段的信息,但是Linux内核在mm_struct结构体里面,还有一个专门的数据结构vm_area_struct来管理每个区域的属性。 struct vm_area_struct * mmap ; /*listofVMAs*/ struct rb_root mm_rb ; mmap:为一个单链表,将所有的区域串联起来 mm_rb:为一个红黑树,方便查找和修改内存区域。 下面看一下vm_area_struct数据结构: struct vm_area_struct { /*ThefirstcachelinehastheinfoforVMAtreewalking.*/ unsigned long vm_start; /*Ourstartaddresswithinvm_mm.*/ unsigned long vm_end; /*Thefirstbyteafterourendaddresswithinvm_mm.*/ /*linkedlistofVMareaspertask,sortedbyaddress*/ struct vm_area_struct * vm_next ,* vm_prev ; struct rb_node vm_rb ; struct mm_struct * vm_mm ; /*Theaddressspacewebelongto.*/ struct list_head anon_vma_chain ; /*Serializedbymmap_sem& *page_table_lock*/ struct anon_vma * anon_vma ; /*Serializedbypage_table_lock*/ /*Functionpointerstodealwiththisstruct.*/ const struct vm_operations_struct * vm_ops ; struct file * vm_file ; /*Filewemapto(canbeNULL).*/ void *vm_private_data; /*wasvm_pte(sharedmem)*/ }__randomize_layout; vm_start、vm_end:为该区域在用户空间的起始和结束地址 vm_next、vm_prev:将该区域添加到链表上,便于管理。 vm_rb:将这个区域放到红黑树上 vm_ops:对该区域可以进行的内存操作 anon_vma:匿名映射 vm_file:文件映射 用户态空间的每个区域都由该结构体来管理,最终形成下面的这个结构: image-20231008184824770 顺便介绍一下 我的圈子: 高级工程师聚集地 ,期待大家的加入。 2、内核态空间管理 上面,我们从源码角度了解了用户态空间管理,下面我们看内核态空间管理。 回顾一下,我们内核态的布局情况是怎么样的呢,还记得吗? image-20231005155942462 我们要知道: 内核态的虚拟空间和任何一个进程都没有关系,所有的进程看到的内核态虚拟空间都是一样的。 在内核态,我们直接操作的依旧是虚拟地址,而非物理地址 不同CPU结构下,内核态空间的布局格式是不变的,但是大小会有所调整,比如ARM和X86的大小空间有所不同。 内核态空间管理并不像用户态那样使用结构体来统一管理,而是直接使用宏来定义每个区域的分界线, 下面我们以x86架构来分析内核态空间的管理 2.1 分界线定义 /* *Userspaceprocesssize:3GB(default). */ # define TASK_SIZEPAGE_OFFSET /*PAGE_OFFSET-thevirtualaddressofthestartofthekernelimage*/ # define PAGE_OFFSET((unsignedlong)__PAGE_OFFSET) # define __PAGE_OFFSET__PAGE_OFFSET_BASE # define __PAGE_OFFSET_BASE_AC(CONFIG_PAGE_OFFSET,UL) configPAGE_OFFSET hex default 0xB0000000 if VMSPLIT_3G_OPT default 0x80000000 if VMSPLIT_2G default 0x78000000 if VMSPLIT_2G_OPT default 0x40000000 if VMSPLIT_1G default 0xC0000000 dependsonX86_32 TASK_SIZE:内核态空间与用户态空间的分界线 PAGE_OFFSET:该宏表示内核镜像起始的虚拟地址。 CONFIG_PAGE_OFFSET:这个宏定义的值,根据实际情况自行设定,默认为0XC0000000,可以设置为0X80000000等。 以上,TASK_SIZE就被定义为0XC0000000作为用户态空间和内核态空间的分界线,将4G虚拟内存分配为3G/1G结构。 image-20231010072937276 2.2 直接映射区定义 直接映射区是定义在PAGE_OFFSET和high_memory之间的区域。 PAGE_OFFSET:表示内核镜像的起始地址,上文已经说明。 high_memory也是表示的就是896M这个值,表示高端内存的分界线。 顺便说明以下,TASK_SIZE和PAGE_OFFSET在不同架构下是不同的,在ARM架构下,两者并不相等,本文以X86架构为例 image-20231010073949813 2.3 安全保护区定义 系统会在high_memory和VMALLOC_START之间预留8M的安全保护区,防止访问越界。 VMALLOC_OFFSET表示的是内核动态映射区的偏移,也就是所谓的安全保护区。 # define VMALLOC_START(((unsignedlong)high_memory+VMALLOC_OFFSET)&~(VMALLOC_OFFSET-1)) # define VMALLOC_OFFSET(8*1024*1024) 可以很清楚的看到VMALLOC_OFFSET定义了8M的空间,VMALLOC_START在high_memory基础上,偏移了VMALLOC_OFFSET 8M空间大小作为安全保护区,以防越界访问。 image-20231010074810831 2.3 动态映射区定义 VMALLOC_START和VMALLOC_END之间称为内核动态映射区。 和用户态进程使用 malloc 申请内存一样,在这块动态映射区内核是使用 vmalloc 进行内存分配。 # define VMALLOC_START(((unsignedlong)high_memory+VMALLOC_OFFSET)&~(VMALLOC_OFFSET-1)) # ifdef CONFIG_HIGHMEM # define VMALLOC_END(PKMAP_BASE-2*PAGE_SIZE) # else # define VMALLOC_END(LDT_BASE_ADDR-2*PAGE_SIZE) # endif PKMAP_BASE:是永久映射区的起始地址。 VMALLOC_END:在永久映射区的起始地址下,偏移2个PAGE_SIZE作为安全保护区。 image-20231010075717944 2.4 永久映射区定义 PKMAP_BASE 到 FIXADDR_START 的空间称为永久内核映射,在内核的这段虚拟地址空间中允许建立与物理高端内存的长期映射关系。 比如内核通过 alloc_pages() 函数在物理内存的高端内存中申请获取到的物理内存页,这些物理内存页可以通过调用 kmap 映射到永久映射区中。 # define PKMAP_BASE\ ((LDT_BASE_ADDR-PAGE_SIZE)&PMD_MASK) # define LDT_BASE_ADDR\ ((CPU_ENTRY_AREA_BASE-PAGE_SIZE)&PMD_MASK) # define CPU_ENTRY_AREA_BASE\ ((FIXADDR_TOT_START-PAGE_SIZE*(CPU_ENTRY_AREA_PAGES+1))\ &PMD_MASK) # define FIXADDR_TOT_START(FIXADDR_TOP-FIXADDR_TOT_SIZE) # define FIXADDR_TOP((unsignedlong)__FIXADDR_TOP) # define FIXADDR_TOT_SIZE(__end_of_fixed_addresses<
  • 热度 5
    2023-6-26 06:37
    1157 次阅读|
    0 个评论
    Iperf 是一个网络性能测试工具,可以测试最大 TCP 和 UDP 带宽性能,具有多种参数和UDP特性,可以根据需要调整,可以报告带宽、延迟抖动和数据包丢失。 Iperf3 在 NLNR/DAST 开的的原始版本进行重新设计,其目标是更小、更简单的代码库,并且还提供 Iperf 所不具备的新功能,如: nuttcp 和 netperf iperf 有 Linux,Windows,android,Mac 等版本,下面结合实际网络场景进行 iperf 工具使用的介绍 确保使用 Iperf 测试的服务端和客户端都处于同一局域网内! 1、Iperf环境准备 Iperf 下载链接 : 推荐下载源码路径 , 官网下载 、 Github下载 或者 其他地址2 1.1 Linux源码安装Iperf 以 Ubuntu20.04 为例,下载压缩包 iperf-3.1.3.tar.gz ,解压并进入目录。 tar -zxvf iperf-3.1.3.tar.gz #解压 cd iperf-3.1.3/ #进入解压目录 mkdir linux_install_dir #创建安装目录 ./configure --prefix = /home/dong/WorkSpace/Program/iperf-3.1.3/linux_install_dir #--prefix设置安装目录,即iperf3生成路径,绝对路径 make clean #清除掉之前编译的文件,确保不影响 make #编译 make install #安装 进入 linux_install_dir/bin 安装目录,可以看到 iperf3 可执行文件。我们可以通过 readelf -h iperf3 | grep Machine 可以查看运行平台。 Machine: Advanced Micro Devices X86-64 1.2 Arm交叉编译Iperf 以 Arm 平台为例,解压 iperf-3.11.tar.gz ,并进入目录。 tar -zxvf iperf-3.1.3.tar.gz #解压 cd iperf-3.1.3/ #进入解压目录 mkdir arm_install_dir #创建安装目录 ​ ./configure --host = arm-linux-gnueabihf --prefix = /home/dong/WorkSpace/Program/iperf-3.1.3/arm_install_dir/ CFLAGS = -static # --host设置使用的编译器; --prefix 安装目录; CFLAGS静态编译 ​ make clean #清除掉之前编译的文件,确保不影响 make #编译 make install #安装 进入 arm_install_dir/bin 安装目录,可以看到 iperf3 可执行文件。我们可以通过 readelf -h iperf3 | grep Machine 可以查看运行平台。 Machine: ARM 最后,将 arm_install_dir/bin 目录下的 iperf3 ,拷贝到目标运行平台即可! 至此, IPerf 环境搭建完毕! 2、指令分析 iperf 工具是基于服务器和客户端的工作模式,通讯双方可以作为服务端和客户端进行测试。 Iperf 与 Iperf3 命令些许有些细微的差别,下面简单介绍一下相关命令。 我们先键入 iperf3 -h ,查看命令列表 下面对常用的命令进行分析: Server 服务端指令: iperf -s / iperf3 -s 启动服务,默认监听UDP,监听的默认端口为5201 iperf -s -w 32M -D / iperf3 -s -D 启动服务,-w 设置最大窗口,-D作为守护进程运行于后台 iperf -i1 -u -s -p 5003 / iperf3 -s -p 5003 启动服务,更换监听端口为5003 Client iperf/iperf3 -c remotehost -i 1 -t 30 启动iperf客户端,remotehost为连接的IP,-i为时间间隔,-t为测试时间 iperf/iperf3 -c remotehost -i 1 -t 20 -R 本机的测 iperf/iperf3 -c remotehost -u -i 1 -b 200M 启动iperf客户端,-u即测试udp,-b为最大测试带宽为200M -d 运行双测试模式,进行上下行带宽测试 这将使服务器端反向连接到客户端,使用-L 参数中指定的端口(或默认使用客户端连接到服务器端的端口)。 -P :多线程模式,指定同时连接到服务器的数量。缺省值为1.需要客户端和服务器上的线程支持。如: iperf -c 192.168.1.1 -P 10 -t 60 客户端同时向服务器端发起10个连接线程。 -p :指定服务器侦听和客户端连接的服务器端口,缺省值是5201 -w :设置最大窗口 -D :作为守护进程运行于后台 -u :使用 UDP 通信 -R :反向测试 -i :设置时间间隔 -t :设置测试时间 -b :设置最大测试带宽 3、Iperf测试 3.1 Linux平台 iperf3 -c 192.168.x.1 -b 200M -u -O 3 -R 说明:带宽测试通常采用UDP模式,因为能测出极限带宽、时延抖动、丢包率。在进行测试时,首先以链路理论带宽作为数据发送速率进行测试,例如,从客户端到服务器之间的链路的理论带宽为100Mbps,先用-b 100M进行测试,然后根据测试结果(包括实际带宽,时延抖动和丢包率),再以实际带宽作为数据发送速率进行测试,会发现时延抖动和丢包率比第一次好很多,重复测试几次,就能得出稳定的实际带宽 3.2 ARM平台 iperf3 -s 3.3 测试结果 .\iperf3.exe -c 192.168.4.234 Connecting to host 192.168.4.234, port 5201 local 192.168.4.85 port 55914 connected to 192.168.4.234 port 5201 Interval Transfer Bandwidth 0.00-1.01 sec 6.38 MBytes 53.0 Mbits/sec 1.01-2.00 sec 5.88 MBytes 49.6 Mbits/sec 2.00-3.01 sec 5.50 MBytes 45.6 Mbits/sec 3.01-4.01 sec 6.00 MBytes 50.6 Mbits/sec 4.01-5.01 sec 6.00 MBytes 50.4 Mbits/sec 5.01-6.00 sec 6.00 MBytes 50.6 Mbits/sec 6.00-7.01 sec 5.62 MBytes 46.7 Mbits/sec 7.01-8.01 sec 6.25 MBytes 52.7 Mbits/sec 8.01-9.01 sec 6.12 MBytes 51.4 Mbits/sec 9.01-10.00 sec 6.12 MBytes 51.7 Mbits/sec - - - - - - - - - - - - - - - - - - - - - - - - - Interval Transfer Bandwidth 0.00-10.00 sec 59.9 MBytes 50.2 Mbits/sec sender 0.00-10.00 sec 59.9 MBytes 50.2 Mbits/sec receiver ​ iperf Done. 4、总结 PC和模组确保在同一个局域网内 PC运行 iperf3 -s 作为服务器,模组运行 iperf3 -c 192.168.x.x -b 200M -u -O 3 作为客户端,测试上行带宽,看 sender 模组运行 iperf3 -s 作为服务器,PC运行 iperf3 -c 192.168.x.x -b 200M -u -O 3 作为客户端,测试下行带宽,看 receiver
  • 热度 4
    2023-6-20 20:55
    2057 次阅读|
    0 个评论
    Linux内核态内存泄露检测工具 1、Kmemleak介绍 在 Linux 内核开发中, Kmemleak 是一种用于 检测内核中内存泄漏的工具 。 内存泄漏 指的是程序中已经不再使用的内存没有被妥善地释放,导致内存的浪费。内核中的内存泄漏同样会导致系统性能下降、系统崩溃等问题。 Kmemleak 能够检测内核中的内存泄漏,通过检测内核中未被释放但又无法找到其使用位置的内存,进一步定位、修复内存泄漏的问题。 在用户空间,我们常用 Valgrind 来检测; 在内核空间,我们常用 Kmemleak 来检测。 2、如何使用Kmemleak 2.1 内核配置 内核打开相应配置 : CONFIG_DEBUG_KMEMLEAK : Kmemleak 被加入到内核 CONFIG_DEBUG_KMEMLEAK_EARLY_LOG_SIZE 设置为 16000 :该参数为记录内存泄露信息的内存池,越大记录信息越多。 CONFIG_DEBUG_KMEMLEAK_DEFAULT_OFF : Kmemleak 默认开关状态 依赖的配置 : CONFIG_DEBUG_KERNEL :打开内核调试功能 CONFIG_DEBUG_FS :需要借助到 debugfs CONFIG_STACKTRACE :记录进程的堆栈信息 2.2 用户空间配置 我们要想使用 Kmemleak ,需要挂在 debugfs ,来查看泄露的情况。 进入文件系统后,进行挂载 : mount -t debugfs nodev /sys/kernel/debug/ # 挂在debugfs 设置扫描时间 : echo scan = 10 /sys/kernel/debug/kmemleak # 10S扫描一次 默认内存泄露检测时间为 10min ,上面设置为 10s 一次 查看泄露情况 : cat /sys/kernel/debug/kmemleak # 查看内存泄露情况 其他指令 : echo /sys/kernel/debug/kmemleak #触发一次扫描 echo clear /sys/kernel/debug/kmemleak #清除当前 kmemleak 记录的泄露信息 echo /sys/kernel/debug/kmemleak #关闭kmemleak(不可逆转的) echo stack = /sys/kernel/debug/kmemleak #关闭任务栈扫描 echo stack = /sys/kernel/debug/kmemleak #使能任务栈扫描 echo scan = /sys/kernel/debug/kmemleak #启动自动内存扫描线程 echo scan = /sys/kernel/debug/kmemleak #停止自动内存扫描线程 echo scan = /sys/kernel/debug/kmemleak #设置自动扫描线程扫描间隔,默认是600,设置0则是停止扫描 echo dump = /sys/kernel/debug/kmemleak /sys/kernel/debug/kmemleak即可查看详细信息 2.3 通过Linux启动参数控制开关 Kmemleak 的默认开关状态可以通过 CONFIG_DEBUG_KMEMLEAK_DEFAULT_OFF 配置来控制,当然也可以通过向 Linux 内核启动参数中加入 kmemleak=off 来控制。 3、Kmemleak原理 Kmemleak 提供了一种跟踪垃圾回收器 tracing garbage collector 的原理,来检测内核中存在的内存泄露,其不同之处在于:孤立的对象并没有被释放掉,而是通过 /sys/kernel/debug/kmemleak 仅仅被报告。 这种方法同样应用于 Valgrind 中,不过该工具主要用于检测用户空间不同应用的内存泄露情况。 在用户空间,我们常用 Valgrind 来检测应用进程; 在内核空间,我们常用 Kmemleak 来检测内核代码。 通过 kmalloc() 、 vmalloc() 、 kmem_cache_alloc() 等函数分配内存时,会跟踪指针,堆栈等信息,将其存储在一个红黑树中。 同时跟踪相应的释放函数调用,并从 kmemleak 数据结构中删除指针。 简单理解 :相当于追踪内存分配相关接口,记录分配内存的首地址,堆栈大小等信息,在内存释放阶段将其删除。 我们通过查看相关内核文档可知,内存泄露检测的扫描算法步骤如下: 将所有对象标记为白色(最后剩余的白色对象将被视为孤立对象) 从数据段和堆栈开始扫描内存,根据红黑树中存储的地址信息来检查值,如果找到指向白色对象的指针,则添加到灰色列表 扫描灰色列表以查找地址匹配的对象,直到灰色列表完成 剩下的白色对象被视为孤立对象,并通过/sys/kernel/debug/kmemleak进行报告 4、Kmemleak API接口 kmemleak_init - 初始化 kmemleak kmemleak_alloc - 内存块分配通知 kmemleak_alloc_percpu - 通知 percpu 内存块分配 kmemleak_vmalloc - 通知 vmalloc () 内存分配 kmemleak_free - 通知内存块释放 kmemleak_free_part - 通知释放部分内存块 kmemleak_free_percpu - 通知 percpu 内存块释放 kmemleak_update_trace - 更新对象分配堆栈跟踪 kmemleak_not_leak - 将对象标记为非泄漏 kmemleak_ignore - 不扫描或报告对象泄漏 kmemleak_scan_area - 在内存块内添加扫描区域 kmemleak_no_scan - 不扫描内存块 kmemleak_erase - 擦除指针变量中的旧值 kmemleak_alloc_recursive - 作为kmemleak_alloc,但检查递归性 kmemleak_free_recursive - 作为kmemleak_free,但检查递归性 5、Kmemleak特殊情况 漏报 :真正内存泄露了,但是未报告,因为在内存扫描期间找到的值指向此类对象。为了减少误报的数量, kmemleak 提供了 kmemleak_ignore , kmemleak_scan_area , kmemleak_no_scan 和 kmemleak_erase 功能 误报 :实际没有泄露,但是却错误的报告了内存泄露。 kmemleak 提供了 kmemleak_not_leak 功能。 6、Kmemleak验证 内核也提供了一个示例: kmemleak-test 模块,该模块用以判断是否打开了 Kmemleak 功能。通过配置 CONFIG_DEBUG_KMEMLEAK_TEST 选项可以选择。 # modprobe kmemleak-test /sys/kernel/debug/kmemleak # cat /sys/kernel/debug/kmemleak unreferenced object 0xffff89862ca702e8 (size 32 ): comm "modprobe" , pid 2088 , jiffies 4294680594 (age 375 .486s) hex dump (first 32 bytes): 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b kkkkkkkkkkkkkkkk 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b a5 kkkkkkkkkkkkkkk. backtrace: 0xffffffffc01d2036 do_one_initcall + 0x41/0x1df do_init_module + 0x55/0x200 load_module + 0x203c/0x2480 __do_sys_finit_module + 0xba/0xe0 do_syscall_64 + 0x43/0x110 entry_SYSCALL_64_after_hwframe + 0x44/0xa9 ... 7、参考文章 内核官方文档 : https://www.kernel.org/doc/html/latest/dev-tools/kmemleak.html 其他文章推荐: https://blog.csdn.net/weixin_41944449/article/details/123441820
  • 热度 17
    2013-6-6 14:34
    1029 次阅读|
    0 个评论
    学习Linux内核的参考资料!希望对大家有用!
  • 热度 22
    2012-4-22 22:10
    3076 次阅读|
    0 个评论
    今天编译了一下飞凌的OK6410的uboot和linux内核。发现飞凌的用户手册讲得不够详细。只按着他的步骤走会出现找不到gcc的问题。后来在网上搜了一下,发现是路径的问题。最后进行了如下设置: 1、使用gedit 命令编辑://etc/bash.bashrc。在文件结尾增加:       export PATH=$PATH:/usr/local/arm/4.3.2/bin       export PATH 2、重新编译可以通过了。 最后,抱怨一下飞凌: 1、用户手册更新不够。基本上它官网上有好多与我一样问题的用户。 2、提供的资料不过新。ubuntu9好像已经不支持了。导致我重新安装了一下ubuntu11。 3、反正按着他提供的用户手册很有可能会出问题。还得上网上去找答案。 另,附上《 VMware下Ubuntu与宿主机XP共享文件 》链接。写得挺详细,我也不再废话,地址: http://www.cppblog.com/life02/archive/2012/01/06/163751.aspx
相关资源
  • 所需E币: 3
    时间: 2024-3-14 16:15
    大小: 12.97MB
    上传者: Bymyself
    本书基于Linux 5.x内核的源代码讲述Linux内核中核心模块的实现。本书主要介绍ARM64架构、Linux内核内存管理以及进程管理和调度三大块内容。本书重点介绍Linux内核重要的基础架构实现原理。本书共9章,主要内容包括ARM64架构,ARM64在Linux内核中的实现,内存管理的预备知识,物理内存与虚拟内存,内存管理的高级主题,内存管理的实战案例,进程管理的基础知识,进行管理中的调度和负载均衡,进程管理中的调试与案例分析。本书适合从事Linux系统开发人员、嵌入式系统开发人员及Android开发人员阅读,也可供计算机专业的师生阅读。
  • 所需E币: 3
    时间: 2024-3-14 16:16
    大小: 11.3MB
    上传者: Bymyself
    本书基于Linux 5.0内核的源代码讲述Linux内核的调试技巧和案例。本书共6章。主要内容包括并发与同步,中断管理,内核调试和性能优化,基于x86_64的宕机难题解决方案,基于ARM64的宕机题解决方案,安全漏洞的产生原理与修复方案等。 本书适合从事Linux系统开发人员、嵌入式系统开发人员及Android开发人员阅读,也可供计算机相关专业的师生阅读。
  • 所需E币: 5
    时间: 2019-12-26 01:10
    大小: 135.55KB
    上传者: 16245458_qq.com
    基于ARM的ucLinux、linux内核、驱动、应用调试……
  • 所需E币: 5
    时间: 2019-12-25 11:55
    大小: 4.76MB
    上传者: quw431979_163.com
    本书对Linux早期操作系统内核(v0.11)全部代码文件进行了详细全面的注释和说明,旨在使读者能够在尽量短的时间内对Linux的工作机理获得全面而深刻的理解,为进一步学习和研究Linux系统打下坚实的基础。虽然所选择的版本较低,但该内核已能够正常编译运行,其中已经包括了LINUX工作原理的精髓,通过阅读其源代码能快速地完全理解内核的运作机制。书中首先以Linux源代码版本的变迁历史为主线,详细介绍了Linux系统的发展历史,着重说明了各个内核版本之间的重要区别和改进方面,给出了选择0.11(0.95)版作为研究的对象的原因。另外介绍了内核源代码的组织结构及相互关系,同时还说明了编译和运行该版本内核的方法。然后本书依据内核源代码的组织结构对所有内核程序和文件进行了注释和详细说明。每章的安排基本上分为具体研究对象的概述、每个文件的功能介绍、代码内注释、代码中难点及相关……
  • 所需E币: 5
    时间: 2019-12-24 18:22
    大小: 259.8KB
    上传者: 2iot
    当完成对linux内核的配置以后,需要对内核进行编译,生成最终可以再嵌入式系统上运行的可执行代码。里仁教育分享嵌入式linux内核的编译基础!www.lirenedu.org里仁教育―中国3G嵌入式培训的领航者!就业咨询热线:400-028-9880嵌入式linux内核编译基础http://www.lirenedu.org/目录1、linux内核编译基本步骤2、rules.make文件3、makefile配置文件的用法4、配置、编译linux内核命令说明5、linux内核配置编译实例http://www.lirenedu.org/linux内核编译基本步骤(1):执行如下命令,删除过时的文件:#makecleanmakeclean会删除原来的编译结果,以及一些旧的数据文件。(2):执行如下命令进行依赖性编译:#makedep(3):执行如下命令。生成可执行的内核映像文件:#make这一步是实际的编译过程,最终会生成可运行在嵌入式系统上的内核映像文件,当执行完成这一步后,会在当前目录下生成一个内核映像文件zimage。http://www.lirenedu.org/rules.make文件用法rules.make文件包含了各级目录下的makefile共同遵循的编译规则,比如将C文件编译成目标文件的规则、将汇编文件生成目标文件的规则等。各级子目录下的makefile通过语句include$/rules.make将其包含,用以识别各makefile中所定义的一些变量,比如.……
  • 所需E币: 5
    时间: 2019-12-24 10:56
    大小: 60.5KB
    上传者: 16245458_qq.com
    linux内核编译详解linux内核编译详解linux内核编译详解||| linux内核编译详解[本文最初由solaris发布]||一、内核简介||内核,是一个操作系统的核心。它负责管理系统的进程、内存、设备驱||动程序、文件和网络系统,决定着系统的性能和稳定性。||||linux的一个重要的特点就是其源代码的公开性,所有的内核源程序都可以在/||usr/src/linux下找到,大部分应用软件也都是遵循GPL而设计的,你都可以获||取相应的源程序代码。全世界任何一个软件工程师都可以将自己认为优秀的代||码加入到其中,由此引发的一个明显的好处就是Linux修补漏洞的快速以及对||最新软件技术的利用。而Linux的内核则是这些特点的最直接的代表。||想象一下,拥有了内核的源程序对你来说意味着什么?首先,我们可以了||解系统是如何工作的。通过通读源代码,我们就可以了解系统的工作原理,这||在||Windows下简直是天方夜谭。其次,我们可以针对自己的情况,量体裁衣,定||制适合自己的系统,这样就需要重新编译内核。在Windows下是什么情况呢?||相信很多人都被越来越庞大的Windows整得莫名其妙过。再次,我们可以对内||核进行修改,以符合自己的需要。这意味着什么?没错,相当于自己开发了一……