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

转自:http://demo.netfoucs.com/lights_joy/article/details/44106589

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  修改内核代码

 

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

 

view plaincopy to clipboardprint?

  1. 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)中的查询函数:

 

view plaincopy to clipboardprint?

  1. 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函数中打开接收使能:

 

view plaincopy to clipboardprint?

  1. 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();    }}  

 

 

修改了这一行:

 

view plaincopy to clipboardprint?

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

 

原来的代码是这样的:

 

view plaincopy to clipboardprint?

  1. 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-12-26 17:07:35

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

使用 ftrace 调试 Linux 内核【转】

转自:http://blog.csdn.net/adaptiver/article/details/7930646 使用 ftrace 调试 Linux 内核,第 1 部分 http://blog.csdn.net/tommy_wxie/article/details/7340701 简介: ftrace 是 Linux 内核中提供的一种调试工具.使用 ftrace 可以对内核中发生的事情进行跟踪,这在调试 bug 或者分析内核时非常有用.本系列文章对 ftrace 进行了介绍,分为三部分.本文

用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/)的方式,把内核当成一个进程启

Linux 内核的测试和调试(1)

Linux 内核的测试和调试(1) Linux 内核测试哲学 不管是开源还是闭源,所有软件的开发流程中,测试是一个重要的.不可或缺的环节,Linux 内核也不例外.开发人员自测.系统测试.回归测试.压力测试,都有各自不同的目的,但是从更高一个层次上看,这些测试的最终目的又是一样的:保证软件能一直运行下去,当有新功能加进去时,要保证新功能可以正常工作. 在软件释出 release 版之前,不用回归测试就能保证稳定性,并且尽量避免在软件发布后被用户发现 bug.调试被用户发现的 bug 是一项非常浪

如何在Ubuntu/CentOS上安装Linux内核4.0

如何在Ubuntu/CentOS上安装Linux内核4.0 大家好,今天我们学习一下如何从Elrepo或者源代码来安装最新的Linux内核4.0.代号为'Hurr durr I'm a sheep'的Linux内核4.0是目前为止最新的主干内核.它是稳定版3.19.4之后发布的内核.4月12日是所有的开源运动爱好者的大日子,Linux Torvalds宣布了Linux内核4.0的发布,它现在就已经可用了.由于包括了一些很棒的功能,例如无重启补丁(实时补丁),新的升级驱动,最新的硬件支持以及很多有

Asp.net 3.5控件和组件开发技术系列—服务器控件开发中的调试技术

本章内容 2.1 预置代码示例 2.2 调试页面服务端代码 2.3 服务器控件的调试 2.4 JavaScript 脚本调试方法 2.5 Ajax Library 对JavaScript调试支持 2.1 预置代码示例 熟悉ASP.NET 开发的读者朋友可能对于服务器控件的调试技术更容易上手,不过如果您刚刚接 触ASP.NET 也没关系,本章会从最基本的调试开始讲解. 在调试之前,要先建立一个调试控件的项目环境.关于如何建立环境在这里就不讲了,第1 章 已经讲得非常详细了. 首先在Web 控件项目

嵌入式开发修改u-boot与Linux调试串口总结

近期一个嵌入式开发项目,使用TI Cortex-A8的芯片AM3517作为主控开发.前期使用某公司的核心板搭建开发环境.在自己做底板布板的时候的时候涂个布线方便,改用UART1作为调试串口,而原来某公司给的开发包,已经TI的AM3517 PSP均以UART3作为调试串口.于是在底板焊接完成调试的时候就有了一天痛苦的经历. 嵌入式开发.jpg 在原版的PSP中, 一共有五处使用到UART3作为打印和调试串口: (1)Xloader的打印串口 (2)u-boot的打印串口 (3)内核解压时的信息打印

Windows Phone 7开发教程(2)——Windows Phone XNA 4.0 3D游戏开发

程序代码编译环境Visual Stuido 2010, Windows Phone 7 SDK, XNA 4.0 Game Studio, 下载链接: http://files.cnblogs.com/aawolf/XNA_aawolf_3D.rar 今天有点空余时间,在看Windows Phone 7的开发.看到Silverlight for phone和XNA 4.0的开发文章已经有了不少,而且质量很高.我就来说说XNA 4.0 的3D开发这个领域吧,正好跟目前的工作有些关系,而且XNA 4

WinForm控件开发总结(十一) 调试控件的设计时行为

前面的一些文章绝大部分都是要讲控件的设计时的行为,既然涉及到这么多的设计时行为的代码编写 ,那么就有必要就一下如何来调试控件的设计行为. 调试控件的设计时行为和调试DLL的方式非常的相似,因为DLL是不能够单独运行的,而一般的控件也 会在一个DLL里.当然如果你不考虑类的可复用性而把控件写在一个Windows Application里面也无可厚非 ,这样调试倒也变的简单了.但是我们还是要考虑更通常的情况.一般来说,我们调试DLL时,都是创建 一个可独立运行的应用程序,在这个应用程序里引用你希望调

软件开发-安装的调试器不能被识别出来

问题描述 安装的调试器不能被识别出来 开发-安装的调试器不能被识别出来-调试器开发"> 解决方案