内核树的建立及其Hello World 模块的加载

原创 2012年09月20日 09:06:53
内核树的建立及其Hello World 模块的加载
       每每到了一定程度过后,对自己所做过的事,看过的书等做一些总结是很有必要的。初学驱动编程,面对的第一个难题就是这个驱动编程该怎么学,入门是关键。在前辈们推荐下和在网上搜索中,得出结论:不知道怎么学和该学些什么,那就看这两本书:O'REILLY写的《LINUX设备驱动程序》和宋宝华的《LINUX设备驱动程序(第3版)》,或者你有兴趣的话把这本书《嵌入式Linux应用程序开发标准教程(华清远见)》也看了。学习的过程不能只看书,需要在理论和实践中获得进步。下面是我在学习过程中做的一些总结。
内核树的建立
       我在一开始就遇到了第一个问题就是:为什么要建立内核树?内核树就是在网上下载内核源代码编译过后的文件,简单地可以理解为我们在编译驱动模块时需要用到的一些依赖文件,也就是一些库相关的,也可以说是一种驱动模块编译环境。由此又有新的问题:难道我们的Linux系统不能提供驱动模块编译的环境吗?答案是否定的,当然发布的Linux肯定是提供了这样一套驱动模块编译的环境的,但是发布的Linux为了使系统变得很轻量级,不得不把一些臃肿的不是必须的工具、文件等都删掉了。这就是我们为什么要建立内核树,因为它提供了调试内核模块等功能。
在明白了第一个问题过后,我需要做的就是如何把下载好的源代码编译成内核树。首先,我们需要下源码,最好下载对应系统版本号的源码:
查看内核版本:uname –r    --->  2.6.32-41-generic(我的内核版本)
得到对应的源码:
sudo apt-cache search linux-source
sudo apt-get install linux-source-2.6.32
下载完过后,在/usr/src/ 下面有个对应的压缩包,解压过后进入linux-source-2.6.32
此时要对内核编译进行配置:oldconfig、 menuconfig、 xconfig 选择其中一种就行了,一般用:make menuconfig 现在只是搭建内核树,因此不用怎么改,直接保存就行了。
而后就开始编译:
make
make bzImage
结束后生成:vmlinux 其属性为:-rwxr-xr-x
到这里,要进行加载内核模块编译,需要root用户
make modules  /* 编译内核经常会用到的 */
make modules_install /* 安装模块 */
执行结束后,会在/lib/modules下生成新的目录
在随后的编译模块文件时,要用到这个路径下 的build目录,至此内核编译完成,可以重启一下系统。
Hello World 模块的加载
就拿《Linux设备驱动》上的那个hello world为例吧:
#include <linux/init.h>
#include <linux/module.h>
MODULE_LICENSE(“Dual BSD/GPL”);
static int hello_init(void) //加载模块需要的初始化函数
{
printk(KERN_ALERT “Hello, world\n”);
return 0;
}
static void hello_exit(void) //卸载模块需要的结束函数
{
Printk(KERN_ALERT “Goodbye, Cruel world\n”);
}
module_init(hello_init);  //加载模块
module_exit(hello_exit);  //卸载模块
模块程序编写好了,但是要怎样编译这个模块呢?这里就需要一个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 *.cmd *.ko *.mod.c: modules modules_install clean
else
obj-m :=hello.o
endif
然后再目录下make一下,我在这里出现过很多问题:主要是有编译时的内核路径不对的,你也可以在到/lib/modules/目录下看有哪些内核路径,修改成自己相应的就行了;还有就是$(MAKE)前面是用的tab键而不是空格。
编译完成后,会生成个.ko文件,这个就是要的模块的文件,后来要做到任务就是将这个模块加载到内核中:
sudo insmod ./hello.ko
加载之前,可以先执行:cat /var/log/messages 查看系统消息;
加载完成过后:lsmod 或者cat /proc/devices | grep hello
卸载模块:rmmod hello
在加载过程中常常会遇到这个问题:
insmod: error inserting 'helloworld.ko': -1 Invalid module format
一个原则就是下载的内核源码与具体要使用加载模块的内核环境版本要一致。
一些说明:
       如果你需要编译一个模块给一个特定的内核版本, 你将需要使用这个特定版本的建立系统和源码树. 前面展示过的在例子 makefile 中简单修改 KERNELDIR 变量, 就完成这个动作。
       内核接口在各个发行之间常常变化. 如果你编写一个模块想用来在多个内核版本上工作(特别地是如果它必须跨大的发行版本), 你可能只能使用宏定义和 #ifdef 来使你的代码正确建立。

Linux---我的第一个内核模块之Hello World

1、什么是内核模块? 内核模块是Linux内核向外部提供的一个插口,其全称为动态可加载内核模块(Loadable Kernel Module,LKM),简称为模块。Linux内核之所以提供模块机...
  • L_in12
  • L_in12
  • 2015年11月04日 17:24
  • 787

Linux 最简单内核模块 Hello World 示例

注:如果想要按照本篇实践,需要有能运行的arm开发板和对应版本的内核(如果想在Linux主机上编译运行,请参考附1) 1. 在相应版本内核的driver目录下新建如下文件: module fil...
  • chinaeran
  • chinaeran
  • 2015年04月28日 08:38
  • 5967

Linux内核驱动程序之最简单的Hello World模块

这里不为真实的硬件设备编写内核驱动程序,为了方便描述编写内核驱动程序的过程,我们使用一个虚拟的硬件设备。先大概看下内核驱动程序的编写流程,例子没有实际意义,只是模板。 1.在kernel/drive...
  • zhangyongfeiyong
  • zhangyongfeiyong
  • 2017年03月30日 10:46
  • 514

linux内核编程(hello world示例程序)

linux内核编程(hello world) Linux可加载内核模块是 Linux 内核的最重要创新之一。它们提供了可伸缩的、动态的内核。其它开发者可以不用重新编译整个内核便可以开发内核层的程序...
  • qq_15437667
  • qq_15437667
  • 2017年04月07日 00:46
  • 623

编写一个简单的内核模块程序Hello World!

一、Linux内核模块基本原理Linux 内核模块(LKM)是一些在启动的操作系统内核需要时可以载入内核执行的代码块,不需要时由操作系统卸载。它们扩展了操作系统内核功能却不需要重新编译内核、启动系统。...
  • sh21_
  • sh21_
  • 2017年03月09日 16:47
  • 2695

Nginx的第一个模块-Hello World

麻雀虽小,五脏俱全,小小的Hello World盛行于程序世界,就在于其代码虽短,但要真正运行起来,需要我们略通基本语法,稍懂编译运行环境,知晓操作过程,最后,还有一颗持之以恒,不怕折腾的心。前一阵子...
  • u013140542
  • u013140542
  • 2014年08月25日 21:34
  • 1228

你知道Hello World程序的由来吗?

Hello World是一个最著名的程序。对每一位程序员来说,这个程序几乎是每一门编程语言中的第一个示例程序。实际上,这个程序的功能只是告知计算机显示Hello World这句话。传统意义上,程序员一...
  • testcs_dn
  • testcs_dn
  • 2016年09月26日 20:56
  • 2280

vs创建第一个经典程序:hello wold

好,我们的VS安装好后,怎样来开启我的程序之旅呢? 这边文章,主要介绍: 1、如何用VS来创建一个工程项目 2、实现计算机世界里的第一个程序:hello world 3、如何使...
  • xiongxianhe
  • xiongxianhe
  • 2014年11月22日 21:13
  • 2114

<ARM嵌入式开发学习>我的第一个驱动程序-hello world

第一次接触ARM开发板,整整用了一天才把板子原来的wince系统烧写为Linux,其中就卡在制作SD卡启动的时候,使用的是8G的卡,结果官方提供的制作软件不支持~~~~     使用的开发板子:TQ2...
  • GQB1226
  • GQB1226
  • 2015年04月23日 19:43
  • 864

ubuntu12.04 编译第一个hello world模块!

在把自己的内核升级到了3.4.38之后,接下来的一个工作就是编译第一个模块喽!在网上也看到不少的类似的帖子,但是自己跟着做的时候,还是出现了很多问题,觉得有必要记录下来,望和我一样的初学者多多留意,不...
  • XIAXIA__
  • XIAXIA__
  • 2013年04月05日 20:58
  • 1868
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:内核树的建立及其Hello World 模块的加载
举报原因:
原因补充:

(最多只允许输入30个字)