在linux下编译一个简单的字符模块,模块在/proc目录下生成一个记录系统进程的内存文件ps。
get.c通过读取ps的内容来打印出进程信息。
字符模块ps.c传递代码如下:
#include<linux/kernel.h>
#include<linux/module.h>
#include<linux/proc_fs.h>
#include<linux/init.h>
#include<linux/sched.h>
#include<linux/list.h>
MODULE_LICENSE("GPL");
MODULE_AUTHOR("cxt");
static int find_read(char *buffer, char **buffer_location, off_t offset, int count, int *eof, void *data)
{
struct task_struct *p;
char tmp[128];
if(offset >0)
return 0;
memset(buffer,0,sizeof(buffer));
//read_lock(&tasklist_lock);
for_each_process(p) //遍例内核进程链表.
{
sprintf(tmp,"%d/t/t%d/t/t/t%s/n",p->pid,p->parent->pid,p->comm);
strcat(buffer,tmp);
memset(tmp,0,sizeof(tmp));
}
//read_unlock(&tasklist_lock);
return strlen(buffer);
}
static int __init find_init(void)
{
struct proc_dir_entry *entry;
entry = create_proc_entry("ps", 0444, &proc_root);
if (entry == 0)
{
printk(KERN_ERR "creat_proc_entry failed/n");
return -1;
}
entry->mode = S_IFREG | 0444;
entry->size = 1024;
//entry->owner = THIS_MODULE;
//entry->uid = 0;
//entry->gid = 0;
entry->read_proc = find_read;
return 0;
}
void __exit find_exit(void)
{
remove_proc_entry("ps", &proc_root);
}
module_init(find_init);
module_exit(find_exit);
Makefile的内容如下:
TARGET = ps
obj-m := $(TARGET).o
KERNELDIR=/lib/modules/`uname -r`/build
PWD=`pwd`
default :
$(MAKE) -C $(KERNELDIR) M=$(PWD) modules
install :
insmod $(TARGET).ko
uninstall :
rmmod $(TARGET).ko
clean :
rm -rf *.o *.mod.c *.ko
程序get.c的代码如下:
#include<stdio.h>
#include<stdlib.h>
#include<sys/types.h>
#include<fcntl.h>
#include<unistd.h>
int main()
{
int fd;
char buf[1024];
fd = open("/proc/ps", O_RDONLY);
if (fd < 0)
{
printf("error/n");
exit(1);
}
//bzero(buf, sizeof(buf));
if (read(fd, buf, 1024) < 0)
{
printf("read error/n");
exit(1);
}
printf("process info :/npid/tppid/t/tname /n%s/n", buf);
//printf("getpid = %d/n", getpid());
return 0;
}
运行过程如下:
[root@localhost proc_c]# make
make -C /lib/modules/`uname -r`/build M=`pwd` modules
make[1]: Entering directory `/usr/src/kernels/2.6.18-1.2798.fc6-i586'
Building modules, stage 2.
MODPOST
make[1]: Leaving directory `/usr/src/kernels/2.6.18-1.2798.fc6-i586'
[root@localhost proc_c]# insmod ps.ko
[root@localhost proc_c]# gcc -o get get.c
[root@localhost proc_c]# ./get
process info :
pid ppid name
1 0 init
2 1 migration/0
3 1 ksoftirqd/0
4 1 watchdog/0
5 1 events/0
6 1 khelper
7 1 kthread
10 7 kblockd/0
11 7 kacpid
72 7 cqueue/0
75 7 khubd
77 7 kseriod
135 7 pdflush
136 7 pdflush
137 7 kswapd0
138 7 aio/0
286 7 kpsmoused
316 7 scsi_eh_0
321 7 kmirrord
328 7 kjournald
349 7 kauditd
375 1 udevd
710 7 kgameportd
1266 7 kmpathd/0
1289 7 kjournald
1295 1 vmhgfs
1297 7 kjournald
1645 1 syslogd
1648 1 klogd
1675 1 portmap
1694 1 rpc.statd
1723 1 rpc.idmapd
1790 1 vmmemctl
1856 1 vmware-guestd
1878 1 dbus-daemon
1887 1 hcid
1899 1 sdpd
1910 1 krfcommd
1945 1 pcscd
1962 1 hidd
1976 1 automount
1993 1 acpid
2002 1 hpiod
2007 1 python
2017 1 cupsd
2026 1 sshd
2036 1 xinetd
2048 1 ntpd
2065 2048 ntpd
2118 1 gpm
2127 1 crond
2162 1 xfs
2179 1 atd
2193 1 yum-updatesd
2212 1 hald
2213 2212 hald-runner
2219 2213 hald-addon-acpi
2224 2213 hald-addon-keyb
2236 2213 hald-addon-stor
2310 1 smartd
2315 1 mingetty
2316 1 mingetty