develop/debug linux kernel 最高效优雅的方式是什么
What is the most efficient and elegant way develop/debug linux kernel
最近开始开发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
然后重新启动并选择我的新内核版本。
不知道是不是有些多余的步骤?
任何指南或帮助将不胜感激。
这是我关于如何构建和运行自定义内核的笔记。
获取资源
Linus Torvalds 的树是 [1]。
它在 [2] 上标记为 "mainline"。
要克隆它,请使用来自 [1] 的信息:
$ git clone git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
现在转到 linux/
目录并在 master 分支上签出(我们需要使用最新的
变化作为发展的起点):
$ cd linux
$ git checkout master
在实际开发之前不要忘记更新你的分支:
$ git pull --rebase
建筑
我机器上的内核版本:
$ uname -r
3.16.0-4-amd64
要从系统 运行ning 在我的机器上获取配置:
$ cp /boot/config-`uname -r` ./.config
为了更新我的配置(使用默认答案),我使用了下一个命令:
$ make olddefconfig
禁用(不构建)当前系统中未加载的模块:
$ make localmodconfig
要使用默认答案回答所有问题,我只需单击 Enter 直到完成
(实际上只有两次)。
接下来我做了:
$ make menuconfig
并选择下一个配置选项:
CONFIG_LOCALVERSION_AUTO=y
CONFIG_LOCALVERSION="-joe"
设置缓存和构建环境:
$ 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,select 下一个条目:
-> 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
命令后被替换。
正在删除自定义内核
如果您不再需要您的自定义内核,您可能想要删除它。
要删除已安装的内核,请执行下一步。
删除安装到 /boot 的所有文件:
$ sudo rm -f *joe*
删除所有安装的模块:
$ sudo rm -rf /lib/modules/*joe*
更新 GRUB:
$ sudo update-grub
正在清理内置内核
如果您不需要进行增量构建,而是想进行干净构建
(例如,您结帐到另一个版本),您可能想要清理您的内置
首先是文件:
$ make -j4 distclean
链接
[1] https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/
如前所述,唯一多余且耗时的步骤是 "make clean" 如果您正在重新编译内核。内核构建系统使用 Makefiles 构建,依次遵循增量构建过程,即构建系统比较源文件及其各自目标文件的最近构建时间,如果源文件的时间戳恰好比其目标文件更新,然后再次编译源文件 else skipped.Where as "make clean" 删除所有以前的构建输出并使内核模块准备好从头开始构建。
使用ccache
;这会显着加快后续构建速度
通过网络启动;嵌入式设备的bootloader通常有一些tftp下载机制;对于 PC,您可以使用 PXE 引导
将模块放在由 make modules-install INSTALL_MOD_PATH=$nfs-root
填充的 NFS 根文件系统上
当您只使用一个驱动程序时,您只能通过 make -C $kernelsources M=$driverpath
构建它
最近开始开发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
然后重新启动并选择我的新内核版本。
不知道是不是有些多余的步骤? 任何指南或帮助将不胜感激。
这是我关于如何构建和运行自定义内核的笔记。
获取资源
Linus Torvalds 的树是 [1]。
它在 [2] 上标记为 "mainline"。
要克隆它,请使用来自 [1] 的信息:
$ git clone git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
现在转到 linux/
目录并在 master 分支上签出(我们需要使用最新的
变化作为发展的起点):
$ cd linux
$ git checkout master
在实际开发之前不要忘记更新你的分支:
$ git pull --rebase
建筑
我机器上的内核版本:
$ uname -r
3.16.0-4-amd64
要从系统 运行ning 在我的机器上获取配置:
$ cp /boot/config-`uname -r` ./.config
为了更新我的配置(使用默认答案),我使用了下一个命令:
$ make olddefconfig
禁用(不构建)当前系统中未加载的模块:
$ make localmodconfig
要使用默认答案回答所有问题,我只需单击 Enter 直到完成 (实际上只有两次)。
接下来我做了:
$ make menuconfig
并选择下一个配置选项:
CONFIG_LOCALVERSION_AUTO=y
CONFIG_LOCALVERSION="-joe"
设置缓存和构建环境:
$ 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,select 下一个条目:
-> 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
命令后被替换。
正在删除自定义内核
如果您不再需要您的自定义内核,您可能想要删除它。 要删除已安装的内核,请执行下一步。
删除安装到 /boot 的所有文件:
$ sudo rm -f *joe*
删除所有安装的模块:
$ sudo rm -rf /lib/modules/*joe*
更新 GRUB:
$ sudo update-grub
正在清理内置内核
如果您不需要进行增量构建,而是想进行干净构建 (例如,您结帐到另一个版本),您可能想要清理您的内置 首先是文件:
$ make -j4 distclean
链接
[1] https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/
如前所述,唯一多余且耗时的步骤是 "make clean" 如果您正在重新编译内核。内核构建系统使用 Makefiles 构建,依次遵循增量构建过程,即构建系统比较源文件及其各自目标文件的最近构建时间,如果源文件的时间戳恰好比其目标文件更新,然后再次编译源文件 else skipped.Where as "make clean" 删除所有以前的构建输出并使内核模块准备好从头开始构建。
使用
ccache
;这会显着加快后续构建速度通过网络启动;嵌入式设备的bootloader通常有一些tftp下载机制;对于 PC,您可以使用 PXE 引导
将模块放在由
make modules-install INSTALL_MOD_PATH=$nfs-root
填充的 NFS 根文件系统上
当您只使用一个驱动程序时,您只能通过
make -C $kernelsources M=$driverpath
构建它