Ubuntu12编译、打包、换内核

本人成功的环境是在Ubuntu12下将内核换成linux-3.2.58。

一、实验目的

学习虚拟内存的基本原理和Linux虚拟内存管理技术;

深入理解、掌握Linux的按需调页过程;

掌握内核模块的概念和操作方法,和向/proc文件系统中增加文件的方法;

综合运用内存管理、系统调用、proc文件系统、内核编译的知识。

二、实验内容

1.原理

Linux的虚拟内存技术采用按需调页,当CPU请求一个不在内存中的页面时,会发生缺页,缺页被定义为一种异常(缺页异常),会触发缺页中断处理流程。每种CPU结构都提供一个do_page_fault处理缺页中断。由于每发生一次缺页都要进入缺页中断服务函数do_page_fault一次,所以可以认为执行该函数的次数就是系统发生缺页的次数。因此可以定义一个全局变量pfcount 作为计数变量,在执行do_page_fault时,该变量值加1。本实验通过动态加载模块的方法,利用/proc文件系统作为中介来获取该值。

2.实验环境

操作系统:Ubuntu 12.04(内核版本为3.2.0-23-generic-pae)

内核源码:linux-3.2.58

实验指导

  1. 下载一份内核源代码并解压

Linux受GNU通用公共许可证(GPL)保护,其内核源代码是完全开放的。现在很多Linux的网站都提供内核代码的下载。推荐使用Linux的官方网站:http://www.kernel.org

在terminal下可以通过wget命令下载源代码:

$ cd /tmp

$ wget http://www.kernel.org/pub/linux/kernel/v3.x/linux-3.2.58.tar.xz

切换到root身份,解压源代码到/usr/src目录下:

# xz –d linux-3.2.58.tar.xz

# tar –xvf linux-3.2.58.tar –C /usr/src

2. 修改内核源代码,添加统计变量

1、切换到预编译内核目录

#cd /usr/src/linux-3.2.58

2、修改处理内存访问异常的代码

//用gedit 编辑器打开fault.c,一般使用Intel x86体系结构,则修改arch/x86/目录下的文件

#gedit arch/x86/mm/fault.c

//在do_page_fault函数的上一行定义统计缺页次数的全局变量pfcount

unsigned long volatile pfcount;

//将pfcount加入到do_page_fault中,用以统计缺页次数

pfcount++;

3、修改内存管理代码

//用gedit 编辑器打开头文件mm.h

#gedit include/linux/mm.h

//在mm.h中加入全局变量pfcount的声明,代码加在extern int page_cluster;语句之后

extern unsigned long volatile pfcount;

4、导出pfcount全局变量,让整个内核(包括模块)都可以访问。方法是:

#gedit kernel/kallsyms.c

//在文件最后加入一行代码

 

EXPORT_SYMBOL(pfcount);

  1. 配置编译新内核

用编译Linux内核预备实验中的方法完成新内核的配置、编译、替换,重启后验证是否完成替换。

#uname –r    //如果为3.2.58(与你采用的新内核版本一至)说明替换完成

步骤:

1.安装需要的环境

apt-get install kernel-package build-essential libncurses5-dev fakeroot

2.使用make menuconfig 生成的内核配置文件,决定将内核的各个功能系统编译进内核还是编译为模块还是不编译。

(可以什么都不加,直接exit退出,yes保存。)

 

3.配置内核:

建议使用当前系统配置文件,使用当前系统配置文件方法:

 #cp /boot/config-3.2.0-23-generic  ./.config,然后进入menuconfig选择load选项。

4. 编译内核:

make,这可能需要2~3个小时的时间。

make完成如图:

5.加入模块

#make modules_install

6.安装内核:

#make install

即复制.config,vmlinuz,initrd.img,System.map文件到/boot目录、更新grub。对于RedHat系统以下三个grub文件自动会更新,默认启动新内核。

/etc/grub.conf

/boot/grub/menu.lst

/boot/grub/grub.conf生成可执行的内核引导文件:

 

7.重启系统:

#reboot

可以看到内核已经换成功了。

4. 编写读取pfcount值的模块代码

系统重启后,执行如下操作:

#mkdir source      //在当前用户目录下创建source文件夹,用于存放编写的用户程序

#cd source         //切换到source目录

#vi pf.c           //新建用于构建模块的代码

--------------------------------------------

/*pf.c*/ 

/*modules program*/

#include <linux/init.h>

#include <linux/module.h>

#include <linux/kernel.h>

#include <linux/mm.h>

#include <linux/proc_fs.h>

#include <linux/string.h>

#include <asm/uaccess.h>

 

struct proc_dir_entry *proc_pf;     

struct proc_dir_entry *proc_pfcount;

extern unsigned long volatile pfcount;

 

static inline struct proc_dir_entry *proc_pf_create(const char* name, mode_t mode, read_proc_t * get_info)

{

    return create_proc_read_entry(name,mode,proc_pf,get_info,NULL);

}

 

int get_pfcount(char *buffer, char **start, off_t offset, int length, int *peof, void *data)

{

    int len = 0;

    len = sprintf(buffer, "%ld \n", pfcount);

    return len;

}

 

static int pf_init(void)

{

    proc_pf = proc_mkdir("pf", 0);

    proc_pf_create("pfcount", 0, get_pfcount);

    return 0;

}

 

static void pf_exit(void)

{

    remove_proc_entry("pfcount",proc_pf);

    remove_proc_entry("pf",0);

}

 

module_init(pf_init);

module_exit(pf_exit);

MODULE_LICENSE("GPL");

 

  1. 编译、构建内核模块

#vi Makefile    //在source目录下建立Makefile文件

在Makefile中添加如下内容:

ifneq ($(KERNELRELEASE),)

obj-m:=pf.o

else

KDIR:= /lib/modules/$(shell uname -r)/build

PWD:= $(shell pwd)

default:

$(MAKE) -C $(KDIR) M=$(PWD) modules

clean:

$(MAKE) -C $(KDIR) M=$(PWD) clean

endif

make

 

  1. 加载模块到内核中

执行加载模块命令:

#insmod pf.ko

查看统计缺页次数:

#cat /proc/pf/pfcount 

 

问题:出现错误

解决:换成了ubuntu12解决。

问题:类型冲突

 

解决:返现实验指导书上的pfcount类型和之前的内核里面的不一致,改过来解决。

  • 实验心得

。。。。。。。。。。

参考链接:https://blog.csdn.net/lqglqglqg/article/details/43229669

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值