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资料看了一段时间了,个人觉得开发效率相当高,也参考了网上很多大牛的技术博客,在这里面我也记录一下,方便以后自己翻阅查看,同时也给新手最一点点指引.如果有侵权大牛博客文章,请告诉我, ...
随机推荐
- SpringBoot 上传、下载(四)
工程目录结构 完整代码: 1.pom.xml 首先当然是添加依赖,用到thymeleaf模板渲染html页面 <project xmlns="http://maven.apache.o ...
- 1.3 CPU简介
目录 CPU的功能模块 cpu总线 CPU寄存器 16位cpu的寄存器组 32位cpu的寄存器组 64位cpu的寄存器组 CPU的功能模块 CPU从逻辑上可以划分成3个模块,分别是控制单元.运算单元和 ...
- 深入理解java虚拟机---虚拟机工具jstat(十七)
jstack---没什么用 jstack用于生成java虚拟机当前时刻的线程快照.线程快照是当前java虚拟机内每一条线程正在执行的方法堆栈的集合,生成线程快照的主要目的是定位线程出现长时间停顿的原因 ...
- SQL-7查找薪水涨幅超过15次的员工号emp_no以及其对应的涨幅次数t (group 与count)
题目描述 查找薪水涨幅超过15次的员工号emp_no以及其对应的涨幅次数tCREATE TABLE `salaries` (`emp_no` int(11) NOT NULL,`salary` int ...
- SUSE_LINUX 11 SP3 安装 IBM MQ 7.5
0.环境介绍 mq7.5 suse linux 11 1. 上传安装包 上传安装包到 softWare/CI79IML.tar.gz 2. 安装证书 sh ./mqlicense.sh 输入 1 同意 ...
- 6.Python爬虫入门六之Cookie的使用
大家好哈,上一节我们研究了一下爬虫的异常处理问题,那么接下来我们一起来看一下Cookie的使用. 为什么要使用Cookie呢? Cookie,指某些网站为了辨别用户身份.进行session跟踪而储存在 ...
- 关于orm 的基础3 day67
day67 ORM 特殊的语法 一个简单的语法 --翻译成--> SQL语句 语法: 1. 操作数据库表 创建表.删除表.修改表 2. 操作数据库行 增.删.改.查 怎么连数据库: 需要手动创建 ...
- python里面如何拷贝一个对象,deecopy和copy的区别
copy仅拷贝对象的本身,而不拷贝对象引用的其它对象. deecopy除拷贝对象本身,而拷贝对象引用的其它对象.
- NAVICAT for 32位/64位 及破解工具PatchNavicat
Navicat提供多达 7 种语言供客户选择,被公认为全球最受欢迎的数据库前端用户介面工具. 它可以用来对本机或远程的 MySQL.SQL Server.SQLite.Oracle 及 Postgre ...
- Linux用管道命令对文件的移动
我的问题是这样的:我有一个文件夹,里面有大约有1000个文件,然后我想把这样的一部分文件给随机分成两部分,一部分含有100张,另外一部分含有剩下的所有的文件,这个时候如果是在Linux图形界面的话直接 ...