question B:
lightblue.c
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/proc_fs.h>
#include <linux/jiffies.h>
#include <asm/uaccess.h>
#include <linux/moduleparam.h>
#include <linux/sched.h>
#define MODULE_NAME "Myproc"
#define MYDATA_LEN 3000
//sprintf不是追加是覆盖
/*
在这里做的一个非常愚蠢的错误发生在下面的美观部分。
为了让代码进行缩进
我使用了
for(index=0;index<count;index++){
//sprintf(str,"%s","\t");
strcat(mydata.value,"\t");
}
中被注释掉的部分显然str在for中基本没有变化,sprintf是覆盖!!!!!!!!!!!!!!!!!
*/
//放用户空间传入的数据
struct my_proc_data{
char value[3000];
};
struct my_proc_data mydata;
//proc 结构变量
static struct proc_dir_entry *probe_dir;
static struct proc_dir_entry *probe_file;
static int param;
module_param(param, int , 0644);
//读文件 myfile 的读驱动函数
static int proc_read(char *page, char **start,off_t off,int count,int *eof,void *data ){
int len=0 ;
struct my_proc_data *mydatap = (struct my_proc_data *) data;
len+=sprintf(page,"%s \n",mydatap->value);
return len;
}
//写文件 myfile 的写驱动函数
static int proc_write(struct file *file,const char *buffer,unsigned long count,void *data){
int len ;
struct my_proc_data *mydatap = (struct my_proc_data *) data;
if(count>MYDATA_LEN)
len = MYDATA_LEN;
else
len = count;
if(copy_from_user(mydatap->value,buffer,len)){
return -EFAULT;
}
mydatap->value[len-1] = '\0';
return len;
}
//装入模块
int init_module(void)
{
probe_dir = (struct proc_dir_entry * )proc_mkdir("probe_dir",0);
if(probe_dir == 0){
printk("mkdir fail\n");
return -1;
}
probe_file = (struct proc_dir_entry * )create_proc_entry("probe_file",0666,probe_dir);
if(probe_file == 0){
remove_proc_entry("myfile",0);
printk("mkfile fail\n");
return -ENOMEM;
}
int index=0;
int count=1;
char str[3000];
struct task_struct *p=current;
while(p->pid!=1){
strcat(mydata.value,"\n");
for(index=0;index<count;index++){
//sprintf(mydata.value,"%s","\t");
strcat(mydata.value,"\t");
}
count++;
sprintf(str,"%d ",p->pid);
strcat(mydata.value,str);
p=p->parent;
}
strcat(mydata.value,"\n");
for(index=0;index<count;index++){
//sprintf(mydata.value,"%s","\t");
strcat(mydata.value,"\t");
}
sprintf(str,"init is:%d\n",p->pid);
strcat(mydata.value,str);
sprintf(str,"%s","print all the process\n");
strcat(mydata.value,str);
struct task_struct *lp;
count=0;
for_each_process(lp){
if(count%10==0){//换行
//sprintf(str,"%s\n",NULL);
strcat(mydata.value,"\n");
}
sprintf(str,"%d ",lp->pid);
strcat(mydata.value,str);
count++;
}
probe_file->data=&mydata;
probe_file->read_proc=&proc_read;
probe_file->write_proc=&proc_write;
return 0;
}
//卸载模块
void cleanup_module(void)
{
remove_proc_entry("myfile",probe_dir);
remove_proc_entry("probe_dir",NULL);
printk("Goodbye.\n");
}
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("Test");
MODULE_AUTHOR("lightblue");
question C:
probe.c
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/proc_fs.h>
#include <linux/sched.h>
//access jiffies
#include <linux/jiffies.h>
//access HZ
#include <asm/param.h>
#include <asm/uaccess.h>
#include <linux/moduleparam.h>
#define MODULE_NAME "Myproc"
#define MYDATA_LEN 16
char* whattodo="";
module_param(whattodo,charp,0644);
struct my_proc_data{
char value[MYDATA_LEN];
};
struct my_proc_data mydata;
static struct proc_dir_entry *probe_dir;
static struct proc_dir_entry *probe_file;
static int proc_read(char *page, char **start,off_t off,int count,int *eof,void *data ){
int len=0 ;
struct my_proc_data *mydatap = (struct my_proc_data *) data;
len+=sprintf(page,"%s\n",mydatap->value);
return len;
}
static int proc_write(struct file *file,const char *buffer,unsigned long count,void *data){
int len ;
struct my_proc_data *mydatap = (struct my_proc_data *) data;
if(count>MYDATA_LEN)
len = MYDATA_LEN;
else
len = count;
if(copy_from_user(mydatap->value,buffer,len)){
return -EFAULT;
}
mydatap->value[len-1] = '\0';
return len;
}
int init_module(void)
{
if(strcmp(whattodo,"HZ")==0){
sprintf(mydata.value,"HZ is: %d",HZ);
}
else if(strcmp(whattodo,"jiffies")==0){
sprintf(mydata.value,"jiffies is: %lu ",jiffies);
}
else {
sprintf(mydata.value,"%s","wrong parameter");
}
probe_dir = (struct proc_dir_entry * )proc_mkdir("probe_dir",0);
if(probe_dir == 0){
printk("mkdir fail\n");
return -1;
}
probe_file = (struct proc_dir_entry * )create_proc_entry("probe_file",0666,probe_dir);
if(probe_file == 0){
remove_proc_entry("probe_dir",0);
printk("mkfile fail\n");
return -ENOMEM;
}
probe_file->data=&mydata;
probe_file->read_proc=&proc_read;
probe_file->write_proc=&proc_write;
return 0;
}
void cleanup_module(void)
{
remove_proc_entry("probe_dir",probe_dir);
remove_proc_entry("probe_file",NULL);
printk("Goodbye.\n");
}
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("probesystem");
MODULE_AUTHOR("lightblue");