实验二 (一) Linux内核编译
一,实验题目linux内核编译
makefile文件的生成
添加内核模块
二,实验目的了解linux系统如何编译并安装内核
如何使用autotools工具生成makefile文件
如何向自己操作系统内核添加模块。
三,实验平台一台装有Linux Mint17.3,内核版本为4.2.0-18-generic的笔记本,用到的工具以及版本号如下:
GNU Make 3.81
automake (GNU automake) 1.15( 下载地址:http://ftp.gnu.org/gnu/automake)
autoconf (GNU Autoconf) 2.69(下载地址:http://ftp.gnu.org/gnu/autoconf)
(因为使用系统自带的工具出问题了,比如autoscan会执行很久而且生成的configure.scan文件会有很多的信息,所以我在官网下了相关工具后,基本上没有出现什么问题了)
所编译的内核为linux-3.18.28.tar.xz。
四,要求自主完成
五,流程
Created with Raphaël 2.1.2开始获取内核配置内核特性编译内核安装内核模块安装内核验证并测试结束1.获取内核源码,解压到/user/src
阅读安装手册README
保持干净源代码
2.配置内核特性(我使用allyesconfig,不用像menuconfig那样去选择)
3.编译内核
使用
$ cat/proc/cpuinfo|more
$ lspci
两个命令查询本机的配置,如图可知我的CPU物理核心总数是2。
$ make-j#
//#号最多为CPU物理核心总数的两倍(-j 选项为可选选项,可以不选)
4.安装内核模块
$ make modules_install
5.安装内核
$ make install
6.验证并测试
查看新内核是否已经添加,然后重启系统并测试
如图,grub已经检测到内核版本3.18.28。
六,心得体会编译内核是一件重要的事情。我们可以通过自己编译内核,来自己定制一个适合自己,适合自己机器的操作系统。编译内核是一件细心活,选择定制的各项功能需要自己明白自己需要什么功能,自己的机器硬件的相关信息。
总之,通过这次内核编译的实践,我受益良多。
(二)生成makefile文件
Created with Raphaël 2.1.2开始预先按装需要的autotools软件写下c源码和Makefile.am文件运行autoscan修改configure.scan文件依次运行aclocal,autoheader,autoconf,automake运行./configure,即可生成makefile文件测试并结束预先按装需要的软件automake,autoconf。
创建test目录,在test目录下,写下fib.c,fib.h,main.c。
//------------------------fib.c
#include"fib.h"
intfib(intn)
{
if(n==0)
return0;
if(n==1||n==2)
return1;
returnfib(n-1)+fib(n-2);
}
//-------------------------main.c
#include
#include"fib.h"
intmain()
{
intn=0;
printf("input n = \n");
scanf("%d",&n);
printf("fib(%d) = %d\n",n,fib(n));
return0;
}
//-------------------------fib.h
intfib(intn);运行autoscan,test目录下生成autoscan.log和configure.scan文件。
将configure.scan改成configure.ac,并修改。(使用mv configur.scan configure.ac 修改文件名,修改后的内容如下图所示)
# -*- Autoconf -*-
#Process this file with autoconf to produce a configure script.
AC_PREREQ([2.69])
AC_INIT(fib,1.0,498120236@qq.com)
AC_CONFIG_SRCDIR([main.c])
AC_CONFIG_HEADERS([config.h])
AM_INIT_AUTOMAKE(fib,1.0)
# Checks for programs.
AC_PROG_CC
# Checks for libraries.
# Checks for header files.
AC_CHECK_HEADERS([stdio.h])
# Checks for typedefs, structures, and compiler characteristics.
# Checks for library functions.
AC_OUTPUT(Makefile)AC_INIT(fib, 1.0, 498120236@qq.com) (括号里需要修改的是程序名称,版本号,BUG提交联系地址)
自己增加:AM_INIT_AUTOMAKE(fib,1.0)
指定生成makefile:AC_OUTPUT(Makefile)新建Makefile.am
AUTOMAKE_OPTIONS=foreign
bin_PROGRAMS=fib
fib_SOURCES=main.c fib.c fib.hforeign选项是当成一般文件处理,不需生成GNU要求的其他相关文件
bin_PROGRAMS=fib:指定生产程序名
fib_SOURCES=main.c fib.c fib.h:指定了生成程序的相关源文件
运行aclocal,扫描configure.ac文件,生成aclocal.m4文件和autom4te.cache两个文件。
运行autoheader,成功之后,会在目录下产生 config.h.in 这个新文件。
运行autoconf,成功之后,会在目录下产生 configure 这个新文件。
运行automake --add-missing(将Makefile.am和configure.in两个文件生成Makefile.in文件)
运行./configure(会生成make需要的Makefile文件)
运行make,测试并运行
(在此,只需使用 make dist 命令,就可以将写的程序打包成 *.tar.xz格式的软件压缩包)
心得在Unix或者Unix-like上写过程序的人尤其是用 C 来开发程序的人一般都会使用 Makefile,用 make 来开发和编译程序的确很方便,可是要写出一个Makefile就不是一件简单的事情。使用Autoconf 及 Automake这两个软件就可以轻松产生Makefile 文件。当软件打包后,用户只要使用 “./configure”, “make”, “make install” 就可以把程序安裝到系统中,用户不需指定安装路径。
(三) 内核模块的添加
Created with Raphaël 2.1.2开始新建c源文件编写Makefile文件执行make命令加载模块insmod观察模块dmesg卸载模块rmmod结束Linux内核模块动态添加
新建一个目录path,在path目录中新建c源文件,其代码如下:
#include
#include
#include//三个都是驱动程序需要的头文件
staticinthello_init(void)
{
printk(KERN_ALERT"Hello World!/n");
//printk和printf一样的功能,只是运行在内核态。
return0;
}
staticvoidhello_exit(void)
{
printk(KERN_ALERT"Bye World!/n");
}
module_init(hello_init);
module_exit(hello_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("WFJ");
/***************代码不是我自己写的******************/编写Makefile文件,其内容如下(必须命名为Makefile):
obj-m:=hello.o
KDIR:=/lib/modules/4.2.0-18-generic/build
#其中,4.2.0-18-generic 根据linux系统版本确定,可以通过
# uname -r 来确定
default:
make-C $(KDIR)M=$(shell pwd)modules
clean:
rm-rf*.o*.ko*.mod.c.*.cmd.tmp_versions*.order*.symversMakefile是对比不同大神的文件,自己修改适合自己情况的makefile文件执行make命令
make成功后,当前目录下生成hello.ko文件。加载模块insmod hello.ko(需要超级权限)
观察模块dmesg(需要超级权限)
卸载模块rmmod hello.ko(需要超级权限)
心得这个实验开始时毫无头绪,不知从哪里下手,花费了许多时间翻阅有经验人士的资料后,依葫芦画瓢,才得以顺利进行。当对一件事情毫无办法时,借鉴他人的做法,无疑是上上之选。当然,他人的经验绝不可以原样照搬,要选取适合自己情况的经验,自己加以思考,方能达到预期目的。经过这次实验,我深深地认识到自己的不足,除了知识储备不够,就是不懂得实践,以为弄清楚他人的每一步,就可以顺顺利利的完成实验,却没有首先想到自己先试一试。网上有位大神说过,只要拥有入门的知识就可以开始实践了,在实践的过程中,发现不足就通过学习来补足知识漏洞。这种学习方法也许是一种高效的学习方法。