交叉编译内核和内核模块问题

Cross Compilation kernel and kernel modules problems

上周我一直在努力达到一个 objective 但我仍然没有达到。

我的最终目标是针对某些架构进行交叉编译(在这个问题中,我将仅以 MIPSLE 为例)一对我想在我的家庭路由器上使用的内核模块,通过在运行时使用 INSMOD 加载它们。

我的路由器缺少一些 iptables 功能,这就是为什么在内核编译期间,编译它的人决定摆脱它们。

The current kernel version is quite obsolete: Linux version 2.6.36+ by doing /proc/version

我读了很多文档,但我仍然不确定是否可以只编译一些模块,或者是否有必要每次都编译整个内核(有些人说对于某些模块是可能的,而对于其他模块更多的依赖关系不是,是真的吗?).

在这种情况下,我需要的内核模块位于 /net/ipv4/netfilter/

因为我不知道如何以独立的方式只编译内核模块,所以我决定交叉编译整个内核并获取我需要的模块。

所以我已经下载了正确的工具链(uclibc mipsle 工具链)并且我成功地编译了一个简单的工作 hello world,我在我有 ssh 的路由器上执行了它 shell。

所以我确定我使用的工具链是正确的。


现在,因为我想用最新版本的内核进行测试,所以我已经下载了最新的 ubuntu 20 和相应的内核,并且我已经成功编译了它和我之前谈到的内核模块, 在 .ko 格式 的 netfilter 文件夹中,完美!

我明明把我主机的/boot/config_file当成.config

因此,在我下载了与我的路由器 (2.6.36) 完全相同的内核版本之后,我尝试使用我在 GitHub 上找到的 .config 文件对其进行编译与具有相同内核版本的 mipsle 设备有关。

这里我认为我们遇到了第一个问题,我试图找到我的设备的 .config 以便顺利配置,但我没有 /boot 文件夹,而且在不在 /proc.

我怎样才能得到它?

反正我用过,编译好像没有失败,但是最后几行:

  CC      drivers/usb/storage/usual-tables.o
  LD      drivers/usb/storage/usb-storage.o
  LD      drivers/usb/storage/built-in.o
  LD      drivers/usb/built-in.o
  LD      drivers/video/built-in.o
  LD      drivers/built-in.o
  LD      vmlinux.o
  MODPOST vmlinux.o
  GEN     .version
  CHK     include/generated/compile.h
  UPD     include/generated/compile.h
  CC      init/version.o
  LD      init/built-in.o
  LD      .tmp_vmlinux1
  KSYM    .tmp_kallsyms1.S
  AS      .tmp_kallsyms1.o
  LD      .tmp_vmlinux2
  KSYM    .tmp_kallsyms2.S
  AS      .tmp_kallsyms2.o
  LD      vmlinux
  SYSMAP  System.map
  SYSMAP  .tmp_System.map
  OBJCOPY arch/mips/boot/vmlinux.bin
  Building modules, stage 2.
  MODPOST 1 modules
  CC      drivers/scsi/scsi_wait_scan.mod.o
  LD [M]  drivers/scsi/scsi_wait_scan.ko

它说“1 个模块”,但我不明白为什么在 /net/ipv4/netfilter 文件夹中现在我有 .o 文件而不是 .ko 就像他们没有已链接。

由于我很生气,在尝试了几次之后我不知道该多尝试什么,所以我决定使用我主机的配置文件(ubuntu 2020,内核 5.4.0.26)编译成功,文件夹内有.ko个文件

问题是,显然它们是为 x86-64 而不是 MIPS 编译的模块和其他与我的 x86-64 机器配置相关的明确 "problems"。

所以,我现在想的是,我发现的 .config 可能以某种方式被破坏,我也试图通过添加评论来禁用那个 SCSI 模块,但没有,我总是得到同样的东西。

而且显然在每次尝试之间我总是做 make distcleanmake clean

你建议我做什么?我什至不会 post 我读过的关于这些东西的所有参考资料,因为我可以用那么多的数据 sigsegv Whosebug 的服务器。

感谢大家,对不起墙-post.

i'm not sure if it possible to compile just some modules or if it's necessary to compile the whole kernel every time

好吧,您可以只编译单个模块,但是编译模块需要已经构建内核。一旦你这样做了一次,你应该能够单独编译其他模块。也就是说,当然,如果您不希望将它们嵌入内核本身(CONFIG_XXX=y 而不是 CONFIG_XXX=m)。你 应该 能够像这样只编译你想要的模块(假设 /path/to/linux 是你已经构建的内核源所在的目录):

$ cd /path/to/linux
$ cd path/to/module/folder
$ make -C /path/to/linux M=$(pwd) modules

I tried to find the .config of my device in order to have a smooth configuration but i don't have the /boot folder and it also was not in /proc. How can i get it?

你具体看哪里了? /proc/config.gz 的存在取决于 CONFIG_IKCONFIG_PROC (see also here)。如果您找不到该文件,那么很可能是因为在构建内核时该配置选项被禁用了。您可以尝试查看 /boot(正如您已经做过的那样)或 /lib/modules/$(uname -r)/build/.config,但不幸的是,除此之外别无他法。

我见过有人 suggest 尝试 运行 modprobe configs 然后检查 /proc/config.gz,但这看起来很奇怪,因为据我所知内核配置应该无法配置为可加载模块。

What do you suggest me to do?

那么,您现在最重要的事情就是找到您的路由器(或兼容路由器)的配置文件。如果你找不到它,就很难把一切都做好。您可能想要搜索适用于您的路由器(如果有)的 OpenWRT 版本,或者只要您能找到合适的配置,就可以在互联网上的任何其他地方搜索。在您的搜索中包括您的路由器品牌 and/or 型号。尽管如此,Whosebug 并不能真正帮助你。

您可以尝试使用默认配置加上您想要的模块交叉编译 5.4 内核。例如,假设您已经准备好正确的交叉编译工具链:

cd /path/to/linux
make ARCH=mips CROSS_COMPILE=your-cross-toolchain-prefix- defconfig
make ARCH=mips CROSS_COMPILE=your-cross-toolchain-prefix- menuconfig

# ... enable the module, tune the config ...

make -j ARCH=mips CROSS_COMPILE=your-cross-toolchain-prefix-

无论如何,考虑到从 2.6 内核跳到 5.4 内核是一个相当大的变化,并且最终可能会破坏所有内容,因此请务必在尝试任何操作之前备份您的路由器固件.