内核编译

来源:互联网 发布:美工培训课程 编辑:程序博客网 时间:2024/06/02 06:57

今天整理工作时需要编译内核与内核模块,这里整理一下作为备忘。

1.手动编译

(1)下载内核源码。对内核源码做一些修改。(patch文件,patch -p(x) < xx.patch)

  (2)  对源码进行配置: make menuconfig 或者 使用原来的配置文件 .config 运行 make oldconfig。

 (3) 设置编译的环境变量:

            export PATH = $(PATH):xxxx/bin 

            export ARCH = ARM

            export 

 (4)  make uImage

2. 用openembed 自动编译内核的使用方法:(待续)


编译某个内核模块

新的内核模块编程中的make命令里有个M选项,如下: 
make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules
M=$(PWD) 意思是返回到当前目录继续读入、执行当前的Makefile。 
请参考:
从 2.4 到 2.6:Linux 内核可装载模块机制的改变对设备驱动的影响

这个M是kbuild的东西呢,还是make本来自己就有的东西呢? 
按理说,它是make的一个参数,应该是make的东西,但是make的doc里又找不到, 
如果是kbuild里的东西,它应该怎样来实现呢?

经查证这个M是内核根目录下的Makefile中使用的变量。 
M是makefile脚本中的一个变量(variable) 


# Use make M=dir to specify directory of external module to build
# Old syntax make ... SUBDIRS=$PWD is still supported
# Setting the environment variable KBUILD_EXTMOD take precedence
ifdef SUBDIRS
KBUILD_EXTMOD ?= $(SUBDIRS)
endif
ifdef M //如果没有定义或赋值M,此处M未定义(undefined)

ifeq ("$(origin M)", "command line") //如果定义了,此句用来判断M是否从命令行来

KBUILD_EXTMOD := $(M)
endif
endif





以下是来自:从 2.4 到 2.6:Linux 内核可装载模块机制的改变对设备驱动的影响

清单3:2.6 内核模块的Makefile模板
# Makefile2.6 ifneq ($(KERNELRELEASE),) #kbuild syntax. dependency relationshsip of files and target modules are listed here. mymodule-objs := file1.o file2.o obj-m := mymodule.o  else PWD  := $(shell pwd) KVER ?= $(shell uname -r) KDIR := /lib/modules/$(KVER)/build all:  $(MAKE) -C $(KDIR) M=$(PWD)  clean: rm -rf .*.cmd *.o *.mod.c *.ko .tmp_versions endif 

KERNELRELEASE是在内核源码的顶层Makefile中定义的一个变量,在第一次读取执行此Makefile时,KERNELRELEASE没有被定义, 所以make将读取执行else之后的内容。如果make的目标是clean,直接执行clean操作,然后结束。当make的目标为all时,-C $(KDIR) 指明跳转到内核源码目录下读取那里的Makefile;M=$(PWD) 表明然后返回到当前目录继续读入、执行当前的Makefile。当从内核源码目录返回时,KERNELRELEASE已被被定义,kbuild也被启动去解析kbuild语法的语句,make将继续读取else之前的内容。else之前的内容为kbuild语法的语句, 指明模块源码中各文件的依赖关系,以及要生成的目标模块名。mymodule-objs := file1.o file2.o表示mymoudule.o 由file1.o与file2.o 连接生成。obj-m := mymodule.o表示编译连接后将生成mymodule.o模块。

补充一点,"$(MAKE) -C $(KDIR) M=$(PWD)"与"$(MAKE) -C $(KDIR) SUBDIRS =$(PWD)"的作用是等效的,后者是较老的使用方法。推荐使用M而不是SUBDIRS,前者更明确。

通过以上比较可以看到,从Makefile编写来看,在2.6内核下,内核模块编译不必定义复杂的CFLAGS,而且模块中各文件依赖关系的表示简洁清晰。


模块的加载:

将生成模块 x.ko放到 /.lib/module下面,运行depmod。 然后就可以直接加载模块:modprobe xx.ko

insmod 与 modprobe 都是载入 kernel module,不过一般差别于 modprobe 能够处理 module 载入的相依问题。
  比方你要载入 a module,但是 a module 要求系统先载入 b module 时,直接用 insmod 挂入通常都会出现错误讯息,不过 modprobe 倒是能够知道先载入 b module 后才载入 a module,如此相依性就会满足。
  不过 modprobe 并不是大神,不会厉害到知道 module 之间的相依性为何,该程式是读取 /lib/modules/2.6.xx/modules.dep 档案得知相依性的。而该档案是透过 depmod 程式所建立。
补充说明:modprobe可载入指定的个别模块,或是载入一组相依的模块。modprobe会根据depmod所产生的相依关系,决定要载入哪些模块。若在载入过程中发生错误,在modprobe会卸载整组的模块。

[举例]
*查看modules的配置文件:
$modprobe -c
这里,可以查看modules 的配置文件,比如模块的<a href="http://www.linuxso.com/command/%3Ca%20href=" http:="" www.linuxso.com="" command="" alias.html'="" target="_blank" style="color: rgb(8, 65, 214); text-decoration: initial;">alias.html' target='_blank'>别名是什么等。会打印许多行信息,例如其中的一行会类似如下:
alias symbol:ieee80211_remove_wds_addr wlan

*列出内核中所有已经或者未挂载的所有模块:
$modprobe -l
这里,我们能查看到我们所需要的模块,然后根据我们的需要来挂载;其实modprobe -l 读取的模块列表就位于 /lib/modules/'uname -r' 目录中;其中uname -r 是内核的版本.例如输出结果的其中一行是:
/lib/modules/2.6.27-7-generic/kernel/arch/x86/oprofile/oprofile.ko

*挂载vfat模块:
#modprobe vfat
这里,使用格式"modprobe 模块名"来挂载一个模块。挂载之后,用lsmod可以查看已经挂载的模块。模块名是不能带有后缀的,我们通过modprobe -l 所看到的模块,都是带有.ko 或.o后缀。

*移除已经加载的模块:
#modprobe -r  模块名
这里,移除已加载的模块,和rmmod 功能相同。注意:模块名是不能带有后缀的,我们通过modprobe -l 所看到的模块,都是带有.ko 或.o后缀. 

与内核模块操作相关的命令还有:lsmod     modinfo   depmod    rmmod    inmod    modprobe   

 

  • modprobe 命令是根据depmod -a的输出/lib/modules/version/modules.dep来加载全部的所需要模块。  
  • 删除模块的命令是:modprobe -r filename  
  • 系统启动后,正常工作的模块都在/proc/modules文件中列出。使用lsmod命令也可显示相同内容。  
  • 在内核中有一个“Automatic kernel module loading"功能被编译到了内核中。当用户尝试打开某类型的文件时,内核会根据需要尝试加载相应的模块。/etc/modules.conf或 /etc/modprobe.conf文件是一个自动处理内核模块的控制文件。
    参  数:
      -a或--all  载入全部的模块。 
      -c或--show-conf  显示所有模块的设置信息。 
      -d或--debug  使用排错模式。 
      -l或--list  显示可用的模块。 
      -r或--remove  模块闲置不用时,即自动卸载模块。 
      -t或--type  指定模块类型。 
      -v或--verbose  执行时显示详细的信息。 
      -V或--version  显示版本信息。 
      -help  显示帮助。

原创粉丝点击