我正在为外部内核模块编写一个简单的 Makefile。
构建它:
obj-m += usbtherm.o
all:
make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules
仅编译外部模块,这很好。
但安装它时:
install:
make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules_install
安装内核源代码树中的所有模块,但我不知道如何将该模块安装到drivers/usb/misc
.
所以我像这样安装模块:
install:
cp $(shell pwd)/usbtherm.ko /lib/modules/$(shell uname -r)/kernel/drivers/usb/misc
depmod -a
它将仅安装外部模块。
但它对我来说看起来不太优雅——我错过了什么?
答案1
当我用 sudo 安装时
sudo -E make install
仅安装了我的外部模块并重新运行 depmod。
在没有环境保存标志的情况下运行会导致重新安装我用来更新内核的内核源代码树中内置的所有模块。看起来使用 sudo 可能在对内核树进行更改时可能没有正确设置 PWD,但这也许会帮助遇到此问题的其他人。
答案2
我又仔细观察了一下modules_install
。在 Linux Makefile 中:
# Target to install modules
PHONY += modules_install
modules_install: _modinst_ _modinst_post
PHONY += _modinst_
_modinst_:
@rm -rf $(MODLIB)/kernel
@rm -f $(MODLIB)/source
@mkdir -p $(MODLIB)/kernel
@ln -s `cd $(srctree) && /bin/pwd` $(MODLIB)/source
@if [ ! $(objtree) -ef $(MODLIB)/build ]; then \
rm -f $(MODLIB)/build ; \
ln -s $(CURDIR) $(MODLIB)/build ; \
fi
@cp -f $(objtree)/modules.order $(MODLIB)/
@cp -f $(objtree)/modules.builtin $(MODLIB)/
$(Q)$(MAKE) -f $(srctree)/scripts/Makefile.modinst
我从中了解到的是,它需要一个源代码树,卸载现有模块,进行一些清理,然后运行scripts/Makefile.modinst
以安装模块 - 将外部模块安装到extra
:
# Modules built outside the kernel source tree go into extra by default
INSTALL_MOD_DIR ?= extra
实际上,当在没有内核源代码但安装了标头的系统上构建外部模块时,内置的模块是/usr/src/linux-headers-$(uname -r)
从 符号链接的/lib/modules/$(uname -r)/build
,虽然 和all
目标clean
成功,但modules_install
会失败,因为modules.order
如果只安装了标头,则 ie 不存在。
但是通过复制 *.ko 并运行来安装外部模块depmod -a
可以正常工作。