Chinaunix首页 | 论坛 | 博客
  • 博客访问: 21800
  • 博文数量: 7
  • 博客积分: 10
  • 博客等级: 民兵
  • 技术积分: 50
  • 用 户 组: 普通用户
  • 注册时间: 2012-02-21 01:23
个人简介

This is pipilucn.

文章分类

全部博文(7)

文章存档

2013年(7)

我的朋友

分类: LINUX

2013-03-23 01:37:59

       嵌入式Linux内核模块的配置与编译
一、简介
 本文通过一个简单的示例,首先介绍了如何在Linux下编译出一个内核模块,然后介绍了Linux内核中的配置系统,讲述了如何将一个自定义的模块作为系统源码的一部分编译出新的操作系统,注意,在这里我们介绍的内容均在内核2.6.13.2(也是笔者的开发平台的版本)上编译运行通过,在2.6.*的版本上基本上是可以通用的。
二、单独编译内核模块
 内核模块的编译与普通应用程序的编译一样,也使用的GCC,但是内核模块在用GCC编译的时候时需要使用特定的参数并定义一些宏。 这是因为在编译普通应用程序的可执行文件和内核模块时,内核头文件起的作用是不同的。在以往的内核版本需要我们去在Makefile中手动设置这些设定, 虽然这些Makefile都是按目录分层次存放的,但使用维护起来还是比较伏在。幸运的是,一种称为kbuild的新方法被引入,现在外部的可加载内核模 块的编译的方法已经同内核编译统一起来,编译新的内核模块或者将自己的内核模块集成到内核源码中都已经变得非常简单了。
 现在让我们看一下如何编译一个名字叫做test.c的模块。
 首先,我们需要写一个简单的Makefile文件:
 obj-m += test.o
 将test.c和Makefile文件放在同一个目录下,然后就可以开始编译了,使用编译命令:
 make -C /usr/src/linux-2.6.13.2/ SUBDIRS=$PWD modules
 回车后,也许你会发现有一堆的报错,请检查如下配置是否正确:
 1、在/usr/src/下有无放置你需要使用的内核源码树?如果没有,请上网down一个你需要的内核源码版本,解压后放在这里。
 2、如果你已经将内核源码解压在/usr/src/下了,那么请先使用在内核源码的主目录下,在笔者的系统中就是/usr/src/linux-2.6.13.2/,使用:
 make config或者make menuconfig或者make gconfig等命令来配置内核,然后使用make all将整个内核完整编译一次。 (有的linux系统版本make menuconfig时会出现错误,可能是缺少curses 库的原因,可以自己搜索相关帖子解决,在这我上传一个: ncurses-devel-5.5-24.20060715.i386.rar   )
 3、上述命令中的linux-2.6.13.2是笔者使用的内核源码的目录名,你需要将它改成你自己使用对应版本的的内核源码的目录名。
 经过上述三步,一般来将,该内核模块都可以编译通过了,生成的test.ko就是我们需要的内核模块的最终版本,你可以使用:
 insmod ./test.ko将该模块载入系统。 请注意:如果想将模块载入系统,请保证编译模块使用的内核源码的版本与要载入的系统的版本一致!否则无法载入!
一旦版本不一致就汇报如下错误:
insmod: error inserting 'helloworld.ko': -1 Invalid module format
这个问题你可以参看我的两个帖子:
http://blog.chinaunix.net/uid-25100840-id-372511.html  
和: http://blog.chinaunix.net/uid-25100840-id-371803.html
(这2个是遇到问题和解决办法)


三.
嵌入式开发实作(Linux内核编译及安装)

内核配置
先定义内核需要什么特性,并进行配置。内核构建系统(The kernel build system)远不是简单用来构建整个内核和模块,想了解更多的高级内核构建选项,你可以查看 Documentation/kbuild 目录内的内核文档。

可用的配置命令和方式:

make menuconfig
命令:make menuconfig
编译内核
编译和安装内核
编译步骤:

$ cd /usr/src/linux2.6
$ make

安装步骤 (logged as
$ make install
$ make modules_install

提升编译速度
多花一些时间在内核配置上,并且只编译那些你硬件需要的模块。这样可以把编译时间缩短为原来的1/30,并且节省数百MB的空间。另外,你还可以并行编译多个文件:
$ make -j <number>
make 可以并行执行多个目标(target)(KEMIN:前提是目标规则间没有交叉依赖项,这个怎么做到的?)

$ make -j 4
即便是在单处理器的工作站上也会很快,读写文件的时间被节省下来了。多线程让CPU保持忙碌。
number大于4不见得有效了,因为上下文切换过多反而降低的工作的速度。
make -j <4*number_of_processors>
内核编译tips

查看完整的 (gcc, ld)命令行: $ make V=1
清理所有的生成文件 (to create patches...): $ make mrproper
部分编译:$ make M=drivers/usb/serial
单独模块编译:$ make drivers/usb/serial/visor.ko

四.
最终生成的文件
vmlinux 原始内核镜像,非压缩的
arch/<arch>/boot/zImage zlib压缩的内核镜像(Default image on arm)
arch/<arch>/boot/bzImage bzip2压缩的内核镜像。通常很小,足够放入一张软盘(Default image on i386)
安装的文件
/boot/vmlinuz-<version> 内核镜像;
/boot/System.map-<version> 保存有内核的符号地址(symbol addresses);
/boot/initrd-<version>.img Initial RAM disk:保存有你需要在引导时挂接最终根文件系统的模块。安装命令“make install”为替你运行“mkinitrd ”生成initrd;
/etc/grub.conf or /etc/lilo.conf
bootloader的配置文件:“make install”会为你的新内核更新相应的bootloader的配置文件。如果你使用的是LILO,它会在生成配置文件后,执行/sbin/lilo,让LILO的配置生效。
/lib/modules/<version>/ Kernel modules + extras
build/
为本<version>的内核添加模块所需的所有东西: .config file (build/.config), module symbol information (build/module.symVers), kernel headers (build/include/)
kernel/
内核模块文件 .ko (Kernel Object),目录结构与源代码目标一一对应。
modules.alias
模块别名记录(用于insmod和modprobe),例如:
alias sound--service--?-0 snd_mixer_oss
modules.dep
模块依赖记录(用于insmod和modprobe)
modules.symbols
标识某符号是属于哪个模块的。
这个目录的所有文件都是文本文件,可以直接查看。

五.
小结编译及安装步骤:
编辑Makefile版本信息
定义内核特性,生成配置文件.config,用于编译:make xconfig
编译内核:make
安装内核:make install
安装模块:make modules_install

六.
交叉编译内核
Makefile修改
通常通过修改已有的makefile获得
你必须修改目标平台,假设目标平台是ARM,修改以下:
ARCH ?= arm
CROSS_COMPILE ?= arm-linux-

或运行带参数的make:
$ cd /usr/scr/linuxXX
$ make ARCH=arm CROSS_COMPILE=arm-linux-
  

内核配置文件
配置过程和本地配置一样; 可以把生成的配置文件(.config)分享给其他人,比如像:
$ cp .config arch/<arch>/config/acme_defconfig
这样其他同样开发ACME系统的开发人员可以通过以下命令编译出同样的内核:

$ make acme_defconfig

建立交叉编译环境(Cross--compiling setup)
假设你有ARM的交叉编译工具(cross--compiling toolchain)在 in /usr/local/arm/3.3.2/, 你得把它输出到PATH:
$ export PATH=/usr/local/arm/3.3.2/bin:$PATH

注意查看内核文档(在Documentation/Changes)有关最低工具版本要求。
编译并安装内核
1. $ make //如果你修改了Makefile
或者
1'. $ make ARCH=arm CROSS_COMPILE=arm-linux-
2. 拷贝 arch/<platform>/boot/zImage 到目标系统
$ make modules_install
3. 拷贝 /lib/modules/<version> 到目标系统

你可以通过 arch/<arch>/boot/install.sh 自定义安装,让”make install“自动代劳。
阅读(1313) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~