开发/调试linux内核最有效、最优雅的方法是什么

开发/调试linux内核最有效、最优雅的方法是什么,linux,linux-kernel,linux-device-driver,Linux,Linux Kernel,Linux Device Driver,最近我开始开发linux设备驱动程序 当我想用内核代码进行调试,并在内核文件中添加一些printkdebug消息时,我面临一个问题 例如,最近我在\uu debug\u locks\u off()中添加了一些printk()和dump\u stack(),它位于include/linux/debug\u locks.h中 然后我执行以下步骤,这非常耗时 make clean make bzImage make modules make modules_install mkinitrfmfs -o

最近我开始开发linux设备驱动程序

当我想用内核代码进行调试,并在内核文件中添加一些
printk
debug消息时,我面临一个问题

例如,最近我在
\uu debug\u locks\u off()
中添加了一些
printk()
dump\u stack()
,它位于
include/linux/debug\u locks.h

然后我执行以下步骤,这非常耗时

make clean
make bzImage
make modules
make modules_install
mkinitrfmfs -o /boot/initrd.img 3.12.6[my kernel version] 
cp arch/x86/boot/bzImage /boot
update-grub 
然后重新启动并选择我的新内核版本

我不知道是否有多余的步骤?
任何指导或帮助都将不胜感激。

以下是我关于如何构建和运行自定义内核的说明

获取来源 Linus Torvalds的树是[1]

它在[2]上标记为“主线”

要克隆它,请使用[1]中的信息:

$ git clone git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
现在转到
linux/
dir并在主分支上签出(我们需要使用最新的 作为发展起点的变化):

在实际开发之前,不要忘记更新您的分支:

$ git pull --rebase
建筑 我的计算机上的内核版本:

$ uname -r

3.16.0-4-amd64
$ cp /boot/config-`uname -r` ./.config
要从我的计算机上运行的系统获取配置,请执行以下操作:

$ uname -r

3.16.0-4-amd64
$ cp /boot/config-`uname -r` ./.config
要更新配置(使用默认答案),我使用了下一个命令:

$ make olddefconfig
要禁用(不构建)当前系统中未加载的模块,请执行以下操作:

$ make localmodconfig
要使用默认答案回答所有问题,我只需单击Enter直到完成 (实际上只有两次)

接下来我做了:

$ make menuconfig
并选择下一个配置选项:

CONFIG_LOCALVERSION_AUTO=y
CONFIG_LOCALVERSION="-joe"
设置ccache和构建环境:

$ ccache -C
$ ccache -M 4G
$ export CC="ccache gcc"
构建内核(使用
ccache
):

构建的内核映像是:

arch/x86_64/boot/bzImage
安装 为内核安装模块:

$ sudo make modules_install
安装新内核:

$ sudo make install
安装的模块位于
/lib/modules/*-joe/kernel/

安装的内核文件位于
/boot/*joe*

- config-*joe*
- initrd.img-*joe*
- System.map-*joe*
- vmlinuz-*joe*
updategrub
是作为
makeinstall
脚本的一部分运行的,因此无需运行它 手动

注意
模块安装
必须在安装之前运行,因为用模块填充initramfs映像需要
安装
规则。 检查
/boot/initrd.img-*joe*
文件的大小:它必须>=15 MiB (如果较小,则模块可能不在其中)

启动定制内核 通常,您的自定义内核的版本应该大于发行版内核, 因此,默认情况下应该运行自定义内核。如果没有,请进一步阅读

重新启动,转到GRUB,选择下一项:

-> Advanced options for Debian GNU/Linux
  -> Debian GNU/Linux, with Linux 4.0.0-rc7-joe-00061-g3259b12
默认情况下使您的发行版内核加载 由于视频可能无法在自定义内核中工作(视频驱动程序必须是 为此,您可能希望默认情况下由GRUB加载发行版内核

为此,只需编辑
/etc/default/grub
文件:

$ sudo vim /etc/default/grub
换乘

GRUB_DEFAULT=0

其中
“1>3”
表示: -转到GRUB中的第二行,输入 -使用第四行引导

本次运行后:

$ sudo update-grub
注意:不要编辑
/boot/grub/grub.cfg
文件,因为它是自动生成的,并且将 每次
更新grub
命令后都要进行替换

删除自定义内核 如果您不再需要自定义内核,您可能需要删除它。 要删除已安装的内核,请执行下一步

  • 删除安装到/boot的所有文件:

    $ sudo rm -f *joe*
    
  • 卸下所有已安装的模块:

    $ sudo rm -rf /lib/modules/*joe*
    
  • 更新GRUB:

    $ sudo update-grub
    
  • 清理构建的内核 如果您不需要进行增量构建,而是希望进行干净构建 (例如,您签出到另一个版本),您可能希望清理构建的 文件优先:

    $ make -j4 distclean
    
    链接 [1]

    [2]


    [3]

    如前所述,如果要重新编译内核,唯一一个冗余且耗时的步骤就是“清理”。内核构建系统使用Makefiles进行构建,而构建过程又遵循增量构建过程,即构建系统比较源文件的最近一次构建时间及其各自的目标文件,如果源文件的时间戳恰好比其目标文件更近,则再次编译源文件,否则将跳过。其中“makeclean”删除所有以前的构建输出,并使内核模块准备从头开始构建

  • 使用
    ccache
    ;这将显著加快后续构建

  • 通过网络引导;嵌入式设备的引导加载程序通常有一些tftp下载机制;对于PC,您可以使用PXE引导

  • 将模块放在NFS根文件系统上,该文件系统由
    make modules install\u MOD\u PATH=$NFS root

  • 当您仅使用单个驱动程序时,您只能通过
    make-C$kernelsources M=$driverpath


  • 在大多数情况下,
    makeclean
    不需要在一些更改后重新编译内核:内核构建系统(以及
    make
    本身)聪明到只编译这些文件,这取决于更改的源。因此,除了“清除”步骤外,还需要执行其他步骤?如果不更改函数的签名,也可以跳过“生成模块”和“生成模块”安装步骤。其他步骤不太耗时(当然,除了
    make bzImage
    ,但这是强制性的)。我不知道我的理解是否正确。因此,即使函数是在头文件中定义的,如果我不更改签名,我也不需要让模块和模块安装?另一个想法是在调试时在虚拟机中运行操作系统,这样你就不必重新启动机器,也可以继续工作。
    $ make -j4 distclean