【问题标题】:What is the most efficient and elegant way develop/debug linux kernel开发/调试linux内核最有效和最优雅的方式是什么
【发布时间】:2015-09-09 05:29:59
【问题描述】:

最近开始开发linux设备驱动,

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

例如,最近我在位于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 

然后重启并选择我的新内核版本。

不知道有没有多余的步骤? 任何指南或帮助将不胜感激。

【问题讨论】:

  • 在大多数情况下,经过一些更改后重新编译内核不需要make clean:内核构建系统(以及make 本身)足够聪明,可以只编译那些文件,这取决于更改的源.
  • 那么除了 make clean 步骤之外,其他步骤还需要做吗?
  • 如果你不改变函数的签名,你也可以跳过make modulesmake modules_install步骤。其他步骤并没有那么耗时(当然make bzImage 除外,但它是强制性的)。
  • 不知道我的理解对不对。所以即使在头文件中定义了函数,如果我不更改签名,我不需要做模块和模块安装?
  • 另一个想法是在调试时在虚拟机中运行你的操作系统,这样你就不必重新启动你的机器并且可以继续工作。

标签: linux linux-kernel linux-device-driver


【解决方案1】:

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

获取来源

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 运行,因为使用模块填充initramfs 映像需要install 规则。 检查/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 的第二行,输入 - 并使用第 4 行启动。

运行后:

$ 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/KernelCompilation

【讨论】:

    【解决方案2】:

    如前所述,如果要重新编译内核,唯一多余且耗时的步骤是“make clean”。内核构建系统使用 Makefiles 来构建,而后者又遵循增量构建过程,即构建系统比较源文件和它们各自的目标文件的最近一次构建时间,如果源文件的时间戳恰好比它的目标文件更新,然后再次编译源文件,否则跳过。其中“make clean”会删除所有以前的构建输出,并使内核模块准备好从头开始构建。

    【讨论】:

      【解决方案3】:
      1. 使用ccache;这会显着加快后续构建速度

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

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

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2010-09-21
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-09-23
        • 1970-01-01
        • 2010-09-06
        相关资源
        最近更新 更多