编译linux本机的内核模块需要内核源码树么,编译第一个hello内核模块(在内核源码树外编译)...

刚接触内核模块,现在只知道编译内核模块有两种方式,一种是在内核源码树外编译,另一种是在内核源码树内编译。

这篇文章是有关内核源码树之外编译的情况。

首先搭建环境:

内核源码树:我的ubunut10.10安装后有自带的内核源码树,在lib/modules/2.6.35-22-generic目录下有build文件。

新建一个文件夹:假设我的是~/Desktop/driverStudy/hello,在这个文件夹下新建两个文件hello.c、Makefile。

hello.c:

#include

#include

#include

static int hello_init(void)

{

printk(KERN_ALERT "Hello,World\n");

return 0;

}

static void hello_exit(void)

{

printk(KERN_ALERT "Goodbye,World\n");

}

module_init(hello_init);

module_exit(hello_exit);

MODULE_LICENSE("Dual BSD/GPL");头文件说明:

/linux/init.h: module_init()、module_exit()

/linux/module.h:MODULE_LICENSE()

/linux/kernel.h:printk(),KERN_ALERT

Makefile:

ifeq ($(KERNELRELEASE),)

KERNELDIR ?=/lib/modules/$(shell uname -r)/build

PWD := $(shell pwd)

modules:

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

modules_install:

$(MAKE) -C $(KERNELDIR) M=$(PWD) modules_install

clean:

rm -rf *.o *~ core .depend .*.cmd *.ko *.mod.c .tmp_versions

else

obj-m := hello.o

endif

进入~/Desktop/driverStudy/hello目录,输入make,之后执行的步骤如下:

1.首先会判断ifeq ($(KERNELRELEASE),),KERNELRELEASE是内核源码树下Makefile中定义的一个宏。显然执行make后判断ifeq ($(KERNELRELEASE),)时KERNELRELEASE是空的,所以向下执行,不进行跳转。

2.KERNELDIR ?=/lib/modules/$(shell uname -r)/build,如果没有定义KERNELDIR ,那么定义为/lib/modules/$(shell uname -r)/build,即/lib/modules/2.6.35-22-generic/build,$(shell pwd)的值为/root/Desktop/driverStudy/hello

3.make的默认目标是mudules(如果把modules和modules_install换一下位置,应该默认是modules_install?,这里插一句make modules和make modules_install的区别,分别是生成相应的模块和把模块拷贝到需要的目录中),执行$(MAKE) -C $(KERNELDIR) M=$(PWD) modules,替换后得到:

make -C /lib/modules/2.6.35-22-generic/build M=/root/Desktop/driverStudy/hello modules

4.对3中的make语句要重点分析:首先它进入/lib/modules/2.6.35-22-generic/build目录读取build下的Makefile文件,并从中得到一些信息,例如变量KERNELRELEASE在这时被赋值,读取内核源码树的Makefile之后,会到M表示的目录下执行该目录下的Makefile文件。

5.M表示的目录是什么呢?正是/root/Desktop/driverStudy/hello,就是我们执行make的目录,所以上面的Makefile再一次被调用,但是此时的KERNELRELEASE已经在4中被赋值了,所以直接执行else之后的语句,即obj-m := hello.o,生成了hello.o文件。

6.此时MODPOST程序将被调用,生成hello.mod.c文件,最后链接hello.o和hello.mod.c文件,生成hello.ko模块文件。把1-5称为stage1,6为stage2。

以下是我的build log

root@yin-vm:~/Desktop/driverStudy/hello# make

make -C /lib/modules/2.6.35-22-generic/build M=/root/Desktop/driverStudy/hello modules

make[1]: Entering directory `/usr/src/linux-headers-2.6.35-22-generic'

CC [M] /root/Desktop/driverStudy/hello/hello.o

Building modules, stage 2.

MODPOST 1 modules

CC /root/Desktop/driverStudy/hello/hello.mod.o

LD [M] /root/Desktop/driverStudy/hello/hello.ko

make[1]: Leaving directory `/usr/src/linux-headers-2.6.35-22-generic'

之后是一些安装模块及测试的情况,直接贴Log了:

root@yin-vm:~/Desktop/driverStudy/hello# insmod hello.ko

root@yin-vm:~/Desktop/driverStudy/hello# dmesg|tail

[ 442.658198] vmci 0000:00:07.7: PCI INT A -> GSI 16 (level, low) -> IRQ 16

[ 442.660608] Found vmci/PCI at 0x1080, irq 16.

[ 442.661212] VMCIUtil: Host capability check: PASSED

[ 442.662897] Registered vmci device.

[ 447.577853] audit_printk_skb: 9 callbacks suppressed

[ 447.578001] type=1400 audit(1416796755.035:15): apparmor="DENIED" operation="capable" parent=13431 profile="/usr/sbin/cupsd" pid=13436 comm="serial" capability=21 capname="sys_admin"

[ 1069.590461] pcnet32 0000:02:01.0: eth0: link up

[ 1069.594377] ADDRCONF(NETDEV_CHANGE): eth0: link becomes ready

[ 3841.719888] hrtimer: interrupt took 8690229 ns

[13123.785160] Hello,World

root@yin-vm:~/Desktop/driverStudy/hello# lsmod|grep hello

hello 692 0

root@yin-vm:~/Desktop/driverStudy/hello# rmmod hello.ko

root@yin-vm:~/Desktop/driverStudy/hello# lsmod|grep hello

root@yin-vm:~/Desktop/driverStudy/hello#

root@yin-vm:~/Desktop/driverStudy/hello# insmod hello.ko

root@yin-vm:~/Desktop/driverStudy/hello# modinfo hello.ko

filename: hello.ko

license: Dual BSD/GPL

srcversion: A8507261C23010472BCCA44

depends:

vermagic: 2.6.35-22-generic SMP mod_unload modversions 686

root@yin-vm:~/Desktop/driverStudy/hello# cat /proc/modules | grep hello

hello 692 0 - Live 0xe0894000

root@yin-vm:~/Desktop/driverStudy/hello# ls /sys/module/

8250 ehci_hcd ipv6 mptbase powernow_k7 shpchp snd_timer vmblock

ac97_bus eisa_bus kernel mptscsih ppdev snd soundcore vmci

acpi floppy keyboard mptspi printk snd_ac97_codec speedstep_lib vmhgfs

acpi_cpufreq fuse kgdboc netpoll processor snd_ens1371 speedstep_smi vmware_balloon

acpiphp gameport libata parport psmouse snd_page_alloc spurious vmxnet

agpgart gx_suspmod longhaul parport_pc rfkill snd_pcm sr_mod vsock

apparmor hello lp pcie_aspm sbs snd_rawmidi tcp_cubic vt

battery i2c_piix4 md_mod pciehp scsi_mod snd_seq thermal wmi

binfmt_misc i8042 mii pci_hotplug scsi_transport_spi snd_seq_device uhci_hcd

cpufreq_nforce2 intel_agp mmc_core pci_slot serio_raw snd_seq_midi usbcore

debug_core intel_idle mousedev pcnet32 sg

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值