作者:华清远见讲师 刘洪涛
本文主要介绍一个linux内核线程的实例,以及在QEMU平台上测试的过程。
编写一个字符设备驱动,在驱动注册时,开启一个内核线程。在用户向设备写入数据时,字符设备的wirte方法能够激活此内核线程,并在线程中实现打印用户输入的数据。
驱动代码如下(在2.6.22内核上测试通过),关键部分加上了注释:
QEMU可以模拟很多硬件平台,使用QEMU适用于你手边没用硬件平台,或没用很好的内核调试工具的情况。
这里主要介绍使用QEMU模拟ARM开发环境,并运行linux系统的过程。
操作系统平台:Ubuntu 10.10
交叉工具:arm-softfloat-linux-gnu
测试内核:Linux2.6.22
测试平台:RealView-EB (QEMU 模拟)
使用新立得获取安装包
(1)配置好交叉开发工具
(2)配置内核
#cp arch/arm/configs/realview_defconfig .config
#make menuconfig
配置支持initial ramdisk
配置支持Ramdisk块设备:
Device Drivers ->Block devices->RAM disk support
其中:Default RAM disk size (kbytes)必须要改成和你的RAMDISK镜像一样的大小。
配置内核添加调试选项:
Kernel hacking ->Compile the kernel with debug info
设置内核支持ext2文件系统
保存退出。
(3) 将上述的内核线程驱动加入到内核中,然后编译内核。
#make zImage
制作一个8M的ramdisk根文件系统。这个步骤没有什么特别的,可以参考其它资料。
(1)下载GDB源码:
http://ftp.gnu.org/gnu/gdb/gdb-7.2.tar.bz2
(2)交叉编译GDB
#./configure --target=arm-softfloat-linux-gnu –prefix=/home/lht/QEMU/arm-gdb
#make && make install
#qemu-system-arm -M realview-eb -kernel ./zImage -initrd ./initrd.img -nographic -append "console=ttyAMA0" -m 64 -s -S
系统会暂停,等待远端gdb连接调试。在另一终端下运行:
#ddd -debugger /home/lht/QEMU/arm-gdb/bin/arm-softfloat-linux-gnu-gdb ~/disk2/s3c2410/linux-2.6.22.6-qemu/vmlinux
此时会出现ddd运行界面,然后运行远程连接命令:
(gdb)target remote localhost:1234
此时就可以运行gdb命令调试内核了。
如:在kthread_fun函数中设置一个断点的方法
连接后,搜索栏中输入kthead_fun,出现如下图的显示.
在view菜单中打开汇编窗口,然后在汇编窗口中设置断点(比在c中准确)。
Gdb命令行输入c
(gdb) c
启动目标系统
系统会在断点处停止,接下就可以用ddd提供图形调试工具调试代码了。
系统正常启动后,测试结果如下:
[root@farsight /]# echo 123456 > /dev/kthread
123456
in kthread
[root@farsight /]# ps w
PID USER VSZ STAT COMMAND
1 0 0 SW [swapper]
2 0 0 SW< [kthreadd]
3 0 0 SWN [ksoftirqd/0]
4 0 0 SW< [watchdog/0]
5 0 0 SW< [events/0]
6 0 0 SW< [khelper]
40 0 0 SW< [kblockd/0]
41 0 0 SW< [kseriod]
53 0 0 SW [pdflush]
54 0 0 SW [pdflush]
55 0 0 SW< [kswapd0]
56 0 0 SW< [aio/0]
131 0 0 SW< [kthreadtestd]
188 0 0 SW< [mtdblockd]
196 0 0 SW< [kpsmoused]
202 0 1996 S init
206 0 1492 S < /bin/udevd --daemon
208 0 2000 S -/bin/sh
209 0 2000 R ps w