[Topic DIscussion] 使用localmodconfig缩短编译时间
Tofloor
poster avatar
jiutian123
deepin
2021-02-16 19:04
Author

使用localmodconfig缩短编译时间

本节介绍使用make localmodconfig生成精简的.config文件,缩短内核编译时间的方法。

为了能够应对各种各样的环境,发布版的内核包含很多内核模块。但是在某个特定机器,例如,大家自己平时使用的PC上实际用到的模块只是其中的极小一部分。重新构建内核时,对不使用的模块进行编译就会浪费时间。编译后的模块存放在磁盘里,因此也会造成磁盘空间的浪费。

将localmodconfig作为make的目标,就可以生成仅以正在使用的内核模块为对象的.config文件,可以在Linux内核2.6.32以后的版本中使用它。使用这条命令,可以生成仅启用必要模块的.config文件,从而缩短内核的编译时间。

localmodconfig的使用方法

将运行中的内核源代码解压缩,并在源码树的根下执行下列命令。

 

# make localmodconfig

如果是一般的发布版,只需进行这一操作就可以生成.config文件,将要编译的内核模块缩减到最少。此后只需执行下列命令,照常进行内核的编译、安装。

 

# make

# make modules_install

# make install

localmodconfig的效果

使用两种.config文件对上游内核(Linux 2.6.34)进行了编译,并记录分别花费的时间。

第一次是使用Fedora13的默认内核.config文件对Linux 2.6.34进行了编译,将其记为“2.6.34-fc13”。第二次使用的是在2.6.34-fc13的.config文件的基础上使用localmodconfig生成的.config文件,编译后的文件记为“2.6.34-localmod”。两次花费的编译时间如下所示。

 

2.6.34-fc13:26分13秒

 2.6.34-localmod:8分20秒

通过使用localmodconfig生成的.config文件,将编译时间缩短到了1/3以内。

另外,还对内核模块的数量以及它们所在目录的总容量进行了比较。

 

# du -sh /lib/modules/2.6.34-fc13/kernel/

  75M    /lib/modules/2.6.34-fc13/kernel

# find /lib/modules/2.6.34-fc13/kernel -name '*.ko' | wc -l

  2046

 

# du -sh /lib/modules/2.6.34-localmod/kernel/

  9.2M    /lib/modules/2.6.34-localmod/kernel/

# find /lib/modules/2.6.34-fc13-localmod1/kernel -name '*.ko' | wc -l

  138

localmodconfig使内核模块的数量减少到约1/15,占用的磁盘空间也减少到约1/8。

localmodconfig的结构

localmodconfig是通过内核源码树的下列脚本执行的。

scripts/kconfig/streamline_config.pl

localmodconfig首先会尝试提取一套配置选项作为模型。使用的模型为源码树的.config文件或者/boot下正在运行的内核的.config文件(/boot/config-<内核版本>)。当这些不存在时,将从正在运行的内核映像(/boot/vmlinuz-<内核版本>)、保存了设置信息的内核模块(configs.ko)等提取信息。

另外,要从内核映像或configs.ko提取出配置选项的信息,内核必须是在指定CONFIG_IKCONFIG选项的情况下编译的。当无法提取用做模型的配置选项时,即,找不到.config文件,且正在运行的内核是在未指定CONFIG_IKCONFIG选项的情况下编译的,就会导致localmodconfig失败。

然后,localmodconfig通过lsmod获取当前安装到内核中的内核模块列表,找出对它们进行编译所需的配置选项并记录下来。

最后,localmodconfig将模型的配置选项中指定要作为内核模块进行编译的部分(CONFIG_*=m)进行如下修改,并输出为.config文件。

当前安装到内核的内核模块所需要的选项:不修改

此外:改为禁用

模型中指定要静态安装到内核的选项(CONFIG_=y)、设置为禁用的选项(# CONFIG_ is not set)不进行修改,直接输出。

小贴士:通过把作为模型的配置选项指定到模块中,却未安装到内核的内核模块中,导致其配置选项失效,无法编译。因此,在执行localmodconfig命令之前,可以将需要编译的内核模块手动安装到内核中。例如,可以使用下列命令,将用来虚拟化的模块kvm.ko安装到内核中。

 

# modprobe kvm

当然,localmodconfig生成了.config文件后,也可以使用make menuconfig等手动对.config文件进行修改。

localyesconfig

localyesconfig是与localmodconfig相似的make目标。使用这条命令,通过localmodconfig设置为内核模块的配置选项,将设置为在无提示的情况下安装到内核中。

在编写不使用initramfs启动的内核时localyesconfig非常方便。

小结

对于不是很清楚的配置选项,应当先启用,以避免出现内核无法启动的情况。相信凡是自己构建(make)过内核的人对这一点都深有体会。如果使用localmodconfig就不再需要担心这个问题。localmodconfig既能够节约详细检查config选项的时间,又能缩短编译所花费的时间,为我们提供了强有力的支持。

Reply Favorite View the author
All Replies
1 / 2
To page
jiutian123
deepin
2021-02-16 19:32
#1

Most people uses the kernel shipped by distros - and that's good. But some people like to compile their own kernels from kernel.org, or maybe they like following the Linux development and want to try it. Configuring your own kernel, however, has become a very difficult and tedious task - there're too many options, and some times userspace software will stop working if you don't enable some key option. You can use a standard distro .config file, but it takes too much time to compile all the options it enables.

 

To make the process of configuration easier, a new build target has been added: make localmodconfig. It runs "lsmod" to find all the modules loaded on the current running system. It will read all the Makefiles to map which CONFIG enables a module. It will read the Kconfig files to find the dependencies and selects that may be needed to support a CONFIG. Finally, it reads the .config file and removes any module "=m" that is not needed to enable the currently loaded modules. With this tool, you can strip a distro .config of all the unuseful drivers that are not needed in our machine, and it will take much less time to build the kernel. There's an additional "make localyesconfig" target, in case you don't want to use modules and/or initrds.

 

以上内容摘自:Kernel Newbies。

大概意思是说, make localmodconfig 会执行 lsmod 命令查看当前系统中加载了哪些模块 (Modules), 并最后将原来的 .config 中不需要的模块去掉,仅保留前面 lsmod 出来的这些模块,从而简化了内核的配置过程。 

 

这样做确实方便了很多,但是也有个缺点:该方法仅能使编译出的内核支持当前内核已经加载的模块。

因为该方法使用的是 lsmod 的结果,如果有的模块当前没有加载,那么就不会编到新的内核中。

例如,我有的时候需要制作 squashfs , 因此在当前的内核中,将 squashfs 编译成了模块。 当使用 make localmodconfig 来配置 Kernel 的时候,如果当前系统中没有加载这个模块, 那么新编出来的内核中就不会将 squashfs 编译成模块,在新的内核中就没办法使用这个模块了。

所以建议在使用 make localmodconfig 之前,首先折腾一下系统,插个优盘,开开摄像头之类, 以便让内核加载上平时使用时候所需要的模块;执行 make localmodconfig 之后,再执行一下 make menuconfig 来手动检查一下, 是否还有其他模块需要手动选择。

Reply View the author
SamLukeYes
deepin
2021-02-17 00:07
#2

通常不推荐在基于二进制发布的发行版上用这么精简的内核。如果喜欢裁剪内核的话,可以去用 gentoo 了

Reply View the author
jiutian123
deepin
2021-02-17 01:28
#3
SamLukeYes

通常不推荐在基于二进制发布的发行版上用这么精简的内核。如果喜欢裁剪内核的话,可以去用 gentoo 了

笔记本也不行么  选项比较复杂,不是一个一个驱动名排好的 没办法 不影响使用就好

Reply View the author
剥壳白煮蛋
deepin
2021-02-19 02:35
#4

我快瞎了

Reply View the author
SamLukeYes
deepin
2021-02-19 02:51
#5
jiutian123

笔记本也不行么  选项比较复杂,不是一个一个驱动名排好的 没办法 不影响使用就好

诶,等等,好像也不是不行。最近看到一个好东西,可以让 make localmodconfig 更“智能”:https://github.com/graysky2/modprobed-db

Reply View the author
jiutian123
deepin
2021-02-20 03:21
#6
SamLukeYes

诶,等等,好像也不是不行。最近看到一个好东西,可以让 make localmodconfig 更“智能”:https://github.com/graysky2/modprobed-db

怎么操作的?英文翻译不太懂

Reply View the author
SamLukeYes
deepin
2021-02-20 05:15
#7
jiutian123

怎么操作的?英文翻译不太懂

装好以后执行 systemctl --user enable --now modprobed-db,使用一段时间,在初次启用服务到编译内核前用到尽量多的内核模块,然后编译的时候就可以用 make LSMOD=$HOME/.config/modprobed.db localmodconfig 来自动设置编译选项,比直接 make localmodconfig 多了记录使用历史的功能

Reply View the author
jiutian123
deepin
2021-02-20 05:18
#8
SamLukeYes

装好以后执行 systemctl --user enable --now modprobed-db,使用一段时间,在初次启用服务到编译内核前用到尽量多的内核模块,然后编译的时候就可以用 make LSMOD=$HOME/.config/modprobed.db localmodconfig 来自动设置编译选项,比直接 make localmodconfig 多了记录使用历史的功能

怎么安装?

Reply View the author
SamLukeYes
deepin
2021-02-20 05:31
#9
jiutian123

怎么安装?

我是从 AUR 上安装的。按照 README 的说法,其他发行版应该 make && sudo make install 就行了

Reply View the author
jiutian123
deepin
2021-02-21 06:16
#10
SamLukeYes

装好以后执行 systemctl --user enable --now modprobed-db,使用一段时间,在初次启用服务到编译内核前用到尽量多的内核模块,然后编译的时候就可以用 make LSMOD=$HOME/.config/modprobed.db localmodconfig 来自动设置编译选项,比直接 make localmodconfig 多了记录使用历史的功能

root@nsz-PC:/home/nsz/Downloads/modprobed-db-master/modprobed-db-master# make

Setting version

root@nsz-PC:/home/nsz/Downloads/modprobed-db-master/modprobed-db-master# make install

Installing main script and skel config...

install -p -d "/usr/bin"

install -p -d "/usr/share/modprobed-db"

install -p -m755 common/modprobed-db "/usr/bin/modprobed-db"

install -p -m644 common/modprobed-db.skel "/usr/share/modprobed-db/modprobed-db.skel"

install -p -d "/usr/share/zsh/site-functions"

install -p -m644 common/zsh-completion "/usr/share/zsh/site-functions/_modprobed-db"

install -p -d "/usr/lib/systemd/user"

install -p -m644 init/modprobed-db.service "/usr/lib/systemd/user/modprobed-db.service"

install -p -m644 init/modprobed-db.timer "/usr/lib/systemd/user/modprobed-db.timer"

Installing manpage...

install -p -d "/usr/share/man/man8"

install -p -m644 doc/modprobed-db.8 "/usr/share/man/man8/modprobed-db.8"

gzip -9 "/usr/share/man/man8/modprobed-db.8"

root@nsz-PC:/home/nsz/Downloads/modprobed-db-master/modprobed-db-master# systemctl --user enable --now modprobed-db

Failed to connect to bus: 没有那个文件或目录

root@nsz-PC:/home/nsz/Downloads/modprobed-db-master/modprobed-db-master# 

命令好像不对

Reply View the author
jiutian123
deepin
2021-02-21 06:24
#11
SamLukeYes

我是从 AUR 上安装的。按照 README 的说法,其他发行版应该 make && sudo make install 就行了

nsz@nsz-PC:~/Downloads/modprobed-db-master/modprobed-db-master$  systemctl --nsz enable --now modprobed-db

systemctl: unrecognized option '--nsz'

nsz@nsz-PC:~/Downloads/modprobed-db-master/modprobed-db-master$  systemctl --root enable --now modprobed-db

Unknown operation modprobed-db.

nsz@nsz-PC:~/Downloads/modprobed-db-master/modprobed-db-master$  systemctl --user enable --now modprobed-db

Created symlink /home/nsz/.config/systemd/user/default.target.wants/modprobed-db.service → /usr/lib/systemd/user/modprobed-db.service.

nsz@nsz-PC:~/Downloads/modprobed-db-master/modprobed-db-master$ 

 

 

这样是不是启动成功了?

Reply View the author
SamLukeYes
deepin
2021-02-21 06:30
#12
jiutian123

nsz@nsz-PC:~/Downloads/modprobed-db-master/modprobed-db-master$  systemctl --nsz enable --now modprobed-db

systemctl: unrecognized option '--nsz'

nsz@nsz-PC:~/Downloads/modprobed-db-master/modprobed-db-master$  systemctl --root enable --now modprobed-db

Unknown operation modprobed-db.

nsz@nsz-PC:~/Downloads/modprobed-db-master/modprobed-db-master$  systemctl --user enable --now modprobed-db

Created symlink /home/nsz/.config/systemd/user/default.target.wants/modprobed-db.service → /usr/lib/systemd/user/modprobed-db.service.

nsz@nsz-PC:~/Downloads/modprobed-db-master/modprobed-db-master$ 

 

 

这样是不是启动成功了?

用 systemctl --user list-timers 来确认一下,能看到它的 timer 就是启用成功了

Reply View the author
jiutian123
deepin
2021-02-21 07:44
#13
SamLukeYes

用 systemctl --user list-timers 来确认一下,能看到它的 timer 就是启用成功了

待机唤醒是不是内核模块?5.11编译的唤醒了 屏幕显示不正常

Reply View the author
jiutian123
deepin
2021-02-21 07:47
#14
SamLukeYes

用 systemctl --user list-timers 来确认一下,能看到它的 timer 就是启用成功了

nsz@nsz-PC:~$ systemctl --user list-timers 

NEXT                         LEFT          LAST PASSED UNIT               ACTIVATES

Sun 2021-02-21 04:24:38 CST  4h 41min left n/a  n/a    modprobed-db.timer modprobed-db.service

 

1 timers listed.

Pass --all to see loaded but inactive timers, too.

nsz@nsz-PC:~$ 

 时间显示好像有问题

Reply View the author
SamLukeYes
deepin
2021-02-21 07:53
#15
jiutian123

待机唤醒是不是内核模块?5.11编译的唤醒了 屏幕显示不正常

不知道

Reply View the author
SamLukeYes
deepin
2021-02-21 07:54
#16
jiutian123

nsz@nsz-PC:~$ systemctl --user list-timers 

NEXT                         LEFT          LAST PASSED UNIT               ACTIVATES

Sun 2021-02-21 04:24:38 CST  4h 41min left n/a  n/a    modprobed-db.timer modprobed-db.service

 

1 timers listed.

Pass --all to see loaded but inactive timers, too.

nsz@nsz-PC:~$ 

 时间显示好像有问题

看起来没啥问题啊

Reply View the author
jiutian123
deepin
2021-02-21 20:39
#17
SamLukeYes

看起来没啥问题啊

刚安装上 就显示4个多小时了,

Reply View the author
SamLukeYes
deepin
2021-02-21 20:55
#18
jiutian123

刚安装上 就显示4个多小时了,

是下次触发在四个小时后

Reply View the author
jiutian123
deepin
2021-02-22 02:26
#19
SamLukeYes

用 systemctl --user list-timers 来确认一下,能看到它的 timer 就是启用成功了

在初次启用服务到编译内核前用到尽量多的内核模块      这个有啥说法  

Reply View the author
SamLukeYes
deepin
2021-02-22 02:50
#20
jiutian123

在初次启用服务到编译内核前用到尽量多的内核模块      这个有啥说法  

和一般的 localmodconfig 是一个道理,只不过可以在 modprobed.db 中记录你使用过的模块。这个记录不会因关机而丢失,所以你可以先用它来记着,以后再编译内核的时候就很方便了。

Reply View the author
1 / 2
To page