2014年10月15日星期三

Linux内核编译和替换

Linux内核编译和替换小结

一 准备工作

1 当前Linux 环境

系统版本为 3.8.13.13-cdos

2 下载内核源码

在网站 www.kernel.org ,选择合适的版本下载。

本次下载版本为官方最新开发版本 linux-3.17.tar.xz


 

二 内核编译

1 解压源码

当前系统的源码位置为 /usr/src/linux-headers-3.8.13.13-cdos

新的源码解压到 /opt/linux-3.17,使用命令 #tar xvf linux-3.17.tar.xz –C /opt


 

2 make mrproper

Remove all generated files + config + various backup files

"make mrproper"命令清理源代码树,包括过去曾经配置的内核配置文件".config"都将被清除。即进行新的编译工作时将原来老的配置文件给删除到,以免影响新的内核编译。

即检查有无不正确的.o文件和依赖关系,如果使用刚下载的完整的源程序包即第一次进行编译,那么本步可以省略。而如果你多次使用了这些源程序编译内核,则最好要先运行一下这个命令。


 

3 make olddefconfig

将当前系统存在的.config 文件拷贝至3.17.0源码目录,使用make olddefconfig 命令配置内核选项。

make olddefconfig 的含义为:采用已有的.config文件的参数作为默认参数,同时升级依赖属性,新属性设置为默认值不再提醒。


 

也可以使用以下两个命令:

make config:纯文本界面配置。

make menuconfig:基于文本的彩色菜单、单选列表、对话框。(常用)


 

4 make dep

如果内核从未编译过,此步可跳过

根据配置结果,建立文件依赖关系。

该命令将会修改linux中每个子目录下的.depend文件,该文件包含了该目录下每个目标文件所需要的头文件(绝对路径的方式列举)。


 

5 make clean

如果内核从未编译过,此步可跳过

Remove most generated files but keep the config and enough build support to build external modules

清理一些不必要的文件,如果你在上次编译的基础上,删去了一些选项,执行这一步操作,否则,就没有必要了。


 

6 make –j

生成内核模块、bzImage、System.map等文件。

-j[N]: 同时允许N个任务,而如果-j后不跟任何数字,则不限制处理器并行编译的任务数。


 

本步也可以分别执行 make bzImage 、make modules。


 

三 安装内核和模块

1 make modules_install

编译成功后,系统会在/lib/modules目录下生成一个3.17.0子目录,里面存放着新内核的所有可加载模块(即将编译好的modules拷贝到/lib/modules下)。


 

2 make install

执行该命令后,/boot 文件夹下会增加一下内容:

cp .config /boot/config-3.17.0

cp System.map /boot/System.map-3.17.0

cp /arch/i386/boot/bzImage /boot/vmlinuz-3.17.0


 

3 mkinitramfs

敲入命令生成内核版本相对应的img 文件:

#mkinitramfs 3.17.0 –o /boot/initrd.img-3.17.0


 

至此,更换内核所需的所有文件config、System.map、vmlinuz、initrd.img 都已经完成了。


 

4 update-grub2

更新启动文件grub.cfg,将3.17.0添加至系统启动选项中。


 

三 总结

恭喜您,到这里所有的内核更换工作已经完成,可以reboot 检验下了。

 

Linux UML 内核调试方法

Linux UML 内核调试方法小结

一 UML环境的搭建

1 下载內核

从官网www.kernel.org 选择版本 linux-3.10.57.tar.xz

解压到相应路径     /opt/um/linux-3.10.57


 

2 基于 um的内核配置

#cd /opt/um/linux-3.10.57

#cp cd /boot/config-3.8.13.13-cdos .config

# make olddefconfig ARCH=um


 

为方便进行调试,修改配置文件

#make mrproper

#make mrproper ARCH=um

# make menufconfig ARCH=um

在选择配置时确保选中:

Kernel Hacking->

Compile the kernel with debug info(对应的DEBUG_INFO配置为yes)

和Compile the kernel with frame pointers(对应的FRAME_POINTER配置为yes)

这样生成的二进制内核linux中才有详细的调试信息。


 

同时,生成完.config文件后,编译之前,可以用编辑器打开源码根目录下的Makefile文件,把编译优化等级-O2调成-O1,这样可以在保证编译通过的前提下生成的内核文件具有较好的调试效果。

3 编译内核及模块

#make linux ARCH=um

#make modules ARCH=um

#make modules_install ARCH=um


 

生成我们需要的内核了,而且支持调试了。


 

4 制作文件系统

直接启动会有问题的,提示找不到root文件系统。这样我们用人家现成的。


http://fs.devloop.org.uk/ 下载 CentOS6.x-x86-root_fs.bz2

通过gunzip2 解压 得到 CentOS6.x-x86-root_fs

注: CentOS 经过实践可用,同样的 Ubuntu Trusty 运行时会遇到各种问题.

当下载或制作好更文件系统中后,可以将上一步生成的modules拷贝到UML根文件系统的对应目录中去。在Host Linux和UML根文件系统之间传递文件,最简单的方式就是使用挂载UML根文件系统到Host Linux中的目录,然后使用cp。拷贝Host Linux中源码根目录下mods中的文件到UML根文件系统中:

#mount -o loop CentOS6.x-x86-root_fs /mnt

#cp –R /opt/um/linux-3.10.57/mods/lib/modules/3.10.57 /mnt/lib/modules

#umount /mnt


 

5 制作文件交换系统

一般情况下不使用交换文件系统也是可以的,使用交换系统可能对系统的稳定性有些好处。

使用以下命令生成:

#dd if=/dev/zero of=swap_fs bs=1M count=512


 

#mkswap ./swap_fs


 


 

二 gdb 调试UML

经过以上步骤,调试所需要的环境已经准备好,接下来就可以开始调试工作了。

1 运行 User-Mode Linux

在 编译好的/opt/um/linux-3.10.57 根目录下,执行Linux运行

# ./vmlinux ubda=.CentOS6.x-x86-root_fs ubdb=swap_fs

或者 # ./linux ubda=.CentOS6.x-x86-root_fs ubdb=swap_fs


 

出现以下信息,说明UML运行成功,默认使用root 账户登录,无密码。

CentOS release 6.5 (Final)

Kernel 3.10.57 on an i686


 

localhost login:


 

2 gdb 调试uml

保持上一步中的UML 保持运行状态,开启另一个终端。

首先查询UML 的进程号,可以看到其中的uml根进程号为29142,但是gdb绑定的是其子进程29143。

root@liuyw-OptiPlex-9010:/opt/um/linux-3.10.57# ps -el|grep linux

4 S 0 29413 30142 27 80 0 - 8836 hrtime pts/22 00:00:02 linux

1 S 0 29420 29413 0 80 0 - 8836 SyS_io pts/22 00:00:00 linux

1 S 0 29421 29413 0 80 0 - 8836 unix_s pts/22 00:00:00 linux

1 S 0 29422 29413 0 80 0 - 8836 poll_s pts/22 00:00:00 linux

1 t 0 29423 29413 0 80 0 - 346 ptrace pts/22 00:00:00 linux

1 t 0 29551 29413 0 80 0 - 167 ptrace pts/22 00:00:00 linux

1 t 0 29702 29413 0 80 0 - 172 ptrace pts/22 00:00:00 linux

1 t 0 30000 29413 0 80 0 - 242 ptrace pts/22 00:00:00 linux

1 t 0 30025 29413 0 80 0 - 357 ptrace pts/22 00:00:00 linux

1 t 0 30032 29413 0 80 0 - 381 ptrace pts/22 00:00:00 linux


 

启动gdb,进入gdb调试环境

#gdb linux

#attach 29143


 

3 测试gdb

在gdb 环境中设置断点在sys_clone。

#b sys_clone

#i b


 

在UML环境中执行命令ls -l,系统将会在sys_clone()函数处停下来,现在就可以在gdb中查看sys_clone()函数运行的状态。


 

至此,UML 调试环境已经搭建起来了,我们就可以对linux 内核进行基本的调试了。


 

参考文档

1 http://blog.csdn.net/ztz0223/article/details/7874759

2 http://blog.chinaunix.net/uid-21525518-id-1824661.html

3 http://blog.sina.com.cn/s/blog_70dd16910101akk2.html