@[toc]

在这里插入图片描述

https://github.com/wdfk-prog/linux-study

前言

  • 之所以写这个文章,是因为阅读linux源码时被坑了.直接F12跳转到了其他地方.分析了半天都看不明白.晕头转向的.跳回来在分析了一遍才发现有个坑的地方.特除记录说明.

lib/decompress_inflate.c

  • 这里的__gunzip函数需要进行malloc.如果直接用F12进行跳转到函数声明与定义的地方,大概率是跳转到include/linux/decompress/mm.h
1
2
3
4
5
6
/* Use defines rather than static inline in order to avoid spurious
* warnings when not needed (indeed large_malloc / large_free are not
* needed by inflate */

#define malloc(a) kmalloc(a, GFP_KERNEL)
#define free(a) kfree(a)
  • 实际上这里还未进行内核初始化与内存初始化.new_kmalloc_cache并未调用,slab的索引数组并未进行任何赋值定义.进行相关分析,一定是分析错误的.一定是会分析到回收的逻辑去.这就陷入的死循环的僵局了.

arch/arm/boot/compressed/decompress.c

  • 这时回头看一下arch/arm/boot/compressed/decompress.c
  • 可以发现decompress_inflate.c是使用include进入,而不是进行引用的
1
2
3
4
5
6
7
8
9
10
11
#define STATIC static
#define STATIC_RW_DATA /* non-static please */

#ifdef CONFIG_KERNEL_GZIP
#include "../../../../lib/decompress_inflate.c"
#endif

int do_decompress(u8 *input, int len, u8 *output, void (*error)(char *x))
{
return __decompress(input, len, NULL, NULL, output, 0, NULL, error);
}

lib/decompress_inflate.c

  • 带着#define STATIC static再来分析这个源文件
  • #include <linux/decompress/mm.h>注意这里的头文件,定义了STATIC时,malloc使用的是简单的版本
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
#ifdef STATIC

MALLOC_VISIBLE void *malloc(int size)
{
void *p;

if (size < 0)
return NULL;
if (!malloc_ptr)
malloc_ptr = free_mem_ptr;

malloc_ptr = (malloc_ptr + 7) & ~7; /* Align */

p = (void *)malloc_ptr;
malloc_ptr += size;

if (free_mem_end_ptr && malloc_ptr >= free_mem_end_ptr)
return NULL;

malloc_count++;
return p;
}

MALLOC_VISIBLE void free(void *where)
{
malloc_count--;
if (!malloc_count)
malloc_ptr = free_mem_ptr;
}

#endif

总结

所以decompress.c在boot阶段还未进入内核时,调用的malloc是简单版本,并不是linux内核中的kmalloc函数.