如何调试和阅读linux内核源码

1)SourceInsight 必备工具
2)Makefile 中
CC =$(CROSSCOM_PILE)gcc 改成
CC =$(CROSSCOM_PILE)gcc -g
这样产生的vmlinux带有调试信息

3)
vmlinux: 处
$(LD) ... 改成
$(LD) -Map vmlinux.Map
这样能生成Mapfile vmlinux.Map,里面可能有有用信息

4)
看linux入口,各段信息
objdump -h vmlinux
更详细的符号表
objdump -x vmlinux
c和汇编的混合文件,非常有用
objdump -Slz vmlinux
调试信息
objdump -g vmlinux

5)
gdb vmlinux
(gdb)info file
(gdb)l start_kernel
(gdb)info line
(gdb)info source
虽然gdb不能调试内核,但查找函数,变量定义的位置非常方便
唯一缺点不能查到宏
尤其参看初始化函数的时候非常有用,比如
objdump -x vmlinux|grep .setup.init
gdb vmlinux
(gdb)l __setup_ide_setup
(gdb)info line
(gdb)info source

6)产生宏展开
linux内核有这个规则了

make drivers/block/floppy.i
make arch/i386/kernel/head.s
分别产生drivers/block/floppy.c和arch/i386/kernel/head.S的预编文件

7)
make vmlinux产生的信息很有用,尤其ld 时各个.o的顺序
虽然vmlinux.lds中的ENTRY()和Makefile中的ld -e指定程序的起始地址,
但一般第一个.o就是内核开始执行的地方
当然最关键的是 -T vmlinux.lds
看懂vmlinux.lds的内容,很重要
Makefile和lds文件的语法可以查info
更好的方法是
info make > make.txt
info ld > ld.txt
然后到make.txt和ld.txt中搜

8)
用skyeye来调试内核
注意skyeye的conf文件要跟skyeye的版本一致
安装可以到skyeye的主页上看,只要安装二进制文件即可。
目前能调试arm uclinux 和arm linux。
9)寻找宏定义的位置
比如寻找arch/armnommu/kernel/setup.c中宏定义的END_MEM的定义在什么地方
make arch/armnommu/kernel/setup.i则命令行上提示
arm-elf-gcc -E -D__KERNEL__
-I/usr/src/skyeye/uClinux-Samsung/linux-2.4.x/include -Wall
-Wstrict-prototypes -Wno-trigraphs -O2 -fno-strict-aliasing -fno-common
-fno-common -pipe -fno-builtin -D__linux__ -g -DNO_MM -mapcs-32
-mtune=arm7tdmi -mshort-load-bytes -msoft-float
arch/armnommu/kernel/setup.c > arch/armnommu/kernel/setup.i
我们把它改一下 cat arch/armnommu/kernel/setup.c - |arm-elf-gcc -E
-D__KERNEL__ -I/usr/src/skyeye/uClinux-Samsung/linux-2.4.x/include -Wall
-Wstrict-prototypes -Wno-trigraphs -O2 -fno-strict-aliasing -fno-common
-fno-common -pipe -fno-builtin -D__linux__ -g -DNO_MM -mapcs-32
-mtune=arm7tdmi -mshort-load-bytes -msoft-float - >
arch/armnommu/kernel/setup.i
运行
然后输入#define END_MEM 0
CTRL_D退出
这时gcc打出warning
:662: warning: `END_MEM' redefined
/usr/src/skyeye/uClinux-Samsung/linux-2.4.x/include/asm/arch/memory.h:18:
warning: this is the location of the previous definition
这样我们就找到了END_MEM定义的地方了。
上面方法用到了-(减号)在linux下代表终端的意思,这样的好处是不用修改源文件。
不知道还有没有更好的办法。





转自:http://embedlinux.ycool.com/post.2798483.html
专注于嵌入式LINUX,总结工作经验,深入内核世界。锻造嵌入式LINUX整体解决方案的构建能力。
坚持对文章的内容及形式进行持续改进...
坚持原创。坚持工作过程总结。坚持图片文章...
渐近式嵌入式LINUX原创技术积累...
经典代码阅读和读书笔记记录...
汇编语言及C语言编程不断磨练印记...

你可能感兴趣的:(如何调试和阅读linux内核源码)