CentOS升级内核到2.6.27.46

本文介绍了一次从头开始升级Linux内核的过程,特别关注于启用KVM虚拟化功能。作者选择了2.6.27.46版本的内核,并详细记录了从下载源码、配置选项到最终解决启动问题的全过程。

想用KVM,而不太想用Xen,折腾来折腾去,最后决定升级内核。


先到 Linux Kernel ( http://www.kernel.org/ ) 找一个稳定的版本,我选了2.6.27.46 。


安装的过程很简单,

1, 准备

tar -jxvf linux-2.6.27.46.tar.bz2 -C /usr/src

cd /usr/src/linux-2.6.27.46

make mrproper

以上完成了准备工作,其中 make mrproper是做清理,保证整个代码清洁。

2, 配置选项

这一步最关键,配置好是升级内核成功的关键。有几种选择:

1) make config

这种是最简单的,一问一答的形式

2) make menuconfig

简单的菜单,我用这种形式,感觉不错,推荐。

3) make gconfig  或 make xconfig 

这两个,一个是基于Qt,一个是gtk吧,具体的不知道。

具体的配置,我没有用现在已有内核的配置,直接在默认配置上来,我主要改动的用三处吧

1) 在processer family里选了自己机器的cpu类型

2) 在virtualization里选了kvm 等。

3) 在File system中把ext3选为build-in。

4) 就是iptables的一些,第一次没有注意到这里,新内核启动后iptables不能正常工作,害的我又重新配置,重新编译了一遍。

有个《 iptalbes中文HOWTO文档》,里面讲的很详细吧,大家百度(或google?)一下吧。

3,编译,安装

make bzImage

make modules

make modules_install

make install

这样就好了,新的内核已经加入到grub的menu.lst中了,不过没有设为默认。


重启,在grub中选新内核启动,有两个FAILED,一个是“Loading additional iptables modules: ip_conntrack_netbios_n[FAILED]”,我在以下网址上找到了解决方案:

http://www.linode.com/wiki/index.php/CentOS#TIP:_Loading_additional_iptables_modules_.5BFAILED.5D

另一个是 eth0找不到,可能是原来的网卡驱动在新内核下不能很好的运行吧,我是intel的网卡,就去其官网下了驱动,重新安装后就好了。


好,现在把grub的默认启动改了,开始体验新内核!

networking/ntpd.c: In function ‘update_local_clock’: networking/ntpd.c:1624:49: warning: format ‘%ld’ expects argument of type ‘long int’, but argument 2 has type ‘long long int’ [-Wformat=] 1624 | bb_error_msg("p adjtimex freq:%ld offset:%+ld status:0x%x tc:%ld", | ~~^ | | | long int | %lld 1625 | tmx.freq, tmx.offset, tmx.status, tmx.constant); | ~~~~~~~~ | | | long long int networking/ntpd.c:1624:61: warning: format ‘%ld’ expects argument of type ‘long int’, but argument 3 has type ‘long long int’ [-Wformat=] 1624 | bb_error_msg("p adjtimex freq:%ld offset:%+ld status:0x%x tc:%ld", | ~~~^ | | | long int | %+lld 1625 | tmx.freq, tmx.offset, tmx.status, tmx.constant); | ~~~~~~~~~~ | | | long long int networking/ntpd.c:1624:80: warning: format ‘%ld’ expects argument of type ‘long int’, but argument 5 has type ‘long long int’ [-Wformat=] 1624 | bb_error_msg("p adjtimex freq:%ld offset:%+ld status:0x%x tc:%ld", | ~~^ | | | long int | %lld 1625 | tmx.freq, tmx.offset, tmx.status, tmx.constant); | ~~~~~~~~~~~~ | | | long long int networking/ntpd.c:1739:48: warning: format ‘%ld’ expects argument of type ‘long int’, but argument 3 has type ‘long long int’ [-Wformat=] 1739 | VERB4 bb_error_msg("adjtimex:%d freq:%ld offset:%+ld status:0x%x", | ~~^ | | | long int | %lld 1740 | rc, tmx.freq, tmx.offset, tmx.status); | ~~~~~~~~ | | | long long int networking/ntpd.c:1739:60: warning: format ‘%ld’ expects argument of type ‘long int’, but argument 4 has type ‘long long int’ [-Wformat=] 1739 | VERB4 bb_error_msg("adjtimex:%d freq:%ld offset:%+ld status:0x%x", | ~~~^ | | | long int | %+lld 1740 | rc, tmx.freq, tmx.offset, tmx.status); | ~~~~~~~~~~ | | | long long int CC networking/parse_pasv_epsv.o CC networking/ping.o CC networking/pscan.o CC networking/route.o CC networking/slattach.o networking/slattach.c: In function ‘slattach_main’: networking/slattach.c:225:17: warning: ignoring return value of ‘system’ declared with attribute ‘warn_unused_result’ [-Wunused-result] 225 | system(extcmd); | ^~~~~~~~~~~~~~ CC networking/ssl_client.o CC networking/tc.o networking/tc.c: In function ‘cbq_print_opt’: networking/tc.c:236:27: error: ‘TCA_CBQ_MAX’ undeclared (first use in this function); did you mean ‘TCA_CBS_MAX’? 236 | struct rtattr *tb[TCA_CBQ_MAX+1]; | ^~~~~~~~~~~ | TCA_CBS_MAX networking/tc.c:236:27: note: each undeclared identifier is reported only once for each function it appears in networking/tc.c:249:16: error: ‘TCA_CBQ_RATE’ undeclared (first use in this function); did you mean ‘TCA_TBF_RATE64’? 249 | if (tb[TCA_CBQ_RATE]) { | ^~~~~~~~~~~~ | TCA_TBF_RATE64 networking/tc.c:255:16: error: ‘TCA_CBQ_LSSOPT’ undeclared (first use in this function) 255 | if (tb[TCA_CBQ_LSSOPT]) { | ^~~~~~~~~~~~~~ networking/tc.c:256:61: error: invalid application of ‘sizeof’ to incomplete type ‘struct tc_cbq_lssopt’ 256 | if (RTA_PAYLOAD(tb[TCA_CBQ_LSSOPT]) < sizeof(*lss)) | ^ networking/tc.c:261:16: error: ‘TCA_CBQ_WRROPT’ undeclared (first use in this function) 261 | if (tb[TCA_CBQ_WRROPT]) { | ^~~~~~~~~~~~~~ networking/tc.c:262:61: error: invalid application of ‘sizeof’ to incomplete type ‘struct tc_cbq_wrropt’ 262 | if (RTA_PAYLOAD(tb[TCA_CBQ_WRROPT]) < sizeof(*wrr)) | ^ networking/tc.c:267:16: error: ‘TCA_CBQ_FOPT’ undeclared (first use in this function) 267 | if (tb[TCA_CBQ_FOPT]) { | ^~~~~~~~~~~~ networking/tc.c:268:59: error: invalid application of ‘sizeof’ to incomplete type ‘struct tc_cbq_fopt’ 268 | if (RTA_PAYLOAD(tb[TCA_CBQ_FOPT]) < sizeof(*fopt)) | ^ networking/tc.c:273:16: error: ‘TCA_CBQ_OVL_STRATEGY’ undeclared (first use in this function) 273 | if (tb[TCA_CBQ_OVL_STRATEGY]) { | ^~~~~~~~~~~~~~~~~~~~ networking/tc.c:274:67: error: invalid application of ‘sizeof’ to incomplete type ‘struct tc_cbq_ovl’ 274 | if (RTA_PAYLOAD(tb[TCA_CBQ_OVL_STRATEGY]) < sizeof(*ovl)) | ^ networking/tc.c:277:50: error: invalid application of ‘sizeof’ to incomplete type ‘struct tc_cbq_ovl’ 277 | (unsigned) sizeof(*ovl)); | ^ networking/tc.c:293:23: error: invalid use of undefined type ‘struct tc_cbq_lssopt’ 293 | if (lss && lss->flags) { | ^~ networking/tc.c:296:24: error: invalid use of undefined type ‘struct tc_cbq_lssopt’ 296 | if (lss->flags&TCF_CBQ_LSS_BOUNDED) { | ^~ networking/tc.c:296:32: error: ‘TCF_CBQ_LSS_BOUNDED’ undeclared (first use in this function) 296 | if (lss->flags&TCF_CBQ_LSS_BOUNDED) { | ^~~~~~~~~~~~~~~~~~~ networking/tc.c:300:24: error: invalid use of undefined type ‘struct tc_cbq_lssopt’ 300 | if (lss->flags&TCF_CBQ_LSS_ISOLATED) { | ^~ networking/tc.c:300:32: error: ‘TCF_CBQ_LSS_ISOLATED’ undeclared (first use in this function) 300 | if (lss->flags&TCF_CBQ_LSS_ISOLATED) { | ^~~~~~~~~~~~~~~~~~~~ networking/tc.c:308:24: error: invalid use of undefined type ‘struct tc_cbq_wrropt’ 308 | if (wrr->priority != TC_CBQ_MAXPRIO) | ^~ networking/tc.c:308:38: error: ‘TC_CBQ_MAXPRIO’ undeclared (first use in this function) 308 | if (wrr->priority != TC_CBQ_MAXPRIO) | ^~~~~~~~~~~~~~ networking/tc.c:309:46: error: invalid use of undefined type ‘struct tc_cbq_wrropt’ 309 | printf("prio %u", wrr->priority); | ^~ networking/tc.c:313:43: error: invalid use of undefined type ‘struct tc_cbq_wrropt’ 313 | printf("/%u ", wrr->cpriority); | ^~ networking/tc.c:314:32: error: invalid use of undefined type ‘struct tc_cbq_wrropt’ 314 | if (wrr->weight != 1) { | ^~ networking/tc.c:315:65: error: invalid use of undefined type ‘struct tc_cbq_wrropt’ 315 | print_rate(buf, sizeof(buf), wrr->weight); | ^~ networking/tc.c:318:32: error: invalid use of undefined type ‘struct tc_cbq_wrropt’ 318 | if (wrr->allot) | ^~ networking/tc.c:319:57: error: invalid use of undefined type ‘struct tc_cbq_wrropt’ 319 | printf("allot %ub ", wrr->allot); | ^~ networking/tc.c:236:24: warning: unused variable ‘tb’ [-Wunused-variable] 236 | struct rtattr *tb[TCA_CBQ_MAX+1]; | ^~ make[1]: *** [scripts/Makefile.build:198:networking/tc.o] 错误 1 make: *** [Makefile:744:networking] 错误 2
最新发布
06-12
<think>我们面对的是两个问题:1.格式化字符串类型不匹配:在ntpd.c和tc.c文件中,使用'%ld'格式说明符来打印longlongint类型的变量,导致编译警告。2.未声明的标识符:在tc.c文件中,TCA_CBQ_MAX等标识符未声明。首先,我们分析第一个问题:格式化字符串类型不匹配。在C语言中,longlongint类型的变量应该使用%lld格式说明符(对于有符号)或%llu(对于无符号)来打印。如果代码中使用了%ld,则会产生警告,因为%ld用于longint类型,而longlongint通常占8字节(64位),而longint在32位系统上是4字节,在64位系统上可能是8字节(但标准要求longlong至少8字节,且不小于long)。为了可移植性,应该使用%lld。因此,我们需要在代码中找到所有使用%ld打印longlongint类型的地方,改为%lld。其次,第二个问题:TCA_CBQ_MAX等未声明。这些标识符(如TCA_CBQ_MAX)通常定义在Linux内核的头文件中,特别是与网络流量控制(trafficcontrol)相关的头文件。在用户空间程序中,这些定义通常来自<linux/pkt_sched.h>头文件。如果编译时找不到这个头文件,或者头文件中没有定义这些宏,就会出现未声明的错误。解决方案:1.确保包含正确的头文件。在tc.c文件中,应该包含<linux/pkt_sched.h>。2.如果系统中没有这个头文件,可能需要安装内核头文件包。3.如果安装头文件后问题仍然存在,可能是内核版本较新,一些宏已经改变,需要检查宏定义是否存在,或者改用其他方式。具体步骤:对于第一个问题(格式化字符串):-在ntpd.c和tc.c文件中搜索printf、fprintf等格式化输出函数,检查参数类型是否为longlongint,并检查格式字符串。-将对应位置的%ld替换为%lld(如果是无符号的,则用%llu)。示例代码修改前:```clonglongintvalue=...;printf("value=%ld\n",value);```修改后:```cprintf("value=%lld\n",value);```对于第二个问题(未声明标识符):-在tc.c文件的开头,确保包含<linux/pkt_sched.h>头文件。-如果已经包含但仍然未定义,可能是因为内核头文件的版本问题。可以尝试在包含之前定义一些宏来启用所需的定义(但通常不需要,因为<linux/pkt_sched.h>应该包含必要的定义)。如果系统中没有安装内核头文件,需要安装。在基于RPM的系统(如CentOS)上,可以使用:```bashsudoyuminstallkernel-headers```在Debian/Ubuntu上:```bashsudoapt-getinstalllinux-headers-$(uname-r)```如果安装后仍然找不到头文件,可能需要检查头文件路径,并在编译时添加额外的包含路径。如果头文件中确实没有这些宏,可能是因为内核版本不同,这些宏被移除了或者改名了。在这种情况下,需要根据内核版本来调整代码。比如,可以查看当前内核的pkt_sched.h头文件,确认是否有TCA_CBQ_MAX等宏。如果没有,可能需要查找替代方案或者根据内核版本进行条件编译。由于TCA_CBQ_MAX等宏属于TC(流量控制)的CBQ(ClassBasedQueueing)选项,在较新的内核中可能被其他队列规则替代。所以,如果确定不需要使用CBQ,也可以考虑在配置时禁用相关的功能。但是,如果代码必须使用CBQ,而当前内核头文件没有这些宏,可以尝试手动定义这些宏(需要参考旧内核的头文件定义,注意风险)。通常情况下,TCA_CBQ_MAX的取值在旧内核中(如2.6.x)定义如下(举例,具体值可能不同):```c#defineTCA_CBQ_MAX256```但是,这只是一例,具体需要查看头文件。不建议手动定义,因为可能变化。更可靠的方法是检查当前内核头文件,确认是否有这些宏。如果没有,考虑使用更新的宏(如果代码比较旧)或者使用其他方法。由于我们无法得知用户的具体环境,以上是常见解决方案。总结步骤:步骤1:修改格式化字符串在ntpd.c和tc.c中,将所有用于longlongint类型的%ld改为%lld,%lu改为%llu(根据有符号或无符号)。步骤2:确保包含<linux/pkt_sched.h>在tc.c文件中,添加:```c#include<linux/pkt_sched.h>```步骤3:安装内核头文件(如果缺失)步骤4:如果安装后仍然报错,检查<linux/pkt_sched.h>中是否有TCA_CBQ_MAX等宏。如果没有,可能需要手动定义(不推荐,但作为临时解决方案)或者更新代码。步骤5:如果手动定义,需要在tc.c文件中添加类似下面的代码(注意:这些值可能因内核版本而异,需要用户根据实际情况调整):```c#ifndefTCA_CBQ_MAX#defineTCA_CBQ_MAX256//这里只是示例,具体值需要查旧版本内核#endif```或者从旧内核中复制缺失的宏定义。由于手动定义存在风险,建议优先使用系统内核头文件中的定义。如果用户是在为嵌入式系统编译,可能需要使用交叉编译工具链的内核头文件,确保头文件与目标系统内核匹配。如果用户使用的是非常新的内核(如4.x或5.x),而代码是基于旧内核2.6.x)编写的,可能已经废弃了一些宏,那么就需要重写部分代码来适应新内核的API。鉴于问题复杂,请用户根据实际情况尝试。最后,编译并测试。生成相关问题:1.如何检查系统当前内核版本?2.如何获取与当前内核版本匹配的内核头文件?3.如何解决交叉编译环境下内核头文件缺失的问题?4.如何在旧版代码中适配新版内核API?5.C语言中格式化输出还有哪些常见错误?</think> 针对 `ntpd.c` 和 `tc.c` 文件的编译问题,以下是逐步解决方案: --- ### 一、格式化字符串类型不匹配警告(`%ld` 与 `long long int`) 问题本质:C语言中 `%ld` 适用于 `long int` 类型,但 `long long int` 需要 `%lld`。 #### 修改步骤: 1. **定位问题行** 搜索源文件中所有 `printf`/`sprintf` 调用,找到以下模式: ```c long long int value = ...; printf("... %ld ...", value); // 警告来源 ``` 2. **统一修改为 `%lld`** ```diff // ntpd.c 或 tc.c 中 - printf("Value: %ld", (long long)var); + printf("Value: %lld", (long long)var); ``` 3. **跨平台适配** 添加编译器兼容宏: ```c #if defined(_WIN32) || defined(_WIN64) #define LL_FORMAT "%I64d" // Windows #else #define LL_FORMAT "%lld" // Linux/macOS #endif printf("Value: " LL_FORMAT, (long long)var); ``` --- ### 二、未声明标识符错误(`TCA_CBQ_MAX` 等) 问题原因:缺少内核头文件或未启用流量控制(QoS)支持。 #### 解决方案: 1. **安装内核头文件** ```bash # Debian/Ubuntu sudo apt install linux-headers-$(uname -r) # RHEL/CentOS sudo yum install kernel-devel ``` 2. **检查包含路径** 在 `tc.c` 顶部添加: ```c #include <linux/pkt_sched.h> // 包含TCA_CBQ_*宏定义 ``` 3. **编译时指定头文件路径** ```bash gcc -I/usr/src/linux-headers-$(uname -r)/include -o tc tc.c ``` 4. **确认内核支持** ```bash grep CONFIG_NET_SCH_CBQ /boot/config-$(uname -r) # 输出应为 CONFIG_NET_SCH_CBQ=y ``` - 若返回 `=m`,需加载模块:`sudo modprobe cbq` - 若未启用,需重新编译内核启用 `CONFIG_NET_SCH_CBQ` --- ### 三、额外建议 1. **启用编译器严格模式** 添加编译选项捕获其他警告: ```bash CFLAGS="-Wall -Wextra -Werror -Wformat=2" ./configure ``` 2. **验证修改效果** ```bash # 检查未定义符号 nm tc.o | grep UND # 测试运行 sudo ./tc qdisc show ``` 3. **参考NTPD补丁方案** 根据错误类型: - **权限问题**:确保启动顺序在网络初始化后[^3] - **系统库缺失**:通过RPM安装依赖[^4] ```bash wget https://gitcode.com/Premium-Resources/2b5eb/-/raw/main/autogen-libopts-5.18-5.el7.x86_64.rpm sudo rpm -i autogen-libopts-5.18-5.el7.x86_64.rpm ``` --- ### 相关问题 1. 如何修复 Linux 内核编译中的未定义符号错误? 2. `printf` 格式化说明符有哪些常见陷阱? 3. 如何为嵌入式系统裁剪 NTPD 以减少依赖? 4. 如何在低内存环境下调试内存对齐导致的格式化错误? 5. 如何为跨平台 C 项目编写类型安全的格式化输出宏?
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值