Linux 内核编译

Linux  内核编译

环境   Vmware   + CentOS4.6

一、下载 Linux 内核源码包

查看当前系统的 linux 内核版本

# uname  –r

2.6.9-67.ELsmp

查看 CentOS 发行版版本

#  cat /etc/redhat-release

CentOS release 4.6 (Final)

发行版版本信息一般保存在 /etc/issue 文件中,也可以用 cat /etc/issue 命令 查看

Linux内核发布的网站是 http://www.kernel.org ,但需要打补丁。可到 centos网站上,下载带 CentOS补丁的 rpm包。

rpm包有两种,

  • Source RPM .src.rpm )包含一个 SPEC 文件( .spec ),源码包( .tar.gz, .tar.bz2 ),还有其它的一些源文件和补丁
  • Binary RPM .i386.rpm, .i686.rpm, .sparc64.rpm ),包括一些已编译文件,文档, 配置文件和 pre/post install/uninstall的脚本。

此处要编译源文件,下载前者。

CentOS网站上找到相应的内核版本 kernel-`uname -r`.src.rpm

RPMS文件夹中放着 Binary RPM SPRAMS文件夹中存放着 Source RPM文件。

下载 http://vault.centos.org/4.6/apt/i386/SRPMS.os/kernel-2.6.9-67.EL.src.rpm 到本地系统中。

二、安装 Linux 内核源码树

安装 rpm

# rpm -ivh kernel-2.6.9-67.EL.src.rpm

-i 安装, -v 显示安装包的真实名称 * 1 -h显示安装进度

主要是一个解压的过程。

/usr/src/redhat 目录下生成两个文件夹 SOURCES SPECS

# cd /usr/src/redhat/;ls

SOURCES  SPECS

  • SOURCES SOURCES  存储源代码。
  • SPECS SPECS  包含 spec  文件

SOURCE S目 录下主要 linux内核源码包 linux-2.6.9.tar.bz2 1000多个 patch文件及 .config文件。

SPECS目录下包含 kernel-2.6.spec文件

 

Spec文件可看作 rpm工作的脚本文件。

image

spec 文件规范

它包含了软件包的诸多信息,如软件包的名字、版本、类别、 说明摘要、创建时要执行什么指令、安装时要执行什么操作、以及软件包所要包含的文件列表等等。

它主要包括

  • 文件头   包括软件包名,版本,开发者等
  • %prep   这个段是预处理段,通常用来执行一些解开源程序包的命令,为下一步的编译安装作准 备。
  • % b uild   本段是建立段,所要执行的命令为生成软件包服务,如 make  命令。
  • %install   本段是安装段,其中的命令在安装软件包时将执行,如 make install 命令。
  • %files   本段是文件段,用于定义软件包所包含的文件
  • %changelog   修改日志段

#  cd /usr/src/SPECS

# rpmbuild -bp --target=`uname  –m` kernel-2.6.spec

-bp build through %prep (unpack sources and app ly patches) from <specfile>, <specfile> 文件的 %prep 段开始建立(解开源码包并打补丁)。

-bp 命令只执行 %prep 段,解压源码包并打补丁。

执 行完这一步后将会在 /usr/src/redhat/BUILD/kernel-2.6.9/linux-2.6.9 目录下生成完整的内核源码树。

image

三、 配置 Linux 内 核

linux-2.6.9目录链接到 /usr/src/linux

# cd /usr/src/

# ln -s /usr/src/redhat/BUILD/ker nel-2.6.9/linux-2.6.9/ linux

切 换到 linux 目 录下

#  cd /usr/src/linux

# vi Makefile

修 改 Makefile 文 件,修改 EXTRAVERSION 选 项,给自己编译的内核盖个戳。

image

把 当前内核的配置文件拷贝到 linux 目 下下重命名为 .config

# cp  /boot/config-`uname  r` .config

.config 文 件本应该用 make menuconfig 来 生成,在本实验中,直接把当前内核的配置信息复制过来。就省去了 make me nuconfig 的麻烦。

# make menuconfig

此 处只是一个流程,选择默认 ,退出。

image

四、编译内核及内核模块

# make

这 是最主要的一步。 Makefile 的编译流程,

  • 使用命令行或者图形界面配置工具,对内核进行裁 减,生成 .config 配置文件
  • 保存内核版本信息到   include/linux/version.h
  • 产生符号链接   include/asm, 指向实际目录   include/asm-$(ARCH)
  • 为最终目标文件的生成进行必要的准备工作
  • 递归进入   /init  /core   /dri vers   /net   /lib等目录和其中的子目录来编译生成所有的目标文件
  • 链接上述过程产生的目标文件生成 vmlinux vmlinux 存放在内核代码树的根目录下
  • 最后根据   arch/$(ARCH)/Makefile 文件定义的后期编译的处理规则建立最终的映象 bootimage, 包括创建引导记录、准备 initrd 映象和相关处理

五、安装内核

Insert 内核模块,理解是,很多的 insmod 操作 * 2

# make modules_install

安 装内核

# make install

boot 目 录下多出了以下 文件

v mlinuz-2.6.9-lunix1.0是可引导的、压缩的内核。

System.map-2.6.9-lunix1.0内核符号表 , Linux内核不使用符号名,而是通过变量或函数的地址来识别变量或 函数名 .  符号表是所有符号连同它们的地址的列表。

image

关于 initrd-2.6.9-lunix1.0.img 文件

/boot/grub/menu.lst 中除了配置 root kernel还要配置 initrd Initrd指定系统启动访问真正的根文件系统前,访问的 ramdisk映象。

initrd***.im g把一段程序打包到 img里,然后在开机的时候在内存里开辟一段区域,一般是 2m,释放到那里运行,都是一些初始化的程序,比如 sisc_mod ext3 sd_mod等模块和 insmod nash等命令。不同内核,初始化的 img可以相同,也可以不同,如果没有,可以在 grub.conf里加上 no initrd,它就跳过 initrd的检测和执行了。

它的作用是在没有 mount / 分区以前,系统要执行一些操作,比如挂载 scsi 驱动,它就把 initrd 释放到内存里,作一个虚拟的 /

现在解压 initrd, 并查看里面的文件

# mkdir initrd

# cd initrd/

# cp /boot/initrd-2.6.9-lunix1.0.img initrd.gz

# gunzip initrd.gz

# cpio -ivmd < initrd

# ls

bin  dev  etc  init  initrd  lib  loopfs  proc  sbin  sys  sysroot

initrd 目录中就是系统启动时临时 root 的内容。目录下有一个 init 文件,该文件最为重要,它就是内核启动后执行的第一个脚本。实际 上内核启动后寻找的就是 /init ; bin/init ;/bin/init,找 到任何一个就执行它。整个的初始化从它开始。用 file cat命令查看一下

# file init

init: a /bin/nash script text executable

# cat init

#!/bin/nash

 

mount -t proc /proc /proc

setquiet

echo Mounted /proc filesystem

echo Mounting sysfs

mount -t sysfs non e /sys

echo Creating /dev

mount -o mode=0755 -t tmpfs none /dev

mknod /dev/console c 5 1

mknod /dev/null c 1 3

mknod /dev/zero c 1 5

mkdir /dev/pts

mkdir /dev/shm

echo Starting udev

/sbin/udevstart

echo -n "/sbin/hotplug" > /proc/sys/kernel/hotplug

echo "L oading scsi_mod.ko module"

insmod /lib/scsi_mod.ko

echo "Loading sd_mod.ko module"

insmod /lib/sd_mod.ko

echo "Loading mptbase.ko module"

insmod /lib/mptbase.ko

echo "Loading mptscsi.ko module"

insmod /lib/mptscsi.ko

echo "Loading mptspi.ko module"

insmod  /lib/mptspi.ko

echo "Loading mptsas.ko module"

insmod /lib/mptsas.ko

echo "Loading mptscsih.ko module"

insmod /lib/mptscsih.ko

echo "Loading libata.ko module"

insmod /lib/libata.ko

echo "Loading ata_piix.ko module"

insmod /lib/ata_piix.ko

echo "Loading jbd .ko module"

insmod /lib/jbd.ko

echo "Loading ext3.ko module"

insmod /lib/ext3.ko

/sbin/udevstart

echo Creating root device

mkrootdev /dev/root

umount /sys

echo Mounting root filesystem

mount -o defaults --ro -t ext3 /dev/root /sysroot

mount -t tmpfs --bind   /dev /sysroot/dev

echo Switching to new root

switchroot /sysroot

umount /initrd/dev

第一行 #!/bin/nash 是一个 redhat 自己的微型解释器。不是 bash

它的主要流程是

mount 命令加载各种内核文件系统 proc,sys

mknod 创建系统启动所必须的 /dev 设备节 点。

insmod 开始安装 scsi 等设 备。

udevstart  开始监听这些设备

 

m krootdev  使它后面的参数 /dev/root成为一个块节点从而使得根分区设备被挂载 ,其中根分区设备由 grub.conf里面的 kernel命令后面所带的参数 root=决定。

 

mount -o defaults --ro -t ext3 /dev/root /sysroot

加载 /dev/root /sysroot下。这时真正的 root才被加载到了系统中。至此 /sysroot下是真正的 root分区。 / initrd的内存盘。

switchroot  切换到新的 root,卸载 /dev,/proc,/sys文件系统,寻找新的 init

六、启动新内核

查看 /boot/grub/menu.lst文件,多了 title CentOS(2.6.9-lunix1.0)设 置为默认启动项。

image

重新启动 reboot

 

启动菜单,多了 2.6.9-lunix1.0

image

用自行编译的内核启动,输入 uname –r显示

image

* 1 显示操作过程中详细信息

* 2 将新编译内核树中的模块( .ko)文件拷贝到 /lib/modules/<version>下,并做模块相关性处理 (depmod);此时不会做 insmod操作

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值