Chinaunix首页 | 论坛 | 博客
  • 博客访问: 3046136
  • 博文数量: 535
  • 博客积分: 15788
  • 博客等级: 上将
  • 技术积分: 6507
  • 用 户 组: 普通用户
  • 注册时间: 2007-03-07 09:11
文章分类

全部博文(535)

文章存档

2016年(1)

2015年(1)

2014年(10)

2013年(26)

2012年(43)

2011年(86)

2010年(76)

2009年(136)

2008年(97)

2007年(59)

分类: 系统运维

2009-04-02 10:33:42

amazon提供的AKI-9b00e5f2(2.6.18-xenU的x86_32版本)内核对应的内核源代码可以从下面的地址下载:


2.6.16的可以从下面的地址下载:


我们可以重新编译该内核源码添加自己需要的模块,在这里我添加ipvs的相关模块

因为ec2上使用的是xen的内核,所以,我们需要通过xen的源码包编译(上面下载的)。

通过Xen的源码包编译,其实也没有什么神秘的。在Xen的源码包中提供了一些内核补丁和内核配置文件等。当我们执行编译命令时,首先编译的是Xen程序本身,然后是编译内核 。在编译内核时,程序会自动判断是否有内核源码 ,xen-3.1.0-src-ec2-v1.0支持内核2.6.18,如果在xen的解压目录下没有(我们这里是有的),他就会自动内核的官方站 下载 linux-2.6.18.tar.bz2。然后就是自动解压并为此内核打补丁。然后系统会根据指令要求,然后采用相应的内核配置文件,或配置内核进行编译。


解压xen-3.1.0-src-ec2-v1.0.tgz后,进入解压目录,会看到以上的文件或文件夹。patches是内核的补丁包,linux-2.6-xen-sparse是支持Xen的内核目录树,内核的配置文件在/opt/kernel/xen-3.1.0-src-ec2-v1.0/buildconfigs目录中

其中,xen0字样的就是我们一般是用于我们运行xen的操作系统的内核,而xenU字样的就是为虚拟操作系统所提供的内核。另外还有x86_32和x86_64之分,这表示CPU的架构。在EC2上,我们需要编译安装xenU

开始编译安装内核:
1、yum install ncurses-devel*

2、cd xen-3.1.0-src-ec2-v1.0
make linux-2.6-xenU-config CONFIGMODE=menuconfig

添加ipvs的选项:
Networking  --->Networking options  --->IP: Virtual Server Configuration  --->

Save Configuration to an Alternate File   保存到.config23中(随便起的),退出

cp /opt/kernel/xen-3.1.0-src-ec2-v1.0/build-linux-2.6.18-xenU_x86_32/.config23 /opt/kernel/xen-3.1.0-src-ec2-v1.0/buildconfigs/linux-defconfig_xenU_x86_32

注:你可能想make linux-2.6-xenU-config CONFIGMODE=menuconfig 不是已经创建新的.config了么,还需要修改linux-defconfig_xenU_x86_32干什么?这里,如果你不修改该文件,下面的安装过程中还是会使用原来的config文件,你会发现,还是没有ipvs模块,所以,按照上面的做吧。当然,如果你知道配置文件的写法和依赖关系,你可以直接手动修改linux-defconfig_xenU_x86_32文件,而不需要make linux-2.6-xenU-config CONFIGMODE=menuconfig。

3、在编译内核时,手动修改version magic为gcc-4.0,否则,所有编译为M的模块都不能被加载,这个问题会在boundle-vol时被发现,因为那时会加载loop设备模块,但是,很明显,加载不上。详细见文章后面的说明。
/opt/kernel/xen-3.1.0-src-ec2-v1.0/linux-2.6.18-xen/include/linux/vermagic.h
将其中:
"gcc-" __stringify(__GNUC__) "." __stringify(__GNUC_MINOR__)
改为
"gcc-4.0"

4、make linux-2.6-xenU-install
注:会复制/opt/kernel/xen-3.1.0-src-ec2-v1.0/buildconfigs/linux-defconfig_xenU_x86_32文件做为安装时的配置文件,你的文件修改好了么?

5、depmod 2.6.18-xenU-ec2-v1.0
   查看一下/lib/modules/2.6.18-xenU-ec2-v1.0文件是否是最新的

6、ok,可以bundle-vol了~~~


另:
如何在正在运行的内核配置基础上添加模块?
1、首先,要获取当前内核的配置(.config 文件)
 2.6内核,在 Gerneal Setup 部分有一个功能叫做 "Kernel .config support" ,允许你访问config。gz文件
"Enabel access to .config through /proc/config.gz“ 
你只需要下面的命令就可以把配置文件导出来
gunzip /proc/config.gz -c > ./.config 

关于模块装载时的版本检查
Linux内核一直在更新、完善,在a版本内核源码下编译的模块在b版本内核下通常不能运行,所以必须有一种机制,限制在a版本内核下编译生成的模块在b版本内核下被加载。
2.4与2.6内核在可装载内核模块的版本检查机制方面发生了根本性的改变,不过这些改变对设备驱动开发人员而言基本是透明的。为了使模块装载时的版本检查机制生效,2.4 内核下,只需在CFLAGS中定义

-DMODVERSIONS -include $(KDIR)/include/linux/modversions.h; 

2.6内核下,开发人员无须采用任何操作。
不过,在此仍有必要阐明2.4与2.6内核对可加载模块的版本检查机制。
2.4内核下, 执行`cat /proc/ksyms`可看到内核符号在名字后还跟随着一串校验字符串,此校验字符串与内核版本有关。在内核源码头文件linux/modules 目录下存在许多*.ver文件,这些文件起着为内核符号添加校验后缀的作用,如ksyms.ver 文件里有一行 #define printk _set_ver(printk)。linux/modversions.h 文件会包含全部的 ver文件 。所以当模块包含linux/modversions.h文件后,编译时,模块里使用的内核符号实质是带有校验后缀的内核符号。在加载模块时,如果模块中所使用内核符号的校验字符串与当前运行内核所导出的相应的内核符号的校验字符串不一致,即当前内核空间并不存在模块所使用的内核符号,就会出现"Invalid module format "的错误。
为内核符号添加校验字符串来验证模块的版本与内核的版本是否匹配是繁杂和浪费内核空间的;而且随着SMP(对称多处理器)、PREEMPT(可抢占内核)等机制在2.6内核的引入和完善,模块运行时对内核的依赖不仅取决于内核版本,还取决于内核的配置,此时内核符号的校验码是否一致不能成为判断模块可否被加载的充分条件。2.6 内核下,在linux/vermagic.h中定义有VERMAGIC_STRING,VERMAGIC_STRING不仅包含内核版本号,还包含有内核使用的gcc版本,SMP与PREEMPT等配置信息。模块在编译时,我们可以看到屏幕上会显示"MODPOST"。在此阶段, VERMAGIC_STRING会添加到模块的modinfo段。 在内核源码目录下scripts\mod\modpost.c文件中可以看到模块后续处理部分的代码。模块编译生成后,通过`modinfo mymodule.ko`命令可以查看此模块的vermagic等信息。2.6 内核下的模块装载器里保存有内核的版本信息,在装载模块时,装载器会比较所保存的内核vermagic与此模块的modinfo段里保存的vermagic信息是否一致,两者一致时,模块才能被装载。譬如Fedora core 4 与core 2 使用的都是2.6 版本内核, 在Fedore Core 2下去加载Fedora Core4下编译生成的hello.ko,会出现"invalid module format" 错误。

#insmod hello.ko
Invalid module format 
hello: version magic '2.6.11-1.1369_FC4 686 REGPARM 4KSTACKS gcc-4.0' 
should be '2.6.5-1.358 686 REGPARM 4KSTACKS gcc-3.3'

关于bundle-vol时出现错误后的解决步骤
在bundle-vol时报错,找不到loop设备

但是确定已经编译了该模块。看来是模块不能正确加载。

使用modprobe -l 发现没有任何模块
depmod -a

手动加载模块,报错
insmod /lib/modules/2.6.18-xenU-ec2-v1.0/kernel/drivers/block/loop.ko 
insmod: error inserting '/lib/modules/2.6.18-xenU-ec2-v1.0/kernel/drivers/block/loop.ko': -1 Invalid module format

查看/var/log/message,有下列信息
Apr  1 04:40:40 domU-12-31-39-03-3D-B4 kernel: [44710.252411] loop: version magic '2.6.18-xenU-ec2-v1.0 SMP mod_unload 686 REGPARM gcc-4.1' should be '2.6.18-xenU-ec2-v1.0 SMP mod_unload 686 REGPARM gcc-4.0'
Apr  1 04:45:41 domU-12-31-39-03-3D-B4 kernel: [45010.769595] loop: version magic '2.6.18-xenU-ec2-v1.0 SMP mod_unload 686 REGPARM gcc-4.1' should be '2.6.18-xenU-ec2-v1.0 SMP mod_unload 686 REGPARM gcc-4.0'

原因:AMI启动时使用的AKI是amazon提供的,通过dmesg查看相关信息
[    0.000000] Linux version 2.6.18-xenU-ec2-v1.0 (root@domU-12-31-39-00-49-B3) (gcc version 4.0.2 20051125 (Red Hat 4.0.2-8)) #2 SMP Tue Feb 19 10:51:53 EST 2008
但是,我们编译安装时使用的GCC是4.1的,所以,模块的vermagic里关于gcc是4.1的,在版本检查时不能通过,所以不能装载module。


解决办法:
方法1、
在加载模块时使用--force-vermagic参数,但是这样就需要手动去加载模块。
modprobe --force-vermagic loop
--force-vermagic 
Every module contains a small string containing important information, such as the kernel and compiler versions. If a module fails to load and the kernel complains that the "version magic" doesn’t match, you can use this option to remove it. Naturally, this check is there for your protection, so this using option is dangerous. 
This applies to any modules inserted: both the module (or alias) on the command line, and any modules it depends on. 

方法2、
在编译内核时,手动修改version magic为gcc-4.0
/opt/kernel/xen-3.1.0-src-ec2-v1.0/linux-2.6.18-xen/include/linux/vermagic.h
将其中:
"gcc-" __stringify(__GNUC__) "." __stringify(__GNUC_MINOR__)
改为
"gcc-4.0"


相关文章:


阅读(1847) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~