使用 INSTALL_MOD_STRIP 在 modules_install 的時候 strip 驅動, 減少磁盤佔用

#1 問題描述

最近自己編譯內核安裝內核的時候, 總是遇到 /lib/modules 下空間不夠, 導致內核安裝有問題. 所以就想裁剪下.
分析的時候發現, 系統原生內核 /lib/modules/uname -r` 目錄驅動大小隻有 100M 左右, 但是我自己編譯的驅動目錄 1.4G 左右.

#2 問題分析

##2.1 問題原因

如果我們內核開啓了 CONFIG_DEBUG_INFO 選項, 那麼我們編譯的二進制會帶上很多調試信息. 內核鏡像 Image 都是經過裁剪和優化的. 但是驅動沒有. 所以導致單個 KO 的大小就很大.

因此可以把每個 KO 都 strip 一下子.

make modules_install 安裝驅動之後, strip 一下子.

find /lib/modules/XXX -name *.ko | xargs strip -g

##2.2 INSTALL_MOD_STRIP 選項

內核難道沒有提供現成的選項麼:

https://elixir.bootlin.com/linux/v5.3.6/source/Documentation/kbuild/kbuild.rst#182

https://elixir.bootlin.com/linux/v5.3.6/source/Documentation/kbuild/makefiles.rst#L1481

The default kernel configuration is configured to support as many hardware as possible. A non-stripped kernel with default configuration resulted in a size of 1897996 kB (including kernel + modules). When stripping many unnecessary drivers and options, it resulted in a size of 892892 kB which is a size reduction of 53% compared to the stock kernel.

    When installing the kernel modules, append the INSTALL_MOD_STRIP=1 option. This will strip all debugging symbols and reduced the size by 92% for me (from 892892 kB to 69356 kB). Note this will only affects modules to be installed and not the kernel (vmlinuz) itself.


Use the INSTALL_MOD_STRIP option for removing debugging symbols:

# make INSTALL_MOD_STRIP=1 modules_install
Similarly, for building the deb packages:
# make INSTALL_MOD_STRIP=1 deb-pkg

##2.3 INSTALL_MOD_STRIP 的實現

如果在 build and install ko 的時候(make modules_install) 的時候加上INSTALL_MOD_STRIP =1的話
則build ko的時候 會加上–strip-debug 這樣會讓build出的ko size大幅縮小.
具體是在 kernel 根目錄下面 Makefile 中有對INSTALL_MOD_STRIP=1 進行處理

#
# INSTALL_MOD_STRIP, if defined, will cause modules to be
# stripped after they are installed. If INSTALL_MOD_STRIP is '1', then
# the default option --strip-debug will be used. Otherwise,
# INSTALL_MOD_STRIP value will be used as the options to the strip command.

ifdef INSTALL_MOD_STRIP
ifeq ($(INSTALL_MOD_STRIP),1)
mod_strip_cmd = $(STRIP) --strip-debug
else
mod_strip_cmd = $(STRIP) $(INSTALL_MOD_STRIP)
endif # INSTALL_MOD_STRIP=1
else
mod_strip_cmd = true
endif # INSTALL_MOD_STRIP
export mod_strip_cmd

可見

  • 如果設置了 INSTALL_MOD_STRIP 爲 1, 那麼 mod_strip_cmd = strip --strip-debug
  • 如果設置了 INSTALL_MOD_STRIP 爲其他參數, 那麼 mod_strip_cmd = strip $(INSTALL_MOD_STRIP)
  • 如果沒設置 INSTALL_MOD_STRIP, mod_strip_cmd 只會設置爲 true

最終會在 scripts/Makefile.modinst中用到mod_strip_cmd

# Don't stop modules_install if we can't sign external modules.
quiet_cmd_modules_install = INSTALL $@
      cmd_modules_install = \
    mkdir -p $(2) ; \
    cp $@ $(2) ; \
    $(mod_strip_cmd) $(2)/$(notdir $@) ; \
    $(mod_sign_cmd) $(2)/$(notdir $@) $(patsubst %,|| true,$(KBUILD_EXTMOD)) ; \
    $(mod_compress_cmd) $(2)/$(notdir $@)
# Modules built outside the kernel source tree go into extra by default
INSTALL_MOD_DIR ?= extra
ext-mod-dir = $(INSTALL_MOD_DIR)$(subst $(patsubst %/,%,$(KBUILD_EXTMOD)),,$(@D))

modinst_dir = $(if $(KBUILD_EXTMOD),$(ext-mod-dir),kernel/$(@D))

$(modules):
 $(call cmd,modules_install,$(MODLIB)/$(modinst_dir))

modules_install 中會用驅動拷貝到安裝目錄, 然後用 mod_strip_cmd 處理驅動.
如果設置了 INSTALL_MOD_STRIP, 就會對驅動做 strip, 否則就什麼也不做.

#3 參考資料

why-is-install-mod-strip-not-on-by-default

如何編譯(Compile) Linux的核心(Kernel)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章