编译内核时一定要make modules这一步

本文通过一次实验经历揭示了在Linux环境下编译内核时,仅编译bzImage而不编译modules将导致无法启动新内核的问题。特别强调了对于含有模块支持的内核版本(如linux-2.6.36.2),编译modules的重要性。

最近做实验时发现linux编译内核,若只是make bzImage而不make modules,最后即使全都正常操作,也无法进入新的内核系统。我的内核版本为:linux-2.6.36.2,书上查了一下,说是如果配置的内核有模块支持,这一步是必不可少的!

模块一般用来支持那些不经常使用的功能。例如,通常情况下你仅使用拨号网络,因此网络功能并不是任何候都需要的,那么就应该使用可装入的模块来提供这个功能。仅在你进行拨号联接的候,该模块才被装入。而在你断掉连接的候它会被自动卸下。这样会使内核使用内存的量最小,减小系统的负荷。 当然,那些象硬盘访问这样刻刻都需要的功能,则必须作在内核里。如果你搭一台网络工作站或 web服务器,那么网络功能是刻都需要的,你就应该考虑把网络功能编译内核里。另外一个方法是在启动的候就装入网络模块。这种方法的优点是你不需要重新编译内核。而缺点是网络功能不能特别高效。 按照以上的原则,我们首先列出一张清单,看看 kernel 中哪些选项是非有不可的,也就是说,这些东西是必须被编译内核中的。将那些非必需的模块剔除到内核以外。 第一个是root所在的硬盘配置。 哪果您的硬盘是IDE接口,就把 ide 的选项标记下来。如果是SCSI接口,请把您的接口参数及 SCSI id 记标下来。 第二个是选择使用哪一个文件系统。 Linux的默认文件系统是是 ext2 ,那么就一定要把它标记下来。如果机器中还其它的操作系统,如win98或windows NT,您还会可能选择FAT32或NTFS的支持,不过后面你可以通过手工加载的方式来加入新的模块支持。 第三个是选择Linux所支持的可执行文件格式。这里有两种格式可供选择: elf:这是当前Linux普遍支持的可执行文件格式,必须编译内核中 。 a.out: 这是旧版的Linux的可执行文件各函数库的格式,如果你确认肯定用不到这种格式的可执行文件,那么就可以不把它编译内核当中。 以上这些内容,是必须要编译内核中的。其它的内容凡是所有选项中m提示的,都选择m,这样可以通过手工的方式添加该模块。 ** Loadable module support*Enable loadable module support (CONFIG_MODULES) [Y/n/?]Set version information on all symbols for modules (CONFIG_MODVERSIONS) [N/y/?]Kernel daemon support (e.g. autoload of modules) (CONFIG_KERNELD) [Y/n/?] 分别回答 Y,N,Y 。其中 CONFIG_KERNELD 的 default 值是 N, 所以要注意选择Y。 make config 完后,仍旧是 make dep; make clean。 接下来要 make zlilo 或 make zImage。 然后 make modules ; make modules_install 。完成之后,就编译出一个没有调入多余模块的一个“干净的”内核映像文件了。
<think>我们正在讨论Linux内核中`tcp_v4_rcv`函数的归属问题以及编译内核是否需要执行`make modules_install`。 根据之前的讨论,`tcp_v4_rcv`函数是TCP/IPv4协议栈的核心函数,位于`net/ipv4/tcp_ipv4.c`文件中。它的编译归属取决于内核配置选项: 1. **内核配置选项**: - 如果内核配置中启用了`CONFIG_IPV4=y`(直接编译内核)且`CONFIG_TCP=y`,则`tcp_v4_rcv`会被编译内核核心映像(`vmlinux`)中,不属于任何模块。 - 如果配置为模块(例如`CONFIG_IPV4=m`或`CONFIG_TCP=m`),则`tcp_v4_rcv`会被编译进`tcp_ipv4.ko`模块中(具体模块名可能因内核版本而异)。 2. **引用内容分析**: - 引用[1]提到配置内核需要设置`CONFIG_MODULES`、`CONFIG_KALLSYMS_ALL`等选项,这些选项确保模块支持和符号表信息完整,便于调试。 - 引用[2]说明了内核中模块的加载机制,例如`try_module_get()`用于检查模块是否加载,这暗示了某些功能(如网络协议族)可能以模块形式存在。 3. **是否需要执行`make modules_install`**: - 如果内核配置中包含模块(即至少有一个选项设置为`=m`),则编译后需要运行`make modules_install`将模块安装到指定目录(默认为`/lib/modules/$(uname -r)/`)。 - 如果所有选项都编译内核(没有模块),则不需要此步骤。 因此,关于`tcp_v4_rcv`: - 它**不一定**属于内核模块,具体取决于配置。 - 若配置为模块,则必须执行`make modules_install`才能使用该模块。 验证方法: - 检查内核配置文件(`.config`)中的`CONFIG_TCP`和`CONFIG_IPV4`: ```bash grep -E "CONFIG_IPV4=|CONFIG_TCP=" .config ``` 若结果为`=y`,则编译内核;若为`=m`,则为模块。 结论: - 若`tcp_v4_rcv`被编译为模块,则必须执行`make modules_install`并加载模块(如`modprobe tcp_ipv4`)才能使用。 - 若编译内核,则无需额外操作。 §§相关问题§§ 1. 如何查看当前运行的Linux内核中`tcp_v4_rcv`函数属于核心还是模块? 2. 如何在内核配置文件中将`tcp_v4_rcv`从模块改为直接编译内核? 3. 加载TCP/IPv4模块的命令是什么? </think>### `tcp_v4_rcv`的模块属性分析及编译要求 #### 1. **`tcp_v4_rcv`是否属于内核模块?** - **核心结论**:取决于内核配置: - 若 `CONFIG_IPV4=y` 且 `CONFIG_TCP=y`,则`tcp_v4_rcv`编译进**内核核心**(非模块)[^1][^3]。 - 若 `CONFIG_IPV4=m` 或 `CONFIG_TCP=m`,则属于**可加载模块**(如 `tcp_ipv4.ko`)[^2]。 **验证方法**: ```bash grep -E "CONFIG_IPV4=|CONFIG_TCP=" .config # 查看编译选项 ``` - 输出 `=y`:静态链接进内核 - 输出 `=m`:属于模块 #### 2. **是否需要执行 `make modules_install`?** - **需要执行的情况**(满足任一条件): 1. 内核配置中包含 `=m` 选项(存在动态模块) 2. 需要安装模块到 `/lib/modules/$(uname -r)/` 目录供系统加载 3. 使用模块化功能(如动态加载/卸载网络协议栈) - **无需执行的情况**: - 所有功能配置为 `=y`(纯静态内核) - 仅需内核镜像(`vmlinuz`)无需模块(如嵌入式场景) **操作建议**: ```bash # 完整编译流程(含模块安装) make -j$(nproc) # 编译内核和模块 make modules_install # 安装模块到系统目录 make install # 安装内核镜像 ``` ### 关键配置选项解析 | 配置选项 | 作用 | 对 `tcp_v4_rcv` 的影响 | |---------|------|-----------------------| | `CONFIG_IPV4=y` | IPv4 支持编译内核 | 函数直接链接到内核核心 | | `CONFIG_IPV4=m` | IPv4 支持编译为模块 | 函数位于 `ipv4.ko` 或 `tcp_ipv4.ko` | | `CONFIG_TCP=y` | TCP 协议栈支持 | 必需选项,否则函数不存在 | | `CONFIG_MODULES=y` | 启用模块支持 | 允许将功能编译为模块[^1] | > 注:引用[2]中提到的 `try_module_get()` 机制验证了内核可通过模块化方式加载网络协议栈函数[^2]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值