开发/debugginglinux内核的最高效和优雅的方式是什么?

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

当我想用内核代码进行debugging时,我遇到了一个问题,并在内核文件中添加了一些printkdebugging消息。

例如,最近我在include/linux/debug_locks.h中的__debug_locks_off()中添加了一些printk()dump_stack()

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

 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 

然后重新启动并select我的新内核版本。

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

Solutions Collecting From Web of "开发/debugginglinux内核的最高效和优雅的方式是什么?"

这里是我如何构建和运行自定义内核的笔记。

获取来源

Linus Torvalds的树是[1]。

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

要克隆它使用来自[1]的信息:

 $ git clone git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git 

现在转到linux/ dir并在master分支上进行签出(我们需要使用最新的更改作为开发的起点):

 $ cd linux $ git checkout master 

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

 $ git pull --rebase 

建造

我的机器上的内核版本:

 $ 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 ):

 $ reset $ make -j4 $ make -j4 modules 

构建的内核映像是:

 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* 

update-grub作为make install脚本的一部分运行,所以不需要手动运行它。

modules_install必须 install 之前运行,因为需要install规则来为模块填充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 

 GRUB_DEFAULT="1>3" 

其中"1>3"表示: – 转到GRUB中的第二行,输入 – 并使用第四行进行引导。

经过这个运行:

 $ sudo update-grub 

注意:不要编辑/boot/grub/grub.cfg文件,因为它是自动生成的,每次update-grub命令后都会被替换。

删除自定义的内核

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

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

     $ sudo rm -f *joe* 
  2. 删除所有安装的模块:

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

     $ sudo update-grub 

清理内核

如果你不需要增量构建,而是想做干净的构建(例如,你使用了另一个版本),你可能需要先清理你的构建文件:

 $ make -j4 distclean 

链接

[1] https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/

[2] https://kernel.org/

[3] http://kernelnewbies.org/FAQ/coreelCompilation

如前所述,如果您正在重新编译内核,那么冗余且耗时的唯一步骤是“make clean”。 内核构建系统使用Makefile来构建,然后依次执行增量构建过程,即构建系统比较源文件的最近构建时间和它们各自的对象文件,并且如果源文件的时间戳恰好比其目标文件更新,那么源代码文件会被再次编译,否则就会被忽略。因为“make clean”会删除所有以前的编译输出,并且可以从头开始准备内核模块。

  1. 使用ccache ; 这大大加快了后续的构建

  2. 通过网络启动; 嵌入式设备的bootloader通常有一些tftp的下载机制; 对于PC,您可以使用PXE启动

  3. 将这些模块放在由根make modules-install INSTALL_MOD_PATH=$nfs-root填充的NFS根文件系统上make modules-install INSTALL_MOD_PATH=$nfs-root

  4. 当你只使用一个驱动程序时,只能通过make -C $kernelsources M=$driverpath