VELT-0.1.5开发:使用kgdb调试Linux内核

VELT的全称是Visual EmbedLinuxTools,它是一个与visual gdb类似的visual studio插件,用以辅助完成Linux开发。利用这个插件,将可以在visual studio的IDE中进行Linux应用程序的开发(包括编译和调试),也可以进行uboot和linux内核的编译,并根据编译时的错误信息正确定位到源码。目前的版本是0.1.4,仅支持vs2013。此插件可以在CSDN下载频道下载(http://download.csdn.net/detail/lights_joy/8429771),安装过程参见《用vs2013+velt-0.1.4进行嵌入式开发:插件安装》。下面是它的基本功能:

  1. 支持x86 Linux,海思hi3516/hi3520,MinGW这几个平台,提供这几个平台的项目模板。
  2. 完成UBOOT的编译,并根据编译的错误信息自动定位到相应的文件位置。
  3. 完成LINUX内核的编译,并根据编译的错误信息自动定位到相应的文件位置。
  4. 在VS下完成Linux内核的配置。
  5. 不使用Makefile进行Linux应用程序的编译。
  6. 使用Makefile进行Linux应用程序的开发。
  7. 使用SSH连接目标机器并用gdb进行应用程序的调试。
  8. 使用Telnet连接目标机器并用gdb进行应用程序的调试。
  9. 在VS中集成Linux终端(Poderosa),支持SSH/Telnet/Com,在打开终端时自动将VS的变量导出为bash里的变量,如ProjectDir等。

接下来尝试通过串口调试Linux内核。

以hi3520的内核为试验对象。

1.1  打开内核的调试开关

首先打开内核的调试开关:

加上内核的调试信息:

打开kgdb

1.2  引导参数配置

在UBOOT下配置传递给内核的参数:

Kernel command line: mem=127m console=ttyAMA0,115200ip=192.168.110.10:::255.255.255.0::eth0: root=mtd:work02 init=/sbin/initmtdparts=hi_sfc:256K(uboot01),64K(env01),64K(sysinfo01),3712k(configs01),8M(boot01),20M(work01),256K(uboot02),64K(env02),64K(sysinfo02),3712k(configs02),8M(boot02),20M(work02)kgdboc=ttyAMA0,115200 kgdbwait

这里最重要的是kgdboc和kgdbwait两个参数,前一个参数指明要使用的串口参数,后一个参数让kgdb在内核启动的时候进行等待。

加载内核:

kgdb: Registered I/O driver kgdboc.

kgdb: Waiting for connection from remote gdb...

然后系统开始等待。

1.3  用MinGW gdb连接内核

直接用MinGW gdb打开编译内核时生成的vmlinux文件,

然后用

target remote COM1

连接串口,很遗憾,超时!

1.3  修改内核代码

检查了一下内核的代码,在等待连接时内核停在了下面的位置:

static int gdbstub_read_wait(void)
{
	int ret = dbg_io_ops->read_char();
	while (ret == NO_POLL_CHAR)
		ret = dbg_io_ops->read_char();
	return ret;
}

它将不停地查询串口上是否有数据,刚开始时怀疑是串口参数配置不正确导致读取不到数据,但跟踪进去后发现这里的read_char可以正确地调用串口驱动(amba-pl011.c)中的查询函数:

static int pl010_get_poll_char(struct uart_port *port)
{
	struct uart_amba_port *uap = (struct uart_amba_port *)port;
	unsigned int status, ena_status;

	status = readw(uap->port.membase + UART01x_FR);
	ena_status = readw(uap->port.membase + UART011_CR);
	if (status & UART01x_FR_RXFE)
		return NO_POLL_CHAR;

	return readw(uap->port.membase + UART01x_DR);
}

只不过在读取UART01x_FR寄存器时总是返回无数据的结果。

进一步的检查发现这个时候串口的接收使能是关闭的,而发送使能则是打开的!因此串口当然只能发送数据不能接收了!

不太想追究为什么会这样,直接在shutdown函数中打开接收使能:

static void pl011_shutdown(struct uart_port *port)
{
	struct uart_amba_port *uap = (struct uart_amba_port *)port;

	/*
	 * disable all interrupts
	 */
	spin_lock_irq(&uap->port.lock);
	uap->im = 0;
	writew(uap->im, uap->port.membase + UART011_IMSC);
	writew(0xffff, uap->port.membase + UART011_ICR);
	spin_unlock_irq(&uap->port.lock);

	pl011_dma_shutdown(uap);

	/*
	 * Free the interrupt
	 */
	free_irq(uap->port.irq, uap);

	/*
	 * disable the port
	 */
	uap->autorts = false;
	writew(UART01x_CR_UARTEN | UART011_CR_TXE | UART011_CR_RXE, uap->port.membase + UART011_CR);

	/*
	 * disable break condition and fifos
	 */
	pl011_shutdown_channel(uap, uap->lcrh_rx);
	if (uap->lcrh_rx != uap->lcrh_tx)
		pl011_shutdown_channel(uap, uap->lcrh_tx);

	/*
	 * Shut down the clock producer
	 */
	clk_disable(uap->clk);

	if (uap->port.dev->platform_data) {
		struct amba_pl011_data *plat;

		plat = uap->port.dev->platform_data;
		if (plat->exit)
			plat->exit();
	}

}

修改了这一行:

	writew(UART01x_CR_UARTEN | UART011_CR_TXE | UART011_CR_RXE, uap->port.membase + UART011_CR);

原来的代码是这样的:

	writew(UART01x_CR_UARTEN | UART011_CR_TXE, uap->port.membase + UART011_CR);

直接给上加上使能标记!

再执行gdb的target remote COM1命令,可以正常连接了!!

1.5  kdb

在HI3520的内核中已经带了kdb的支持:

当选上最下面的那个选项时将启用kdb,这样我们就可以在目标机器上执行一些简单的调试命令了,也不需要依赖于主机上的gdb。

但由于我们希望通过gdb结合源码进行调试,因此不选择kdb,仅仅用kgdb。

??

时间: 2024-10-26 07:15:18

VELT-0.1.5开发:使用kgdb调试Linux内核的相关文章

用 kGDB 调试 Linux 内核

简介 这个文档记录了用kGDB调试Linux内核的全过程,都是在前人工作基础上的一些总结.以下操作都是基于特定板子来进行,但是大部分都能应用于其他平台. 要使用KGDB来调试内核,首先需要修改config配置文件,打开相应的配置,配置内核启动参数,甚至修改串口驱动添加poll支持,然后才能通过串口远程调试内核. 配置内核 基本配置 在内核配置文件:.config中,需要打开如下选项 CONFIG_KGDB 加入KGDB支持 CONFIG_KGDB_SERIAL_CONSOLE 使KGDB通过串口

用KGdb和VMware调试Linux内核,System Call

Linux的内核和System Call不好调试,参考这里: http://stackoverflow.com/questions/5999205/cannot-step-into-system-call-source-code 简单来说,如果想在本机调试system call,那么当你进入system call时,系统已经在挂起状态了,那么它又怎样能响应用户的输入? 所以,有一个UML(http://user-mode-linux.sourceforge.net/)的方式,把内核当成一个进程启

【转】TI-Davinci开发系列之六CCS5.2调试Linux内核

上转博文<TI-Davinci开发系列之五CCS5.2使用gdbserver远程调试应用程序> 使用CCS5.2远程调试内核时,只需导入Linux内核源码,而不需要编译内核,也就不会用到交叉编译链,同时不需要使用gdbserver,但需要仿真器XDS560V2,所以Windows和Linux都可以完成,但考虑到Windows CCS5.2软件成熟,bug较少,且Windows易于操作,故本文推荐并主要介绍Windows版CCS5.2调试内核的方法.在介绍远程调试Linux之前,务必保证仿真器X

调试Linux内核环境MenuOS系统

调试Linux内核环境MenuOS系统 一.实验简介 本文采用自己搭建环境的方式对gdb进行了模拟. (1)工具介绍 1)QEMU介绍 QEMU是一个主机上的VMM(virtual machine monitor),通过动态二进制转换来模拟CPU,并提供一系列的硬件模型,使guest os认为自己和硬件直接打交道,其实是同QEMU模拟出来的硬件打交道,QEMU再将这些指令翻译给真正硬件进行操作.通过这种模式,guest os可以和主机上的硬盘,网卡,CPU,CD-ROM,音频设备和USB等设备进

大杀招之使用QEMU调试Linux内核代码

Linux内核代码的调试非常麻烦,一般都是加printk, 或者用JTAG调试. 这里的方法是用QEMU来调试Linux内核.因为QEMU自己实现了一个gdb server, 所以可以非常方便的使用gdb来调内核. 这对内核的学习也非常有帮助. 为了尽量不多花时间在QEMU设置上,这里直接使用以下的内核image: http://free-electrons.com/community/demos/qemu-arm-directfb/ 1. QEMU的安装 这个可以自己去QEMU的官网下载编译,

跟踪调试Linux内核的启动过程

跟踪调试Linux内核的启动过程---使用gdb 符钰婧 原创作品转载请注明出处 <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 ” 本次的实验是使用gdb跟踪调试内核从start_kernel到init进程启动,并分析启动的过程. 1.首先是在实验楼虚拟机上进行调试跟踪的过程. (1) 先构造一个简单的Linux系统 (2) 接下来使用gdb跟踪调试内核 启动(窗口被冻结) 另开一个shell窗口(水平分割)

使用QEMU调试Linux内核代码

Linux内核代码的调试非常麻烦,一般都是加printk, 或者用JTAG调试.这里的方法是用QEMU来调试Linux内核.因为QEMU自己实现了一个gdb server, 所以可以非常方便的使用gdb来调内核. 这对内核的学习也非常有帮助. 为了尽量不多花时间在QEMU设置上,这里直接使用以下的内核image: http://free-electrons.com/community/demos/qemu-arm-directfb/ 1,QEMU的安装 这个可以自己去QEMU的官网下载编译,如果

用qemu调试linux内核

1)dd if=/dev/zero of=./busybox.img bs=1M count=642)mkfs.ext3 busybox.img3)下载busybox,http://www.busybox.net/downloads/#tar jxvf busybox-1.18.0.tar.bz2 (解压busybox压缩包)#cd busybox-1.18.0 (进入到解压后的busybox源码目录)#make menuconfig (配置busybox)注意配置时,一定要选择静态链接选项,该

调试linux内核环境搭建方法(ddd+busybox+qemu+linux3.5.4内核)

环境搭建 1.1.准备工作 (1).qemu虚拟机 (2).busybox软件 (3).linux-3.5.4内核 (4).ddd 调试工具(终端中输入 sudo apt-get install ddd 安装) 1.2.编译内核 (1)建立工作目录:mkdir -p ~/work/qemu (2)切换到此目录:cd ~/work/qemu (3)下载 linux内 核 (4)解压内核:tar -jxvf linux-3.5.4.tar.bz2 (5)切换到linux-3.5.4目录: cd li