我的源代码运行正常,请看一下。如果任何人受益或看到对其他人有帮助,请给一些+Ve标记。
另外,请告诉我为什么我在这个问题上得到 -Ve 分数!!
1."chardev.c"
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/fs.h>
#include <asm/uaccess.h>
#include "./chardev.h"
#define SUCCESS 0
#define DEVICE_NAME "char_dev_rfk"
#define BUF_LEN 80
static int Device_Open = 0;
static char Message[BUF_LEN];
static char *Message_Ptr;
static int device_open(struct inode *inode, struct file *file)
{
printk(KERN_INFO "\n\rdevice_open(%p)\n", file);
if (Device_Open) return -EBUSY;
Device_Open++;
Message_Ptr = Message;
try_module_get(THIS_MODULE);
return SUCCESS;
}
static int device_release(struct inode *inode, struct file *file)
{
printk(KERN_INFO "\n\rdevice_release(%p,%p)\n", inode, file);
Device_Open--;
module_put(THIS_MODULE);
return SUCCESS;
}
static ssize_t device_read(struct file *file,char __user * buffer,size_t length, loff_t * offset)
{
int bytes_read = 0;
printk(KERN_INFO "\n\rdevice_read(%p,%p,%d)\n", file, buffer, length);
if (*Message_Ptr == 0) return 0;
while (length && *Message_Ptr_k)
{
put_user(*(Message_Ptr_k++), buffer++);
length--;
bytes_read++;
}
printk(KERN_INFO "Read %d bytes, %d left\n", bytes_read, length);
return bytes_read;
}
static ssize_t device_write(struct file *file,const char __user * buffer, size_t length, loff_t * offset)
{
int i;
printk(KERN_INFO "\n\rdevice_write(%p,%s,%d)", file, buffer, length);
for (i = 0; i < length && i < BUF_LEN; i++)
get_user(Message[i], buffer + i);
Message_Ptr = Message;
return i;
}
int device_ioctl(struct inode *inode, struct file *file, unsigned int ioctl_num, unsigned long ioctl_param)
{
int i;
char *temp;
char ch;
switch (ioctl_num)
{
case IOCTL_SET_MSG:
temp = (char *)ioctl_param;
get_user(ch, temp);
for (i = 0; ch && i < BUF_LEN; i++, temp++)
get_user(ch, temp);
device_write(file, (char *)ioctl_param, i, 0);
break;
case IOCTL_GET_MSG:
i = device_read(file, (char *)ioctl_param, 99, 0);
put_user('\0', (char *)ioctl_param + i);
break;
case IOCTL_GET_NTH_BYTE:
return Message[ioctl_param];
break;
}
return SUCCESS;
}
struct file_operations Fops =
{
.read = device_read,
.write = device_write,
.ioctl = device_ioctl,
.open = device_open,
.release = device_release,
};
int init_module()
{
int ret_val;
ret_val = register_chrdev(MAJOR_NUM, DEVICE_NAME, &Fops);
if (ret_val < 0)
{
printk(KERN_ALERT "%s failed with %d\n","Sorry, registering the character device ", ret_val);
return ret_val;
}
printk(KERN_INFO "%s The major device number is %d.\n","Registeration is a success", MAJOR_NUM);
return 0;
}
void cleanup_module()
{
}
MODULE_LICENSE("GPL");
2."chardev.h"
#ifndef CHARDEV_H
#define CHARDEV_H
#include <linux/ioctl.h>
#define MAJOR_NUM 100
#define IOCTL_SET_MSG _IOR(MAJOR_NUM, 0, char *)
#define IOCTL_GET_MSG _IOR(MAJOR_NUM, 1, char *)
#define IOCTL_GET_NTH_BYTE _IOWR(MAJOR_NUM, 2, int)
#define DEVICE_FILE_NAME "char_dev_rfk"
#endif
3."ioctl.c"
#include "chardev.h"
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/ioctl.h>
ioctl_set_msg(int file_desc, char *message)
{
int ret_val;
printf("\n\rioctl_set_msg():Called\n");
ret_val = ioctl(file_desc, IOCTL_SET_MSG, message);
if (ret_val < 0)
{
printf("ioctl_set_msg failed:%d\n", ret_val);
exit(-1);
}
}
ioctl_get_msg(int file_desc)
{
int ret_val;
char message[100];
printf("\n\rioctl_get_msg():Called\n");
ret_val = ioctl(file_desc, IOCTL_GET_MSG, message);
if (ret_val < 0)
{
printf("ioctl_get_msg failed:%d\n", ret_val);
exit(-1);
}
printf("\n\rget_msg message:%s\n", message);
}
ioctl_get_nth_byte(int file_desc)
{
int i;
char c;
printf("\n\rioctl_get_nth_byte():Called\n");
printf("\n\rget_nth_byte message:");
i = 0;
do {
c = ioctl(file_desc, IOCTL_GET_NTH_BYTE, i++);
if (c < 0)
{
printf("ioctl_get_nth_byte failed at the %d'th byte:\n",i);
exit(-1);
}
putchar(c);
} while (c != 0);
putchar('\n');
}
main()
{
int file_desc, ret_val;
char *msg = "Message passed from Uesr:Rofique\n";
file_desc = open("./char_dev_rfk", O_RDWR);
if (file_desc < 0)
{
printf("Can't open device file: %s\n", DEVICE_FILE_NAME);
exit(-1);
}
ioctl_set_msg(file_desc, msg);
ioctl_get_msg(file_desc);
close(file_desc);
}
我已经为 ARM9 板交叉编译它。所以,制作文件如下。
4.“生成文件”
ifneq ($(KERNELRELEASE),)
obj-m:= chardev.o
else
CROSS=arm-linux-
KDIR := /opt/linux-2.6.32.2/
all:ioctl
make -C $(KDIR) M=$(PWD) modules ARCH=arm CROSS_COMPILE=arm-linux-
ioctl:ioctl.c
$(CROSS)gcc -o ioctl ioctl.c
$(CROSS)strip ioctl
clean:
rm -f *.ko *.o *.mod.o *.mod.c *symvers modul* ioctl
endif