# 4.1 Linux 内核调试 - [准备工作](#准备工作) ## 准备工作 与用户态程序不同,为了进行内核调试,我们需要两台机器,一台调试,另一台被调试。在调试机上需要安装必要的调试器(如GDB),被调试机上运行着被调试的内核。 这里选择用 Ubuntu16.04 来展示,因为该发行版默认已经开启了内核调试支持: ``` $ cat /boot/config-4.13.0-38-generic | grep GDB # CONFIG_CFG80211_INTERNAL_REGDB is not set CONFIG_SERIAL_KGDB_NMI=y CONFIG_GDB_SCRIPTS=y CONFIG_HAVE_ARCH_KGDB=y CONFIG_KGDB=y CONFIG_KGDB_SERIAL_CONSOLE=y # CONFIG_KGDB_TESTS is not set CONFIG_KGDB_LOW_LEVEL_TRAP=y CONFIG_KGDB_KDB=y ``` #### 获取符号文件 下面我们来准备调试需要的符号文件。看一下该版本的 code name: ``` $ lsb_release -c Codename: xenial ``` 然后在下面的目录下新建文件 `ddebs.list`,其内容如下(注意看情况修改Codename): ``` $ cat /etc/apt/sources.list.d/ddebs.list deb http://ddebs.ubuntu.com/ xenial main restricted universe multiverse deb http://ddebs.ubuntu.com/ xenial-security main restricted universe multiverse deb http://ddebs.ubuntu.com/ xenial-updates main restricted universe multiverse deb http://ddebs.ubuntu.com/ xenial-proposed main restricted universe multiverse ``` `http://ddebs.ubuntu.com` 是 Ubuntu 的符号服务器。执行下面的命令添加密钥: ``` $ wget -O - http://ddebs.ubuntu.com/dbgsym-release-key.asc | sudo apt-key add - ``` 然后就可以更新并下载符号文件了: ``` $ sudo apt-get update $ uname -r 4.13.0-38-generic $ sudo apt-get install linux-image-4.13.0-38-generic-dbgsym ``` 完成后,符号文件将会放在下面的目录下: ``` $ file /usr/lib/debug/boot/vmlinux-4.13.0-38-generic /usr/lib/debug/boot/vmlinux-4.13.0-38-generic: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), statically linked, BuildID[sha1]=f00f4b7ef0ab8fa738b6a9caee91b2cbe23fef97, not stripped ``` 可以看到这是一个静态链接的可执行文件,使用 gdb 即可进行调试,例如这样: ``` $ gdb -q /usr/lib/debug/boot/vmlinux-4.13.0-38-generic Reading symbols from /usr/lib/debug/boot/vmlinux-4.13.0-38-generic...done. gdb-peda$ p init_uts_ns $1 = { kref = { refcount = { refs = { counter = 0x2 } } }, name = { sysname = "Linux", '\000' , nodename = "(none)", '\000' , release = "4.13.0-38-generic", '\000' , version = "#43~16.04.1-Ubuntu SMP Wed Mar 14 17:48:43 UTC 2018", '\000' , machine = "x86_64", '\000' , domainname = "(none)", '\000' }, user_ns = 0xffffffff822517a0 , ucounts = 0x0 , ns = { stashed = { counter = 0x0 }, ops = 0xffffffff81e2cc80 , inum = 0xeffffffe } } ``` #### 获取源文件 将 `/etc/apt/sources.list` 里的 `deb-src` 行都取消掉注释: ``` $ sed -i '/^#\sdeb-src /s/^#//' "/etc/apt/sources.list" ``` 然后就可以更新并获取 Linux 内核源文件了: ``` $ sudo apt-get update $ mkdir -p ~/kernel/source $ cd ~/kernel/source $ apt-get source $(dpkg-query '--showformat=${source:Package}=${source:Version}' --show linux-image-$(uname -r)) ``` ``` $ ls linux-hwe-4.13.0/ arch CREDITS debian.master firmware ipc lib net security tools zfs block crypto Documentation fs Kbuild MAINTAINERS README snapcraft.yaml ubuntu certs debian drivers include Kconfig Makefile samples sound usr COPYING debian.hwe dropped.txt init kernel mm scripts spl ```