使用GDB调试linux设备驱动程序命令

要调试Linux设备驱动程序命令,可以按照以下步骤进行:

1. 编译驱动程序:首先,要确保已经安装好了Linux系统和相应的开发工具链,然后根据实际情况选择合适的驱动程序源代码。进入驱动程序所在目录,执行make命令进行编译。

2. 加载驱动程序:编译成功后,可以使用insmod命令加载驱动程序到Linux内核中。例如,执行insmod mydriver.ko命令来加载名为mydriver的驱动程序。

3. 检查驱动程序是否加载成功:可以使用lsmod命令来查看已加载的驱动程序列表,确认驱动程序是否已经加载到内核中。

4. 检查驱动程序打印信息:驱动程序通常会在加载时输出一些打印信息,以便于调试。可以通过dmesg命令查看内核日志,或者使用tail -f /var/log/messages命令实时查看系统日志,以获取驱动程序的打印信息。

5. 调试驱动程序:可以使用gdb命令对驱动程序进行调试。首先,确保驱动程序编译时已开启调试信息,可以在Makefile中添加”-g”选项。然后,使用gdb mydriver命令启动gdb调试工具,然后使用”target remote localhost:1234″命令连接到驱动程序所在的目标机,最后使用”break”命令设置断点,”run”命令运行驱动程序,并使用其他gdb命令进行调试。

6. 卸载驱动程序:在调试完成后,可以使用rmmod命令卸载已加载的驱动程序,例如执行rmmod mydriver命令来卸载名为mydriver的驱动程序。

总结:以上就是调试Linux设备驱动程序命令的一般步骤。通过编译、加载、检查、调试和卸载等步骤,可以有效地进行驱动程序调试工作,帮助解决驱动程序中的问题。

#insmod xxx.ko
#cd /sys/module

#gdb xxx

退出
quit

buntu18.04中,当你配置 GRUB 启动参数时:编辑 GRUB 配置文件,添加内核启动参数。这些参数包括:

  • kgdboc: 指定调试串口和波特率。
  • kgdbwait: 启动时等待调试器连接。

假设你使用的是 ttyS0 串口,波特率为 115200:

打开 /etc/default/grub 文件:

sudo nano /etc/default/grub

找到 GRUB_CMDLINE_LINUX 行,并添加 kgdbockgdbwait 参数。例如:

GRUB_CMDLINE_LINUX="... kgdboc=ttyS0,115200 kgdbwait"

Ctrl-O保存;Ctrl-X退出后。

保存并更新 GRUB 配置:

sudo update-grub

最后重启后,遇到报错:waiting connection form remote gdb...

kdb(current=0xffff8c099be9700,pid 1)on processor 1 due to keyborard

[1]kdb>_

原因:复制代码错误信息表明内核正在等待调试器连接,但由于未成功连接到远程 GDB,它进入了 KDB(内核调试器)模式。这通常是因为 GDB 没有正确连接或配置。
这种情况下要恢复计算机:

e 键进入编辑模式。

删除"kgdboc=ttyS0,115200 kgdbwait"

F10重启即可。

重启后,还需进行修改;

sudo nano /etc/default/grub
更新 GRUB 配置:
sudo update-grub
重启:
reboot

方法二:可以在Windows的Visual Studio Code (VSCode) 中调试 Ubuntu 设备驱动代码。

若遇到"无法打开源文件 asm/io.h" 的问题,通常是由于编译器找不到正确的头文件路径。

解决:

1. 安装WSL(Windows Subsystem for Linux)

首先,你需要在Windows上安装WSL,以便在Windows上运行Ubuntu环境。

  • 打开PowerShell并运行以下命令安装WSL:

  • wsl --install

    安装完成后,重新启动计算机。

  • 安装Ubuntu发行版:

wsl --install -d Ubuntu

2. 在WSL中安装必要的软件包

  • 启动WSL并安装构建工具和Linux内核头文件:
sudo apt update
sudo apt install build-essential linux-headers-$(uname -r)

3. 配置VSCode进行远程开发

  • 安装VSCode并打开。
  • 安装“Remote - WSL”扩展:
    1. 打开VSCode的扩展视图(通过按 Ctrl+Shift+X)。
    2. 搜索 "Remote - WSL" 并安装。
  • 使用WSL打开你的项目:
    1. Ctrl+Shift+P 打开命令面板。
    2. 输入并选择 Remote-WSL: New Window
    3. 在WSL中导航到你的项目目录并打开它。

4. 配置头文件路径

在你的VSCode项目中,需要配置头文件路径以便VSCode找到正确的头文件。

  • 在你的项目根目录下创建或编辑 c_cpp_properties.json 文件(如果你使用C/C++扩展)。

{
    "configurations": [
        {
            "name": "WSL",
            "includePath": [
                "${workspaceFolder}/**",
                "/usr/include/**",
                "/usr/local/include/**",
                "/usr/src/linux-headers-$(uname -r)/include/**"
            ],
            "defines": [],
            "compilerPath": "/usr/bin/gcc",
            "cStandard": "c11",
            "cppStandard": "c++17",
            "intelliSenseMode": "linux-gcc-x64"
        }
    ],
    "version": 4
}

5. 编译并调试代码

现在,你应该可以在WSL中编译和调试你的Linux设备驱动代码。

  • 在VSCode终端中运行编译命令:make

  • 配置调试器(可以使用 launch.json 配置文件)以适应你的项目需求。

通过这些步骤,你应该能够解决“无法打开源文件 asm/io.h”的问题,并顺利在Windows的VSCode中调试Ubuntu的设备驱动代码。如果还有问题,请检查头文件路径是否正确,或者确认WSL中安装了正确的Linux内核头文件。

使用网络进行内核调试(KGDB over Ethernet)是一种高效的方法,可以避免使用串行端口带来的限制。以下步骤将引导你如何配置和使用网络进行内核调试。

前提条件

  1. 已编译内核模块:确保你已经编译并生成了 short.ko 文件。
  2. 启用调试内核:你的Linux内核需要启用调试支持(即内核配置中启用了 CONFIG_KGDBCONFIG_KGDB_ETHCONFIG_DEBUG_INFO)。
  3. 两台机器:一台作为目标机器(运行内核和模块),另一台作为调试主机(运行GDB)。

步骤1:配置目标机器的内核
1. 修改Grub配置
编辑 /etc/default/grub 文件,添加或修改以下行,使其包含网络调试参数:
GRUB_CMDLINE_LINUX="kgdboc=kgdbeth0,192.168.0.2,192.168.0.1,115200"

其中:

kgdbeth0 是你的网络接口(可以使用 eth0 或其他适当的接口名称)。
192.168.0.2 是目标机器的IP地址。
192.168.0.1 是调试主机的IP地址。
115200 是波特率(可以使用默认值)。
更新Grub配置并重启系统:
sudo update-grub
sudo reboot

步骤2:启动KGDB
在目标机器上,启动KGDB:echo g > /proc/sysrq-trigger

步骤3:在调试主机上配置GDB
确保你的调试主机和目标机器在同一个网络中,可以相互通信。

1. 安装GDB
确保调试主机上安装了GDB:sudo apt-get install gdb

2. 启动GDB并连接到目标机器
在调试主机上,启动GDB并连接到目标机器:
file /path/to/vmlinux
target remote 192.168.0.2:1234

步骤4:加载内核模块符号
获取内核模块的加载地址并在GDB中加载模块符号:cat /proc/modules | grep short
假设加载地址是 0xffffffffc0002000,在GDB中:add-symbol-file /path/to/short.ko 0xffffffffc0002000

配置VSCode进行远程调试

为了使用VSCode进行调试,我们需要配置 launch.jsontasks.json 文件。

1. 创建tasks.json

.vscode目录下创建 tasks.json 文件,定义一个用于编译内核模块的任务:

{
    "version": "2.0.0",
    "tasks": [
        {
            "label": "build",
            "type": "shell",
            "command": "make",
            "args": [],
            "group": {
                "kind": "build",
                "isDefault": true
            },
            "problemMatcher": ["$gcc"],
            "detail": "Build the kernel module"
        }
    ]
}
2. 创建launch.json

.vscode目录下创建 launch.json 文件,配置GDB调试:

{
    "version": "0.2.0",
    "configurations": [
        {
            "name": "Kernel Debug",
            "type": "cppdbg",
            "request": "launch",
            "program": "/path/to/vmlinux",  // 内核符号文件路径
            "args": [],
            "stopAtEntry": false,
            "cwd": "${workspaceFolder}",
            "environment": [],
            "externalConsole": false,
            "MIMode": "gdb",
            "setupCommands": [
                {
                    "description": "Enable pretty-printing for gdb",
                    "text": "-enable pretty-printing",
                    "ignoreFailures": true
                },
                {
                    "description": "Load kernel module symbols",
                    "text": "add-symbol-file /path/to/short.ko 0x<module_load_address>",  // 替换为模块加载地址
                    "ignoreFailures": false
                }
            ],
            "targetArchitecture": "x86_64",
            "miDebuggerPath": "/usr/bin/gdb",
            "miDebuggerArgs": "-ex 'target remote 192.168.0.2:1234'",  // 替换为目标机器IP和端口
            "logging": {
                "trace": true,
                "traceResponse": true,
                "engineLogging": true
            }
        }
    ]
}

请根据实际情况替换以下路径和地址:

  • /path/to/vmlinux:你的内核符号文件的路径。
  • /path/to/short.ko:你的内核模块文件的路径。
  • 0x<module_load_address>:内核模块的加载地址(通过 cat /proc/modules | grep short 获取)。
  • 192.168.0.2:1234:目标机器的IP和端口。

使用VSCode进行调试

  1. 使用VSCode的Remote-SSH插件连接到远程机器。
  2. 确保在VSCode的终端中可以成功构建内核模块:make

遇到问题:

(gdb) file /path/to/vmlinux /path/to/vmlinux: 没有那个文件或目录.

方法一:从现有内核源码编译 vmlinux

1、安装内核源码和编译工具:
确保你的系统上安装了内核源码和必要的编译工具。
sudo apt-get update
sudo apt-get install build-essential libncurses-dev bison flex libssl-dev libelf-dev
sudo apt-get install linux-source

2、获取当前内核的配置:
获取当前正在运行的内核配置文件。
zcat /proc/config.gz > .config
3、下载并解压内核源码:
如果你已经安装了 linux-source 包,可以在 /usr/src 目录下找到源码压缩包。
cd /usr/src
sudo tar -xvf linux-source-<version>.tar.xz
cd linux-source-<version>

4、使用当前配置文件:
将当前内核的配置文件复制到内核源码目录,并配置内核。
cp /boot/config-$(uname -r) .config
make oldconfig

5、编译内核:
编译内核以生成 vmlinux 文件。
make -j$(nproc)
这将在内核源码的根目录中生成 vmlinux 文件。

具体实施:

sudo find /usr -name "vmlinux*"
sudo apt-get update
sudo apt-get install build-essential libncurses-dev bison flex libssl-dev libelf-dev
cd /usr/src
sudo apt-get install linux-source
sudo tar -xvf linux-source-4.15.0.tar.bz2
cd linux-source-4.15.0/
cp /boot/config-$(uname -r) .config
make oldconfig
make -j$(nproc)

点击GDB调试后一直报错:

Unable to start debugging. Unexpected GDB output from command "-target- select remote 192.1 68.100.100:1234". Remote replied unexpectedly to 'vMustReplyEmpty': timeout

查找了网络端口等各种原因,没找到,最后使用:dmesg | tail查看系统日志发现

[    4.831626] audit: type=1400 audit(1716269444.380:9): apparmor="STATUS" operprofile="unconfined" name="/usr/lib/NetworkManager/nm-dhcp-helper" pid=690 comm
[    4.831628] audit: type=1400 audit(1716269444.380:10): apparmor="STATUS" ope profile="unconfined" name="/usr/lib/connman/scripts/dhclient-script" pid=690 c
[    5.553958] IPv6: ADDRCONF(NETDEV_UP): eth0: link is not ready
[    5.748182] IPv6: ADDRCONF(NETDEV_UP): eth0: link is not ready
[    5.750803] IPv6: ADDRCONF(NETDEV_UP): eth1: link is not ready
[    8.267339] rfkill: input handler disabled

网卡(eth0eth1)没有成功配置,可能导致 gdbserver 无法通过网络进行远程调试连接。

重新配置grub,将网卡配置eth1包含192.168.100.100网址的:

echo "add-auto-load-safe-path /usr/src/linux-source-4.15.0/scripts/gdb/vmlinux-gdb.py" >> ~/.gdbinit
reboot

sudo ufw allow 1234/tcp
sudo ufw reload

sudo netstat -tuln | grep 1234
dmesg | tail
ifocnfig

vim /etc/default/grub
sudo update-grub
reboot

然后可以连接,但又报错:

(gdb) target remote 192.168.100.100:1234 Remote debugging using 192.168.100.100:1234 Ignoring packet error, continuing... warning: unrecognized item "timeout" in "qSupported" response Ignoring packet error, continuing... Remote replied unexpectedly to 'vMustReplyEmpty': timeout

出现这些错误信息表明,虽然你能够与 gdbserver 建立初步连接,但在通信过程中出现了一些问题。

进行本地回环测试未通过:

(gdb) target remote 127.0.0.1:1234
Remote debugging using 127.0.0.1:1234
Ignoring packet error, continuing...
warning: unrecognized item "timeout" in "qSupported" response
Ignoring packet error, continuing...
Remote replied unexpectedly to 'vMustReplyEmpty': timeout

找了半天,发现原来是grup地址配置错误。

kgdboc 参数的格式为 kgdboc=<interface>,<debugger-ip>,<target-ip>,<baudrate>,其中 <interface> 是用于 KGDB 调试的网络接口,<debugger-ip> 是运行 GDB 的计算机的 IP 地址,<target-ip> 是目标机器的 IP 地址,<baudrate> 是波特率。

gdbserver 192.168.100.100:1234 /usr/src/linux-source-4.15.0/vmlinux
gdb /usr/src/linux-source-4.15.0/vmlinux
 (gdb) target remote 192.168.100.100:1234

  • 6
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值