在这些高版本的RedHat Linux上,我们如果需要定制内核的话,没有直接的源代码rpm可以安装,只能通过kernel.org下载的tar.gz的包手工安装,或者通过kernel-*.src.rpm编译出kernel-source包再来安装。后面一种方法可以享受到RedHat针对内核的某些参数和代码的优化,因此对使用RedHat发行版特别是企业版本的,是有一定好处的。
但是目前很多人至今分不清内核,内核开发,内核源代码一些包之间的关系,因此在编译内核的时候经常走弯路,同时RedHat官方对于如果得到kernel-source也没有明确的指示,导致很多人不得要领。
首先认清楚各rpm包的内容和用途
kernel-*.rpm ------------- 内核二进制包,没有的话系统都起不来
kernel-sourcecode-*.rpm------------------- 内核源代码包,安装到/usr/src/linux-*下面的,包含内核源代码,编译内核必须(当然是不考虑用kernel.tar.gz编译的情况),但高版本RedHat Linux不再提供此rpm,原因参见官方Release Note,这篇文章的最终目的就是要我们自己把这个包搞出来。
kernel-devel-*.rpm----------------内核开发包,安装到/usr/src/kernels,用于内核模块开发,组织形式跟内核源代码包类似,包含了部分内核源代码。注意很多人误认为这个就是内核源代码包,直接拿它来编译内核,当然不可能成功。这个包只是用于内核模块一级开发,例如驱动程序等,虽然也可以make menuconfig make dep等,但make bzImage是不可能成功的,因为缺失了核心源代码。
kernel-*.src.rpm---------------RedHat提供的用于建立rpm的源代码包,安装到/usr/src/redhat中,使用rpmbuild可以从这个包中build出上面所说的所有包。
现在就来从src.rpm编译出上面的所有的包,除了sourcecode这个包其他的包都可以在不用修改任何地方的情况下直接rpmbuild出来,唯有sourcecode这个比较麻烦,一定要按照下面的步骤来做,我以RedHat AS4 所带的版本为例,其他版本相同。
#首先安装src.rpm
rpm -ivh kernel-2.6.9-5.EL.src.rpm
#进入相应目录,要修改spec文件
cd /usr/src/redhat/SPECS
vi kernel-2.6.spec
#主要修改如下地方:
1,define buildsource 0------------我的这个在第8行,改为1,这就是为什么没有源代码包的原因,因为默认不生成源代码包
2, Requires: qt-devel, gtk2-devel readline-devel ncurses-devel-------我的在572行,如果没用用X的话,把这句注释掉,这样编译出来的包就不依赖于X-window的某些包,因为内核配置是可以make xconfig的,所以默认依赖X-window,我没装X-window,因此这个就去掉了。
#保存退出
touch /etc/beehive-root
#这句命令非必须,如果不做的话,最后编译出来的包都会变成kernel-*.*-root.rpm,多了个root,据说是为了标示包的编译人的,如果touch了这个文件,就没有这个问题了,命名和官方rpm一样。
rpmbuild -ba --target=i686 ./kernel-2.6.spec
#编译i686平台的所有包,这样上面介绍的所有包都会生成,或者换成rpmbuild -bb --target=i686 ./kernel-2.6.spec只编译非src.rpm。
#所有包就会生成到/usr/src/redhat/RPMS/i686下面
#如果只需要sourcecode而并非所有rpm包,那在修改spec文件时还要修改如下行:
48 %ifarch noarch
49 %define builddoc 1
50 %define buildsource 0----------------这里0修改为1
在编译的时候使用rpmbuild -ba --target=noarch ./kernel-2.6.spec,这样仅仅编译soucecode和doc包,会节省很多时间。
注意,此篇文章所讲所有内容仅适用于使用2.6内核的新版本RedHat Linux,2.4版本内核代码组织方式不同,不适用此文章。
以上这篇文章取自互联网,我忘了出处,尊敬作者.
⑵ linux 编译内核几个常见问题解决方法
第一次把自己编译的驱动模块加载进开发板,就出现问题,还好没花费多长时间,下面列举出现的问题及解决方案
1:出现insmod: error inserting 'hello.ko': -1 Invalid mole format
法一(网上的):是因为内核模块生成的环境与运行的环境不一致,用linux-2.6.27内核源代码生成的模块,可能就不能在linux-2.6.32.2内核的linux环境下加载,需要在linux-2.6.27内核的linux环境下加载。
a.执行 uname -r //查看内核版本
b.一般出错信息被记录在文件/var/log/messages中,执行下面命令看错误信息
# cat /var/log/messages |tail
若出现类似下面:
Jun 4 22:07:54 localhost kernel:hello: version magic '2.6.35.6-45.fc14.i686.PAE
' should be '2.6.35.13-92.fc14.i686.PAE'
则把 Makefile里的KDIR :=/lib/moles/2.6.35.6-45.fc14.i686.PAE/build1 改为
KDIR :=/lib/moles/2.6.35.13-92.fc14.i686.PAE/build1 //改成自己内核源码路径
(这里的build1是一个文件链接,链接到/usr/src/kernels/2.6.35.6-45.fc14.i686.PAE和13-92的)
然并卵,我的fedora 14 /usr/src/kernels下并没有2.6.35.13-92.fc14.i686.PAE,只有2.6.35.13-92.fc14.i686,虽然不知道两者有什么区别,但改成2.6.35.13-92.fc14.i686还是不行,照样这个问题,还好后来在看教学视频的到启发
法二:改的还是那个位置
KDIR :=/opt/FriendlyARM/linux-2.6.32.2 //把这里改成你编译生成kernel的那个路径
all:
$ (MAKE) -C $ (KDIR) M = $ (PWD) moles ARCH=arm CROSS_COMPILE=arm-linux- //加这句
2. [70685.298483] hello: mole license 'unspecified' taints kernel.
[70685.298673] Disabling lock debugging e to kernel taint
方法:在模块程序中加入: MODULE_LICENSE("GPL");
3. rmmod: chdir(2.6.32.2-FriendlyARM): No such file or directory 错误解决
方法:lsmod 可查看模块信息
即无法删除对应的模块。
就是必须在/lib/moles下建立错误提示的对应的目录((2.6.32.2)即可。
必须创建/lib/moles/2.6.32.2这样一个空目录,否则不能卸载ko模块.
# rmmod nls_cp936
rmmod: chdir(/lib/moles): No such file or directory
但是这样倒是可以卸载nls_cp936,不过会一直有这样一个提示:
rmmod: mole 'nls_cp936' not found
初步发现,原来这是编译kernel时使用make moles_install生成的一个目录,
但是经测试得知,rmmod: mole 'nls_cp936' not found来自于busybox,并不是来自kernel
1).创建/lib/moles/2.6.32.2空目录
2).使用如下源码生成rmmod命令,就可以没有任何提示的卸载ko模块了[luther.gliethttp]
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>
#include <errno.h>
int main(int argc, char *argv[])
{
const char *modname = argv[1];
int ret = -1;
int maxtry = 10;
while (maxtry-- > 0) {
ret = delete_mole(modname, O_NONBLOCK | O_EXCL);//系统调用sys_delete_mole
if (ret < 0 && errno == EAGAIN)
usleep(500000);
else
break;
}
if (ret != 0)
printf("Unable to unload driver mole \"%s\": %s\n",
modname, strerror(errno));
}
3).把生成的命令复制到文件系统
# arm-linux-gcc -static -o rmmod rmmod.c
# arm-linux-strip -s rmmod
# cp rmmod /nfs/
cp /nfs/rmmod /sbin
代码如下:
proc.c
[html] view plain
<span style="font-size:18px;">#include <linux/mole.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/proc_fs.h> /* Necessary because we use the proc fs */
#define procfs_name "proctest"
MODULE_LICENSE("GPL");
struct proc_dir_entry *Our_Proc_File;
int procfile_read(char *buffer,char **buffer_location,off_t offset, int buffer_length, int *eof, void *data)
{ int ret;
ret = sprintf(buffer, "HelloWorld!\n");
return ret;
}
int proc_init()
{ Our_Proc_File = create_proc_entry(procfs_name, 0644, NULL);
if (Our_Proc_File == NULL) {
remove_proc_entry(procfs_name, NULL);
printk(KERN_ALERT "Error: Could not initialize /proc/%s\n",procfs_name);
return -ENOMEM; }
Our_Proc_File->read_proc = procfile_read;//
// Our_Proc_File->owner = THIS_MODULE;
Our_Proc_File->mode = S_IFREG | S_IRUGO;
Our_Proc_File->uid = 0;
Our_Proc_File->gid = 0;
Our_Proc_File->size = 37;
printk("/proc/%s created\n", procfs_name);
return 0;
}
void proc_exit()
{ remove_proc_entry(procfs_name, NULL);
printk(KERN_INFO "/proc/%s removed\n", procfs_name);
}
mole_init(proc_init);
mole_exit(proc_exit);</span></span></span></span></span>
[html] view plain
<span style="font-size:18px;">
ifneq ($(KERNELRELEASE),)
obj-m :=proc.o
else
KDIR :=/opt/FriendlyARM/linux-2.6.32.2
#KDIR :=/lib/moles/2.6.35.13-92.fc14.i686.PAE/build1
PWD :=$(shell pwd)
all:
$(MAKE) -C $(KDIR) M=$(PWD) moles ARCH=arm CROSS_COMPILE=arm-linux-
clean:
rm -f *.ko *.o *.mod.o *.mod.c *.symvers
endif</span></span></span></span></span>
make后生成proc.ko,再在开发板上insmod proc.ko即可
执行 dmesg 就可以看到 产生的内核信息啦
⑶ cygwin下编译linux2.6 kernel失败,求解决方法!
linux2.6内核成功编译
1) 需要的工具:
(1) 模块工具:motils-2.4.21-23.src.rpm
//负责加载模块,在2.4之前是不必独立编译
//模块存放位置:/lib/moles/内核版本目录/kernel/drivers
//lsmod: 查看已加载的模块
(2) 原始码:linux-2.6.9.tar.gz
//选择需要编译的部分: 最新内核2.6.9 支持NTFS分区(只读)
//查看现有系统支持的文件系统: cat /proc/filesystems
//显示内核版本: uname -r
反引号: 当作命令执行 cd /lib/moles/`uname -r`
(3) 能加上补丁:patch-2.6.9.gz
(2) 编译内核的基本步骤
(1) 主要用的编译命令: make make moles_install make install
(2) 基本安装: 安装模块、安装内核
------------------------------------------------------------------------------------------------------------------------------------------------
安装2.6内核的步骤
1 安装模块:(1)执行rpm命令将motils-2.4.21-23.src.rpm
安装到/usr/src/redhat/SOURCES
//rpm -ivh motils-2.4.21-23.src.rpm
//模块工具是RPM包安装后默认安装在/usr/src/redhat/SOURCES
(2)在SOURCIES中含有2个文件mole-init-tools.tar.gz
motils-2.4.21.tar.gz
将mole-init-tools.tar.gz接压
//tar -xzvf mole-init-tools.tar.gz
// motils-2.4.21.tar.gz文件不是主要要用的,不用接压
(3)mole-init-tools.tar.gz文件接压后会有一个
mole-init-tools-3.0-pre1
(4)进入到mole-init-tools-3.0-pre1 目录中
//cd mole-init-tools-3.0-pre1
(5)在mole-init-tools-3.0-pre1 下编译
//./configure --prefix=/moles然后执行make接着
make install到这模块编译完成
//注释:/moles是自己建立的目录,为了以后管理方便
当编译模块完成后在/moles文件下会有bin man sbin这3个目录
(6)开机自动加载模块编辑/etc/profile
//vi /etc/profile
(7)在/etc/profile文件中在添加 export上面一行 PATH=/moles/bin:/moles/sbin:$PATH
(8)进入到模块的目录/moles
进入到其中的sbin中执行一下命令
./generate_modprobe.conf /etc/modprobe.conf
//注释:generate_modprobe.conf在文件sbin中有这个执行命令
/etc/modprobe.conf是自己输入的,是规定的
//以上操作是为了规定init
(9)重新启动计算机,或着source /etc/profile让其本次操作有效
(10)目前开始编译内核将linux-2.6.9.tar.gz接压到/usr/src
//tar -xzvf linux-2.6.9.tar.gz -C /usr/src
(11)接压后在/usr/src会有 linux-2.6.9目录
(12)将 linux-2.6.9做一个连接文件
//创建链接文件: ln -s linux-2.6.9/ linux
//创建链接文件是为了方便管理
(13)进入到创建链接文件linux中开始编译内核
首先运行make menuconfig选择要编译的内容,默认也能
//注释M: 以模块形式加载
*: 直接编译进内核
空: 不做操作,不编译
然后执行make
再后执行moles_install
最后执行make install
到此内核编译完成
⑷ 我在linux环境下怎么就是编译不成功
编译不成功多半软件功能开关设置及依赖关系不支持。
首先要了解编译的过程,真正了解了编译的过程后就可以比较轻松的编译各种软件了。
1、configure,可以在configure 执行一下./configure --help来大致了解一下该软件的一些开关和支持的性能,然后根据使用需要来设置需要开启的性能和需要关闭的性能,以及需要哪些支持库等等,然后再指定一下编译路径,做完这一切后,满屏幕的check ....就开始了,这就是configrue的过程,和所做的事情
2、make,其实这一步才是真正的编辑步骤,而configure只是做一个环境的check,检查系统环境及lib是不是对上一步所开启的参数支持,只有check不出错,也就是configure不出错,就可以比较顺利的进行编译也就是make
3、make install 安装,当成功编译后就可以通过make install进行安装了,安装完成后就可以使用了。
比较容易报错的地方就是configure这一步,因为这一步会检查软件及在configure这一步的设置开关功能中需要的依赖关系,并对现行系统进行检查,尤其是最小化安装的系统,报错会比较多,可根据具体报错内容来安装相应的安装包来完成软件的依赖,直到check全部通过。有些软件在make时也需要调用一些库,具体要看软件的reademe来了解具体编译要求。如果再不行,就只能网上寻求帮助了。
另外,编译也是一个经验活,只编译得多了,对一些常见的错误就会比较了解了,必定软件依赖的库常见的就那几个,建议每编译一款软件做一个小笔记,把处理的错误或遇到的情况记录下来,这样以后再编译时,会事半功倍!