Linux内核模块编程之Helloworld(初级)
注意printk那里,KERN_ALERT和打印消息之间是没有逗号的,搞得劳资查了半天才发现一直没有提示信息的原因
#include <linux/init.h>
#include <linux/module.h>
MODULE_LICENSE("Dual BSD/GPL");//MODULE_LICENSE()指明认证方式,现在支持的有:“GPL” “GPL v2" "GPL and additional rights" "Dual BSD/GPL" "Dual MIT/GPL" "Dual MPL/GPL" "Proprietary",这是内核2.6里新添加的,实验发现它不是必需的。
static int hello_init(void)
{
printk(KERN_ALERT "Hello, World\n");//printk是内核级别的打印函数,KERN_ALERT是指该条信息是警告信息
return 0;
}
static int hello_exit(void)
{
printk(KERN_ALERT "Goodbye, cruel world\n");
}
module_init(hello_init);//模块入口
module_exit(hello_exit);//模块出口
下面我们来写Makefile(命名为makefile我的会提示错误),-C 去内核源码目录下读取Makefile,m=返回当前路径执行当前目录下的Makefile
。我觉得Makefile这个文件挺6的,该文件会根据xx.o查找相应的xx.c文件
TARGET=hello
KDIR=/usr/src/kernels/3.10.0-514.el7.x86_64 //找到内核文件所在路径,系统不同路径也不同,可以使用find / -name kernel查找
PWD=$(shell pwd) //这个是指执行shell命令pwd,即用PWD记录当前路径
obj-m=$(TARGET).o
default:
make -C $(KDIR) M=$(PWD) modules
那么如何运行呢,首先make
[04:21:42] make
make -C /usr/src/kernels/3.10.0-514.el7.x86_64 M=/root/kernel modules
make[1]: Entering directory `/usr/src/kernels/3.10.0-514.el7.x86_64'
CC [M] /root/kernel/hello.o
/root/kernel/hello.c: In function ‘hello_exit’:
/root/kernel/hello.c:14:1: warning: no return statement in function returning non-void [-Wreturn-type]
}
^
In file included from /root/kernel/hello.c:1:0:
/root/kernel/hello.c: In function ‘__exittest’:
include/linux/init.h:305:4: warning: return from incompatible pointer type [enabled by default]
{ return exitfn; } \
^
/root/kernel/hello.c:17:1: note: in expansion of macro ‘module_exit’
module_exit(hello_exit);
^
Building modules, stage 2.
MODPOST 1 modules
CC /root/kernel/hello.mod.o
LD [M] /root/kernel/hello.ko
make[1]: Leaving directory `/usr/src/kernels/3.10.0-514.el7.x86_64'
[04:21:45] ls
hello.c hello.ko hello.mod.c hello.mod.o hello.o Makefile modules.order Module.symvers
现在进行加载模块,首先在当前终端
[04:21:47] tail -f /var/log/messages
May 22 04:01:01 bogon systemd: Started Session 727 of user root.
May 22 04:01:01 bogon systemd: Starting Session 727 of user root.
May 22 04:10:01 bogon systemd: Started Session 728 of user root.
May 22 04:10:01 bogon systemd: Starting Session 728 of user root.
May 22 04:18:35 bogon kernel: Hello, World//在另一个终端执行insmod ./hello.ko才会出现这个
May 22 04:18:49 bogon kernel: Goodbye, cruel world//在另一个终端执行rmmod hello才会出现这个
May 22 04:20:01 bogon systemd: Started Session 729 of user root.
May 22 04:20:01 bogon systemd: Starting Session 729 of user root.
May 22 04:20:01 bogon kernel: Hello, World
May 22 04:20:11 bogon kernel: Goodbye, cruel world
May 22 04:22:06 bogon kernel: Hello, World
我在另一个终端的执行过程就是进入该目录,然后执行insmod ./hello.ko 然后第一个终端就会显示Hello,world。在执行rmmod hello 就会显示Goodbye, cruel world
但是!根据系统版本的不同还是什么其他原因,有时候信息在/var/log/messages 里看到,使用dmesg可以看到
[root@bogon kernel]# dmesg|tail -5
[ 123.690748] test: module verification failed: signature and/or required key missing - tainting kernel
[ 876.865300] Hello, World
[ 908.638904] Goodbye, cruel world
[ 1235.101965] e1000: ens33 NIC Link is Down
[ 1241.118672] e1000: ens33 NIC Link is Up 1000 Mbps Full Duplex, Flow Control: None
[root@bogon kernel]#
或者是在加载或者移除模块这里看到
也可以像下面这么写,注意,uname -r那里是使用的反引号就是tab键上面的那个键,$(PWD)当前工作目录,clean清除,打印信息是显示在另一个终端的,例如我就是在物理机上使用ssh链接虚拟机centos7,然后执行下面的命令,而在虚拟机的终端上则会显示打印的那几条信息
[root@bogon modules]# cat first.c
#include<linux/kernel.h>
#include<linux/module.h>
int init_module(void){
printk(KERN_ALERT "hi,this is bp\n");
return 0;
}
void cleanup_module(void){
printk(KERN_ALERT "goobye bp\n");
}
[root@bogon modules]# cat Makefile
obj-m=first.o
default:
make -C /usr/src/kernels/`uname -r` M=$(PWD) modules
clean:
make -C /usr/src/kernels/`uname -r` M=$(PWD) clean
[root@bogon modules]# make
make -C /usr/src/kernels/`uname -r` M=/root/modules modules
make[1]: Entering directory `/usr/src/kernels/3.10.0-514.el7.x86_64'
Building modules, stage 2.
MODPOST 1 modules
make[1]: Leaving directory `/usr/src/kernels/3.10.0-514.el7.x86_64'
[root@bogon modules]# modinfo first.ko//查看模块信息
filename: /root/modules/first.ko
rhelversion: 7.3
srcversion: 2523BB278E7311D9141E7F4
depends:
vermagic: 3.10.0-514.el7.x86_64 SMP mod_unload modversions
[root@bogon modules]# insmod first.ko
[root@bogon modules]# rmmod first
[root@bogon modules]# ls
a.c a.mod.o first.ko first.o hello.mod.c Makefile
a.ko a.o first.mod.c hello.c hello.mod.o modules.order
a.mod.c first.c first.mod.o hello.ko hello.o Module.symvers
[root@bogon modules]# make clean
make -C /usr/src/kernels/`uname -r` M=/root/modules clean
make[1]: Entering directory `/usr/src/kernels/3.10.0-514.el7.x86_64'
CLEAN /root/modules/.tmp_versions
CLEAN /root/modules/Module.symvers
make[1]: Leaving directory `/usr/src/kernels/3.10.0-514.el7.x86_64'
[root@bogon modules]# ls
a.c first.c hello.c Makefile
[root@bogon modules]#
Linux内核模块编程之Helloworld(初级)的更多相关文章
- linux c编程之fcntl
fcntl可实现对指定文件描述符的各种操作,其函数原型如下: int fcntl(int fd, int cmd, ... /* arg */ ); 其中,操作类型由cmd决定.cmd可取如下值: F ...
- linux网络编程之shutdown() 与 close()函数详解
linux网络编程之shutdown() 与 close()函数详解 参考TCPIP网络编程和UNP: shutdown函数不能关闭套接字,只能关闭输入和输出流,然后发送EOF,假设套接字为A,那么这 ...
- Linux应用编程之lseek详解
Linux应用编程之lseek详解 1.lseek函数介绍 (1).文件指针:当我们要对一个文件进行读写时,一定要先打开这个文件,所以我们读写的所有文件都是动态文件.动态文件在内存中的形态就是文件流的 ...
- linux C编程之makefile
目的: 基本掌握了 make 的用法,能在Linux系统上编程.环境: Linux系统,或者有一台Linux服务器,通过终端连接.一句话:有Linux编译环境.准备: ...
- (十)Linux 网络编程之ioctl函数
1.介绍 Linux网络程序与内核交互的方法是通过ioctl来实现的,ioctl与网络协议栈进行交互,可得到网络接口的信息,网卡设备的映射属性和配置网络接口.并且还能够查看,修改,删除ARP高速缓存的 ...
- (ubuntu)linux C编程之sleep()和usleep()的使用和区别
### 函数名: sleep 头文件: #include <windows.h> // 在VC中使用带上头文件 #include <unistd.h> // 在gcc编译器中, ...
- linux socket编程之TCP与UDP
转:http://blog.csdn.net/gaoxin1076/article/details/7262482 TCP/IP协议叫做传输控制/网际协议,又叫网络通信协议 TCP/IP虽然叫传输控制 ...
- shell编程之helloworld
/bin/sh与/bin/bash的区别sh:如果前面有语句报错,则报错语句后面的命令不执行bash:如果前面有语句报错,后面的命令也会执行sh跟bash的区别,实际上就是bash有没有开启posix ...
- 170619、springboot编程之HelloWorld
springboot资料看了一段时间了,个人觉得开发效率相当高,也参考了网上很多大牛的技术博客,在这里面我也记录一下,方便以后自己翻阅查看,同时也给新手最一点点指引.如果有侵权大牛博客文章,请告诉我, ...
随机推荐
- python常用内建模块 collections,bs64,struct,hashlib,itertools,contextlib,xml
# 2 collections 是Python内建的一个集合模块,提供了许多有用的集合类. # 2.1 namedtuple #tuple可以表示不变集合,例如,一个点的二维坐标就可以表示成: p ...
- Java的file类
package IO; import java.io.File; import java.io.IOException; public class FileDemo01 { public static ...
- LeetCode 151 翻转字符串里的单词
题目: 给定一个字符串,逐个翻转字符串中的每个单词. 示例 1: 输入: "the sky is blue" 输出: "blue is sky the" 示例 ...
- POJ - 1942 D - Paths on a Grid
Imagine you are attending your math lesson at school. Once again, you are bored because your teacher ...
- synchronized 和 ReentrantLock 区别
synchronized 使用: 1:当一个线程访问object的一个synchronized(this)同步代码块时,它就获得了这个object的对象锁.结果,其它线程对该object对象所有同步代 ...
- <Hadoop重装><centos><NameNode失效>
Overview 记一次真真切切的NameNode单点故障. 学校机房着火之后,刀片机上的四台服务器,唯独就NameNode彻底宕掉了,去机房看了下硬盘都坏了.. 所以只能换一个master咯.基本上 ...
- __autolaod
转载自:https://blog.csdn.net/baidu_30000217/article/details/52743139 php实现类文件自动载入有两种办法: 魔术方法:__autoload ...
- mysql增删改查练习
Mysql增删改查sql语句练习 关于数据库的一些操作: 进入mysql 命令行: mysql -uroot –p 查看所有数据库: show databases; 创建数据库: create dat ...
- 【webdriver自动化】整理API框架(主要是关键字,具体例子在本地)
1. 获取网页源码 pageSource = self.driver.page_source print pageSource.encode("gbk","ignore& ...
- c++ 继承(二)
不能自动继承的成员函数 1.构造函数 2.析构函数 3.=运算符 继承与构造函数 1.基类的构造函数不被继承,派生类中需要声明自己的构造函数 2.声明构造函数时,只需要对本类中新增成员进行初始化,对继 ...