老师给的实验指导书真有点坑。
有用的好东西:
The Linux Kernel Module Programming Guide
Makefile出自上面这个。
create_proc_read_entry函数

系统环境

CentOS 6.10,内核版本2.6.32-754.6.3.el6.x86_64
不推荐更新的内核,因为新版内核API变了,以下代码不再适用。

大概需要注意的地方

  • 源码引号是中文的
  • MODULE_NAME和MODULE_VERSION宏可能会报重复定义
  • &proc_root这玩意应该是一个文件指针,不过传NULL进去默认文件夹就是/proc,所以改成NULL
  • Makefile不好使
  • 编译出来的内核模块是clock.ko

实际使用的源码

模块源码:

#define MODULE

#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/proc_fs.h>

int proc_read_clock(char* page, char** start, off_t off, int count,int* eof,void* data)
{
    int len;
    struct timeval xtime;
    do_gettimeofday(&xtime);
    len = sprintf(page,"%d %d\n",xtime.tv_sec,xtime.tv_usec);
    printk("clock: read_func()\n");
    return len;
}
// proc_dir_entry数据结构
struct proc_dir_entry* proc_my_clock;

int init_module()
{
    printk("clock: init_module()\n");
    proc_my_clock = create_proc_read_entry("clock",0,NULL, proc_read_clock, 0);
    printk(KERN_INFO"%s %s has initialized.\n", "clock", "1.0");
    return 0;
}

void cleanup_module()
{
    printk("clock: cleanup_module()\n");
    remove_proc_entry(proc_my_clock->name, NULL);
    printk(KERN_INFO"%s %s has removed.\n", "clock","1.0");
} 

MODULE_DESCRIPTION("clock module for gettimeofday of proc.");
EXPORT_NO_SYMBOLS;

Makefile:

obj-m += clock.o

all:
	make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules

clean:
	make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean

测试程序:

#include <stdio.h>
#include <sys/time.h>
#include <fcntl.h>
int main(void)
{
	struct timeval getSystemTime;
	char procClockTime[256];
	int infile,len;

	gettimeofday(&getSystemTime,NULL);

	infile = open("/proc/clock",O_RDONLY);
	len = read(infile,procClockTime,256);
	close(infile);

	procClockTime[len] = '\0';

	printf("SystemTime is %d %d\nProcClockTime is %s\n", getSystemTime.tv_sec, getSystemTime.tv_usec, procClockTime);

	sleep(1);
} 

安装、卸载、测试

su #使用管理员
insmod clock.ko

gcc test.c -o test

./tect # 编译运行测试程序

rmmod clock.ko

./test # 再次测试