• i.MX 6ULL 驱动开发 三:字符设备驱动框架实现和调试


    一、概述

    Linux 驱动开发 一:概述_lqonlylove的博客-CSDN博客_linux驱动开发概述

    Linux 驱动开发 二:module_init机制_lqonlylove的博客-CSDN博客_linux module_init

    Linux 驱动开发 三:字符设备驱动框架_lqonlylove的博客-CSDN博客_linux字符设备驱动框架

    Linux 驱动开发 六:字符设备框架再分析_lqonlylove的博客-CSDN博客

    Linux 驱动开发 七:新字符设备驱动框架构思_lqonlylove的博客-CSDN博客

    Linux 驱动开发 八:新字符设备驱动框架实现和测试_lqonlylove的博客-CSDN博客

    二、测试思路:

    1、搭建驱动框架;

    2、在 newchrdev_write 函数中定义 flag 变量。

    3、从应用程序中调用 write 函数传递变量值(为了实现方便,应用程序只向驱动传递的值为 1)。

    4、驱动程序接收应用程序中的值,将值赋值给 flag 变量。

    5、驱动调试过程中,使用 GDB 进行修改 flag 值,以验证 GDB 修改驱动的当前状态。

    6、使用 GDB 将驱动中的值修改为 5,驱动将打印 “gdb debug success!” 字符串。

    三、驱动实现

    1、创建工程目录

    onlylove@ubuntu:~/my/imx6ull_ddrive/newchrdev$ pwd
    /home/onlylove/my/imx6ull_ddrive/newchrdev
    onlylove@ubuntu:~/my/imx6ull_ddrive/newchrdev$ ls -l
    total 0
    onlylove@ubuntu:~/my/imx6ull_ddrive/newchrdev$
    
    • 1
    • 2
    • 3
    • 4
    • 5

    2、创建 vscode 工程

    具体操作如下:

    File --》 Save WorkSpace As ……

    日志信息如下:

    onlylove@ubuntu:~/my/imx6ull_ddrive/newchrdev$ pwd
    /home/onlylove/my/imx6ull_ddrive/newchrdev
    onlylove@ubuntu:~/my/imx6ull_ddrive/newchrdev$ ls -l
    total 4
    -rw-rw-r-- 1 onlylove onlylove 60 Sep 11 18:45 newchrdev.code-workspace
    onlylove@ubuntu:~/my/imx6ull_ddrive/newchrdev$
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    3、创建工程文件

    工程文件包括:

    • newchrdev.c:驱动源码文件;
    • Makefile:makefile 文件;
    onlylove@ubuntu:~/my/imx6ull_ddrive/newchrdev$ ls -l
    total 4
    -rw-rw-r-- 1 onlylove onlylove  0 Sep 11 18:48 Makefile
    -rw-rw-r-- 1 onlylove onlylove  0 Sep 11 18:48 newchrdev.c
    -rw-rw-r-- 1 onlylove onlylove 60 Sep 11 18:45 newchrdev.code-workspace
    onlylove@ubuntu:~/my/imx6ull_ddrive/newchrdev$
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    4、添加头文件路径

    在 VSCode 中添加 Linux 源码中的头文件路径。打开 VSCode,按下 “Crtl+Shift+P” 打开 VSCode 的控制台,然后输入 “C/C++: Edit configurations(JSON) ”,打开 C/C++ 编辑配置文件,添加 Linux 源码头文件路径,修改后内容如下:

    {
        "configurations": [
            {
                "name": "Linux",
                "includePath": [
                    "${workspaceFolder}/**",
                    "/home/onlylove/my/linux/linux-imx-4.1.15/include",
                    "/home/onlylove/my/linux/linux-imx-4.1.15/arch/arm/include",
                    "/home/onlylove/my/linux/linux-imx-4.1.15/arch/arm/include/generated"
                ],
                "defines": [],
                "compilerPath": "/usr/bin/gcc",
                "cStandard": "gnu17",
                "cppStandard": "c++17",
                "intelliSenseMode": "linux-gcc-x64"
            }
        ],
        "version": 4
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    5、makefile

    KERNELDIR := /home/onlylove/my/linux/linux-imx-4.1.15
    CURRENT_PATH := $(shell pwd)
    obj-m := newchrdev.o
    
    build: kernel_modules
    
    kernel_modules:
    	$(MAKE) -C $(KERNELDIR) M=$(CURRENT_PATH) modules
    clean:
    	$(MAKE) -C $(KERNELDIR) M=$(CURRENT_PATH) clean
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    6、驱动文件

    #include "linux/init.h"
    #include "linux/module.h"
    #include "linux/kdev_t.h"
    #include "linux/fs.h"
    #include "linux/cdev.h"
    #include "linux/device.h"
    #include 
    
    #define NEWCHRDEV_MAJOR 0   		/* 主设备号(如果为0则让系统自动分配,如果大于0则使用指定设备号) */
    #define NEWCHRDEV_MINOR 0   		/* 次设备号 */
    #define NEWCHRDEV_COUNT 1   		/* 设备号个数 */
    #define NEWCHRDEV_NAME  "newchrdev" /* 名子 */
    
    typedef struct{
        struct cdev dev;        /* cdev 结构体 */
        int major;              /* 主设备号 */
        int minor;              /* 次设备号 */
        dev_t devid;            /* 设备号 */
        struct class *class;    /* 类 */
        struct device *device;  /* 设备 */
    }newchrdev_t;
    
    newchrdev_t newchrdev;
    
    /*
     * @description		: 打开设备
     * @param - inode 	: 传递给驱动的inode
     * @param - filp 	: 设备文件,file结构体有个叫做private_data的成员变量
     * 					  一般在open的时候将private_data指向设备结构体。
     * @return 			: 0 成功;其他 失败
     */
    static int newchrdev_open(struct inode *inode, struct file *filp)
    {
        printk("newchrdev_open!\r\n");
        filp->private_data = &newchrdev; /* 设置私有数据 */
        return 0;
    }
    
    /*
     * @description		: 从设备读取数据 
     * @param - filp 	: 要打开的设备文件(文件描述符)
     * @param - buf 	: 返回给用户空间的数据缓冲区
     * @param - cnt 	: 要读取的数据长度
     * @param - offt 	: 相对于文件首地址的偏移
     * @return 			: 读取的字节数,如果为负值,表示读取失败
     */
    static ssize_t newchrdev_read(struct file *filp, char __user *buf, size_t cnt, loff_t *offt)
    {
        printk("newchrdev_read!\r\n");
    	return 0;
    }
    
    /*
     * @description		: 向设备写数据 
     * @param - filp 	: 设备文件,表示打开的文件描述符
     * @param - buf 	: 要写给设备写入的数据
     * @param - cnt 	: 要写入的数据长度
     * @param - offt 	: 相对于文件首地址的偏移
     * @return 			: 写入的字节数,如果为负值,表示写入失败
     */
    static ssize_t newchrdev_write(struct file *filp, const char __user *buf, size_t cnt, loff_t *offt)
    {
        int retvalue;
        unsigned char databuf[1];
        unsigned char flag = 0;
        printk("newchrdev_write!\r\n");
        retvalue = copy_from_user(databuf, buf, cnt);
        if(retvalue < 0) {
    		printk("kernel write failed!\r\n");
    		return -EFAULT;
    	}
        flag = databuf[0];
        if(flag == 5){
            printk("gdb debug success!\r\n");
        }
        printk("flag = %d\r\n",flag);
        flag = 0;
        return 0;
    }
    
    /*
     * @description		: 关闭/释放设备
     * @param - filp 	: 要关闭的设备文件(文件描述符)
     * @return 			: 0 成功;其他 失败
     */
    static int newchrdev_release(struct inode *inode, struct file *filp)
    {
        printk("newchrdev_release!\r\n");
    	return 0;
    }
    
    static const struct file_operations newchrdevops = {
        .owner   = THIS_MODULE,
        .open = newchrdev_open,
    	.read = newchrdev_read,
    	.write = newchrdev_write,
    	.release = newchrdev_release,
    };
    
    /* 驱动入口函数 */
    static int __init newchrdev_init(void)
    {
        /* 驱动入口函数具体内容 */
        /* 1、字符设备号分配 */
        int ret;
        newchrdev.major = NEWCHRDEV_MAJOR;
        if(newchrdev.major){
            newchrdev.minor = NEWCHRDEV_MINOR;
            newchrdev.devid = MKDEV(newchrdev.major, newchrdev.minor);
            ret = register_chrdev_region(newchrdev.devid,NEWCHRDEV_COUNT,NEWCHRDEV_NAME);
        }else{
            ret = alloc_chrdev_region(&newchrdev.devid,0,NEWCHRDEV_COUNT,NEWCHRDEV_NAME);
            newchrdev.major = MAJOR(newchrdev.devid);
            newchrdev.minor = MINOR(newchrdev.devid);
        }
        if(ret < 0){
            printk("newchrdev xxx_chrdev_region failed!\r\n");
            goto newchrdev_chrdev_region_failed;
        }
        printk("newchrdev major=%d,minor=%d\r\n",newchrdev.major,newchrdev.minor);
    
        /* 2、注册字符设备 */
        newchrdev.dev.owner = THIS_MODULE;
        cdev_init(&newchrdev.dev,&newchrdevops);
        ret = cdev_add(&newchrdev.dev,newchrdev.devid,NEWCHRDEV_COUNT);
        if(ret < 0){
            printk("newchrdev cdev_add failed!\r\n");
            goto newchrdev_cdev_add_failed;
        }
    
        /* 3、创建类 */
        newchrdev.class = class_create(THIS_MODULE,NEWCHRDEV_NAME);
        if(IS_ERR(newchrdev.class)) {
            printk("newchrdev class_create failed!\r\n");
            goto newchrdev_class_create_failed;
        }
    
        /* 4、创建设备 */
        newchrdev.device = device_create(newchrdev.class,NULL,newchrdev.devid,NULL,NEWCHRDEV_NAME);
        if(IS_ERR(newchrdev.device)){
            printk("newchrdev device_create failed!\r\n");
            goto neschrdev_device_creat_failed;
        }
    
        return 0;
    neschrdev_device_creat_failed:
        class_destroy(newchrdev.class);
    newchrdev_class_create_failed:
        cdev_del(&newchrdev.dev);
    newchrdev_cdev_add_failed:
        unregister_chrdev_region(newchrdev.devid,NEWCHRDEV_COUNT);
    
    newchrdev_chrdev_region_failed:   /* 字符设备号分配失败处理函数(未分配资源,因此不做处理) */
        return ret;
    }
    
    /* 驱动卸载函数 */
    static void __exit newchrdev_exit(void)
    {
        /* 驱动卸载函数具体内容 */
        /* 4、删除设备 */
        device_destroy(newchrdev.class,newchrdev.devid);
        /* 3、删除类 */
        class_destroy(newchrdev.class);
        /* 2、注销字符设备 */
        cdev_del(&newchrdev.dev);
        /* 1、释放设备号 */
        unregister_chrdev_region(newchrdev.devid,NEWCHRDEV_COUNT);
    }
    
    module_init(newchrdev_init);
    module_exit(newchrdev_exit);
    
    MODULE_LICENSE("GPL");
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
    • 130
    • 131
    • 132
    • 133
    • 134
    • 135
    • 136
    • 137
    • 138
    • 139
    • 140
    • 141
    • 142
    • 143
    • 144
    • 145
    • 146
    • 147
    • 148
    • 149
    • 150
    • 151
    • 152
    • 153
    • 154
    • 155
    • 156
    • 157
    • 158
    • 159
    • 160
    • 161
    • 162
    • 163
    • 164
    • 165
    • 166
    • 167
    • 168
    • 169
    • 170
    • 171
    • 172
    • 173
    • 174

    7、编译驱动

    onlylove@ubuntu:~/my/imx6ull_ddrive/newchrdev$ pwd
    /home/onlylove/my/imx6ull_ddrive/newchrdev
    onlylove@ubuntu:~/my/imx6ull_ddrive/newchrdev$ ls -l
    total 16
    -rw-rw-r-- 1 onlylove onlylove  250 Sep 11 19:01 Makefile
    -rw-rw-r-- 1 onlylove onlylove 5225 Sep 11 19:29 newchrdev.c
    -rw-rw-r-- 1 onlylove onlylove   60 Sep 11 18:45 newchrdev.code-workspace
    onlylove@ubuntu:~/my/imx6ull_ddrive/newchrdev$ make
    make -C /home/onlylove/my/linux/linux-imx-4.1.15 M=/home/onlylove/my/imx6ull_ddrive/newchrdev modules
    make[1]: Entering directory '/home/onlylove/my/linux/linux-imx-4.1.15'
      CC [M]  /home/onlylove/my/imx6ull_ddrive/newchrdev/newchrdev.o
      Building modules, stage 2.
      MODPOST 1 modules
      CC      /home/onlylove/my/imx6ull_ddrive/newchrdev/newchrdev.mod.o
      LD [M]  /home/onlylove/my/imx6ull_ddrive/newchrdev/newchrdev.ko
    make[1]: Leaving directory '/home/onlylove/my/linux/linux-imx-4.1.15'
    onlylove@ubuntu:~/my/imx6ull_ddrive/newchrdev$ 
    onlylove@ubuntu:~/my/imx6ull_ddrive/newchrdev$ ls -l
    total 196
    -rw-rw-r-- 1 onlylove onlylove   250 Sep 11 19:01 Makefile
    -rw-rw-r-- 1 onlylove onlylove    63 Sep 11 19:29 modules.order
    -rw-rw-r-- 1 onlylove onlylove     0 Sep 11 19:29 Module.symvers
    -rw-rw-r-- 1 onlylove onlylove  5225 Sep 11 19:29 newchrdev.c
    -rw-rw-r-- 1 onlylove onlylove    60 Sep 11 18:45 newchrdev.code-workspace
    -rw-rw-r-- 1 onlylove onlylove 83332 Sep 11 19:29 newchrdev.ko
    -rw-rw-r-- 1 onlylove onlylove  1267 Sep 11 19:29 newchrdev.mod.c
    -rw-rw-r-- 1 onlylove onlylove 21940 Sep 11 19:29 newchrdev.mod.o
    -rw-rw-r-- 1 onlylove onlylove 62536 Sep 11 19:29 newchrdev.o
    onlylove@ubuntu:~/my/imx6ull_ddrive/newchrdev$
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29

    8、测试驱动程序

    编译成功后将 newchrdev.ko 拷贝到根文件系统中。

    驱动拷贝前:

    / # ls
    bin          home         minicom.log  root         tmp
    dev          include      mnt          sbin         usr
    drivers      lib          music        share        var
    etc          linuxrc      proc         sys          video
    / #
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    驱动拷贝后:

    / # ls
    bin           include       music         share         video
    dev           lib           newchrdev.ko  sys
    drivers       linuxrc       proc          tmp
    etc           minicom.log   root          usr
    home          mnt           sbin          var
    / #
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    驱动测试:

    / # insmod newchrdev.ko 
    newchrdev major=248,minor=0
    / # 
    / # rmmod newchrdev.ko 
    / # 
    / # insmod newchrdev.ko 
    newchrdev major=248,minor=0
    / # rmmod newchrdev.ko 
    / # 
    / # insmod newchrdev.ko 
    newchrdev major=248,minor=0
    / # ls /dev/newchrdev -l
    crw-rw----    1 root     0         248,   0 Jan  1 00:06 /dev/newchrdev
    / # 
    / # rmmod newchrdev.ko 
    / # 
    / # ls /dev/newchrdev -l
    ls: /dev/newchrdev: No such file or directory
    / # 
    / # insmod newchrdev.ko 
    newchrdev major=248,minor=0
    / # ls /dev/newchrdev -l
    crw-rw----    1 root     0         248,   0 Jan  1 00:07 /dev/newchrdev
    / # rmmod newchrdev.ko 
    / # ls /dev/newchrdev -l
    ls: /dev/newchrdev: No such file or directory
    / #
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27

    9、应用程序文件

    newchrdev_app.c 文件内容:

    #include 
    #include 
    #include 
    #include "stdio.h"
    
    int main(int argc, char *argv[])
    {
        int fd = 0, retvalue = 0;
        char writebuf[1] = {1};
        unsigned int connect = 0;
        if(argc != 2){
    		printf("Error Usage!\r\n");
    		return -1;
    	}
    
        fd = open(argv[1],O_RDWR);
        if(fd < 0){
            printf("Can't open file %s\r\n", argv[1]);
            return -1;
        }
        retvalue = write(fd, writebuf, sizeof(writebuf));
    
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

    makefile 文件内容:

    newchrdev_app:
    	arm-linux-gnueabihf-gcc newchrdev_app.c -o newchrdev_app
    
    clean:
    	rm -rf newchrdev_app
    
    • 1
    • 2
    • 3
    • 4
    • 5

    10、编译应用程序

    onlylove@ubuntu:~/my/imx6ull_app/newchrdev$ pwd
    /home/onlylove/my/imx6ull_app/newchrdev
    onlylove@ubuntu:~/my/imx6ull_app/newchrdev$ ls -l
    total 8
    -rw-rw-r-- 1 onlylove onlylove 102 Sep 11 19:48 makefile
    -rw-rw-r-- 1 onlylove onlylove 461 Sep 11 19:48 newchrdev_app.c
    onlylove@ubuntu:~/my/imx6ull_app/newchrdev$ make
    arm-linux-gnueabihf-gcc newchrdev_app.c -o newchrdev_app
    onlylove@ubuntu:~/my/imx6ull_app/newchrdev$ ls -l
    total 20
    -rw-rw-r-- 1 onlylove onlylove   102 Sep 11 19:48 makefile
    -rwxrwxr-x 1 onlylove onlylove 10357 Sep 11 19:49 newchrdev_app
    -rw-rw-r-- 1 onlylove onlylove   461 Sep 11 19:48 newchrdev_app.c
    onlylove@ubuntu:~/my/imx6ull_app/newchrdev$
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    编译成功后将 newchrdev_app 拷贝到根文件系统中。

    11、应用程序和驱动联调测试

    / # ls
    bin            include        music          sbin           var
    dev            lib            newchrdev.ko   share          video
    drivers        linuxrc        newchrdev_app  sys
    etc            minicom.log    proc           tmp
    home           mnt            root           usr
    / # insmod newchrdev.ko 
    newchrdev major=248,minor=0
    / # ls -l /dev/newchrdev 
    crw-rw----    1 root     0         248,   0 Jan  1 01:54 /dev/newchrdev
    / # 
    / # ./newchrdev_app /dev/newchrdev 
    newchrdev_open!
    newchrdev_write!
    flag = 1
    newchrdev_release!
    / # 
    / # rmmod newchrdev.ko 
    / # ls -l /dev/newchrdev 
    ls: /dev/newchrdev: No such file or directory
    / # ./newchrdev_app /dev/newchrdev 
    Can't open file /dev/newchrdev
    / #
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    四、驱动调试

    1、概述

    i.MX 6ULL 驱动开发 二:搭建 KGDB 调试 linux 内核和驱动环境_lqonlylove的博客-CSDN博客

    2、开启 agent-proxy

    agent-proxy 5550^5551 0 /dev/ttyUSB0,115200
    
    • 1

    3、开启日志终端

    telnet localhost 5550
    
    • 1

    4、安装驱动

    在日志终端安装驱动文件,并查看驱动相关信息。

    / # ls
    bin            include        music          sbin           var
    dev            lib            newchrdev.ko   share          video
    drivers        linuxrc        newchrdev_app  sys
    etc            minicom.log    proc           tmp
    home           mnt            root           usr
    / # insmod newchrdev.ko
    newchrdev major=248,minor=0
    / # ls -l /dev/newchrdev
    crw-rw----    1 root     0         248,   0 Jan  1 01:57 /dev/newchrdev
    / # ./newchrdev_app /dev/newchrdev
    newchrdev_open!
    newchrdev_write!
    flag = 1
    newchrdev_release!
    / # rmmod newchrdev.ko
    / # ls -l /dev/newchrdev
    ls: /dev/newchrdev: No such file or directory
    / # ./newchrdev_app /dev/newchrdev
    Can't open file /dev/newchrdev
    / # 
    / # insmod newchrdev.ko
    newchrdev major=248,minor=0
    / # cat /sys/module/newchrdev/sections/.text
    0x7f004000
    / #
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26

    5、触发 KGDB

    echo g > /proc/sysrq-trigger
    
    • 1
    / # echo g > /proc/sysrq-trigger
    sysrq: SysRq : DEBUG
    KGDB: Entering KGDB
    
    • 1
    • 2
    • 3

    6、启动 GDB

    新建终端,并开启 GDB。

    arm-linux-gnueabihf-gdb
    add-symbol-file newchrdev.ko 0x7f004000
    
    • 1
    • 2
    onlylove@ubuntu:~/my/nfs$ ls
    bin  drivers  home     lib      minicom.log  music          newchrdev.ko  root  share  tmp  var
    dev  etc      include  linuxrc  mnt          newchrdev_app  proc          sbin  sys    usr  video
    onlylove@ubuntu:~/my/nfs$ arm-linux-gnueabihf-gdb
    GNU gdb (Linaro_GDB-2017.01) 7.10.1.20160210-cvs
    Copyright (C) 2015 Free Software Foundation, Inc.
    License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
    This is free software: you are free to change and redistribute it.
    There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
    and "show warranty" for details.
    This GDB was configured as "--host=x86_64-unknown-linux-gnu --target=arm-linux-gnueabihf".
    Type "show configuration" for configuration details.
    For bug reporting instructions, please see:
    <http://www.gnu.org/software/gdb/bugs/>.
    Find the GDB manual and other documentation resources online at:
    <http://www.gnu.org/software/gdb/documentation/>.
    For help, type "help".
    Type "apropos word" to search for commands related to "word".
    (gdb) add-symbol-file newchrdev.ko 0x7f004000
    add symbol table from file "newchrdev.ko" at
    	.text_addr = 0x7f004000
    (y or n) y
    Reading symbols from newchrdev.ko...done.
    (gdb)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

    7、开启调试终端

    tar rem localhost:5551
    
    • 1

    调试终端日志:

    onlylove@ubuntu:~/my/nfs$ arm-linux-gnueabihf-gdb
    GNU gdb (Linaro_GDB-2017.01) 7.10.1.20160210-cvs
    Copyright (C) 2015 Free Software Foundation, Inc.
    License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
    This is free software: you are free to change and redistribute it.
    There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
    and "show warranty" for details.
    This GDB was configured as "--host=x86_64-unknown-linux-gnu --target=arm-linux-gnueabihf".
    Type "show configuration" for configuration details.
    For bug reporting instructions, please see:
    <http://www.gnu.org/software/gdb/bugs/>.
    Find the GDB manual and other documentation resources online at:
    <http://www.gnu.org/software/gdb/documentation/>.
    For help, type "help".
    Type "apropos word" to search for commands related to "word".
    (gdb) add-symbol-file newchrdev.ko 0x7f004000
    add symbol table from file "newchrdev.ko" at
    	.text_addr = 0x7f004000
    (y or n) y
    Reading symbols from newchrdev.ko...done.
    (gdb) 
    (gdb) 
    (gdb) tar rem localhost:5551
    Remote debugging using localhost:5551
    0x8009d45c in ?? ()
    (gdb)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26

    日志终端日志:

    / # echo g > /proc/sysrq-trigger
    sysrq: SysRq : DEBUG
    KGDB: Entering KGDB
    +$#00+$OK#9a+$#00+$S05#b8+$mfffffffe,01,02,03,04,05,06,07,08,09,0a,0b,0c,0d,0e,0f,10,11#4d+$m12,13,14,15,16,17,18,28,29,2e,2f,30,31,32,33,34,35#5c+$m36,37,38,39,3a,3b,3c,3d,3e,41,42,53,54#b1+$#00+$#00+$OK#9a+$QC53#fc+$13000000000000000000000000000000c489aa80c889aa8004c5a0800700000000000000000051880000000020b54a0000000000b81e5188cc6131805cd4098000000000000000000000000000000000000000000000000000000000000000000000000000000000#ec+$mfffffffe,01,02,03,04,05,06,07,08,09,0a,0b,0c,0d,0e,0f,10,11#4d+$m12,13,14,15,16,17,18,28,29,2e,2f,30,31,32,33,34,35#5c+$m36,37,38,39,3a,3b,3c,3d,3e,41,42,53,54#b1+$#00+$ffdeffe7#fd+$33ff2fe1#60+$ffdeffe7#fd+$33ff2fe1#60+$ffde#95+$2fe1#2e+$33ff#32+$ffde#95+$2fe1#2e+$33ff#32+$ffdeffe7#fd+$33ff2fe1#60+$ffdeffe7#fd+$33ff2fe1#60+$ffdeffe7#fd+$ffdeffe7#fd+$ffdeffe7#fd+$13000d60#be+$fcb44a00#54+$a4b44a00#20
    
    • 1
    • 2
    • 3
    • 4

    8、调试驱动

    1、设置断点

    b 72
    
    • 1
    onlylove@ubuntu:~/my/nfs$ ls
    bin  drivers  home     lib      minicom.log  music          newchrdev.ko  root  share  tmp  var
    dev  etc      include  linuxrc  mnt          newchrdev_app  proc          sbin  sys    usr  video
    onlylove@ubuntu:~/my/nfs$ arm-linux-gnueabihf-gdb
    GNU gdb (Linaro_GDB-2017.01) 7.10.1.20160210-cvs
    Copyright (C) 2015 Free Software Foundation, Inc.
    License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
    This is free software: you are free to change and redistribute it.
    There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
    and "show warranty" for details.
    This GDB was configured as "--host=x86_64-unknown-linux-gnu --target=arm-linux-gnueabihf".
    Type "show configuration" for configuration details.
    For bug reporting instructions, please see:
    <http://www.gnu.org/software/gdb/bugs/>.
    Find the GDB manual and other documentation resources online at:
    <http://www.gnu.org/software/gdb/documentation/>.
    For help, type "help".
    Type "apropos word" to search for commands related to "word".
    (gdb) add-symbol-file newchrdev.ko 0x7f004000
    add symbol table from file "newchrdev.ko" at
    	.text_addr = 0x7f004000
    (y or n) y
    Reading symbols from newchrdev.ko...done.
    (gdb) tar rem localhost:5551
    Remote debugging using localhost:5551
    0x8009d45c in ?? ()
    (gdb) b 72
    Breakpoint 1 at 0x7f00409c: file /home/onlylove/my/imx6ull_ddrive/newchrdev/newchrdev.c, line 72.
    (gdb) 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29

    2、运行驱动

    c
    
    • 1

    3、在日志终端使用应用程序调用驱动程序

    / # echo g > /proc/sysrq-trigger
    sysrq: SysRq : DEBUG
    KGDB: Entering KGDB
    +$#00+$OK#9a+$#00+$S05#b8+$mfffffffe,01,02,03,04,05,06,07,08,09,0a,0b,0c,0d,0e,0f,10,11#4d+$m12,13,14,15,16,17,18,28,29,2e,2f,30,31,32,33,34,35#5c+$m36,37,38,39,3a,3b,3c,3d,3e,41,42,53,54#b1+$#00+$#00+$OK#9a+$QC53#fc+$13000000000000000000000000000000c489aa80c889aa8004c5a0800700000000000000000051880000000020b54a0000000000b81e5188cc6131805cd4098000000000000000000000000000000000000000000000000000000000000000000000000000000000#ec+$mfffffffe,01,02,03,04,05,06,07,08,09,0a,0b,0c,0d,0e,0f,10,11#4d+$m12,13,14,15,16,17,18,28,29,2e,2f,30,31,32,33,34,35#5c+$m36,37,38,39,3a,3b,3c,3d,3e,41,42,53,54#b1+$#00+$ffdeffe7#fd+$33ff2fe1#60+$ffdeffe7#fd+$33ff2fe1#60+$ffde#95+$2fe1#2e+$33ff#32+$ffde#95+$2fe1#2e+$33ff#32+$ffdeffe7#fd+$33ff2fe1#60+$ffdeffe7#fd+$33ff2fe1#60+$ffdeffe7#fd+$ffdeffe7#fd+$ffdeffe7#fd+$13000d60#be+$fcb44a00#54+$a4b44a00#20+$a4009fe5#2e+$3442007f#ca+$0f10dde5#59+$OK#9a+$#00+$OK#9a+/ # sysrq: SysRq : HELP : loglevel(0-9) reboot(b) crash(c) terminate-all-tasks(e) memory-full-oom-kill(f) debug(g) kill-all-tasks(i) thaw-filesystems(j) sak(k) show-backtrace-all-active-cpus(l) show-memory-usage(m) nice-all-RT-tasks(n) poweroff(o) show-registers(p) show-all-timers(q) unraw(r) sync(s) show-task-states(t) unmount(u) show-blocked-tasks(w) 
    
    / # ./newchrdev_app /dev/newchrdev
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    4、日志终端输出信息如下:

    / # ./newchrdev_app /dev/newchrdev
    newchrdev_open!
    newchrdev_write!
    $T05thread:74;#11+$00000000c97bf07e000000800100000000000000c87bf07ec87bf07e88ff778884f6008000e07788000000000000000000000000e0fe7788cc40007f9c40007f00000000000000000000000000000000000000000000000000000000000000000000000000000000#db+$0f10dde5#59+$1200001a#b5+$0f10dde5#59+$1200001a#b5+$0f10#f7+$001a#f2+$1200#c3+$0f10#f7+$001a#f2+$1200#c3+$0f10dde5#59+$1200001a#b5+$0f10dde5#59+$1200001a#b5+$0f10dde5#59+$0f10dde5#59+$0f10dde5#59+$mfffffffe,01,02,03,05,07,08,09,0a,0b,0c,0d,0e,0f,10,11,12,13#4a+$m14,15,16,17,18,28,29,2e,30,31,32,33,34,36,37,38,39#3f+$m3a,3b,3c,3d,3e,41,42,53,54,70,73,74#17+$#00+$OK#9a+$ecd70e80#60+$ecd70e80#60+$4cd08de2#5e+$35ff2fe1#62+$4cd08de2#5e+$35ff2fe1#62+$4cd0#2b+$2fe1#2e+$35ff#34+$4cd0#2b+$2fe1#2e+$35ff#34+$4cd08de2#5e+$35ff2fe1#62+$4cd08de2#5e+$35ff2fe1#62+$4cd08de2#5e+$4cd08de2#5e+$4cd08de2#5e+$13000b60#bc+$ecd70e80#60+$ecd70e80#60+$E22#a9+$0104010000000000#06
    
    • 1
    • 2
    • 3
    • 4

    5、调试终端输入信息如下:

    onlylove@ubuntu:~/my/nfs$ ls
    bin  drivers  home     lib      minicom.log  music          newchrdev.ko  root  share  tmp  var
    dev  etc      include  linuxrc  mnt          newchrdev_app  proc          sbin  sys    usr  video
    onlylove@ubuntu:~/my/nfs$ arm-linux-gnueabihf-gdb
    GNU gdb (Linaro_GDB-2017.01) 7.10.1.20160210-cvs
    Copyright (C) 2015 Free Software Foundation, Inc.
    License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
    This is free software: you are free to change and redistribute it.
    There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
    and "show warranty" for details.
    This GDB was configured as "--host=x86_64-unknown-linux-gnu --target=arm-linux-gnueabihf".
    Type "show configuration" for configuration details.
    For bug reporting instructions, please see:
    <http://www.gnu.org/software/gdb/bugs/>.
    Find the GDB manual and other documentation resources online at:
    <http://www.gnu.org/software/gdb/documentation/>.
    For help, type "help".
    Type "apropos word" to search for commands related to "word".
    (gdb) add-symbol-file newchrdev.ko 0x7f004000
    add symbol table from file "newchrdev.ko" at
    	.text_addr = 0x7f004000
    (y or n) y
    Reading symbols from newchrdev.ko...done.
    (gdb) tar rem localhost:5551
    Remote debugging using localhost:5551
    0x8009d45c in ?? ()
    (gdb) b 72
    Breakpoint 1 at 0x7f00409c: file /home/onlylove/my/imx6ull_ddrive/newchrdev/newchrdev.c, line 72.
    (gdb) c
    Continuing.
    [New Thread 116]
    [New Thread 112]
    [New Thread 115]
    [Switching to Thread 116]
    
    Breakpoint 1, newchrdev_write (filp=<optimized out>, buf=0x7ef07bc8 "\001\004\001", cnt=0, offt=<optimized out>)
        at /home/onlylove/my/imx6ull_ddrive/newchrdev/newchrdev.c:72
    72	    flag = databuf[0];
    (gdb) 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39

    6、使用 GDB 调试驱动

    onlylove@ubuntu:~/my/nfs$ ls
    bin  drivers  home     lib      minicom.log  music          newchrdev.ko  root  share  tmp  var
    dev  etc      include  linuxrc  mnt          newchrdev_app  proc          sbin  sys    usr  video
    onlylove@ubuntu:~/my/nfs$ arm-linux-gnueabihf-gdb
    GNU gdb (Linaro_GDB-2017.01) 7.10.1.20160210-cvs
    Copyright (C) 2015 Free Software Foundation, Inc.
    License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
    This is free software: you are free to change and redistribute it.
    There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
    and "show warranty" for details.
    This GDB was configured as "--host=x86_64-unknown-linux-gnu --target=arm-linux-gnueabihf".
    Type "show configuration" for configuration details.
    For bug reporting instructions, please see:
    <http://www.gnu.org/software/gdb/bugs/>.
    Find the GDB manual and other documentation resources online at:
    <http://www.gnu.org/software/gdb/documentation/>.
    For help, type "help".
    Type "apropos word" to search for commands related to "word".
    (gdb) add-symbol-file newchrdev.ko 0x7f004000
    add symbol table from file "newchrdev.ko" at
    	.text_addr = 0x7f004000
    (y or n) y
    Reading symbols from newchrdev.ko...done.
    (gdb) tar rem localhost:5551
    Remote debugging using localhost:5551
    0x8009d45c in ?? ()
    (gdb) b 72
    Breakpoint 1 at 0x7f00409c: file /home/onlylove/my/imx6ull_ddrive/newchrdev/newchrdev.c, line 72.
    (gdb) c
    Continuing.
    [New Thread 116]
    [New Thread 112]
    [New Thread 115]
    [Switching to Thread 116]
    
    Breakpoint 1, newchrdev_write (filp=<optimized out>, buf=0x7ef07bc8 "\001\004\001", cnt=0, offt=<optimized out>)
        at /home/onlylove/my/imx6ull_ddrive/newchrdev/newchrdev.c:72
    72	    flag = databuf[0];
    (gdb) list
    67	    retvalue = copy_from_user(databuf, buf, cnt);
    68	    if(retvalue < 0) {
    69			printk("kernel write failed!\r\n");
    70			return -EFAULT;
    71		}
    72	    flag = databuf[0];
    73	    if(flag == 5){
    74	        printk("gdb debug success!\r\n");
    75	    }
    76	    printk("flag = %d\r\n",flag);
    (gdb) p flag
    $1 = <optimized out>
    (gdb) next
    73	    if(flag == 5){
    (gdb) p flag
    $2 = 1 '\001'
    (gdb) set variable flag = 5
    (gdb) p flag
    $3 = 5 '\005'
    (gdb) c
    Continuing.
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60

    7、日志终端内容如下:

    / # ./newchrdev_app /dev/newchrdev
    newchrdev_open!
    newchrdev_write!
    $T05thread:74;#11+$00000000c97bf07e000000800100000000000000c87bf07ec87bf07e88ff778884f6008000e07788000000000000000000000000e0fe7788cc40007f9c40007f00000000000000000000000000000000000000000000000000000000000000000000000000000000#db+$0f10dde5#59+$1200001a#b5+$0f10dde5#59+$1200001a#b5+$0f10#f7+$001a#f2+$1200#c3+$0f10#f7+$001a#f2+$1200#c3+$0f10dde5#59+$1200001a#b5+$0f10dde5#59+$1200001a#b5+$0f10dde5#59+$0f10dde5#59+$0f10dde5#59+$mfffffffe,01,02,03,05,07,08,09,0a,0b,0c,0d,0e,0f,10,11,12,13#4a+$m14,15,16,17,18,28,29,2e,30,31,32,33,34,36,37,38,39#3f+$m3a,3b,3c,3d,3e,41,42,53,54,70,73,74#17+$#00+$OK#9a+$ecd70e80#60+$ecd70e80#60+$4cd08de2#5e+$35ff2fe1#62+$4cd08de2#5e+$35ff2fe1#62+$4cd0#2b+$2fe1#2e+$35ff#34+$4cd0#2b+$2fe1#2e+$35ff#34+$4cd08de2#5e+$35ff2fe1#62+$4cd08de2#5e+$35ff2fe1#62+$4cd08de2#5e+$4cd08de2#5e+$4cd08de2#5e+$13000b60#bc+$ecd70e80#60+$ecd70e80#60+$E22#a9+$0104010000000000#06+$0f10dde5#59+$0f10dde5#59+$050051e3#c3+$OK#9a+$OK#9a+$T05thread:74;#11+$0000000001000000000000800100000000000000c87bf07ec87bf07e88ff778884f6008000e07788000000000000000000000000e0fe7788cc40007fa040007f00000000000000000000000000000000000000000000000000000000000000000000000000000000#ea+$050051e3#c3+$0f10dde5#59+$050051e3#c3+$0f10dde5#59+$0500#c5+$dde5#62+$0f10#f7+$0500#c5+$dde5#62+$0f10#f7+$050051e3#c3+$0f10dde5#59+$050051e3#c3+$0f10dde5#59+$050051e3#c3+$050051e3#c3+$050051e3#c3+$OK#9a+$mfffffffe,01,02,03,05,07,08,09,0a,0b,0c,0d,0e,0f,10,11,12,13#4a+$m14,15,16,17,18,28,29,2e,30,31,32,33,34,36,37,38,39#3f+$m3a,3b,3c,3d,3e,41,42,53,54,70,73,74#17+$#00+$OK#9a+$0000000005000000000000800100000000000000c87bf07ec87bf07e88ff778884f6008000e07788000000000000000000000000e0fe7788cc40007fa040007f00000000000000000000000000000000000000000000000000000000000000000000000000000000#ee+$050051e3#c3+$0f10dde5#59+$050051e3#c3+$0f10dde5#59+$0500#c5+$dde5#62+$0f10#f7+$0500#c5+$dde5#62+$0f10#f7+$050051e3#c3+$0f10dde5#59+$050051e3#c3+$0f10dde5#59+$050051e3#c3+$050051e3#c3+$050051e3#c3+$OK#9a+$OK#9a+gdb debug success!
    flag = 5
    newchrdev_release!
    / #
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    通过以上日志可以确定 “gdb debug success!” 字符串成功打印,因此,GDB 修改 flag 变量成功。

    9、不使用 GDB 修改 flag 变量的输入日志内容如下:

    / # ./newchrdev_app /dev/newchrdev
    newchrdev_open!
    newchrdev_write!
    $T05thread:78;#15+$00000000c91bc27e000000800100000000000000c81bc27ec81bc27e889f068884f6008000800688000000000000000001000000e09e0688cc40007f9c40007f00000000000000000000000000000000000000000000000000000000000000000000000000000000#28+$0f10dde5#59+$1200001a#b5+$0f10dde5#59+$1200001a#b5+$0f10#f7+$001a#f2+$1200#c3+$0f10#f7+$001a#f2+$1200#c3+$0f10dde5#59+$1200001a#b5+$0f10dde5#59+$1200001a#b5+$0f10dde5#59+$0f10dde5#59+$0f10dde5#59+$mfffffffe,01,02,03,07,08,09,0a,0b,0c,0d,0e,0f,10,11,12,14,15#4c+$m16,17,18,28,29,2e,30,31,32,33,34,36,37,38,39,3a,3b#9d+$m3c,3d,3e,41,42,53,54,70,73,77,78#34+$#00+$OK#9a+$ecd70e80#60+$ecd70e80#60+$4cd08de2#5e+$35ff2fe1#62+$4cd08de2#5e+$35ff2fe1#62+$4cd0#2b+$2fe1#2e+$35ff#34+$4cd0#2b+$2fe1#2e+$35ff#34+$4cd08de2#5e+$35ff2fe1#62+$4cd08de2#5e+$35ff2fe1#62+$4cd08de2#5e+$4cd08de2#5e+$4cd08de2#5e+$13000b60#bc+$ecd70e80#60+$ecd70e80#60+$E22#a9+$0104010000000000#06+$0f10dde5#59+$0f10dde5#59+$050051e3#c3+$OK#9a+$OK#9a+$T05thread:78;#15+$0000000001000000000000800100000000000000c81bc27ec81bc27e889f068884f6008000800688000000000000000001000000e09e0688cc40007fa040007f00000000000000000000000000000000000000000000000000000000000000000000000000000000#3e+$050051e3#c3+$0f10dde5#59+$050051e3#c3+$0f10dde5#59+$0500#c5+$dde5#62+$0f10#f7+$0500#c5+$dde5#62+$0f10#f7+$050051e3#c3+$0f10dde5#59+$050051e3#c3+$0f10dde5#59+$050051e3#c3+$050051e3#c3+$050051e3#c3+$OK#9a+$OK#9a+$OK#9a+flag = 1
    newchrdev_release!
    / #
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    未打印 “gdb debug success!” 字符串。

  • 相关阅读:
    Flutter知识点
    Vue2.0 —— 由设计模式切入,实现响应式原理
    react+IntersectionObserver实现页面丝滑帧动画
    C++ Primer Plus第五版笔记(p51-100)
    AUTOSAR AP硬核知识点梳理(1)
    设置TOMCAT SESSIONID 字符长度和生成算法
    Three.js使用InstancedMesh实现性能优化
    TDengineGUI无法连接TDengine
    在MySQL上实现间隔5分钟汇总取数及相关字符串、时间处理方法实践
    100天精通Oracle-实战系列(第21天)Oracle 数据泵常用参数和命令
  • 原文地址:https://blog.csdn.net/OnlyLove_/article/details/126816325