|
|
EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
. S* w, Z( A h3 P# c$ B/ }# K9 Y' o8 _linux 内核庞大而复杂。内核代码阅读的时候,有没有遇到因为宏定义或者inline层次太深而不知道到底代码是什么样子。代码预处理可以解决这个难题。( ~ G/ @* z# w
7 f; Y0 X( t4 X9 a# M& G
平台:linux 3.4.5 ARM,PC linux上类似,更简单些。
/ U* H2 i. Y: Y) o3 H1 v4 U+ y: V7 c1 l
加V=1重新编译内核
# Z: [( {* N# G$ N" j+ B- G" V/ g+ A7 H2 X& @ ~
make内核增加V=1选项,会详细打印编译过程,-B是要求重新编译内核所有模块。
. C2 Q- v: N$ k4 f6 H1 A( ]& K! e( C$ q: y, |2 B" J- M
- cd linux-3.4.5 && make ARCH=arm defconfig && make ARCH=arm CROSS_COMPILE=arm-buildroot-linux-uclibcgnueabi- EXTRAVERSION=- -B V=1 uImage/ {5 a# V8 @) b# n1 W2 E5 V
9 T1 S5 S% o: P2 X
编译内核并保存编译log到文件,搜索你要预编译的文件,如mm/slab.c,会找到如下编译命令:
" h4 o+ ^ i+ K! e+ T7 } r& @2 N& r# @3 D3 n2 }- x% E
- arm-buildroot-linux-uclibcgnueabi-gcc -Wp,-MD,mm/.slab.o.d -nostdinc -isystem /home/test/build/gcc-4.9.8/build_arm/staging_dir/usr/bin/../lib/gcc/arm-buildroot-linux-uclibcgnueabi/4.9.8/include -I/home/test/linux/kernels/linux-3.4.5/arch/arm/include -Iarch/arm/include/generated -Iinclude -include /home/test/linux/kernels/linux-3.4.5/include/linux/kconfig.h -D__KERNEL__ -mlittle-endian -Iarch/arm/mach-zx297510/include -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs -fno-strict-aliasing -fno-common -Werror-implicit-function-declaration -Wno-format-security -fno-delete-null-pointer-checks -O2 -marm -fno-dwaRF2-cfi-asm -mabi=aapcs-linux -mno-thumb-interwork -funwind-tables -D__LINUX_ARM_ARCH__=7 -march=armv7-a -msoft-float -Uarm -Wframe-larger-than=1024 -fno-stack-protector -Wno-unused-but-set-variable -fomit-frame-pointer -g -fno-inline-functions-called-once -Wdeclaration-after-statement -Wno-pointer-sign -fno-strict-overflow -fconserve-stack -DCC_HAVE_ASM_GOTO -D"KBUILD_STR(s)=#s" -D"KBUILD_BASENAME=KBUILD_STR(slab)" -D"KBUILD_MODNAME=KBUILD_STR(slab)" -c -o mm/.tmp_slab.o mm/slab.c% i7 m% f- H2 x
; C8 U: D4 H" d
编译预处理指定文件& z9 B3 H" s6 @0 X3 u" F \. W; B7 J
: P' j9 c7 x( w, ~1 U! U把编译命令修改成预处理命令:-c -o mm/.tmp_slab.o修改成-E -o mm/slab.E mm/slab.c,在内核目录linux-3.4.5直接执行。如果是交叉编译链,可能需要把arm-buildroot-linux-uclibcgnueabi-gcc所在路径加入到环境变量PATH里。* _0 X# H% u! s" Z4 y$ q
& s' w, T- M c i! [$ W# j- arm-buildroot-linux-uclibcgnueabi-gcc -Wp,-MD,mm/.slab.o.d -nostdinc -isystem /home/test/build/gcc-4.9.8/build_arm/staging_dir/usr/bin/../lib/gcc/arm-buildroot-linux-uclibcgnueabi/4.9.8/include -I/home/test/linux/kernels/linux-3.4.5/arch/arm/include -Iarch/arm/include/generated -Iinclude -include /home/test/linux/kernels/linux-3.4.5/include/linux/kconfig.h -D__KERNEL__ -mlittle-endian -Iarch/arm/mach-zx297510/include -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs -fno-strict-aliasing -fno-common -Werror-implicit-function-declaration -Wno-format-security -fno-delete-null-pointer-checks -O2 -marm -fno-dwarf2-cfi-asm -mabi=aapcs-linux -mno-thumb-interwork -funwind-tables -D__LINUX_ARM_ARCH__=7 -march=armv7-a -msoft-float -Uarm -Wframe-larger-than=1024 -fno-stack-protector -Wno-unused-but-set-variable -fomit-frame-pointer -g -fno-inline-functions-called-once -Wdeclaration-after-statement -Wno-pointer-sign -fno-strict-overflow -fconserve-stack -DCC_HAVE_ASM_GOTO -D"KBUILD_STR(s)=#s" -D"KBUILD_BASENAME=KBUILD_STR(slab)" -D"KBUILD_MODNAME=KBUILD_STR(slab)" -E -o mm/slab.E mm/slab.c, s- l( c/ {; I) N( c+ o. D
R% W& V9 F$ d$ g执行完命令,在内核的mm目录就能看到slab.c的预处理后文件slab.E文件了。看一下kmalloc函数代码,是不是清晰很多了。
" h* o: D1 R( c" Q. y. b! u2 J- U6 }" \! R- Q: e& n5 h
slab_def.h里的原始kmalloc v* `( O9 @- ?: a$ i: W* {: D
5 ^0 T9 f( F0 }! U7 B6 k- static __always_inline void *kmalloc(size_t size, gfp_t flags)
- {
- struct kmem_cache *cachep;
- void *ret;
- if (__builtin_constant_p(size)) {
- int i = 0;
- if (!size)
- return ZERO_SIZE_PTR;
- #define CACHE(x) \
- if (size <= x) \
- goto found; \
- else \
- i++;
- #include <linux/kmalloc_sizes.h>
- #undef CACHE
- return NULL;
- found:
- #ifdef CONFIG_ZONE_DMA
- if (flags & GFP_DMA)
- cachep = malloc_sizes.cs_dmacachep;
- else
- #endif
- cachep = malloc_sizes.cs_cachep;
- ret = kmem_cache_alloc_trace(size, cachep, flags);
- return ret;
- }
- return __kmalloc(size, flags);
- }
" R! S) L# _9 C+ ~7 k: R- b 3 D( L" k& m4 n; w6 M+ D* }; V
预处理后的kmalloc,流程是不是清晰多了。
3 c$ ~" E b( V; x% s. I% H% z
( ]: P6 n: F3 P7 ~0 f. e- static inline __attribute__((always_inline)) __attribute__((always_inline)) void *kmalloc(size_t size, gfp_t flags)
- {
- struct kmem_cache *cachep;
- void *ret;
- if (__builtin_constant_p(size)) {
- int i = 0;
- if (!size)
- return ((void *)16);
- # 1 "include/linux/kmalloc_sizes.h" 1
- if (size <= 32) goto found; else i++;
- if (size <= 64) goto found; else i++;
- if (size <= 128) goto found; else i++;
- if (size <= 192) goto found; else i++;
- if (size <= 256) goto found; else i++;
- if (size <= 512) goto found; else i++;
- if (size <= 1024) goto found; else i++;
- if (size <= 2048) goto found; else i++;
- if (size <= 4096) goto found; else i++;
- if (size <= 8192) goto found; else i++;
- if (size <= 16384) goto found; else i++;
- if (size <= 32768) goto found; else i++;
- if (size <= 65536) goto found; else i++;
- if (size <= 131072) goto found; else i++;
- if (size <= 262144) goto found; else i++;
- if (size <= 524288) goto found; else i++;
- if (size <= 1048576) goto found; else i++;
- if (size <= 2097152) goto found; else i++;
- if (size <= 4194304) goto found; else i++;
- # 145 "include/linux/slab_def.h" 2
- return ((void *)0);
- found:
- cachep = malloc_sizes.cs_cachep;
- ret = kmem_cache_alloc_trace(size, cachep, flags);
- return ret;
- }
- return __kmalloc(size, flags);
- }5 L1 z4 O( U, \+ d$ R4 W+ E
|
|