导航:首页 > 源码编译 > 编写和编译内核的注意事项

编写和编译内核的注意事项

发布时间:2022-07-23 11:32:10

A. linux内核编译遇到的问题求助

你再仔细查看一下相关的环境变量设置的是否正确?以及编译选项是否正确?因为关于 gcc 编译器的使用,有时候虽然你的源程序是正确的,但是由于环境变量的设置不正确(例如: INCLUDE、LIB等)、或者是虽然环境变量设置正确、但是编译选项的不正确(例如:-Imy_include_file、-Lmy_lib_file等),都有可能导致程序无法正确编译通过。所以必须要仔细检查所有的细节问题。另外,你还必须保证 makefile 文件的语法必须是正确的,即:所需要编译的源文件、以及中间代码文件(*.o)等,它们之间的顺序也是很重要的,如果这些顺序不正确的话,那么也会产生出错信息。

B. 编译Linux内核的具体步骤

1. 下载内核源代码,并解压家目录
2. 设置好编译环境
3. 修改好Makefile和.config
4. 执行make -j4
等一下,编译就会结束了。

C. 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 就可以看到 产生的内核信息啦

D. linux下编译内核 和 编译 应用程序的问题

E. 如何编译内核及制作RPM包

前言

要编译自内核能各种同答案列举:
1 研究习内核源码
2 支持新硬件或者打某项内核功能
3 升级内核更新版本
4 按自要求定制优化内核功能
种种...
折腾需要理由我说面直接进入主题
编译式
编译内核种式kernel.org载选择载需要版本内核源码
:linux-2.6.32-rc1.tar.bz2载内核源码/home/user/目录进入载目录解压压缩

#cd /home/user/
#tar -xjvf linux-2.6.32-rc1.tar.bz2

二 准备编译环境

始前首先确认面软件包已经安装(编译标普华4.0直接全部安装CD3保证条件)
* rpmdevtools
* yum-utils
fedora系统使用命令安装:
#yum install yum-utils rpmdevtools

1. rpmbuild命令工作所需目录树面命令完该操作手建立目录树
命令建立:
#rpmdev-setuptree

命令/usr/src/rpmbuild/目录目录结构(位置没则能前用户目录).

# tree /usr/src/rpmbuild/
rpmbuild/
|-- BUILD
|-- RPMS
|-- SOURCES
|-- SPECS
`-- SRPMS
面部rpmbuild环境建立rpm
3. 安装内核源码包需要依赖组件(跳步操作)

su -c 'yum-builddep kernel-.src.rpm'
4.安装内核源码系统默认目录/usr/src/neoshine:

rpm -Uvh kernel-.src.rpm

三 配置内核(config配置文件)

面介绍何解源码包并修改配置重新打包源码
1. 解源码包并打所补丁BUILD目录

cd ~/rpmbuild/SPECS
rpmbuild -bp --target=`uname -m` kernel.spec

kernel源码找:

/usr/src/neoshine/rpmbuild/BUILD/kernel-/linux-. directory

配置内核源码
1. 进入内核源码:

cd ~/rpmbuild/BUILD/kernel-2.6.$ver/linux-2.6.$ver.$arch/
2. 复制/boot/config*配置文件源码目录,config文件已经配或者其备份kernel配置文件:

cp /boot/config2.6- 2.6.$ver.$arch .config
3. 先检查kernel配置新增选项:

make oldconfig
4. 定制内核功能关闭initrd支持选项执行图形化内核配置工具:

make menuconfig
注:generic setup选项找initial RAM system and RAM disk(initramfs and initrd) support 项取消编译同确保跟文件系统应驱系统所存储器应驱都已经编译内核(否则启系统).

5. .config文件第行改面内容(注意:没行面编译报错)

# i386
6. 拷贝.configSOURCES/:

cp .config ../SOURCES/config-$arch

四 编译新内核

1. 面始准备编译新内核包
打SPEC/kernel.spec

vim SPEC/kernel.spec
改变面行内容定制自内核扩展名(fc10类):

%define buildid .
步新内核rpm包程需要编译内核源码包
使用面命令新内核源码包
rpmbuild -bb --with baseonly --without debuginfo --target=`uname -m` kernel.spec

参数说明:bb表示编译二进制包即源码包without debuginfo 表示没调试信息
target=`uname -r`表示应前平台内核包
面命令功执行完BUILD/i686目录新内核安装包

五 安装新内核

rpm -ivh kernel-$ver-$arch.rpm
步操作自安装内核boot目录安装应内核模块/lib/moles/目录并且新内核应grub引导菜单
修改grub引导菜单格式

title new kernel
kernel /boot/vmlinuz-$ver-$arch root=/dev/sdax(hdax)

注意处要使用uuid指定跟文件系统(能挂载根区导致内核死机)要再加显示相关参数(内核支持应设置看黑黑屏幕)
至禁用initrd新内核配置安装完毕

F. linux编译内核步骤

一、准备工作
a) 首先,你要有一台PC(这不废话么^_^),装好了Linux。
b) 安装好GCC(这个指的是host gcc,用于编译生成运行于pc机程序的)、make、ncurses等工具。
c) 下载一份纯净的Linux内核源码包,并解压好。

注意,如果你是为当前PC机编译内核,最好使用相应的Linux发行版的源码包。

不过这应该也不是必须的,因为我在我的Fedora 13上(其自带的内核版本是2.6.33.3),就下载了一个标准的内核linux-2.6.32.65.tar.xz,并且顺利的编译安装成功了,上电重启都OK的。不过,我使用的.config配置文件,是Fedora 13自带内核的配置文件,即/lib/moles/`uname -r`/build/.config

d) 如果你是移植Linux到嵌入式系统,则还要再下载安装交叉编译工具链。

例如,你的目标单板CPU可能是arm或mips等cpu,则安装相应的交叉编译工具链。安装后,需要将工具链路径添加到PATH环境变量中。例如,你安装的是arm工具链,那么你在shell中执行类似如下的命令,假如有类似的输出,就说明安装好了。
[root@localhost linux-2.6.33.i686]# arm-linux-gcc --version
arm-linux-gcc (Buildroot 2010.11) 4.3.5
Copyright (C) 2008 Free Software Foundation, Inc.
This is free software; see the source for ing conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
注:arm的工具链,可以从这里下载:回复“ARM”即可查看。

二、设置编译目标

在配置或编译内核之前,首先要确定目标CPU架构,以及编译时采用什么工具链。这是最最基础的信息,首先要确定的。
如果你是为当前使用的PC机编译内核,则无须设置。
否则的话,就要明确设置。
这里以arm为例,来说明。
有两种设置方法():

a) 修改Makefile
打开内核源码根目录下的Makefile,修改如下两个Makefile变量并保存。
ARCH := arm
CROSS_COMPILE := arm-linux-

注意,这里cross_compile的设置,是假定所用的交叉工具链的gcc程序名称为arm-linux-gcc。如果实际使用的gcc名称是some-thing-else-gcc,则这里照葫芦画瓢填some-thing-else-即可。总之,要省去名称中最后的gcc那3个字母。

b) 每次执行make命令时,都通过命令行参数传入这些信息。
这其实是通过make工具的命令行参数指定变量的值。
例如
配置内核时时,使用
make ARCH=arm CROSS_COMPILE=arm-linux- menuconfig
编译内核时使用
make ARCH=arm CROSS_COMPILE=arm-linux-

注意,实际上,对于编译PC机内核的情况,虽然用户没有明确设置,但并不是这两项没有配置。因为如果用户没有设置这两项,内核源码顶层Makefile(位于源码根目录下)会通过如下方式生成这两个变量的值。
SUBARCH := $(shell uname -m | sed -e s/i.86/i386/ -e s/sun4u/sparc64/ \
-e s/arm.*/arm/ -e s/sa110/arm/ \
-e s/s390x/s390/ -e s/parisc64/parisc/ \
-e s/ppc.*/powerpc/ -e s/mips.*/mips/ \
-e s/sh[234].*/sh/ )
ARCH?= $(SUBARCH)
CROSS_COMPILE ?=

经过上面的代码,ARCH变成了PC编译机的arch,即SUBARCH。因此,如果PC机上uname -m输出的是ix86,则ARCH的值就成了i386。

而CROSS_COMPILE的值,如果没配置,则为空字符串。这样一来所使用的工具链程序的名称,就不再有类似arm-linux-这样的前缀,就相当于使用了PC机上的gcc。

最后再多说两句,ARCH的值还需要再进一步做泛化。因为内核源码的arch目录下,不存在i386这个目录,也没有sparc64这样的目录。

因此顶层makefile中又构造了一个SRCARCH变量,通过如下代码,生成他的值。这样一来,SRCARCH变量,才最终匹配到内核源码arch目录中的某一个架构名。

SRCARCH := $(ARCH)

ifeq ($(ARCH),i386)
SRCARCH := x86
endif

ifeq ($(ARCH),x86_64)
SRCARCH := x86
endif

ifeq ($(ARCH),sparc64)
SRCARCH := sparc
endif

ifeq ($(ARCH),sh64)
SRCARCH := sh
endif

三、配置内核

内核的功能那么多,我们需要哪些部分,每个部分编译成什么形式(编进内核还是编成模块),每个部分的工作参数如何,这些都是可以配置的。因此,在开始编译之前,我们需要构建出一份配置清单,放到内核源码根目录下,命名为.config文件,然后根据此.config文件,编译出我们需要的内核。

但是,内核的配置项太多了,一个一个配,太麻烦了。而且,不同的CPU架构,所能配置的配置项集合,是不一样的。例如,某种CPU的某个功能特性要不要支持的配置项,就是与CPU架构有关的配置项。所以,内核提供了一种简单的配置方法。

以arm为例,具体做法如下。

a) 根据我们的目标CPU架构,从内核源码arch/arm/configs目录下,找一个与目标系统最接近的配置文件(例如s3c2410_defconfig),拷贝到内核源码根目录下,命名为.config。

注意,如果你是为当前PC机编译内核,最好拷贝如下文件到内核源码根目录下,做为初始配置文件。这个文件,是PC机当前运行的内核编译时使用的配置文件。
/lib/moles/`uname -r`/build/.config
这里顺便多说两句,PC机内核的配置文件,选择的功能真是多。不编不知道,一编才知道。Linux发行方这样做的目的,可能是想让所发行的Linux能够满足用户的各种需求吧。

b) 执行make menuconfig对此配置做一些需要的修改,退出时选择保存,就将新的配置更新到.config文件中了。

G. Linux内核编译的具体操作过程及注意问题

你好,楼主:
1、配置.config文件,将你要编译的配置XXX_config准备好,使用make XXX_config来进行配置;
2、这时你就可以在内核根目录下进行make menuconfig来使用图形界面配置内核选项,配置后保存即可;
3、最后只需要使用make或者make uImage生成相应的镜像即可。
注意问题多在config这里,如果配置时报错,可尝试make clobber来清除原来的依赖关系。

H. 如何编译一个内核

1. 预备工作
我推荐使用root用户执行下面所有的步骤. 如果你还没有创建root登陆口令, 请运行下面的命令:
sudo passwd root

然后, 以root身份登陆:
su

如果你想使用一般用户来替代root用户, 记住在本文所有命令前输入sudo, 比如当我运行
apt-get update

你需要运行下面的命令来替代, 等.
sudo apt-get update

1.1 Ubuntu 6.10上的/bin/sh ("Edgy Eft")
在Ubuntu 6.10, /bin/sh缺省是一个链接到/bin/dash的字符链接. 当你编译软件源代码的时候, /bin/dash似乎还存在问题. 至少我已经遇到了一些问题. 所以我把/bin/sh链接到了/bin/bash.

如果你使用Ubuntu 6.10, 现在你可以运行:
rm -f /bin/sh
ln -s /bin/bash /bin/sh

2 安装必需的软件包 (为内核编译做准备)
首先我们升级软件(包)库:
apt-get update

然后我们安装所有需要的软件包:
apt-get install kernel-package libncurses5-dev fakeroot wget bzip2

3 下载内核源代码
接下来我们下载需要的内核到/usr/src目录(去www.kernel.org网站下载你需要的内核版本, 比如. linux-2.6.18.1tar.bz2(你可以从这里下载所有的2.6内核: http://www.kernel.org/pub/linux/kernel/v2.6/). 然后下载到/usr/src目录:
cd /usr/src
wget http://www.kernel.org/pub/linux/kernel/v2.6/linux-2.6.18.1.tar.bz2

然后解压内核源代码, 创建一个指向内核源代码目录的linux字符链接:
tar xjf linux-2.6.18.1.tar.bz2
ln -s linux-2.6.18.1 linux
cd /usr/src/linux

4 给内核源代码打补丁(可选)
有时你的缺省内核不支持新买的设备, 你需要安装新的驱动. 或者你需要使用虚拟技术或其它高级的技术, 而这些现有的内核都不支持. 这样情况下你需要给给内核源代码打补丁(当然补丁已经发布..)

现在我们假设你已经下载需要的补丁(以下例子我叫它patch.bz2)到/usr/src. 运行下面的命令给内核源代码直接打上补丁(你的用户必须位于/usr/src/linux目录):
bzip2 -dc /usr/src/patch.bz2 | patch -p1 --dry-run
bzip2 -dc /usr/src/patch.bz2 | patch -p1

第一个命令用于测试, 对内核没有任何影响. 如果没有显示错误, 你可以运行第二个命令给内核打补丁. 如果第一个命令有误, 请务继续的操作!

你也能够通过内核的prepatches方式打补丁. 比如, 如果你需要一个功能, 而这个功能仅存在于2.6.19-rc4中,
正式完整的内核版本仍没有发布, 而patch-2.6.19-rc4.biz2已经发布. 你可以把这个补丁打到2.6.18的内核源代码中,
但请不要达到2.6.18.1或2.6.18.2, 等. 这个规则在接下来的网页中注明:
http://kernel.org/patchtypes/pre.html

prepatches等同于linux中的测试发行; 他们位于存档的测试目录中,
我们可以使用patch(1)工具对上一个完整发行版(版本号分三部分)打补丁(例如, 2.6.12-rc4
prepatch只可以给2.6.11内核源代码打补丁, 而不是2.6.11.10.)

所以如果你想编译2.6.19-rc4内核, 你必须在步骤3.1下载2.6.18(http://www.kernel.org/pub/linux/kernel/v2.6/linux-2.6.18.tar.bz2)替代2.6.18.1内核源代码!

下面是如何给2.6.18打上2.6.19-rc4补丁:
cd /usr/src
wget http://www.kernel.org/pub/linux/kernel/v2.6/testing/patch-2.6.19-rc4.bz2
cd /usr/src/linux
bzip2 -dc /usr/src/patch-2.6.19-rc4.bz2 | patch -p1 --dry-run
bzip2 -dc /usr/src/patch-2.6.19-rc4.bz2 | patch -p1

5. 配置内核
使用当前工作内核的配置文件做为新内核配置文件的基础是一个很好的主意. 因此我们拷贝已存的配置文件到/usr/src/linux:
cp /boot/config-`uname -r` ./.config

然后运行
make menuconfig

然后我们看到内核的配置菜单. 移动绿色光标到 Load an Alternate Configuration File 行后选择.config文件(包含了当前工作内核的配置)做为配置文件:

然后浏览内核配置菜单, 选择你需要的功能. 完成配置后, 选择Exit, 回答下面的问题(Do you wish to save your new kernel configuration? 你希望保存新的内核配置吗?), 选择Yes:

6 构建内核
执行下面命令来构建内核:
make-kpkg clean
fakeroot make-kpkg --initrd --append-to-version=-custom -j4 kernel_image kernel_headers

如果要进行交叉编译,可以进行确定架构机器上的编译。
fakeroot make-kpkg --initrd --append-to-version=-custom -j4 --arch i386 kernel_image kernel_headers (比如在64位机器上编译32位的内核)

在--append-to-version= 后面你可以写上任何字符串来区别内核版本, 但是必须以" - "符号开始而且后面不包括任何空格.

保持耐心, 内核编译需要一定时间, 主要看你的内核配置和处理器速度.

7 安装新内核
在成功构建内核后, 你在/usr/src目录能发现两个.deb软件包.
cd /usr/src
ls -l

在我的测试系统上, 他们分别名为
linux-image-2.6.18.1-custom_2.6.18.1-custom-10.00.Custom_i386.deb
(包含了实际的内核) 和
linux-headers-2.6.18.1-custom_2.6.18.1-custom-10.00.Custom_i386.deb
(包含了需要的文件, 用于以后需要编译额外的内核模块). 我是这样安装的:
dpkg -i linux-image-2.6.18.1-custom_2.6.18.1-custom-10.00.Custom_i386.deb
dpkg -i linux-headers-2.6.18.1-custom_2.6.18.1-custom-10.00.Custom_i386.deb

(现在你甚至能够拷贝这两个.deb文件到其它的Ubuntu系统, 通过上面的方式安装. 你将不再需要编译内核.)

然后检查 /boot/grub/menu.lst文件, 现在你将能发现新内核使用的两个引导配置块:
vi /boot/grub/menu.lst

在我测试系统上已经添加好的引导配置块是这样的:
title Ubuntu, kernel 2.6.18.1-custom
root (hd0,0)
kernel /boot/vmlinuz-2.6.18.1-custom root=/dev/sda1 ro quiet splash
initrd /boot/initrd.img-2.6.18.1-custom
savedefault
boot

title Ubuntu, kernel 2.6.18.1-custom (recovery mode)
root (hd0,0)
kernel /boot/vmlinuz-2.6.18.1-custom root=/dev/sda1 ro single
initrd /boot/initrd.img-2.6.18.1-custom
boot

现在重启系统:
shutdown -r now

如果一切进展顺利, 你的新内核正常工作. 你还可以通过运行下面命令来检查新内核是否运行:
uname -r

这将会显示如:
2.6.18.1-custom

如果系统没有起来, 重启一下, 你会看到:

按ESC进入GRUB菜单:

选择你以前的内核启动系统, 现在你能再次尝试编译新的工作内核. 不要忘记从/boot/grub/menu.1st文件中移去不需要的引导内核信息.

阅读全文

与编写和编译内核的注意事项相关的资料

热点内容
华为程序员待遇 浏览:545
程序员带娃的图片 浏览:77
迷你云服务器怎么下载 浏览:813
福州溯源码即食燕窝 浏览:232
当乐服务器怎么样 浏览:713
nc编程软件下载 浏览:382
如何限制手机app的使用 浏览:307
安卓华为手机怎么恢复桌面图标 浏览:956
我的世界电脑版服务器地址在哪找 浏览:533
违抗了命令 浏览:256
安卓如何实现拖拽放置 浏览:91
净资产收益率选股指标源码 浏览:599
血压力传感器计算公式单片机 浏览:466
全网接口vip影视解析源码 浏览:916
如何破解服务器远程密码错误 浏览:377
平安深圳app如何实名认证 浏览:500
linux网络监控软件 浏览:889
内网服务器如何上传文件 浏览:140
程序员在你心中是什么 浏览:1
苹果手机怎么找回app账号 浏览:466