Chinaunix首页 | 论坛 | 博客
  • 博客访问: 2275343
  • 博文数量: 668
  • 博客积分: 10016
  • 博客等级: 上将
  • 技术积分: 8588
  • 用 户 组: 普通用户
  • 注册时间: 2008-05-29 19:22
文章分类

全部博文(668)

文章存档

2011年(1)

2010年(2)

2009年(273)

2008年(392)

分类:

2008-10-03 09:18:53

参考网上相关资料,现将我在FC6上建立过程归一下
个人用的Linux版本为:FC6/Linux,内核版本为:2.6.18-1.2798.fc6 编译工具:gcc-3.4.1
1.获得Linux内核的源代码,即构建LDD3(Linux Device Drivers 3rd)上面所说的内核树。 
       假如安装的Linux系统中已自带了源代码的话,应该在/usr/src目录下。假如该
目录为空的话,则需要自己手动下载源代码。下载代码的方法和链接很多,也能够在上通
过去下载。但是,下载的内
核版本最好和所运行的Linux系统的内核版本一致。当然,也能够比Linux系统内核的版
本低,但高的话应该不行(个人尚未实践)。
2.下载完成后,安装在/usr/src下,文档名为:2.6.18-1.2798.fc6-i586.tar.bz2,是个压缩包,解压缩既能够得到整个内核的源代码: 
# tar jxvf 2.6.18-1.2798.fc6-i586.tar.bz2 
解压后生成一个新的目录/usr/src/2.6.18-1.2798.fc6-i586,任何的源代码都在该目录下。 
注:该目录会因内核版本的不同而不同,各位动手实践的朋友只需知道自己的源代码所在的具体位置即可。 
3.稍微更改一下Makefile:
每个内核的名字都包含了他的版本号,这也是 uname -r 命令显示的值。内核Makefile 的前四行定义了内核的名字。为了保护官方的内核不被破坏,Makefile
经过了修改,以生成一个和运行中的内核不同的名字。在一个模块插入运行中的内核前,这个模块必须针对运行中的内核进行编译。为此,您必须编辑内核的
Makefile。
例如,假如 uname -r 返回字符串2.6.18-1.2798.fc6,就将 EXTRAVERSION 定义从:
EXTRAVERSION = -prep
修改为:
EXTRAVERSION = -1.2798.fc6
VERSION = 2
PATCHLEVEL = 6
SUBLEVEL = 18
也就是最后一个连字符后面的任何内容。
4.配置及编译内核。 
进入/usr/src/2.6.18-1.2798.fc6-i586/目录下,能够看到Makefile文档,他包含了整个内核树编译信息。该文档最上面四行是关于内核版本的信息。对于整个Makefile能够不用做修改,采用默认的就能够了。 
一般情况下,需要先用命令诸如"make menuconfig", "make xconfig"或"make oldcofig"对内核进行配置,这几个都是对内核进行配置的命令,只是他们运行的环境不相同,执行一下这几个命令中的任何一个即可对内核进行配置: make menuconfig是基于界面的内核配置方法,make xconfig应该是基于QT库的,更有make gcofig也是基于图像的配置方法,应该是需要GTK的环境,make oldcofig就是对内核树原有的.config文档进行配置一下即可。 
其实内核的配置部分,主要是确保内核启动模块可动态加载的配置,默认配置里面应该已包含了这样的内容,因此,我用的是make menuconfig. 
注意:
您的内核必须已启用这些选项进行了编译,用以支持模块的动态加载。
(用make menuconfig调出内核配置菜单):
Loadable module support --->
  •  Enable loadable module support
  •  Module unloading
    [ ] Module versioning support (EXPERIMENTAL)
  •  Automatic kernel module loading
    注:该步没做时,在make modules时将出错。
    Kernel Feautre -> Preemptible Kernel

  • 注:该项为内核抢占式调度配置, 必须确保在构建运行的内核和编译环境的内核时都选上,一般PC机运行的内核已选上了,否则在insmod时将出现如下错误:
    # insmod st7565p_driver26.ko
    Using st7565p_driver26.ko
    st7565p_driver26: version magic '2.6.14.7 ARMv4 gcc-3.4' should be '2.6.14.7 preempt ARMv4 
    gcc-3.4'
    insmod: cannot insert `st7565p_driver26.ko': Invalid module format (-1): Exec format error
    在内核源码的目录下执行: 
    # make 
    # make bzImage      编译内核 
    其中,第一个make也能够不执行,直接make bzImage。这个过程可能比较长,因为是对整个内核重新编译了。执行结束后,能够看到在当前目录下生成了一个新的文档: vmlinux, 其属性为-rwxr-xr-x。 
    然后执行: 
    # touch *  // 时间或时区配置,源代码的时间戳比本机的时间更新,否则产生:make[2]: 警告:检测到时钟错误。您的创建可能是不完整的。
    # make modules          编译模块
    # make modules_install    安装编译
    对内核的任何模块进行编译和安装。完成“内核树”的安装:
    执行结束之后,会在/lib/modules下生成新的目录/lib/modules/2.6.18-1.2798.fc6/。 在随后的编译模块文档时,要用到这个路径下的build目录。至此,内核编译完成。                         目录“/usr/src/2.6.18-1.2798.fc6-i586/”中就是所谓的“内核代码树”但是“/lib/modules/2.6.18-1.2798.fc6/build”是个符号链接,也指向这个目录,所以这里也能够叫做“内核代码树”,能够重启一下系统。 
    5.编写模块文档及Makefile 
    以LDD3上的hello.c为例:
    #include 
    #include 
    #include 
    MODULE_LICENSE("Dual BSD/GPL");
    static int hello_init(void)
    {
    printk("hello,world.\n");
    return 0;
    }

    static void hello_exit(void)
    {
    printk("Good bye!\n");

    }

    module_init(hello_init);
    module_exit(hello_exit);

    Makefile如下:
    obj-m := hello.o
    #KERNELDIR:=/lib/modules/$(shell uname -r)/build
    PWD:=$(shell pwd)

    all:
           make -C $(KERNELDIR) M=$(PWD) modules

    clean:
           rm -rf *.o *~ core .depend .*.cmd *.ko *.mod.c .tmp_versions
    上面的Makefile是这样确定内核源码树所在的目录的: 我们先到/lib/modules目录, 会看到一些以内核版本为名的目录, 目录中有一个build文档, 他是个符号连接, 指向内核源码树. 那么如何确定进入哪个内核版本的目录呢? 这就能够通过 $ uname -r 来确定, 他指出了当前运行内核的版本.
    上面的例子中只讨论了任何的代码在一个文档中的情况. 若代码分布在多个源文档中,  比如file1.c, file2.c, 生成hello.ko. 应该这样写Makefile:
    obj-m :=  hello.o
    hello-objs := file1.o file2.o
    注意, 虽然我们的目的是生成.ko文档, 但在Makefile中写为.o!
    hello.c和Makefile文档应该位于同一个目录下,能够放在/home下。 
    6.:编译和装载模块 
    在文档所处的目录下,执行: 
    # make 
    然后查看该目录下有哪些文档生成:可见,已生成模块文档hello.ko. 
    hello.ko
    hello.mod.c
    hello.mod.o
    hello.o
    运行命令:
    # insmod hello.ko
    应该能够看到返回的信息:Hello, world
    以通过lsmod来查看模块是否加载进内核
    然后再运行命令:
    # rmmod hello
    应该能够看到返回的信息:Goodbye! 
    假如没看到,就是输出到系统的日志文档中去了,能够查看文档:
    tail –f /var/log/messages
    cat /var/log/syslog
    应该有信息的输出。
    以通过lsmod来查看该模块是否被卸载.



    本文来自ChinaUnix博客,假如查看原文请点:http://blog.chinaunix.net/u2/62451/showart_487605.html 
  • 阅读(1200) | 评论(0) | 转发(0) |
    给主人留下些什么吧!~~