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进行嵌入式开发:插件安装》。下面是它的基本功能:
支持x86 Linux,海思hi3516/hi3520,MinGW这几个平台,提供这几个平台的项目模板。
完成UBOOT的编译,并根据编译的错误信息自动定位到相应的文件位置。
完成LINUX内核的编译,并根据编译的错误信息自动定位到相应的文件位置。
在VS下完成Linux内核的配置。
不使用Makefile进行Linux应用程序的编译。
使用Makefile进行Linux应用程序的开发。
使用SSH连接目标机器并用gdb进行应用程序的调试。
使用Telnet连接目标机器并用gdb进行应用程序的调试。
在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。
VELT-0.1.5开发:使用kgdb调试Linux内核【转】的更多相关文章
- 用 kGDB 调试 Linux 内核
简介 这个文档记录了用kGDB调试Linux内核的全过程,都是在前人工作基础上的一些总结.以下操作都是基于特定板子来进行,但是大部分都能应用于其他平台. 要使用KGDB来调试内核,首先需要修改conf ...
- 【转】TI-Davinci开发系列之六CCS5.2调试Linux内核
上转博文<TI-Davinci开发系列之五CCS5.2使用gdbserver远程调试应用程序> 使用CCS5.2远程调试内核时,只需导入Linux内核源码,而不需要编译内核,也就不会用到交 ...
- 使用 ftrace 调试 Linux 内核【转】
转自:http://blog.csdn.net/adaptiver/article/details/7930646 使用 ftrace 调试 Linux 内核,第 1 部分 http://blog.c ...
- 用qemu+gdb tcp server+CDT调试linux内核启动-起步
用qemu+gdb tcp server+CDT调试linux内核启动-起步 说明: 环境信息与 用virtualbox+模拟串口+CDT调试linux内核 TCP IP协议栈-起步 提到的一样,并且 ...
- 使用QEMU调试Linux内核代码
http://blog.chinaunix.net/uid-20729583-id-1884617.html http://www.linuxidc.com/Linux/2014-08/105510. ...
- Gdb远程调试Linux内核遇到的Bug
知识共享许可协议本作品采用知识共享署名 4.0 国际许可协议进行许可.转载保留声明头部与原文链接https://luzeshu.com/blog/gdb-bug 本博客同步在http://www.cn ...
- 跟踪调试Linux内核的启动过程
跟踪调试Linux内核的启动过程---使用gdb 符钰婧 原创作品转载请注明出处 <Linux内核分析>MOOC课程http://mooc.study.163.com/course/UST ...
- 学习构建调试Linux内核网络代码的环境MenuOS系统
构建调试Linux内核网络代码的环境MenuOS系统 一.前言 这是网络程序设计的第三次实验,主要是学习自己编译linux内核,构建一个具有简易功能的操作系统,同时在系统上面进行调试linux内核网络 ...
- 在qemu环境中用gdb调试Linux内核
简介 对用户态进程,利用gdb调试代码是很方便的手段.而对于内核态的问题,可以利用crash等工具基于coredump文件进行调试.其实我们也可以利用一些手段对Linux内核代码进行gdb调试,qem ...
随机推荐
- ElasticSearch搜索实例含高亮显示及搜索的特殊字符过滤
应用说明见代码注解. 1.简单搜索实例展示: public void search() throws IOException { // 自定义集群结点名称 String clusterName = & ...
- Maven 学习笔记——Maven环境配置(1)
在学习Selenium的过程中,接触到了Maven(项目管理工具),不至于学一路忘一路,左耳朵进右耳多出,还是决定边学边记录,毕竟听的不如 看的,看的不如写的吗.首先学一样东西,肯定得明确学的是什么, ...
- Caffe使用: Ubuntu 14.04(x64) 从cuda 7.0 升级到 cuda8.0
由于之前已经在Ubuntu 14.04 x64上面安装cuda7.0+caffe, 并且已经配置好,caffe也已经跑通. 但是最近需要使用Torch,而Torch对cuda的要求是8.0,因此决定对 ...
- 【转】maven常用插件介绍
我们都知道Maven本质上是一个插件框架,它的核心并不执行任何具体的构建任务,所有这些任务都交给插件来完成,例如编译源代码是由maven- compiler-plugin完成的.进一步说,每个任务对应 ...
- gitlab、openvpn配置ldap认证
gitlab配置ldap认证: vim /etc/gitlab/gitlab.rb 添加以下内容: gitlab_rails['ldap_enabled'] = true gitlab_rails[' ...
- Valid BFS? CodeForces - 1037D(思维 bfs)
我真是一只菜狗......emm... 题意: 判断一个从1开始的队列是否可以按照bfs的顺序 进行遍历..必须从1开始...然后后边依次是bfs顺序 解析: 看代码能看懂吧...emm...就是把每 ...
- Magical Girl Haze 南京网络赛2018
题意: 就是使不大于k条路的权值变为零后求最短路 解析: d[i][j]表示使j条路变为权值后从起点到点i的最短路径 这题不能用spfa做 tle #include <iostream> ...
- Spring MVC 异步测试
从spring3.2开始,支持servlet3的异步请求,这对于处理耗时的请求如缓慢的数据库查询是非常有好处的,不至于很快的耗光servlet的线程池,影响可扩展性. 让我们先来了解一下servlet ...
- 如何解决每次打开office 都会出现正在配置的问题
原因:安装offiece的时候直接选择以前安装过的office文件夹,导致文件冲突 解决方法:卸载,然后对准备要安装的文件夹清空或者重新建个新文件夹安装
- 企业级 SpringBoot 教程 (一)构建第一个SpringBoot工程
简介 spring boot 它的设计目的就是为例简化开发,开启了各种自动装配,你不想写各种配置文件,引入相关的依赖就能迅速搭建起一个web工程.它采用的是建立生产就绪的应用程序观点,优先于配置的惯例 ...