搭建基于qemu + eclipse的kernel调试环境(by quqi99)


作者:张华  发表于:2016-02-06版权声明:可以任意转载,转载时请务必以超链接形式标明文章原始出处和作者信息及本版权声明

( http://blog.csdn.net/quqi99 )

使用qemu结合eclipse或者DDD等gdb的图形前端,跟踪协议栈或者文件系统内存管理等都会非常方便。就是与硬件驱动相关的跟踪可能差点。

编译内核

下载Linux Kernel源码,并编译生成压缩的kernel镜像(/bak/linux/linux-2.6/arch/x86_64/boot/bzImage)与用于gdb的非压缩的kernel ELF文件(/bak/linux/linux-2.6/vmlinux)。

cd /bak/linux/ && git clone git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6.git

如何编译内核参考:编译linux kernel及制作initrd ( by quqi99 )

sudo apt-get install libncurses5-dev

make menuconfig   make -j 8 bzImage

制作initrd

制作initrd, 使用initrd时的kernel要使用CONFIG_BLK_DEV_INITRD=y编译。参见我的博客:http://blog.csdn.net/quqi99/article/details/11860241

sudo apt-get install build-essential initramfs-tools

sudo make modules_install            #将生成/lib/modules/4.5.0-rc2+

mkinitramfs -o initrd.img -v 4.5.0-rc2+

使用busybox制作initrd

mkdir -p /bak/linux/initramfs/{bin,sbin,etc,proc,sys,newroot}cd /bak/linuxtouch initramfs/etc/mdev.confwget http://jootamam.net/initramfs-files/busybox-1.10.1-static.bz2 -O - | bunzip2 > initramfs/bin/busyboxchmod +x initramfs/bin/busyboxtouch initramfs/init

chmod +x initramfs/init

initramfs/init文件如下:

#!/bin/sh
#Mount things needed by this script
mount -t proc proc /proc
mount -t sysfs sysfs /sys
#Disable kernel messages from popping onto the screen
echo 0 > /proc/sys/kernel/printk
#Clear the screen
clear
#Create all the symlinks to /bin/busybox
busybox --install -s
#Create device nodes
mknod /dev/null c 1 3
mknod /dev/tty c 5 0
mdev -s
#Function for parsing command line options with "=" in them
# get_opt("init=/sbin/init") will return "/sbin/init"
get_opt() {
	echo "[email protected]" | cut -d "=" -f 2
}
#Defaults
init="/sbin/init"
root="/dev/hda1"
#Process command line options
for i in $(cat /proc/cmdline); do
	case $i in
		root\=*)
			root=$(get_opt $i)
			;;
		init\=*)
			init=$(get_opt $i)
			;;
	esac
done
#Mount the root device
mount "${root}" /newroot
#Check if $init exists and is executable
if [[ -x "/newroot/${init}" ]] ; then
	#Unmount all other mounts so that the ram used by
	#the initramfs can be cleared after switch_root
	umount /sys /proc

	#Switch to the new root and execute init
	exec switch_root /newroot "${init}"
fi
#This will only be run if the exec above failed
echo "Failed to switch_root, dropping to a shell"
exec sh

cd initramfs
find . | cpio -H newc -o > ../initramfs.cpio
cd ..
cat initramfs.cpio | gzip > initramfs.igz

但上述busybox-1.10.1-static.bz2似乎没有ext2模块不能识别qemu的-hda参数传进去ext2格式的硬盘,所以最后改成从busybox-1.24.0的源码编译。

wget https://busybox.net/downloads/busybox-1.24.0.tar.bz2

make menuconfig 
   CONFIG_MKFS_EXT2=y
          Busybox Settings  --->  
           Build Options  ---> 
               [*] Build BusyBox as a static binary (no shared libs) //静态方式编译
   make & make install
   cp -avR /bak/linux/busybox-1.24.0/_install/* /bak/linux/initramfs/

qemu加载内核

wget http://www.nongnu.org/qemu/linux-0.2.img.bz2
sudo qemu-system-x86_64 -hda /bak/images/linux-0.2.img -hdb /bak/linux/disk.img -kernel /bak/linux/linux-2.6/arch/x86_64/boot/bzImage -initrd /bak/linux/initramfs.igz -append "root=/dev/sda init=sbin/init console=ttyS0" -nographic -smp 1,cores=1 -S -s 
参数解释如下:

  1. 其中-s为开启GDB的调试端口1234,而-S则表示运行QEMU时冻结待GDB执行(c)ontinue操作。
  2. console=ttyS0" -nographic表示不开新的图形化窗口,直接使用敲命令的bash窗口
  3. -append "root=/dev/sda init=sbin/init应该与initrd文件里的init脚本一致。

使用gdb调试内核

qemu的-s参数会默认在1234端口开启gdbserver。
   [email protected]:~$ sudo netstat -anp |grep 1234
   tcp    0     0 0.0.0.0:1234        0.0.0.0:*          LISTEN      24309/qemu-system-x
   [email protected]:~$ /bak/java/gdb/bin/gdb /bak/linux/linux-2.6/vmlinux 
    ...
   (gdb) target remote localhost:1234
   Remote debugging using localhost:1234
   0x0000000000000000 in irq_stack_union ()
   (gdb) b start_kernel
   Breakpoint 1 at 0xffffffff81d66b09: file init/main.c, line 498.
   (gdb) info registers
   (gdb) bt
   (gdb) c
   (gdb) list
   (gdb) set architecture
   Requires an argument. Valid arguments are i386, i386:x86-64, i386:x64-32, i8086, i386:intel,i386:x86-64:intel, i386:x64-32:intel, auto.

使用eclipse调试内核

1, Linux源码size太大,设置workspace全局禁止使用eclipse去给代码做自动build。索引可以仍然交由eclipse来做,这样方便在eclipse中进行搜索及代码导航。
   - Preferences -> Generl -> Workspace -> Build automatically (Disable)

2, 将Kernel源码导入为eclipse工程, toolChain选为Linux GCC.
      Import -> C/C++ -> Existing Code as Makefile Project
3, 创建一个debug启动器(Debug configurations -> C/C++ Remote Application)
   选择GDB(DSF) Manual Remote Debugging Launcher
   Main TAB -> -C/C++ Application指向实际uncompress kernel: /bak/linux/linux-2.6/vmlinux
   Main TAB -> -Disable auto build
   Debugger TAB -> Stop on startup at ‘start_kernel‘
   Debugger TAB -> connection -> Host Name or IP Address -> = localhost
   Debugger TAB -> connection -> Port number = 1234

编译gdb解决错误“Remote ‘g‘ packet reply is too long”

cd /bak/java && wget http://ftp.gnu.org/gnu/gdb/gdb-7.7.tar.gz
   修改gdb/remote.c文件,在process_g_packet函数里,将如下代码:
   if (buf_len > 2 * rsa->sizeof_g_packet)
     error (_("Remote ‘g‘ packet reply is too long: %s"), rs->buf);
   修改上两行代码为下面的代码,或者直接注释上两行什么也不加:

if (buf_len > 2 * rsa->sizeof_g_packet) {
  rsa->sizeof_g_packet = buf_len ;

  for (i = 0; i < gdbarch_num_regs (gdbarch); i++) {
    if (rsa->regs[i].pnum == -1)
      continue;

    if (rsa->regs[i].offset >= rsa->sizeof_g_packet)
      rsa->regs[i].in_g_packet = 0;
    else
      rsa->regs[i].in_g_packet = 1;
  }
}

./configure --prefix=/bak/java/gdb && make && make install
   接下来重新配置下Eclipse,点击菜单“Run”->“Debug Configurations…”,在弹出的对话框中,切换到“Debugger”下的“Main”页,修改“GDB debugger:”为刚编译出来的GDB(/bak/java/gdb/bin/gdb),而不是默认的gdb

参考

[1] http://blog.chinaunix.net/uid-26009923-id-3825761.html
[2] http://mgalgs.github.io/2012/03/23/how-to-build-a-custom-linux-kernel-for-qemu.html

[3] http://www.kgdb.info/kgdb/use_kgdb/using_kgdb_base_qemu/

附录1, 使用cscope创建索引

1, 创建cscope.files
LNX=/bak/linux/linux-2.6
cd /
find  $LNX                                                                \
-path "$LNX/arch/*" ! -path "$LNX/arch/i386*" -prune -o               \
-path "$LNX/include/asm-*" ! -path "$LNX/include/asm-i386*" -prune -o \
-path "$LNX/tmp*" -prune -o                                           \
-path "$LNX/Documentation*" -prune -o                                 \
-path "$LNX/scripts*" -prune -o                                       \
-path "$LNX/drivers*" -prune -o                                       \
-name "*.[chxsS]" -print >/bak/linux/linux-2.6/cscope/cscope.files
2, 创建索引数据库
cd /bak/linux/linux-2.6/cscope
3, 使用索引数据库
cscope -d

时间: 2024-07-30 17:54:56

搭建基于qemu + eclipse的kernel调试环境(by quqi99)的相关文章

搭建Eclipse开发和调试环境(真机)

由于工作原因,最近开始了Android开发.之前接触过一段时间Android,还是在2.x时代. 那个时候搭建开发环境还是挺麻烦的.又是Eclipse,又是ADT的,不同的版本还要安装对应开发包.现在方便了,下载一个ADT压缩包就搞定了. 简单记录如下: 工具下载: JDK:http://www.oracle.com/technetwork/java/javase/downloads/index.html ADT:http://developer.android.com/sdk/index.ht

ok6410[002] ubuntu1604系统下搭配ckermit和dnw基于RAM的裸机程序调试环境

ubuntu1604系统下搭配ckermit和dnw基于RAM的裸机程序调试环境 系统:  ubuntu16.04 裸板: 飞凌公司OK6410开发板 目标:搭建基于ubuntu1604系统和基于RAM的裸机程序开发环境 1.安装配置ckermit 在ubuntu1604下一般做裸板开发时都是使用ckermit作为远程通讯终端,下面我们就开始讲解下其安装与配置. 1.1.安装ckermit 在ubuntu系统下安装ckermit,使用 sudo  apt-get  install  ckermi

如何搭建自己的SpringBoot源码调试环境?--SpringBoot源码(一)

1 前言 这是SpringBoot2.1源码分析专题的第一篇文章,主要讲如何来搭建我们的源码阅读调试环境.如果有经验的小伙伴们可以略过此篇文章. 2 环境安装要求 IntelliJ IDEA JDK1.8 Maven3.5以上 3 从github上将SpringBoot源码项目下载下来 首先提供SpringBoot2.1.0的github地址: https://github.com/spring-projects/spring-boot/tree/v2.1.0.RELEASE 因为要进行阅读源码

hadoop之mapreduse 在Eclipse下的调试环境篇

搭建完成环境后,开始调试mapreduse程序.但是遇到不停的报错.本人很讨厌在自己的操作系统环境变量里设置来设置去,包括linux也是.通常喜欢把环境变量设置在启动程序的脚本中,让脚本自己运行的环境中有合适的环境变量值即可.在Eclipse里,我预计需要设置hadoop_home变量的值,设置后,不管怎么调试.都报错: Exception in thread "main" java.lang.UnsatisfiedLinkError: org.apache.hadoop.io.nat

Mac OS下基于Eclipse的Android调试环境搭建

1.安装Eclipse:http://www.eclipse.org/downloads/,网页会自动检测适用的版本(Mac OS x64),下载“Eclipse IDE for java Developers”并安装: 2.尝试运行Eclipse,若提示“您需要安装旧 Java SE 6 运行环境才能打开”,则点击弹出对话框里面的“详情”,跳转到苹果官网的指定页面(如:https://support.apple.com/kb/DL1572?locale=zh_CN),下载需要的文件并安装: 3

基于VSCode的PYTHON 构建调试环境搭建指南

1.安装python解释器,配置好path变量. 下载网址:https://www.python.org/downloads/release/python-374/ 安装python的时候,建议将python添加到path环境变量的复选框勾上,并且使用自定义安装,因为可以自定义安装目录,我是安装在C:\Python37中的 3.下载并安装好vscode编辑器(安装时,将复选框全部勾上) 下载地址:https://code.visualstudio.com/ 4.在vscode中安装python插

搭建基于Windows的React Native 开发环境(For Android)

React Native号称能跨平台开发IOS和Android的原生应用,想来必定会成为一种趋势.刚好计划开发一款手机APP,又没有相应的开发资源,决定自己摸索着试试. 第一步是搭建开发环境,以下是官方文档.网上资料,结合本人实际操作的总结: 一.       准备工作 (1)安装安卓SDK 根据React Native官网的指示(http://facebook.github.io/react-native/docs/android-setup.html#content),首先需要安装Andro

MAC OS环境下搭建基于Python语言的appium自动化测试环境

#1 安装JDK java -version #2 下载SDK http://adt.android-studio.org/ 下载adt #3 配置sdk环境变量 打开终端,依次输入命令 vim .bash_profile 在文本中添加然后保存 export ANDROID_HOME=/Applications/eclipse/sdk export PATH=$PATH:$ANDROID_HOME/platform-tools:$ANDROID_HOME/tools 其中ANDROID_HOME

搭建基于以太坊的私有链环境

零.概述 版本号:Ubuntu-16.04 ethereum-1.6.0-stable go - 1.7.4 一.Ubuntu下安装geth sudo apt-get install software-properties-common sudo add-apt-repository -y ppa:ethereum/ethereum sudo apt-get update sudo apt-get install ethereum 二.创建初始化文件 vim genesis.json {