• 第十章 嵌入式LINUX的调试技术


    1.打印内核调试信息:printk(该函数的用法与printf函数类似,具不过printk函数运行在内核空间, printf函数运自行在用户空间。

    printk函数原型:asmlinkage int printk(const char *fmt,...)第一个参数表示格式字符串,后面是再变参数。

    2.KERN_DEBUG 和KERN_WARNING 是两个宏,它们的值分别为”<7>”和”<4>”

    #define  KERN_EMERG   ”<0>”  紧急事件 , 一般是系统崩溃前显示的信息

    #define  KERN_ALERT   ”<1>”  必须立即处理的行为

    #define  KERN_CRIT    ”<2>”临界状态 ,通常涉及严重的硬件或软件操作失败

    #define  KERN_ERR     ”<3>” 用于报告错误状态,设备驱动程序会经常使用阻KEEN ERR报告来自硬件的问题

    #define  KERN_NOTICE  ”<5>”有必要进行提示的正常情况,许多与安全相关的情况用这个级别进行汇报

    #define  KERN_INFO    ”<6>”内核提示位信怠,很多驱动程序在启动时,以这个级别打印出拢到的硬件信怠

    3.printk 文件是一个简单的有4个数字组成的文本文件,默认值为:6 4 1 7

    6:将消息输出到控制台的级别,只有商于该级别的输出信息才会输出到控制台。

    4:默认的消息日志级别,如果不在printk函数中指定日志级别,就会使用该值作为默认的级别,

    1:控制台日志级别可被设置的最小值(最高优先级别).

    7:控制台日志级别的默认值.

    4.如果想修改printk文件中的内容,在 Linux 终端执行下面的命令

    # echo 8 > /proc/sys/kernel/printk

    5.防止printk函数降低linux驱动性能

    printk函数在控制台(也称为终端)显示消息是通过/dev/console 设备文件实现.该设备文件只在字符界面的控制台下才起作用,所以printk函数只有用在字符界面的控制台上才能正常输出消息.

    6宏:

    (1)可变参数的宏.可变参数宏与固定参数宏的不同之处就是可变参数宏需要通过_VA_VRGS_宏获取可变参数宏的可变参数,定义可变参数宏与定义可变参数函数的方法相同,可变参数必须是宏和函数最后的参数.产生编译错误的原因是_VA_ARGS_宏不支持可变参数个数为 0 的情况.

    (2)do{...}while(0)

    使用do{...}while(0)结构定义的test宏对于上面的if..else结构的代码会翻译成如下形式

    7.通过虚拟文件系统(/proc)进行数据交互,proc 是虚拟文件系统,/proc并不是真正的文件系统,而是内存映射.所有读写/proc_操作都是对内存的读写,所以读写/proc文件系统的速度要远比读写/dev文件系统的速度快.有很多系统信息就是通过/proc文件系统由内核空间的程序向外界提供的.

    8.//在/proc目录下建立虚拟目录

    struct proc_dir_entry *proc_mkdir(const char *name,struct proc_dir_entry *parent)

    //在/proc目录下建立虚拟文件

    struct proc_dir_entry *create_proc_entry(const char *name,mode_t mode,struct proc_dir_entry *parent)

    //在/proc目录下建立虚拟只读文件

    static inline struct proc_dir_entry *create_proc_read_entry(const char *name,mode_t mode,struct proc_dir_entry *base,read_proc_t *read_proc,void *data)

    //在/proc目录下建立虚拟文件或目录

    void remove_proc_entry(const char *name,mode_t mode,struct proc_dir_entry *parent)

    9.如果想把只读文件改成读写文件,只需要设置处理文件写动作的函数,并且

    将文件属性改成0666;linux 文件的读写由属性决定,在程序中可以用八进制表示.如果查看文件属性,会看到文件开头是-rw-rw-rw-.而将文件属性设为0444,则文件属性是-r—r—r--,表示只读.删除虚拟目录之前,要先删除康拟自录中的虚拟文件。

    10.测试虚拟文件:

      # echo 1101 > /proc/proc_demo/bin2dec

    # cat /proc/proc_demo/bin2dec

    # cat /proc/proc_demo/readonly

    11.调试工具

    (1)用gdb调试用户空间程序.gdb可以跟踪调试用户空间的程序,

    (2)用gdbserver远程调试用户空间程序.gdbserver是一个可以运行在 ARM 架构上的服务端程序.也就是说,在开发板上使用gdbserver打开要测试的程序,然后通过串口、有线或无线网络可以在 PC上进行调试.

    首先进入 Android 模拟器的终端,然后进入data/local目录,并执行如下的命令启动gdbserver监听程序通过IP方式连接开发板上的 gdbserver.在开发板端需要执行下面的命令

    # gdbserver  localhost:4321./gdb_debug

    在linux端的gdb控制台需要执行下面的命令连接开发板的gdbserver.

    (gdb) target remote 192.168.17.103  ./gdb_debug

    通过串口连接开发板上的gdbserver,在开发板端需要执行下面的命令.

    # gdbserver /dev/s3c2410_serial0  ./gdb_debug

    (3)用 kgdb 远程调试内核程序.Kgdb 包含了两部分:kgdb内核和一套连接接口,这些接口目前支持串口tty设备连接和以太网连接.其中串口连接需要通过内核参数kgdboc指定要连接的串口tty设备;以太网连接通过内核参kgdboe 指定IP和端口号,kgdb 支持多种处理器架构

     用kgdb调试 Linux内核,首先需要配置Linux内核,使用 make  menuconfig命令进入 Linux内核的配置菜单,进入”Kernel backing气找到并选“KGDB: kernel debugger ”菜单项.

    使用kgdb调试Linux:内核首先需要配置内核参数,这些参数通知 Linux 内核要如何进行调试.通过USB转COM口数据线进行调试,需要将 kgdboc 参数值设为ttyUSBO ,传输数率为115200, 一般会指定kgdbwait.这些参数需要在 S3C开发板启动过程中按回车进入Uboot模式,然后使用setenv命令设置Linux内核的启动参数,然后使用saveenv和reset命令保存和重新启动Linux 内核.

       命令:

    #  setenv bootargs “root=/dev/mtdblock2  rootfstype=yaffs2

    init=/linuxrcconsole=tty1console=ttySAC0,115200 kgdboc=ttyUSB0,115200 kgdbwait ”

    # saveenv

    #reset

    其中ttyUSBO表示USB串口,1:15200表示传输速率,如果设置了kgdbwait,表示开机时会一直等待主机进行连接.

  • 相关阅读:
    【Linux】Vim编辑器-批量注释与反注释
    java_部署jar
    linux_UBUNTU 12.04 上使用 SQUID 架设HTTP正向代理服务器
    crawler_java应用集锦9:httpclient4.2.2的几个常用方法,登录之后访问页面问题,下载文件_设置代理
    linux_coom _ Linux文件比较,文本文件的交集、差集与求差
    linux_之sed用法
    算法-跑道与马-百度面试题
    《Python》常用内置模块
    《Python》内置方法进阶和常用模块
    《Python》反射、内置方法(__str__,__repr__)
  • 原文地址:https://www.cnblogs.com/yqing/p/5653038.html
Copyright © 2020-2023  润新知