Linux内核Makefile

Linux内核Makefile
Linux内核Makefile

Linux内核2.6Makefile文件

===目录

===1概述

===2角色分工

===3内核编译文件

---3.1目标定义

---3.2内嵌对象-obj-y

---3.3可加载模块-obj-m

---3.4导出符号

---3.5库文件-lib-y

---3.6目录递归

---3.7编译标记

---3.8命令依赖

---3.9依赖关系

---3.10特殊规则

===4辅助程序

---4.1简单辅助程序

---4.2组合辅助程序

---4.3定义共享库

---4.4C++语言使用方法

---4.5辅助程序编译控制选项

---4.6何时建立辅助程序

---4.7使用hostprogs-$(CONFIG_FOO)

===1概述

Makefile包括五部分:

Makefile顶层Makefile文件

.config内核配置文件

arch/$(ARCH)/Makefile机器体系Makefile文件

scripts/Makefile.*所有内核Makefiles共用规则

kbuild Makefiles其它makefile文件

通过内核配置操作产生.config文件,顶层Makefile文件读取该文件的配置。顶层Makefile 文件负责产生两个主要的程序:vmlinux(内核image)和模块。顶层Makefile文件根据内核配置,通过递归编译内核代码树子目录建立这两个文件。顶层Makefile文件文本一个名为arch/$(ARCH)/Makefile的机器体系makefile文件。机器体系Makefile文件为顶层makefile 文件提供与机器相关的信息。每一个子目录有一个makefile文件,子目录makefile文件根据上级目录makefile文件命令启动编译。这些makefile使用.config文件配置数据构建各种文件列表,并使用这些文件列表编译内嵌或模块目标文件。scripts/Makefile.*包含了所有的定义和规则,与makefile文件一起编译出内核程序。

===2角色分工

人们与内核makefile存在四种不同的关系:

*用户*用户使用"make menuconfig"或"make"命令编译内核。他们通常不读或编辑内核makefile文件或其他源文件。

*普通开发者*普通开发者维护设备驱动程序、文件系统和网络协议代码,他们维护相关子系统的makefile文件,因此他们需要内核makefile文件整体性的一般知识和关于kbuild公共接口的详细知识。

*体系开发者*体系开发者关注一个整体的体系架构,比如sparc或者ia64。体系开发者既需要掌握关于体系的makefile文件,也要熟悉内核makefile文件。

*内核开发者*内核开发者关注内核编译系统本身。他们需要清楚内核makefile文件的所有方面。

本文档的读者对象是普通开发者和系统开发者。

===3内核编译文件

内核中大多数makefile文件是使用kbuild基础架构的makefile文件。本章介绍kbuild的makefile中的语法。

3.1节“目标定义”是一个快速导引,后面各章有详细介绍和实例。

---3.1目标定义

目标定义是makefile文件的主要部分(核心)。这些目标定义行定义了如何编译文件,特殊的兼容选项和递归子目录。

最简单的makefile文件只包含一行:

Example:obj-y+=foo.o

这行告诉kbuild在该目录下名为foo.o的目标文件(object),foo.o通过编译foo.c或者foo.S而得到。

如果foo.o编译成一个模块,则使用obj-m变量,因此常见写法如下:

Example:obj-$(CONFIG_FOO)+=foo.o

$(CONFIG_FOO)可以代表y(built-in对象)或m(module对象)。

如果CONFIG_FOO不是y或m,那么这个文件不会被编译和链接。

---3.2内嵌对象-obj-y

makefile文件将为编译vmlinux的目标文件放在$(obj-y)列表中,这些列表依赖于内核配置。

Kbuild编译所有的$(obj-y)文件,然后调用"$(LD)-r"合并这些文件到一个built-in.o文件中。built-in.o经过父makefile文件链接到vmlinux。$(obj-y)中的文件顺序很重要。列表中文件允许重复,文件第一次出现将被链接到built-in.o,后续出现该文件将被忽略。

链接顺序之所以重要是因为一些函数在内核引导时将按照他们出现的顺序被调用,如函数(module_init()/__initcall)。所以要牢记改变链接顺序意味着也要改变SCSI控制器的检测顺序和重数磁盘。

例如:#drivers/isdn/i4l/Makefile

#内核ISDN子系统和设备驱动程序Makefile

#每个配置项是一个文件列表

obj-$(CONFIG_ISDN)+=isdn.o

obj-$(CONFIG_ISDN_PPP_BSDCOMP)+=isdn_bsdcomp.o

---3.3可加载模块-obj-m

$(obj-m)表示对象文件(object files)编译成可加载的内核模块。

一个模块可以通过一个源文件或几个源文件编译而成。makefile只需简单地它们加到$(obj-m)。

例如:#drivers/isdn/i4l/Makefile

obj-$(CONFIG_ISDN_PPP_BSDCOMP)+=isdn_bsdcomp.o

注意:在这个例子中$(CONFIG_ISDN_PPP_BSDCOMP)含义是'm'。

如果内核模块通过几个源文件编译而成,使用以上同样的方法。

Kbuild需要知道通过哪些文件编译模块,因此需要设置一个$(-objs)变量。

例如:#drivers/isdn/i4l/Makefile

obj-$(CONFIG_ISDN)+=isdn.o

isdn-objs:=isdn_net_lib.o isdn_v110.o isdn_common.o

在这个例子中,模块名isdn.o.Kbuild首先编译$(isdn-objs)中的object文件,然后运行"$(LD)-r"将列表中文件生成isdn.o.

Kbuild使用后缀-objs、-y识别对象文件。这种方法允许makefile使用CONFIG_符号值确定一个object文件是否是另外一个object的组成部分。

例如:#fs/ext2/Makefile

obj-$(CONFIG_EXT2_FS)+=ext2.o

ext2-y:=balloc.o bitmap.o

ext2-$(CONFIG_EXT2_FS_XATTR)+=xattr.o

在这个例子中,如果$(CONFIG_EXT2_FS_XATTR)表示'y',则ext2.o只有xattr.o组成部分。

注意:当然,当你将对象文件编译到内核时,以上语法同样有效。因此,如果CONFIG_EXT2_FS=y,Kbuild将先编译ext2.o文件,然后链接到built-in.o。

---3.4导出符号目标

在makefile文件中没有特别导出符号的标记。

---3.5库文件-lib-y

obj-*中的object文件用于模块或built-in.o编译。object文件也可能编译到库文件中--lib.a。

所有罗列在lib-y中的object文件都将编译到该目录下的一个单一的库文件中。

包含在0bj-y中的object文件如果也列举在lib-y中将不会包含到库文件中,因为他们不能被访问。但lib-m中的object文件将被编译进lib.a库文件。

注意在相同的makefile中可以列举文件到buit-in内核中也可以作为库文件的一个组成部分。因此在同一个目录下既可以有built-in.o也可以有lib.a文件。

例如:#arch/i386/lib/Makefile

lib-y:=checksum.o delay.o

这样将基于checksum.o、delay.o创建一个lib.a文件。

对于内核编译来说,lib.a文件被包含在libs-y中。将“6.3目录表”。

lib-y通常被限制使用在lib/和arch/*/lib目录中。

---3.6目录递归

makefile文件负责编译当前目录下的目标文件,子目录中的文件由子目录中的makefile 文件负责编译。编译系统将使用obj-y和obj-m自动递归编译各个子目录中文件。

如果ext2是一个子目录,fs目录下的makefile将使用以下赋值语句是编译系统编译ext2子目录。

例如:#fs/Makefile

obj-$(CONFIG_EXT2_FS)+=ext2/

如果CONFIG_EXT2_FS设置成'y(built-in)或'm'(modular),则对应的obj-变量也要设置,内核编译系统将进入ext2目录编译文件。

内核编译系统只使用这些信息来决定是否需要编译这个目录,子目录中makefile文件规定那些文件编译为模块那些是内核内嵌对象。

当指定目录名时使用CONFIG_变量是一种良好的做法。如果CONFIG_选项不为'y'或'm',内核编译系统就会跳过这个目录。

---3.7编译标记

EXTRA_CFLAGS,EXTRA_AFLAGS,EXTRA_LDFLAGS,EXTRA_ARFLAGS

所有的EXTRA_变量只能使用在定义该变量后的makefile文件中。EXTRA_变量被makefile 文件所有的执行命令语句所使用。

$(EXTRA_CFLAGS)是使用$(CC)编译C文件的选项。

例如:#drivers/sound/emu10k1/Makefile

EXTRA_CFLAGS+=-I$(obj)

ifdef

DEBUG EXTRA_CFLAGS+=-DEMU10K1_DEBUG

endif

定义这个变量是必须的,因为顶层makefile定义了$(CFLAGS)变量并使用该变量编译整个代码树。

$(EXTRA_AFLAGS)是每个目录编译汇编语言源文件的选项。

例如:#arch/x86_64/kernel/Makefile

EXTRA_AFLAGS:=-traditional

$(EXTRA_LDFLAGS)和$(EXTRA_ARFLAGS)用于每个目录的$(LD)和$(AR)选项。

例如:#arch/m68k/fpsp040/Makefile

EXTRA_LDFLAGS:=-x

CFLAGS_$@,AFLAGS_$@

CFLAGS_$@和AFLAGS_$@只使用到当前makefile文件的命令中。

$(CFLAGS_$@)定义了使用$(CC)的每个文件的选项。$@部分代表该文件。

例如:#drivers/scsi/Makefile

CFLAGS_aha152x.o=-DAHA152X_STAT-DAUTOCONF

CFLAGS_gdth.o=#-DDEBUG_GDTH=2-D__SERIAL__-D__COM2__\

-DGDTH_STATISTICS CFLAGS_seagate.o=-DARBITRATE-DPARITY-DSEAGATE_USE_ASM

这三行定义了aha152x.o、gdth.o和seagate.o文件的编译选项。

$(AFLAGS_$@)使用在汇编语言代码文件中,具有同上相同的含义。

例如:#arch/arm/kernel/Makefile

AFLAGS_head-armv.o:=-DTEXTADDR=$(TEXTADDR)-traditional

AFLAGS_head-armo.o:=-DTEXTADDR=$(TEXTADDR)-traditional

---3.9依赖关系

内核编译记录如下依赖关系:

1)所有的前提文件(both*.c and*.h)

2)CONFIG_选项影响到的所有文件

3)编译目标文件使用的命令行

因此,假如改变$(CC)的一个选项,所有相关的文件都要重新编译。

---3.10特殊规则

特殊规则使用在内核编译需要规则定义而没有相应定义的时候。典型的例子如编译时头文件的产生规则。其他例子有体系makefile编译引导映像的特殊规则。特殊规则写法同普通的Make规则。

Kbuild(应该是编译程序)在makefile所在的目录不能被执行,因此所有的特殊规则需要提供前提文件和目标文件的相对路径。

定义特殊规则时将使用到两个变量:

$(src):$(src)是对于makefile文件目录的相对路径,当使用代码树中的文件时使用该变量$(src)。

$(obj):$(obj)是目标文件目录的相对路径。生成文件使用$(obj)变量。

例如:#drivers/scsi/Makefile

$(obj)/53c8xx_d.h:$(src)/53c7,8xx.scr$(src)/script_asm.pl

$(CPP)-DCHIP=810-<$<|...$(src)/script_asm.pl

这就是使用普通语法的特殊编译规则。

目标文件依赖于两个前提文件。目标文件的前缀是$(obj),前提文件的前缀是$(src)(因为它们不是生成文件)。

===4辅助程序

内核编译系统支持在编译(compliation)阶段编译主机可执行程序。为了使用主机程序需要两个步骤:第一个步骤使用hostprogs-y变量告诉内核编译系统有主机程序可用。第二步给主机程序添加潜在的依赖关系。有两种方法,在规则中增加依赖关系或使用$(always)变量。具体描述如下。

---4.1简单辅助程序

在一些情况下需要在主机上编译和运行主机程序。下面这行告诉kbuild在主机上建立bin2hex程序。

例如:hostprogs-y:=bin2hex

Kbuild假定使用makefile相同目录下的单一C代码文件bin2hex.c编译bin2hex。

---4.2组合辅助程序

主机程序也可以由多个object文件组成。定义组合辅助程序的语法同内核对象的定义方法。

$(-objs)包含了所有的用于链接最终可执行程序的对象。

例如:#scripts/lxdialog/Makefile

hostprogs-y:=lxdialog

lxdialog-objs:=checklist.o lxdialog.o

扩展名.o文件都编译自对应的.c文件。在上面的例子中checklist.c编译成checklist.o,lxdialog.c编译为lxdialog.o。最后两个.o文件链接成可执行文件lxdialog。

注意:语法-y不能用于定义主机程序。

---4.3定义共享库

扩展名为.so的对象是共享库文件,并且是位置无关的object文件。内核编译系统提供共享库使用支持,但使用方法有限制。在下面例子中libkconfig.so库文件被链接到可执行文件conf中。

例如:#scripts/kconfig/Makefile

hostprogs-y:=conf

conf-objs:=conf.o libkconfig.so

libkconfig-objs:=expr.o type.o

共享库文件需要对应的-objs定义,在上面例子中库libkconfig由两个对象组成:expr.o 和type.o。expr.o和type.o将被编译为位置无关代码并被链接如libkconfig.so。共享库不支持C++语言。

---4.4C++语言使用方法

内核编译系统提供了对C++主机程序的支持以用于内核配置,但不主张其它方面使用这种方法。

例如:#scripts/kconfig/Makefile

hostprogs-y:=qconf

qconf-cxxobjs:=qconf.o

在上面例子中可执行文件由C++文件https://www.360docs.net/doc/c13834639.html,组成-通过$(qconf-cxxobjs)标识。

如果qconf由.c和.cc文件混合组成,附加行表示这种情况。

例如:#scripts/kconfig/Makefile

hostprogs-y:=qconf

qconf-cxxobjs:=qconf.o

qconf-objs:=check.o

---4.5辅助程序编译控制选项

当编译主机程序时仍然可以使用$(HOSTCFLAGS)设置编译选项传递给$(HOSTCC)。这些选项将影响所有使用变量HOST_EXTRACFLAG的makefile创建的主机程序。

例如:#scripts/lxdialog/Makefile

HOST_EXTRACFLAGS+=-I/usr/include/ncurses

为单个文件设置选项使用下面方式:

例如:#arch/ppc64/boot/Makefile

HOSTCFLAGS_piggyback.o:=-DKERNELBASE=$(KERNELBASE)

也可以使用附加链接选项:

例如:#scripts/kconfig/Makefile

HOSTLOADLIBES_qconf:=-L$(QTDIR)/lib

当链接qconf时将使用外部选项"-L$(QTDIR)/lib"。

---4.6何时建立辅助程序

只有当需要时内核编译系统才会编译主机程序。有两种方式:

(1)在特殊规则中作为隐式的前提需求

例如:#drivers/pci/Makefile

hostprogs-y:=gen-devlist

$(obj)/devlist.h:$(src)/pci.ids$(obj)/gen-devlist

(cd$(obj);./gen-devlist)<$<

编译目标文件$(obj)/devlist.h需要先建立$(obj)/gen-devlist。注意在特殊规则中使用主机程序必须加前缀$(obj)。

(2)使用$(always)

当没有合适的特殊规则可以使用,并且在进入makefile文件时就要建立主机程序,可以使用变量$(always)。

例如:#scripts/lxdialog/Makefile

hostprogs-y:=lxdialog

always:=$(hostprogs-y)

这样就告诉内核编译系统即使没有任何规则使用lxdialog也要编译它。

---4.7使用hostprogs-$(CONFIG_FOO)

在Kbuild文件中典型模式如下:

例如:#scripts/Makefile

hostprogs-$(CONFIG_KALLSYMS)+=kallsyms

对Kbuild来说'y'用于内嵌对象'm'用于模块。

因此如果config符号是'm',编译系统也将创建该程序。换句话说内核编译系统等同看待hostprogs-m和hostprogs-y。但如果不涉及到CONFIG符号仅建议使用hostprogs-y。

接上文“Linux内核2.6Makefile文件(一)”

===目录

===5编译清除机制

===6体系Makefile文件

---6.1变量设置

---6.2增加预设置项

---6.3目录表

---6.4引导映像

---6.5编译非内核目标

---6.6编译引导映像命令

---6.7定制编译命令

---6.8预处理连接脚本

---6.9$(CC)支持功能

===7Kbuild变量

===8Makefile语言

===9Credits

===10TODO

===5编译清除机制

"make clean"命令删除在编译内核生成的大部分文件,例如主机程序,列举在$(hostprogs-y)、$(hostprogs-m)、$(always)、$(extra-y)和$(targets)中目标文件都将被删除。代码目录数中的"*.[oas]"、"*.ko"文件和一些由编译系统产生的附加文件也将被删除。

附加文件可以使用$(clean-files)进行定义。

例如:#drivers/pci/Makefile

clean-files:=devlist.h classlist.h

当执行"make clean"命令时,"devlist.h classlist.h"两个文件将被删除。内核编译系统默认这些文件与makefile具有相同的相对路径,否则需要设置以'/'开头的绝对路径。

删除整个目录使用以下方式:

例如:#scripts/package/Makefile

clean-dirs:=$(objtree)/debian/

这样就将删除包括子目录在内的整个debian目录。如果不使用以'/'开头的绝对路径内核编译系统见默认使用相对路径。

通常内核编译系统根据"obj-*:=dir/"进入子目录,但是在体系makefile中需要显式使用如下方式:

例如:#arch/i386/boot/Makefile

subdir-:=compressed/

上面赋值语句指示编译系统执行"make clean"命令时进入compressed/目录。

在编译最终的引导映像文件的makefile中有一个可选的目标对象名称是archclean。

例如:#arch/i386/Makefile

archclean:

$(Q)$(MAKE)$(clean)=arch/i386/boot

当执行"make clean"时编译器进入arch/i386/boot并象通常一样工作。arch/i386/boot中的makefile文件可以使用subdir-标识进入更下层的目录。

注意1:arch/$(ARCH)/Makefile不能使用"subdir-",因为它被包含在顶层makefile文件中,在这个位置编译机制是不起作用的。

注意2:所有列举在core-y、libs-y、drivers-y和net-y中的目录将被"make clean"命令清除。

===6体系Makefile文件

在开始进入各个目录编译之前,顶层makefile文件设置编译环境和做些准备工作。顶层makefile文件包含通用部分,arch/$(ARCH)/Makefile包含该体系架构所需的设置。因此arch/$(ARCH)/Makefile会设置一些变量和少量的目标。

当编译时将按照以下大概步骤执行:

1)配置内核=>产生.config文件

2)保存内核版本到include/linux/version.h文件中

3)符号链接include/asm to include/asm-$(ARCH)

4)更新所有目标对象的其它前提文件

-附加前提文件定义在arch/$(ARCH)/Makefile文件中

5)递归进入init-*core*drivers-*net-*libs-*中的所有子目录和编译所有的目标对象

-上面变量值都引用到arch/$(ARCH)/Makefile文件。

6)链接所有的object文件生成vmlinux文件,vmlinux文件放在代码树根目录下。

最开始链接的几个object文件列举在arch/$(ARCH)/Makefile文件的head-y变量中。

7)最后体系makefile文件定义编译后期处理规则和建立最终的引导映像bootimage。

-包括创建引导记录

-准备initrd映像和相关处理

---6.1变量设置

LDFLAGS$(LD)一般选项

选项使用于链接器的所有调用中。通常定义emulation就可以了。

例如:#arch/s390/Makefile

LDFLAGS:=-m elf_s390

注意:EXTRA_LDFLAGS和LDFLAGS_$@可以进一步订制使用选项,将第7章。LDFLAGS_MODULE$(LD)链接模块的选项

LDFLAGS_MODULE通常设置$(LD)链接模块的.ko选项。

默认为"-r"即可重定位输出文件。

LDFLAGS_vmlinux$(LD)链接vmlinux选项

LDFLAGS_vmlinux定义链接最终vmlinux时链接器的选项。

LDFLAGS_vmlinux支持使用LDFLAGS_$@。

例如:#arch/i386/Makefile

LDFLAGS_vmlinux:=-e stext

OBJCOPYFLAGS objcopy选项

当使用$(call if_changed,objcopy)转化a.o文件时,OBJCOPYFLAGS中的选项将被使用。

$(call if_changed,objcopy)经常被用作为vmlinux产生原始的二进制文件。

例如:#arch/s390/Makefile

OBJCOPYFLAGS:=-O binary

#arch/s390/boot/Makefile

$(obj)/image:vmlinux FORCE$(call if_changed,objcopy)

在上面例子中$(obj)/image是vmlinux的二进制版本文件。$(call if_changed,xxx)

的使用方法见后。

AFLAGS$(AS)汇编选项

默认值见顶层Makefile文件

针对每个体系需要另外添加和修改它。

例如:#arch/sparc64/Makefile

AFLAGS+=-m64-mcpu=ultrasparc

CFLAGS$(CC)编译器选项

默认值见顶层Makefile文件

针对每个体系需要另外添加和修改它。

通常CFLAGS变量值取决于内核配置。

例如:#arch/i386/Makefile

cflags-$(CONFIG_M386)+=-march=i386

CFLAGS+=$(cflags-y)

许多体系Makefiles文件动态启动市场目标机器上的C编译器检测支持的选项:#arch/i386/Makefile

...

cflags-$(CONFIG_MPENTIUMII)+=$(call cc-option,\

-march=pentium2,-march=i686)...

#Disable unit-at-a-time mode...

CFLAGS+=$(call cc-option,-fno-unit-at-a-time)

...

第一个例子当config选项是'y'时将被选中。

CFLAGS_KERNEL$(CC)编译built-in对象的选项

$(CFLAGS_KERNEL)包含外部C编译器选项编译本地内核代码。

CFLAGS_MODULE$(CC)编译模块选项

$(CFLAGS_MODULE)包含外部C编译器选项编译可加载内核代码。

---6.2增加预设置项

prepare:这个规则用于列举开始进入子目录编译前需要的前提文件。通常是些包含汇编常量的头文件。

例如:

#arch/s390/Makefile

prepare:include/asm-$(ARCH)/offsets.h

在这个例子中include/asm-$(ARCH)/offsets.h将在进入子目录前编译。

详见XXX-TODO文件描述了kbuild如何产生offset头文件。

---6.3目录表

体系makefile文件和顶层makefile文件共同定义了如何建立vmlinux文件的变量。注意没有体系相关的模块对象定义部分:所有的模块对象都是体系无关的。

head-y,init-y,core-y,libs-y,drivers-y,net-y

$(head-y)列举首先链接到vmlinux的对象文件。

$(libs-y)列举了能够找到lib.a文件的目录。

其余的变量列举了能够找到内嵌对象文件的目录。

$(init-y)列举的对象位于$(head-y)对象之后。

然后是如下位置秩序:

$(core-y),$(libs-y),$(drivers-y)和$(net-y)。

顶层makefile定义了所有同用目录,arch/$(ARCH)/Makefile文件只需增加体系相关的目录。

例如:#arch/sparc64/Makefile

core-y+=arch/sparc64/kernel/

libs-y+=arch/sparc64/prom/arch/sparc64/lib/

drivers-$(CONFIG_OPROFILE)+=arch/sparc64/oprofile/

---6.4引导映像

体系makefile文件定义了编译vmlinux文件的目标对象,将它们压缩和封装成引导代码,并复制到合适的位置。这包括各种安装命令。如何定义实际的目标对象无法为所有的体系结构提供标准化的方法。

附加处理过程常位于arch/$(ARCH)/下的boot/目录。

内核编译系统无法在boot/目录下提供一种便捷的方法创建目标系统文件。因此arch/$(ARCH)/Makefile要调用make命令在boot/目录下建立目标系统文件。建议使用的方

法是在arch/$(ARCH)/Makefile中设置调用,并且使用完整路径引用arch/$ (ARCH)/boot/Makefile。

例如:#arch/i386/Makefile

boot:=arch/i386/boot

bzImage:vmlinux

$(Q)$(MAKE)$(build)=$(boot)$(boot)/$@

建议使用"$(Q)$(MAKE)$(build)=

"方式在子目录中调用make命令。

没有定义体系目标系统文件的规则,但执行"make help"命令要列出所有目标系统文件,因此必须定义$(archhelp)变量。

例如:#arch/i386/Makefile

define

archhelp echo'*bzImage-Image(arch/$(ARCH)/boot/bzImage)'

endef

当执行不带参数的make命令时,将首先编译第一个目标对象。在顶层makefile中第一个目标对象是all:。

一个体系结构需要定义一个默认的可引导映像。

"make help"命令的默认目标是以*开头的对象。

增加新的前提文件给all目标可以设置不同于vmlinux的默认目标对象。

例如:#arch/i386/Makefile

all:bzImage

当执行不带参数的"make"命令时,bzImage文件将被编译。

---6.5编译非内核目标

extra-y

extra-y定义了在当前目录下创建没有在obj-*定义的附加的目标文件。

在extra-y中列举目标是处于两个目的:

1)是内核编译系统在命令行中检查变动情况

-当使用$(call if_changed,xxx)时

2)内核编译系统知道执行"make clean"命令时删除哪些文件

例如:#arch/i386/kernel/Makefile

extra-y:=head.o init_task.o

上面例子extra-y中的对象文件将被编译但不会练接到built-in.o中。

---6.6编译引导映像命令

Kbuild提供了一些编译引导映像有用的宏。

if_changed

if_changed是后面命令使用的基础。

用法:

target:source(s)

FORCE$(call if_changed,ld/objcopy/gzip)

当这条规则被使用时它将检查哪些文件需要更新,或命令行被改变。后面这种情况将迫使重新编译编译选项被改变的执行文件。使用if_changed的目标对象必须列举在$(targets)中,否则命令行检查将失败,目标一直会编译。

赋值给$(targets)的对象没有$(obj)/前缀。

if_changed也可以和定制命令配合使用,见6.7"kbuild定制命令"。

注意:一个常见错误是忘记了FORCE前导词。

ld

链接目标。常使用LDFLAGS_$@作为ld的选项。

objcopy

复制二进制文件。常用于arch/$(ARCH)/Makefile中和使用OBJCOPYFLAGS作为选项。

也可以用OBJCOPYFLAGS_$@设置附加选项。

gzip

压缩目标文件。使用最大压缩算法压缩目标文件。

例如:#arch/i386/boot/Makefile

LDFLAGS_bootsect:=-Ttext0x0-s--oformat binary

LDFLAGS_setup:=-Ttext0x0-s--oformat binary-e begtext

targets+=setup setup.o bootsect bootsect.o

$(obj)/setup$(obj)/bootsect:%:%.o FORCE

$(call if_changed,ld)

在上面例子中有两个可能的目标对象,分别需要不同的链接选项。使用LDFLAGS_$@语法为每个目标对象设置不同的链接选项。

$(targets)包含所有的目标对象,因此内核编译系统知道所有的目标对象并且将:

1)检查命令行的改变情况

2)执行make clean命令时删除目标对象

":%:%.o"是简写方法,减写setup.o和bootsect.o文件。

注意:常犯错误是忘记"target:="语句,导致没有明显的原因目标文件被重新编译。

---6.7定制编译命令

当执行带KBUILD_VERBOSE=0参数的编译命令时命令的简短信息会被显示。要让定制命令具有这种功能需要设置两个变量:

quiet_cmd_-将被显示的内容

cmd_-被执行的命令

例如:#

quiet_cmd_image=BUILD$@

cmd_image=$(obj)/tools/build$(BUILDFLAGS)\

$(obj)/vmlinux.bin>$@

targets+=bzImage

$(obj)/bzImage:$(obj)/vmlinux.bin$(obj)/tools/build FORCE

$(call if_changed,image)

@echo'Kernel:$@is ready'

执行"make KBUILD_VERBOSE=0"命令编译$(obj)/bzImage目标时将显示:

BUILD arch/i386/boot/bzImage

---6.8预处理连接脚本

当编译vmlinux映像时将使用arch/$(ARCH)/kernel/vmlinux.lds链接脚本。

相同目录下的vmlinux.lds.S文件是这个脚本的预处理的变体。内核编译系统知晓.lds

文件并使用规则*lds.S->*lds。

例如:#arch/i386/kernel/Makefile

always:=vmlinux.lds

#Makefile

export CPPFLAGS_vmlinux.lds+=-P-C-U$(ARCH)

$(always)赋值语句告诉编译系统编译目标是vmlinux.lds。$(CPPFLAGS_vmlinux.lds)赋值语句告诉编译系统编译vmlinux.lds目标的编译选项。

编译*.lds时将使用到下面这些变量:

CPPFLAGS:定义在顶层Makefile

EXTRA_CPPFLAGS:可以设置在编译的makefile文件中

CPPFLAGS_$(@F):目标编译选项。注意要使用文件全名。

---6.9$(CC)支持功能

内核可能会用不同版本的$(CC)进行编译,每个版本有不同的性能和选项,内核编译系统提供基本的支持用于验证$(CC)选项。$(CC)通常是gcc编译器,但其它编译器也是可以。cc-option cc-option用于检测$(CC)是否支持给定的选项,如果不支持就使用第二个可选项。

例如:#arch/i386/Makefile

cflags-y+=$(call cc-option,-march=pentium-mmx,-march=i586)

在上面例子中如果$(CC)支持-march=pentium-mmx则cflags-y等于该值,否则等于-march-i586。如果没有第二个可选项且第一项不支持则cflags-y没有被赋值。

cc-option-yn cc-option-yn用于检测gcc是否支持给定的选项,支持返回'y'否则'n'。

例如:#arch/ppc/Makefile

biarch:=$(call cc-option-yn,-m32)

aflags-$(biarch)+=-a32

cflags-$(biarch)+=-m32

在上面例子中如果$(CC)支持-m32选项则$(biarch)设置为y。当$(biarch)等于y时,变量$(aflags-y)和$(cflags-y)将分别等于-a32和-m32。

cc-option-align gcc版本>=3.0用于定义functions、loops等边界对齐选项。

gcc<3.00

cc-option-align=-malign

gcc>=3.00

cc-option-align=-falign

例如:

CFLAGS+=$(cc-option-align)-functions=4

在上面例子中对于gcc>=3.00来说-falign-functions=4,gcc<3.00版本使用-malign-functions=4。

cc-version cc-version返回$(CC)编译器数字版本号。

版本格式是,均为两位数字。例如gcc3.41将返回0341。

当一个特定$(CC)版本在某个方面有缺陷时cc-version是很有用的。例如-mregparm=3在一些gcc版本会失败尽管gcc接受这个选项。

例如:#arch/i386/Makefile

GCC_VERSION:=$(call cc-version)

cflags-y+=$(shell\

if[$(GCC_VERSION)-ge0300];then echo"-mregparm=3";fi;)

在上面例子中-mregparm=3只使用在版本大于等于3.0的gcc中。

===7Kbuild变量

顶层Makefile文件导出下面这些变量:

VERSION,PATCHLEVEL,SUBLEVEL,EXTRAVERSION

这几个变量定义了当前内核版本号。很少体系体系Makefiles文件直接使用他们,常用$(KERNELRELEASE)代替。

$(VERSION)、$(PATCHLEVEL)和$(SUBLEVEL)定义了三个基本部分版本号,例如"2", "4",和"0"。这三个变量一直使用数值表示。

$(EXTRAVERSION)定义了更细的补钉号,通常是短横跟一些非数值字符串,例如"-pre4"。

KERNELRELEASE

$(KERNELRELEASE)是一个单一字符如"2.4.0-pre4",适合用于构造安装目录和显示版本字符串。一些体系文件使用它用于以上目的。

ARCH

这个变量定义了目标系统体系结构,例如"i386"、“arm"、"sparc".一些内核编译文件测试$(ARCH)用于确定编译哪个文件。默认情况下顶层Makefile文件设置$(ARCH)为主机相同的系统体系。当交叉编译编译时,用户可以使用命令行改变$(ARCH)值:

make ARCH=m68k...

INSTALL_PATH

这个变量定义了体系Makefiles文件安装内核映项和System.map文件的路径。INSTALL_MOD_PATH,MODLIB

$(INSTALL_MOD_PATH)定义了模块安装变量$(MODLIB)的前缀。这个变量通常不在Makefile文件中定义,如果需要可以由用户添加。

$(MODLIB)定义了模块安装目录。

顶层Makefile定义$(MODLIB)为$(INSTALL_MOD_PATH)/lib/modules/$(KERNELRELEASE)。用户可以使用命令行修改这个值。

===8Makefile语言

内核Makefiles设计目标用于运行GNU Make程序。Makefiles仅使用GNU Make提到的特性,但使用了较多的GNU扩展部分。

GNU Make程序支持基本的列表处理功能。内核Makefiles文件结合"if"语句使用了简单的列表建立和维护功能。

GNU Make程序有两种赋值操作符:":="和"="。":="执行时立即计算右值并赋值给左值。"="类似公式定义,当每次使用左值要被使用时计算右值并赋给它。

一些情况中使用"="合适,而一些情况中使用":="才是正确选择。

===9Credits

Original version made by Michael Elizabeth Chastain,Updates

by Kai GermaschewskiUpdates by Sam Ravnborg

===10TODO

-Describe how kbuild support shipped files with_shipped.

-Generating offset header files.

-Add more variables to section7?===5编译清除机制

===6体系Makefile文件

---6.1变量设置

---6.2增加预设置项

---6.3目录表

---6.4引导映像

---6.5编译非内核目标

---6.6编译引导映像命令

---6.7定制编译命令

---6.8预处理连接脚本

---6.9$(CC)支持功能

===7Kbuild变量

===8Makefile语言

===9Credits

===10TODO

Linux内核Makefile浅析

1.配置系统的基本结构

Linux内核的配置系统由三个部分组成,分别是:

1.Makefile:分布在Linux内核源代码中的Makefile,定义Linux内核的编译规则;

2.配置文件(config.in):给用户提供配置选择的功能;

3.

配置工具:包括配置命令解释器(对配置脚本中使用的配置命令进行解释)和配置用户界面(提供基于字符界面、基于Ncurses图形界面以及基于

Xwindows图形界面的用户配置界面,各自对应于Make config、Make menuconfig和make xconfig)。

这些配置工具都是使用脚本语言,如Tcl/TK、Perl编写的(也包含一些用C

编写的代码)。本文并不是对配置系统本身进行分析,而是介绍如何使用配置系统。所以,除非是配置系统的维护者,一般的内核开发者无须了解它们的原理,只需

要知道如何编写Makefile和配置文件就可以。所以,在本文中,我们只对Makefile和配置文件进行讨论。另外,凡是涉及到与具体

CPU体系结构相关的内容,我们都以ARM为例,这样不仅可以将讨论的问题明确化,而且对内容本身不产生影响。

2.Makefile

2.1Makefile概述

Makefile的作用是根据配置的情况,构造出需要编译的源文件列表,然后分别编译,并把

目标代码链接到一起,最终形成Linux内核二进制文件。

由于Linux内核源代码是按照树形结构组织的,所以Makefile也被分布在目录树中。Linux 内核中的Makefile以及与Makefile直接相关的文件有:

1.Makefile:顶层Makefile,是整个内核配置、编译的总体控制文件。

2..config:内核配置文件,包含由用户选择的配置选项,用来存放内核配置后的结果(如make config)。

3.arch/*/Makefile:位于各种CPU体系目录下的Makefile,如arch/arm/Makefile,是针对特定平台的Makefile。

4.各个子目录下的Makefile:比如drivers/Makefile,负责所在子目录下源代码的管理。

5.Rules.make:规则文件,被所有的Makefile使用。

户通过make config配置后,产生了.config。顶层Makefile读入.config中的配置选择。顶层

Makefile有两个主要的任务:产生vmlinux文件和内核模块(module)。为了达到此目的,顶层Makefile

递归的进入到内核的各个子目录中,分别调用位于这些子目录中的Makefile。至于到底进入哪些子目录,取决于内核的配置。在顶层

Makefile中,有一句:include arch/$(ARCH)/Makefile,包含了特定CPU体系结构下的Makefile,这个Makefile中包含了平台相关的信息。

位于各个子目录下的Makefile同样也根据.config给出的配置信息,构造出当前配置下需要的源文件列表,并在文件的最后有include$(TOPDIR)/Rules.make。

Rules.make文件起着非常重要的作用,它定义了所有Makefile共用的编译规则。比如,如果需要将本目录下所有的c程序编译成汇编代码,需要在Makefile中有以下的编译规则:%.s:%.c

$(CC)$(CFLAGS)-S$<-o$@

很多子目录下都有同样的要求,就需要在各自的Makefile中包含此编译规则,这会比较麻烦。而Linux

内核中则把此类的编译规则统一放置到Rules.make中,并在各自的Makefile中包含进了Rules.make(include

Rules.make),这样就避免了在多个Makefile中重复同样的规则。对于上面的例子,在Rules.make中对应的规则为:

%.s:%.c

$(CC)$(CFLAGS)$(EXTRA_CFLAGS)$(CFLAGS_$(*F))$(CFLAGS_$@)-S$<-o$@

2.2Makefile中的变量

顶层Makefile定义并向环境中输出了许多变量,为各个子目录下的Makefile传递一些信息。有些变量,比如SUBDIRS,不仅在顶层Makefile中定义并且赋初值,而且在arch/*/Makefile还作了扩充。

常用的变量有以下几类:

1)版本信息

本信息有:VERSION,PATCHLEVEL,SUBLEVEL,

EXTRAVERSION,KERNELRELEASE。版本信息定义了当前内核的版本,比如VERSION=2,PATCHLEVEL=4,SUBLEVEL=18,EXATAVERSION=-rmk7,它们共同构成

内核的发行版本

KERNELRELEASE:2.4.18-rmk7

2)CPU体系结构:ARCH

在顶层Makefile的开头,用ARCH定义目标CPU的体系结构,比如ARCH:=arm等。许多子目录的Makefile中,要根据ARCH的定义选择编译源文件的列表。

3)路径信息:TOPDIR,SUBDIRS

TOPDIR定义了Linux内核源代码所在的根目录。例如,各个子目录下的Makefile通过$(TOPDIR)/Rules.make就可以找到Rules.make的位置。

SUBDIRS

定义了一个目录列表,在编译内核或模块时,顶层Makefile就是根据SUBDIRS来决定进入哪些子目录。SUBDIRS

的值取决于内核的配置,在顶层Makefile中SUBDIRS赋值为kernel drivers mm fs net ipc lib;根据内核的配置情况,在arch/*/Makefile中扩充了SUBDIRS的值,参见4)中的例子。

4)内核组成信息:HEAD,CORE_FILES,NETWORKS,DRIVERS,LIBS

Linux内核文件vmlinux是由以下规则产生的:

vmlinux:$(CONFIGURATION)init/main.o init/version.o linuxsubdirs

$(LD)$(LINKFLAGS)$(HEAD)init/main.o init/version.o

--start-group

$(CORE_FILES)

$(DRIVERS)

$(NETWORKS)

$(LIBS)

--end-group

-o vmlinux

以看出,vmlinux是由HEAD、main.o、version.o、CORE_FILES、DRIVERS、NETWORKS 和LIBS

组成的。这些变量(如HEAD)都是用来定义连接生成vmlinux的目标文件和库文件列表。其中,HEAD在arch/*/Makefile

中定义,用来确定被最先链接进vmlinux的文件列表。比如,对于ARM系列的CPU,HEAD定义为:

HEAD:=arch/arm/kernel/head-$(PROCESSOR).o

arch/arm/kernel/init_task.o

明head-$(PROCESSOR).o和init_task.o需要最先被链接到vmlinux中。PROCESSOR为armv

或armo,取决于目标CPU。CORE_FILES,NETWORK,DRIVERS和LIBS在顶层Makefile

中定义,并且由arch/*/Makefile根据需要进行扩充。CORE_FILES对应着内核的核心文件,有

kernel/kernel.o,mm/mm.o,fs/fs.o,ipc/ipc.o,可以看出,这些是组成内核最为重要的文件。同时,

arch/arm/Makefile对CORE_FILES进行了扩充:

#arch/arm/Makefile

#If we have a machine-specific directory,then include it in the build.

MACHDIR:=arch/arm/mach-$(MACHINE)

ifeq($(MACHDIR),$(wildcard$(MACHDIR)))

SUBDIRS+=$(MACHDIR)

CORE_FILES:=$(MACHDIR)/$(MACHINE).o$(CORE_FILES)

endif

HEAD:=arch/arm/kernel/head-$(PROCESSOR).o

arch/arm/kernel/init_task.o

SUBDIRS+=arch/arm/kernel arch/arm/mm arch/arm/lib arch/arm/nwfpe

CORE_FILES:=arch/arm/kernel/kernel.o arch/arm/mm/mm.o$(CORE_FILES)

LIBS:=arch/arm/lib/lib.a$(LIBS)

5)编译信息:CPP,CC,AS,LD,AR,CFLAGS,LINKFLAGS

在Rules.make中定义的是编译的通用规则,具体到特定的场合,需要明确给出编译环境,编译环境就是在以上的变量中定义的。针对交叉编译的要求,定义了CROSS_COMPILE。比如:

CROSS_COMPILE=arm-linux-

CC=$(CROSS_COMPILE)gcc

LD=$(CROSS_COMPILE)ld

......

CROSS_COMPILE

定义了交叉编译器前缀arm-linux-,表明所有的交叉编译工具都是以arm-linux-开头的,所以在各个交叉编译器工具之前,都加入了

$(CROSS_COMPILE),以组成一个完整的交叉编译工具文件名,比如arm-linux-gcc。CFLAGS定义了传递给C编译器的参数。

LINKFLAGS是链接生成vmlinux时,由链接器使用的参数。LINKFLAGS在arm/*/Makefile中定义,比如:

#arch/arm/Makefile

LINKFLAGS:=-p-X-T arch/arm/vmlinux.lds

6)配置变量CONFIG_*

.config文件中有许多的配置变量等式,用来说明用户配置的结果。例如CONFIG_MODULES=y表明用户选择了Linux内核的模块功能。

.config

被顶层Makefile包含后,就形成许多的配置变量,每个配置变量具有确定的值:y表示本编译选项对应的内核代码被静态编译进Linux

内核;m表示本编译选项对应的内核代码被编译成模块;n表示不选择此编译选项;如果根本就没有选择,那么配置变量的值为空。

2.3Rules.make变量

前面讲过,Rules.make是编译规则文件,所有的Makefile中都会包括Rules.make。Rules.make文件定义了许多变量,最为重要是那些编译、链接列表变量。

O_OBJS,L_OBJS,OX_OBJS,LX_OBJS:本目录下需要编译进Linux内核vmlinux的目标文件列表,其中OX_OBJS和LX_OBJS中的"X"表明目标文件使用了EXPORT_SYMBOL输出符号。

M_OBJS,MX_OBJS:本目录下需要被编译成可装载模块的目标文件列表。同样,MX_OBJS

中的"X"表明目标文件使用了EXPORT_SYMBOL输出符号。

O_TARGET,

L_TARGET:每个子目录下都有一个O_TARGET或L_TARGET,Rules.make首先从源代码编译生成O_OBJS和

OX_OBJS中所有的目标文件,然后使用$(LD)-r把它们链接成一个O_TARGET或L_TARGET。O_TARGET以

.o结尾,而L_TARGET以.a结尾。

2.4子目录Makefile

子目录Makefile用来控制本级目录以下源代码的编译规则。我们通过一个例子来讲解子目录Makefile的组成:

#

#Makefile for the linux kernel.

#

#All of the(potential)objects that export symbols.

#This list comes from'grep-l EXPORT_SYMBOL*.[hc]'.

export-objs:=tc.o

#Object file lists.

obj-y:=

obj-m:=

obj-n:=

obj-:=

obj-$(CONFIG_TC)+=tc.o

obj-$(CONFIG_ZS)+=zs.o

obj-$(CONFIG_VT)+=lk201.o lk201-map.o lk201-remap.o

#Files that are both resident and modular:remove from modular.

obj-m:=$(filter-out$(obj-y),$(obj-m))

#Translate to Rules.make lists.

L_TARGET:=tc.a

L_OBJS:=$(sort$(filter-out$(export-objs),$(obj-y)))

LX_OBJS:=$(sort$(filter$(export-objs),$(obj-y)))

M_OBJS:=$(sort$(filter-out$(export-objs),$(obj-m)))

MX_OBJS:=$(sort$(filter$(export-objs),$(obj-m)))

include$(TOPDIR)/Rules.make

a)注释

对Makefile的说明和解释,由#开始。

b)编译目标定义

似于obj-$(CONFIG_TC)+=tc.o的语句是用来定义编译的目标,是子目录Makefile

中最重要的部分。编译目标定义那些在本子目录下,需要编译到Linux

内核中的目标文件列表。为了只在用户选择了此功能后才编译,所有的目标定义都融合了对配置变量的判断。

前面说过,每个配置变量取值范围是:

y,n,m和空,obj-$(CONFIG_TC)分别对应着obj-y,obj-n,obj-m,obj-。如果CONFIG_TC 配置为

y,那么tc.o就进入了obj-y列表。obj-y为包含到Linux内核vmlinux中的目标文件列表;obj-m

为编译成模块的目标文件列表;obj-n和obj-中的文件列表被忽略。配置系统就根据这些列表的属性进行编译和链接。

export-objs中的目标文件都使用了EXPORT_SYMBOL()定义了公共的符号,以便可装载模块使用。在tc.c文件的最后部分,有"EXPORT_SYMBOL(search_tc_card);",表明tc.o有符号输出。

里需要指出的是,对于编译目标的定义,存在着两种格式,分别是老式定义和新式定义。老式定义就是前面Rules.make

使用的那些变量,新式定义就是obj-y,obj-m,obj-n和obj-。Linux内核推荐使用新式定义,不过由于

Rules.make不理解新式定义,需要在Makefile中的适配段将其转换成老式定义。

c)适配段

适配段的作用是将新式定义转换成老式定义。在上面的例子中,适配段就是将obj-y和obj-m转换成Rules.make能够理解的L_TARGET,L_OBJS,LX_OBJS,M_OBJS,MX_OBJS。L_OBJS

:=$(sort$(filter-out$(export-objs),$(obj-y)))定义了L_OBJS的生成方式:在

obj-y的列表中过滤掉export-objs(tc.o),然后排序并去除重复的文件名。这里使用到了GNU Make

的一些特殊功能,具体的含义可参考Make的文档(info make)。

d)include$(TOPDIR)/Rules.make

3.配置文件

3.1配置功能概述

除了Makefile的编写,另外一个重要的工作就是把新功能加入到Linux的配置选项中,提供此项功能的说明,让用户有机会选择此项功能。所有的这些都需要在config.in文件中用配置语言来编写配置脚本,

在Linux内核中,配置命令有多种方式:

配置命令解释脚本

Make config,make oldconfig scripts/Configure

Make menuconfig scripts/Menuconfig

Make xconfig scripts/tkparse

字符界面配置(make config)为例,顶层Makefile调用scripts/Configure,按照

arch/arm/config.in来进行配置。命令执行完后产生文件.config,其中保存着配置信息。下一次再做make config

将产生新的.config文件,原.config被改名为.config.old

3.2配置语言

1)顶层菜单

mainmenu_name/prompt//prompt/是用'或"包围的字符串,'与"的区别是'…'中可使用$引用变量的值。mainmenu_name设置最高层菜单的名字,它只在make xconfig时才会显示。2)询问语句

bool/prompt//symbol/

hex/prompt//symbol//word/

Linux内核修改与编译图文教程

Linux 内核修改与编译图文教程 1

1、实验目的 针对Ubuntu10.04中,通过下载新的内核版本,并且修改新版本内核中的系统调用看,然后,在其系统中编译,加载新内核。 2、任务概述 2.1 下载新内核 https://www.360docs.net/doc/c13834639.html,/ 2.2 修改新内核系统调用 添加新的系统调用函数,用来判断输入数据的奇偶性。 2.3 进行新内核编译 通过修改新版内核后,进行加载编译。最后通过编写测试程序进行测试 3、实验步骤 3.1 准备工作 查看系统先前内核版本: (终端下)使用命令:uname -r 2

3.2 下载最新内核 我这里使用的内核版本是 3.3 解压新版内核 将新版内核复制到“/usr/src”目录下 在终端下用命令:cd /usr/src进入到该文件目录 解压内核:linux-2.6.36.tar.bz2,在终端进入cd /usr/src目录输入一下命令: bzip2 -d linux-2.6.36.tar.bz2 tar -xvf linux-2.6.36.tar 文件将解压到/usr/src/linux目录中 3

使用命令: ln -s linux-2.6.36 linux 在终端下输入一下命令: sudo apt-get install build-essential kernel-package libncurses5-dev fakeroot sudo aptitude install libqt3-headers libqt3-mt-dev libqt3-compat-headers libqt3-mt 4

如何自行编译一个Linux内核的详细资料概述

如何自行编译一个Linux内核的详细资料概述 曾经有一段时间,升级Linux 内核让很多用户打心里有所畏惧。在那个时候,升级内核包含了很多步骤,也需要很多时间。现在,内核的安装可以轻易地通过像 apt 这样的包管理器来处理。通过添加特定的仓库,你能很轻易地安装实验版本的或者指定版本的内核(比如针对音频产品的实时内核)。 考虑一下,既然升级内核如此容易,为什么你不愿意自行编译一个呢?这里列举一些可能的原因: 你想要简单了解编译内核的过程 你需要启用或者禁用内核中特定的选项,因为它们没有出现在标准选项里 你想要启用标准内核中可能没有添加的硬件支持 你使用的发行版需要你编译内核 你是一个学生,而编译内核是你的任务 不管出于什么原因,懂得如何编译内核是非常有用的,而且可以被视作一个通行权。当我第一次编译一个新的Linux 内核(那是很久以前了),然后尝试从它启动,我从中(系统马上就崩溃了,然后不断地尝试和失败)感受到一种特定的兴奋。 既然这样,让我们来实验一下编译内核的过程。我将使用Ubuntu 16.04 Server 来进行演示。在运行了一次常规的 sudo apt upgrade 之后,当前安装的内核版本是 4.4.0-121。我想要升级内核版本到 4.17,让我们小心地开始吧。 有一个警告:强烈建议你在虚拟机里实验这个过程。基于虚拟机,你总能创建一个快照,然后轻松地从任何问题中回退出来。不要在产品机器上使用这种方式升级内核,除非你知道你在做什么。 下载内核 我们要做的第一件事是下载内核源码。在 Kernel 找到你要下载的所需内核的URL。找到URL 之后,使用如下命令(我以 4.17 RC2 内核为例)来下载源码文件: wget https://git.kernel/torvalds/t/linux-4.17-rc2.tar.gz

嵌入式Linux系统内核的配置、编译和烧写

实验二 嵌入式Linux系统内核的配置、编译和烧写 1.实验目的 1)掌握交叉编译的基本概念; 2)掌握配置和编译嵌入式Linux操作系统内核的方法; 3)掌握嵌入式系统的基本架构。 2.实验环境 1)装有Windows系统的计算机; 2)计算机上装有Linux虚拟机软件; 3)嵌入式系统实验箱及相关软硬件(各种线缆、交叉编译工具链等等)。 3.预备知识 1)嵌入式Linux内核的配置和裁剪方法; 2)交叉编译的基本概念及编译嵌入式Linux内核的方法; 3)嵌入式系统的基本架构。 4.实验内容和步骤 4.1 内核的配置和编译——配置内核的MMC支持 1)由于建立交叉编译器的过程很复杂,且涉及汇编等复杂的指令,在这里 我们提供一个制作好的编译器。建立好交叉编译器之后,我们需要完成 内核的编译,首先我们要有一个完整的Linux内核源文件包,目前流行 的源代码版本有Linux 2.4和Linux 2.6内核,我们使用的是Linux 2.6内核; 2)实验步骤: [1]以root用户登录Linux虚拟机,建立一个自己的工作路径(如用命令 “mkdir ‐p /home/user/build”建立工作路径,以下均采用工作路径 /home/user/build),然后将“cross‐3.3.2.tar.bz2、dma‐linux‐2.6.9.tar.gz、 dma‐rootfs.tar.gz”拷贝到工作路径中(利用Windows与虚拟机Linux 之间的共享目录作为中转),并进入工作目录; [2]解压cross‐3.3.2.tar.bz2到当前路径:“tar ‐jxvf cross‐3.3.2.tar.bz2”; [3]解压完成后,把刚刚解压后在当前路径下生成的“3.3.2”文件夹移 动到“/usr/local/arm/”路径下,如果在“/usr/local/”目录下没有“arm” 文件夹,用户创建即可; [4]解压“dma‐linux‐2.6.9.tar.gz”到当前路径下:

linux、内核源码、内核编译与配置、内核模块开发、内核启动流程

linux、内核源码、内核编译与配置、内核模块开发、内核启动流程(转) linux是如何组成的? 答:linux是由用户空间和内核空间组成的 为什么要划分用户空间和内核空间? 答:有关CPU体系结构,各处理器可以有多种模式,而LInux这样的划分是考虑到系统的 安全性,比如X86可以有4种模式RING0~RING3 RING0特权模式给LINUX内核空间RING3给用户空间 linux内核是如何组成的? 答:linux内核由SCI(System Call Interface)系统调用接口、PM(Process Management)进程管理、MM(Memory Management)内存管理、Arch、 VFS(Virtual File Systerm)虚拟文件系统、NS(Network Stack)网络协议栈、DD(Device Drivers)设备驱动 linux 内核源代码 linux内核源代码是如何组成或目录结构? 答:arc目录存放一些与CPU体系结构相关的代码其中第个CPU子目录以分解boot,mm,kerner等子目录 block目录部分块设备驱动代码 crypto目录加密、压缩、CRC校验算法 documentation 内核文档 drivers 设备驱动 fs 存放各种文件系统的实现代码 include 内核所需要的头文件。与平台无关的头文件入在include/linux子目录下,与平台相关的头文件则放在相应的子目录中 init 内核初始化代码 ipc 进程间通信的实现代码 kernel Linux大多数关键的核心功能者是在这个目录实现(程序调度,进程控制,模块化) lib 库文件代码 mm 与平台无关的内存管理,与平台相关的放在相应的arch/CPU目录net 各种网络协议的实现代码,注意而不是驱动 samples 内核编程的范例 scripts 配置内核的脚本 security SElinux的模块 sound 音频设备的驱动程序 usr cpip命令实现程序 virt 内核虚拟机 内核配置与编译 一、清除 make clean 删除编译文件但保留配置文件

linux内核编译和生成makefile文件实验报告

操作系统实验报告 姓名:学号: 一、实验题目 1.编译linux内核 2.使用autoconf和automake工具为project工程自动生成Makefile,并测试 3.在内核中添加一个模块 二、实验目的 1.了解一些命令提示符,也里了解一些linux系统的操作。 2.练习使用autoconf和automake工具自动生成Makefile,使同学们了解Makefile的生成原理,熟悉linux编程开发环境 三、实验要求 1使用静态库编译链接swap.c,同时使用动态库编译链接myadd.c。可运行程序生成在src/main目录下。 2要求独立完成,按时提交 四、设计思路和流程图(如:包括主要数据结构及其说明、测试数据的设计及测试结果分析) 1.Makefile的流程图: 2.内核的编译基本操作 1.在ubuntu环境下获取内核源码 2.解压内核源码用命令符:tar xvf linux- 3.18.12.tar.xz 3.配置内核特性:make allnoconfig 4.编译内核:make 5.安装内核:make install

6.测试:cat/boot/grub/grub.conf 7.重启系统:sudo reboot,看是否成功的安装上了内核 8.详情及结构见附录 3.生成makefile文件: 1.用老师给的projec里的main.c函数。 2.需要使用automake和autoconf两个工具,所以用命令符:sudo apt-get install autoconf 进行安装。 3.进入主函数所在目录执行命令:autoscan,这时会在目录下生成两个文件 autoscan.log和configure.scan,将configure.Scan改名为configure.ac,同时用gedit打开,打开后文件修改后的如下: # -*- Autoconf -*- # Process this file with autoconf to produce a configure script. AC_PREREQ([2.69]) AC_INIT([FULL-PACKAGE-NAME], [VERSION], [BUG-REPORT-ADDRESS]) AC_CONFIG_SRCDIR([main.c]) AC_CONFIG_HEADERS([config.h]) AM_INIT_AUTOMAKE(main,1.0) # Checks for programs. AC_PROG_CC # Checks for libraries. # Checks for header files. # Checks for typedefs, structures, and compiler characteristics. # Checks for library functions. AC_OUTPUT(Makefile) 4.新建Makefile文件,如下: AUTOMAKE_OPTIONS=foreign bin_PROGRAMS=main first_SOURCES=main.c 5.运行命令aclocal 命令成功之后,在目录下会产生aclocal.m4和autom4te.cache两个文件。 6.运行命令autoheader 命令成功之后,会在目录下产生config.h.in这个新文件。 7.运行命令autoconf 命令成功之后,会在目录下产生configure这个新文件。 8.运行命令automake --add-missing输出结果为: Configure.ac:11:installing./compile’ Configure.ac:8:installing ‘.install-sh’ Configure.ac:8:installing ‘./missing’ Makefile.am:installing ‘./decomp’ 9. 命令成功之后,会在目录下产生depcomp,install-sh和missing这三个新文件和执行下一步的Makefile.in文件。 10.运行命令./configure就可以自动生成Makefile。 4.添加内核模块

linux2.6内核的编译步骤及模块的动态加载-内核源码学习-linux论坛

[原创]linux2.6内核的编译步骤及模块的动态加载-内核源码 学习-linux论坛 05年本科毕业设计做的是Linux下驱动的剖析,当时就买了一本《Linux设备驱动程序(第二版)》,但是没有实现将最简单的helloworld程 序编译成模块,加载到kernel里。不过,现在自己确实打算做一款芯片的Linux的驱动,因此,又开始看了《Linux设备驱动程序》这本书,不过已 经是第三版了。第二版讲的是2.4的内核,第三版讲的是2.6的内核。两个内核版本之间关于编译内核以及加载模块的方法都有所变化。本文是基于2.6的内核,也建议各位可以先看一下《Linux内核设计与实现(第二版)》作为一个基础知识的铺垫。当然,从实践角度来看,只要按着以下的步骤去做也应该可以实现成功编译内核及加载模块。个人用的Linux版本为:Debian GNU/Linux,内核版本为:2.6.20-1-686.第一步,下载Linux内核的源代码,即构建LDD3(Linux Device Drivers 3rd)上面所说的内核树。 如过安装的Linux系统中已经自带了源代码的话,应该在/usr/src目录下。如果该目录为空的话,则需要自己手动下载源代码。下载代码的方法和链接很多,也可以在CU上通过

https://www.360docs.net/doc/c13834639.html,/search/?key=&;q=kernel&a mp;frmid=53去下载。不过,下载的内核版本最好和所运行的Linux系统的内核版本一致。当然,也可以比Linux系统内核的版本低,但高的话应该不行(个人尚未实践)。 Debian下可以很方便的通过Debian源下载: 首先查找一下可下载的内核源代码: # apt-cache search linux-source 其中显示的有:linux-source-2.6.20,没有和我的内核版本完全匹配,不过也没关系,直接下载就可以了: # apt-get install linux-source-2.6.20 下载完成后,安装在/usr/src下,文件名为: linux-source-2.6.20.tar.bz2,是一个压缩包,解压缩既可以得到整个内核的源代码: # tar jxvf linux-source-2.6.20.tar.bz2

Linux kernel内核升级全过程,教你一次成功

序言 由于开发环境需要在linux-2.6内核上进行,于是准备对我的虚拟机上的Linux系统升级。没想到这一弄就花了两天时间( 反复装系统,辛苦啊~~),总算把Linux系统从2.4.20-8内核成功升级到了2.6.18内核。 网上虽然有很多介绍Linux内核升级的文章,不过要么过时,下载链接失效;要么表达不清,不知所云;更可气的是很多 文章在转载过程中命令行都有错误。刚开始我就是在这些“攻略”的指点下来升级的,以致于浪费了很多时间。 现在,费尽周折,升级成功,心情很爽,趁性也来写个“升级攻略”吧!于是特意又在虚拟机上重新安装一个Linux系统 ,再来一次完美的升级,边升级边记录这些步骤,写成一篇Linux内核升级记实录(可不是回忆录啊!),和大家一起分享 ~~! 一、准备工作 首先说明,下面带#号的行都是要输入的命令行,且本文提到的所有命令行都在终端里输入。 启动Linux系统,并用根用户登录,进入终端模式下。 1、查看Linux内核版本 # uname -a 如果屏幕显示的是2.6.x,说明你的已经是2.6的内核,也用不着看下文了,该干什么干什么去吧!~~~如果显示的是 2.4.x,那恭喜你,闯关通过,赶快进行下一步。 2、下载2.6内核源码 下载地址:https://www.360docs.net/doc/c13834639.html,/pub/linux/kernel/v2.6/linux-2.6.18.tar.bz2 3、下载内核升级工具 (1)下载module-init-tools-3.2.tar.bz2 https://www.360docs.net/doc/c13834639.html,/pub/linux/utils/kernel/module-init-tools/module-init-tools-3.2.tar.bz2 (2)下载mkinitrd-4.1.18-2.i386.rpm https://www.360docs.net/doc/c13834639.html,/fedora/linux/3/i386/RPMS.core/mkinitrd-4.1.18-2.i386.rpm (3)下载lvm2-2.00.25-1.01.i386.rpm https://www.360docs.net/doc/c13834639.html,/fedora/linux/3/i386/RPMS.core/lvm2-2.00.25-1.01.i386.rpm (4)下载device-mapper-1.00.19-2.i386.rpm https://www.360docs.net/doc/c13834639.html,/fedora/linux/3/i386/RPMS.core/device-mapper-1.00.19-2.i386.rpm (2.6.18内核和这4个升级工具我都有备份,如果以上下载地址失效,请到https://www.360docs.net/doc/c13834639.html,/guestbook留下你的邮箱,我给你发过去)

linux实验报告(编译内核)

湖北大学 学生实验报告 实验课程网络实用技术 开课学院计算机与信息工程学院 任课教师徐婕 学生姓名骆婧 学生学号20112211042100 70 专业班级计科一班 学生年级2011级 2013-2014 学年第二学期

一.实验目的 通过实验,熟悉Linux操作系统的使用,掌握构建与启动Linux内核的方法;掌握用户程序如何利用系统调用与操作系统内核实现通信的方法,加深对系统调用机制的理解;进一步掌握如何向操作系统内核增加新的系统调用的方法,以扩展操作系统的功能。 二.实验内容 1.Linux环境下的C或者C++编译和调试工具的使用 2.向Linux内核增加新的系统调用,系统调用的功能为打印出自己的学号和 姓名信息。 3.Linux新内核的编译、安装和配置。 4.编写应用程序以测试新的系统调用并输出测试结果。 三、实验步骤 第一步:解压文件 1.下载linux-3.13.3.tar.xz压缩包。 2.在Ubantu系统下,解压该文件,解压之后得到linux- 3.13.3文件包 # tar –xf linux-3.13.3.tar.xz 3.将解压后的文件包复制到/usr/src # cp linux3.13.3 /usr/src 第二步:修改源程序,增加系统调用 1.gedit /usr/src/linux-3-13.3/kernel/sys.c (增加系统调用,使用面向内核的 打印函数printk打印姓名学号) 使用gedit命令,可以直接在文档编辑器中直接修改。修改好后按保存关闭文档编辑器。 在开头加入头文件: #include 在末尾加入函数 asmlinkage int sys_mycall(void) { printk(KERN_ALERT "My name is XXXX!My studentid is XXXXXXX\n"); return 1; } 2.gedit /usr/src/linux-3-1 3.3/arch/x86/include/asm/syscalls.h 在倒数第二行后插入 asmlinkage int sys_mycall(void);

linux 模块编译步骤(详解)

MODULE_LICENSE("Dual BSD/GPL"); static int hello_init(void) { printk(KERN_ALERT "hello,I am edsionte/n"); return 0; } static void hello_exit(void) { printk(KERN_ALERT "goodbye,kernel/n"); } module_init(hello_init); module_exit(hello_exit); // 可选 MODULE_AUTHOR("Tiger-John"); MODULE_DESCRIPTION("This is a simple example!/n"); MODULE_ALIAS("A simplest example"); Tiger-John说明: 1.> 相信只要是学过 C 语言的同学对第一个程序都是没有问题的。但是也许大家看了第二个程序就有些不明白了。 可能有人会说: Tiger 哥你没疯吧,怎么会把 printf() 这么简单的函数错写成了 printk() 呢。 也有的人突然想起当年在大学学 C 编程时,老师告诉我们“一个 C 程序必须要有 main() 函数,并且系统会首先进入 main() 函数执行 " ,那么你的程序怎么没有 main() 函数呢?没有 main() 函数程序是怎么执行的呢?

可能也会有更仔细的人会发现:怎么两个程序头文件不一样呢?不是要用到输入和输出函数时,一定要用到 这个头文件,你怎么没有呢? -------------------------------------------------------------------------------------------- Tiger 哥很淡定的告诉大家其实第二个程序是正确的,现在我们就来看看到底如何来编写一个内核模块程序。 2. 内核模块编程的具体实现 第一步:首先我们来看一下程序的头文件 #include #include #include 这三个头文件是编写内核模块程序所必须的 3 个头文件。 Tiger-John 说明: 1> 由于内核编程和用户层编程所用的库函数不一样,所以它的头文件也和我们在用户层编写程序时所用的头文件也不一样。 2> 我们在来看看在 L inux 中又是在那块存放它们的头文件 a. 内核头文件的位置: /usr/src/linux-2.6.x/include/ b. 用户层头文件的位置 : /usr/include/ 现在我们就明白了。其实我们在编写内核模块程序时所用的头文件和系统函数都和用层编程时所用的头文件和系统函数是不同的。 第二步:编写内核模块时必须要有的两个函数 : 1> 加载函数: static int init_fun(void)

Linux内核的配置与编译

Computer Knowledge and Technology 电脑知识 与技术第5卷第3期(2009年1月)Linux 内核的配置与编译 胡庆烈 (佛山职业技术学院电子信息工程系,广东佛山528000) 摘要:Linux 是一种实用性很强的现代操作系统,它开放源代码,并允许用户升级其内核。在Redhat 7.2环境中,详细分析了Linux 2.4.18版本的内核配置、编译及新内核切换等操作过程。 关键词:Linux ;内核;配置;编译 中图分类号:TP316文献标识码:A 文章编号:1009-3044(2009)03-0730-02 Configuration and Compiling of Linux Kernel HU Qing-lie (Department of Electonics &Information,Foshan Polytechnic College,Foshan 528000,China) Abstract:Linux is a very practical modern operating system,which opens source coding and allows the user to upgrade its kernel.In the environment of Redhat 7.2,the paper analysis the Linux 2.4.18version of kernel configuration,compiling and new kernel process switch -ing,and so on. Key words:Linux;kernel;configuration;compile 1引言 Linux 是一个自由的多任务操作系统,它以开放源码、对硬件的配置要求低并兼具现代操作系统的优点而得到了迅猛的发展。操作系统的内核是操作系统的核心,它有很多基本的功能,如虚拟内存、多任务、共享库、需求加载、共享的写时拷贝(copy-on-write)、可执行程序和TCP/IP 网络功能等。 用户编译配置Linux 的内核,主要有以下三个原因:1)从现有内核中去除一些不需要的功能,使自定制的内核运行速度更快、更稳定,且具有更少的代码;2)使系统拥有更多的内存,内核部分将不会被交换到虚拟内存中;3)为了提高速度,将某种功能编译到内核中。 2Linux 内核升级的准备 2.1安装一个Linux 操作系统 在编译一个新的Linux 内核之前,首先应在微机中安装一个Linux 操作系统,以便利用该Linux 环境进行新内核的配置和安装。这里是以Redhat 7.2为例,在安装Redhat 7.2的过程中,有两个问题需要注意: 1)硬盘的分区:由于每个硬盘只能拥有4个主分区(Primary Partition ),故用户需要扩展分区,则至少需要腾出一个主分区来划分逻辑分区。在安装Linux 操作系统时,至少需要两个分区,其中本机分区(Linux Native )是供Linux 存放系统文件,而置换分区(Linux Swap )是用作虚拟内存的存取空间。此外,为了和Windows 系统进行文件的复制转换,还应创建一个FAT32类型的分区。 2)安装LILO 启动程序:LILO 是Linux 的核心加载程序,它提供了从DOS 环境启动Linux 的功能,并支持多重启动菜单,让用户选择启动哪一个分区的操作系统。 2.2获取新的Linux 内核源代码 安装了Linux 操作系统后,接下来的工作是寻找新内核的源代码。目前,在Internet 上提供Linux 源代码的站点有很多,如https://www.360docs.net/doc/c13834639.html, 就是Linux 内核版本发布的官方网站,用户可以从该站点上获得最新版本的Linux 内核源代码,这里是以linux- 2.4.18版本为例。 2.3对新的Linux 内核源代码包进行解压 由于大部分开放性操作系统的程序都是以压缩文件(tgz 、zip 、gz 与bz2)的形式进行发布,所以从网络上取得这些压缩文件后,都先要解压缩之后才能安装使用。具体过程如下: 1)执行“GNOME Terminal ”,把X Windows System 图形用户界面切换至文件操作模式; 2)执行“#cp /root/linux-2.4.18.tar.gz /usr/src ”,把从网络下载的压缩包复制至/usr/src 处; 3)执行“#tar -zxvf linux-2.4.18.tar.gz ”,对压缩包进行解压,解压文件存放在/usr/src/linux-2.4.18目录中。 2.4清除不正确文件及其它从属文件 为了确保源代码目录中没有不正确的文件和其它从属文件,一般需要运行mrproper 命令进行清理,具体操作如下: #cd /usr/src/linux-2.4.18 #make mrproper 如果是使用刚下载的完整的源程序包进行编译,则可以省略mrproper 操作。但若已反复多次使用这些源程序来进行内核编译的,则应要先运行一下这个命令。 收稿日期:2008-12-11 作者简介:胡庆烈(1969-),男,揭阳惠来人,电子助理工程师,主要从事电子技术的教研工作。 ISSN 1009-3044Computer Knowledge and Technology 电脑知识与技术Vol.5,No.3,January 2009,pp.730-731,735E-mail:kfyj@https://www.360docs.net/doc/c13834639.html, https://www.360docs.net/doc/c13834639.html, Tel:+86-551-56909635690964

在menuconfig中配置Linux内核裁剪的具体步骤

在menuconfig中配置Linux内核裁剪的具体步骤 在men UC onfig中配置,可以对进行Linux内核配置选项及删改。本文介绍详细配置方法。第一部分:全部删除 Code maturity level options ---> 代码成熟等级选项 [ ]Prompt for development and/or incomplete code/drivers 默认情况下是选择的,这将会在设置界面中显示还在开发或者还没有完成的代码与驱动.不选。 第二部分:除以下选项,其它全部删除 General setup—〉 System V IPC (IPC:Inter Process Communication)是组系统调用及函数库,它能让程序彼此间同步进行交换信息。某些程序以及DOS模拟环境都需要它。为进程提供通信机制,这将使系统中各进程间有交换信息与保持同步的能力。有些程序只有在选Y的情况下才能运行,所以不用考虑,这里一定要选。 第三部分:除以下选项,其它全部删除 Loadable module support ---> 可引导模块支持建议作为模块加入内核 [ ] Enable loadable module support 这个选项可以让你的内核支持模块,模块是什么呢?模块是一小段代码,编译后可在系统内核运行时动态的加入内核,从而为内核增加一些特性或是对某种硬件进行支持。一般一些不常用到的驱动或特性可以编译为模块以减少内核的体积。在运行时可以使用modprobe命令来加载它到内核中去(在不需要时还可以移除它)。一些特性是否编译为模块的原则是,不常使用的,特别是在系统启动时不需要的驱动可以将其编译为模块,如果是一些在系统启动时就要用到的驱动比如说文件系统,系统总线的支持就不要编为模块了,否在无法启动系统。 [ ]Automatic kernel module loading 一般情况下,如果我们的内核在某些任务中要使用一些被编译为模块的驱动或特性时,我们要先使用modprobe命令来加载它,内核才能使用。不过,如果你选择了这个选项,在内核需要一些模块时它可以自动调用modprobe命令来加载需要的模块,这是个很棒的特性,当然要选Y喽。 第四部分:全部删除 Block layer-----〉块设备 第五部分:除以下选项,其它全部删除 Processor type and features ---> 处理器类型 Subarchitecture Type (PC-compatible) ---> 这选项的主要的目的,是使Linux可以支持多种PC标准,一般我们使用的PC机是遵循所谓IBM兼容结构(pc/at)。这个选项可以让你选择一些其它架构。我们一般选择PC-compatible就可以了。 Processor family(386): 它会对每种CPU做最佳化,让它跑的好又快,一般来说,你是什么型号的就选什么型号的就好。我选的是386,这样内核会省下不少空间 第六部分:除以下选项,其它全部删除 Power management options (ACPI, APM) ---> 电源管理选项 [ ] Power Management Debug Support 电源管理的调试信息支持,如果不是要调试内核有关电源管理部份,请不要选择这项。 ACPI Support ---〉高级电源接口配置支持,如果BIOS支持,建议选上这项 [ ]Button 这个选项用于注册基于电源按钮的事件,比如power, sleep等,当你按下按钮时事件将发生,一个守护程序将读取/proc/acpi/event,并执行用户在这些事件上定义的动作比如让系统关机。可以不选择,根据自己的需求。 第七部分:除以下选项,其它全部删除

核心板linux内核及驱动模块编译步骤

核心板linux内核编译及驱动模块编译步骤 一、内核编译: 1,拷贝开发板linux系统源代码(linux-2.6.30)到ubuntu的任意位置,打开终端,进入linux-2.6.30目录,输入命令:cp arch/arm/configs/sbc6045_defconfig .config 回车 2,输入命令:make menuconfig 回车,若提示以下界面 *** Unable to find the ncurses libraries or the *** required header files. *** 'make menuconfig' requires the ncurses libraries. *** *** Install ncurses (ncurses-devel) and try again. *** 输入命令:sudo apt-get install libncurses5-dev 回车,安装ncurses 3,安装完成后,输入命令:make menuconfig 回车,进入配置选项界面,按需修改,目前未修改。 4,输入命令:make uImage 回车,若提示Can't use 'defined(@array)',修改kernel/timeconst.pl 文件中 373行,if (!defined(@val))改为if (!@val) ,重新执行make uImage命令。 二、驱动模块编译(若从未编译过内核,需要先编译内核): 1,将编写好到源文件(如:cgc-pio.c)拷贝到linux-2.6.30/drivers/char/目录 2,修改linux-2.6.30/drivers/char/目录下到Makefile文件,增加一行,内容为:obj-m += xxx.o,如:obj-m += cgc-pio.o 3,打开linux终端,进入linux-2.6.30目录,输入命令:make modules 回车,完成后在linux-2.6.30/drivers/char/目录下会产生对应到.ko文件(如:cgc-pio.ko)。

编译Linux最新内核详细教程

编译Linux最新内核详细教程 [日期:2010-12-23]来源:51cto 作者:zjuedward 一、实验目的 学习重新编译Linux内核,理解、掌握Linux内核和发行版本的区别。 二、实验内容 在Linux操作系统环境下重新编译内核。实验主要内容: A. 查找并且下载一份内核源代码,本实验使用最新的Linux内核2.6.36。 B. 配置内核。 C. 编译内核和模块。 D. 配置启动文件。 本次实验环境是Linux2.6.35内核的环境下,下载并重新编译内核源代码(2.6.36);然后,配置GNU的启动引导工具grub,成功运行编译成功的内核。 三、主要仪器设备(必填) Linux环境:Utuntu 10.10,Linux内核2.6.35 待编译内核:Linux2.6.36 四、操作方法和实验步骤 【1】下载内核源代码 从这里下载最新的Linux内核2.6.36。 【2】部署内核源代码 打开终端,更改用户权限为root。具体做法是在终端输入sudo su,然后按提示输入密码。判断是否是root用户是使用whoami命令,若输出为root则已经切换到root账户。 输入mv linux-2.6.36.tar.gz /usr/src,目的是把下载的内核源代码文件移到/usr/src目录。 输入cd /usr/src切换到该目录下。 输入tar zxvf linux-2.6.36.tar.gz,目的是解压内核包,https://www.360docs.net/doc/c13834639.html,生成的源代码放在linux- 2.6.36目录下。 输入cd linux-2.6.36,切换到该目录下。 输入cp /boot/config-,然后按下Tab键,系统会自动填上该目录下符合条件的文件名,然后继续输入.config,目的是使用在boot目录下的原配置文件。 【3】配置内核 配置内核的方法很多,主要有如下几种: #make menuconfig //基于ncurse库编制的图形工具界面 #make config //基于文本命令行工具,不推荐使用 #make xconfig //基于X11图形工具界面 #make gconfig //基于gtk+的图形工具界面 由于对Linux还处在初学阶段,所以选择了简单的配置内核方法,即make menuconfig。在终端输入make menuconfig,等待几秒后,终端变成图形化的内核配置界面。进行配置时,大部分选项使用其缺省值,只有一小部分需要根据不同的需要选择。 对每一个配置选项,用户有三种选择,它们分别代表的含义如下: 或[*]——将该功能编译进内核 []——不将该功能编译进内核 [M]——将该功能编译成可以在需要时动态插入到内核中的代码 本实验在make menuconfig后,把ext2和ext3文件系统编译进内核。如果用户是在虚拟机下编译的,那么一般要把SCSI设备编译进内核。不是在虚拟机下编译的也可以把它编译进去,不会有什么影响的。 【4】编译内核 这步是时间最长的一个步骤,一般在3个小时左右。 编译内核只需在终端输入make,然后等待编译的完成。

Linux内核裁剪的具体步骤

Linux内核裁剪的具体步骤 在menuconfig中配置: 详细介绍内核配置选项及删改情况 第一部分:全部删除 Code maturity level options ---> 代码成熟等级选项 []Prompt for development and/or incomplete code/drivers 默认情况下是选择的,这将会在设置界面中显示还在开发或者还没有完成的代码与驱动.不选。 第二部分:除以下选项,其它全部删除 General setup—〉 System V IPC (IPC:Inter Process Communication)是组系统调用及函数库,它能让程序彼此间同步进行交换信息。某些程序以及DOS模拟环境都需要它。为进程提供通信机制,这将使系统中各进程间有交换信息与保持同步的能力。有些程序只有在选Y的情况下才能运行,所以不用考虑,这里一定要选。 第三部分:除以下选项,其它全部删除 Loadable module support ---> 可引导模块支持建议作为模块加入内核 [] Enable loadable module support 这个选项可以让你的内核支持模块,模块是什么呢?模块是一小段代码,编译后可在系统内核运行时动态的加入内核,从而为内核增加一些特性或是对某种硬件进行支持。一般一些不常用到的驱动或特性可以编译为模块以减少内核的体积。在运行时可以使用modprobe命令来加载它到内核中去(在不需要时还可以移除它)。一些特性是否编译为模块的原则是,不常使用的,特别是在系统启动时不需要的驱动可以将其编译为模块,如果是一些在系统启动时就要用到的驱动比如说文件系统,系统总线的支持就不要编为模块了,否在无法启动系统。 []Automatic kernel module loading 一般情况下,如果我们的内核在某些任务中要使用一些被编译为模块的驱动或特性时,我们要先使用modprobe命令来加载它,内核才能使用。不过,如果你选择了这个选项,在内核需要一些模块时它可以自动调用modprobe命令来加载需要的模块,这是个很棒的特性,当然要选Y喽。 第四部分:全部删除 Block layer-----〉块设备 第五部分:除以下选项,其它全部删除 Processor type and features ---> 处理器类型 Subarchitecture Type (PC-compatible) ---> 这选项的主要的目的,是使Linux可以支持多种PC标准,一般我们使用的PC机是遵循所谓IBM兼容结构(pc/at)。这个选项可以让你选择一些其它架构。我们一般选择PC-compatible就可以了。 Processor family(386): 它会对每种CPU做最佳化,让它跑的好又快,一般来说,你是

linux内核编译详细教程

详细教程:编译Linux最新内核 一、实验目的 学习重新编译Linux内核,理解、掌握Linux内核和发行版本的区别。 二、实验内容 在Linux操作系统环境下重新编译内核。实验主要内容: A. 查找并且下载一份内核源代码,本实验使用最新的Linux内核2.6.36。 B. 配置内核。 C. 编译内核和模块。 D. 配置启动文件。 本次实验环境是Linux2.6.35内核的环境下,下载并重新编译内核源代码(2.6.36);然后,配置GNU的启动引导工具grub,成功运行编译成功的内核。 三、主要仪器设备(必填) Linux环境:utuntu10.10,linux内核2.6.35 待编译内核:linux2.6.36 四、操作方法和实验步骤 【1】下载内核源代码 从https://www.360docs.net/doc/c13834639.html,/newlinux/files/jijiangmin网站上下载最新的Linux内核2.6.36。

【2】部署内核源代码 打开终端,更改用户权限为root。具体做法是在终端输入sudo su,然后按提示输入密码。判断是否是root用户是使用whoami命令,若输出为root则已经切换到root账户。 输入mv linux-2.6.36.tar.gz /usr/src,目的是把下载的内核源代码文件移到/usr/src目录。 输入cd /usr/src切换到该目录下。 输入tar zxvf linux-2.6.36.tar.gz,目的是解压内核包,生成的源代码放在linux-2.6.36目录下。 输入cd linux-2.6.36,切换到该目录下。 输入cp /boot/config-,然后按下Tab键,系统会自动填上该目录下符合条件的文件名,然后继续输入 .config,目的是使用在boot目录下的原配置文件。//这一步可以不走 【3】配置内核 配置内核的方法很多,主要有如下几种: #make menuconfig //基于ncurse库编制的图形工具界面 #make config //基于文本命令行工具,不推荐使用 #make xconfig //基于X11图形工具界面 #make gconfig //基于gtk+的图形工具界面 由于对Linux还处在初学阶段,所以选择了简单的配置内核方法,即make menuconfi g。在终端输入make menuconfig,等待几秒后,终端变成图形化的内核配置界面。进行配置时,大部分选项使用其缺省值,只有一小部分需要根据不同的需要选择。 对每一个配置选项,用户有三种选择,它们分别代表的含义如下: <*>或[*]——将该功能编译进内核

Linux内核升级全过程 手把手教你一次成功

Linux内核升级全过程手把手教你一次成功 由于开发环境需要在linux-2.6内核上进行,于是准备对我的虚拟机上的Linux系统升级。没想到这一弄就花了两天时间(反复装系统,辛苦啊~~),总算把Linux系统从2.4.20-8内核成功升级到了2.6.18内核。 网上虽然有很多介绍Linux内核升级的文章,不过要么过时,下载链接失效;要么表达不清,不知所云;更可气的是很多文章在转载过程中命令行都有错误。刚开始我就是在这些“攻略”的指点下来升级的,以致于浪费了很多时间。 现在,费尽周折,升级成功,心情很爽,趁性也来写个“升级攻略”吧!于是特意又在虚拟机上重新安装一个Linux系统,再来一次完美的升级,边升级边记录这些步骤,写成一篇Linux内核升级记实录(可不是回忆录啊!),和大家一起分享~~! 首先说明,下面带#号的行都是要输入的命令行,且本文提到的所有命令行都在终端里输入。接下来,让我们一起开始精彩的Linux内核升级之旅吧! 一、准备工作 启动Linux系统,并用根用户登录,进入终端模式下。 1、查看Linux内核版本 #uname-a 如果屏幕显示的是2.6.x,说明你的已经是2.6的内核,也用不着看下文了,该干什么干什么去吧!~~~如果显示的是2.4.x,那恭喜你,闯关通过,赶快进行下一步。 2、下载2.6内核源码 下载地址:https://www.360docs.net/doc/c13834639.html,/pub/linux/kernel/v2.6/linux-2.6.18.tar.bz2 3、下载内核升级工具 (1)下载module-init-tools-3.2.tar.bz2 https://www.360docs.net/doc/c13834639.html,/pub/linux/utils/kernel/module-init-tools/module-init-tool s-3.2.tar.bz2 (2)下载mkinitrd-4.1.18-2.i386.rpm https://www.360docs.net/doc/c13834639.html,/fedora/linux/3/i386/RPMS.core/mkinitrd-4.1.18-2.i386.r pm (3)下载lvm2-2.00.25-1.01.i386.rpm https://www.360docs.net/doc/c13834639.html,/fedora/linux/3/i386/RPMS.core/lvm2-2.00.25-1.01.i386.r pm (4)下载device-mapper-1.00.19-2.i386.rpm https://www.360docs.net/doc/c13834639.html,/fedora/linux/3/i386/RPMS.core/device-mapper-1.00.19-2. i386.rpm (2.6.18内核和这4个升级工具我都有备份,如果以上下载地址失效,请到https://www.360docs.net/doc/c13834639.html,/guestbook留下你的邮箱,我给你发过去) 二、配置工作 好啦,2.6内核和4个升级工具都下载完了(少一个也不行,如果没有下载齐全,请不要尝试下面的步骤,升级是不会成功的),下面回到Linux系统中开始配置工作吧。 4、将下载好的内核和4个升级工具都拷贝到/usr/src文件夹下。怎么拷贝就不用我教了吧~~~~不会拷贝的去撞墙吧!~~呵呵! 5、拷贝完毕,开始解压新内核,具体操作请依次执行以下命令: #cd/usr/src(进入到/usr/src目录下,如果已经在/usr/src目录下,可不执行该命令)

相关文档
最新文档