송보화 의 예시 코드의 기본 문자 장치 구동

5164 단어 LDD3 학습
가장 간단한 문자 장치 구동 코드
scull.c
#include 
#include 
#include 
#include 
#include 
#include 
#include 

#define	SCULL_MAJOR	252
#define SCULL_NAME	"scull"
#define MAX_DATA	0x1000

static	int scull_major = SCULL_MAJOR;
struct scull_dev {
	struct cdev cdev;
	char data[MAX_DATA];
	struct semaphore sem;
};

MODULE_LICENSE("Dual BSD/GPL");
MODULE_AUTHOR("BG2BKK");

struct	scull_dev *scull_devp;

int	scull_open(struct inode *inode, struct file *filp)
{
	struct scull_dev *dev = container_of(inode->i_cdev, struct scull_dev, cdev);
	filp->private_data = dev;
	printk(KERN_ALERT "open the scull device
"); return 0; } int scull_release(struct inode *inode, struct file *filp) { printk(KERN_ALERT "close the scull device
"); return 0; } ssize_t scull_read(struct file *filp, char __user *buf, size_t count, loff_t *f_ops) { struct scull_dev *dev = filp->private_data; unsigned long p = *f_ops; unsigned int cnt = count; int ret = 0; if(down_interruptible(&dev->sem)) return -ERESTARTSYS; if(copy_to_user(buf, dev->data,cnt)){ ret = -EFAULT; } else { *f_ops += cnt; ret = cnt; printk(KERN_ALERT "read %u bytes from %lu
",cnt, p); } up(&dev->sem); printk(KERN_ALERT "read %d bytes
",count); return ret; } ssize_t scull_write(struct file *filp, const char __user *buf, size_t count, loff_t *f_ops) { struct scull_dev *dev = filp->private_data; unsigned long p = *f_ops; unsigned int cnt = count; int ret = 0; if(down_interruptible(&dev->sem)) return -ERESTARTSYS; if(copy_from_user(dev->data,buf, cnt)) ret = -EFAULT; else { *f_ops += cnt; ret = cnt; printk(KERN_ALERT "written %u bytes from %lu
",cnt, p); } up(&dev->sem); printk(KERN_ALERT "write %d bytes
",count); return ret; } struct file_operations scull_fops = { .owner = THIS_MODULE, .open = scull_open, .release= scull_release, .write = scull_write, .read = scull_read, }; static void scull_setup_cdev(struct scull_dev *dev, int index) { int err, devno = MKDEV(scull_major, index); cdev_init(&dev->cdev, &scull_fops); dev->cdev.owner = THIS_MODULE; err = cdev_add(&dev->cdev, devno, 1); if(err) printk(KERN_NOTICE "ERROR %d adding scull_dev %d", err, index); } int scull_init(void) { int result; dev_t devno = MKDEV(scull_major,0); if(scull_major) result = register_chrdev_region(devno, 1, "scull"); else { result = alloc_chrdev_region(&devno, 0, 1, "scull"); scull_major = MAJOR(devno); } if(result < 0) return result; scull_devp = kmalloc(sizeof(struct scull_dev), GFP_KERNEL); if(!scull_devp){ result = -ENOMEM; goto fail_malloc; } memset(scull_devp, 0 , sizeof(struct scull_dev)); scull_setup_cdev(scull_devp, 0); init_MUTEX(&scull_devp->sem); printk(KERN_ALERT "init scull device
"); return 0; fail_malloc: unregister_chrdev_region(devno, 1); return result; } void scull_cleanup(void) { cdev_del(&scull_devp->cdev); kfree(scull_devp); unregister_chrdev_region(MKDEV(scull_major, 0), 1); printk(KERN_ALERT "clean scull device
"); } module_init(scull_init); module_exit(scull_cleanup);
테스트 코드
/*************************************************************************
 *fileName:    test.c
 *description: test the myscull.c
 *author:      Hzc
 *create time: 2007-04-20
 *modify info: -
*************************************************************************/
#include 
#include 
#include 
#include 

/* device path */
char path[] = "/dev/scull";
char buf[10];
char rbuf[10];
int i;
int t = 1;
int
main ()
{
  int f = open (path, O_RDWR);
 
  for (i = 0; i < 10; i++)
    {
      buf[i] = i;
      printf("buf[%d] = %d
",i,buf[i]); } printf("write %d bytes
",write (f, buf, 10)); // close (f); // // // f = open (path, O_RDONLY); // if (f == -1) // { // printf ("device open error 2!
"); // return 1; // } printf ("Read the string from device...
"); printf("read %d bytes
",read (f, rbuf, 10)); for (i = 0; i < 10; i++) { printf ("%d
", rbuf[i]); } close (f); }
Makefile
#KERNEL_DIR := /home/huang/linux-2.6.18/
KERNEL_DIR := /lib/modules/$(shell uname -r)/build
PWD	:= $(shell pwd)

obj-m := scull.o
default:
	$(MAKE) -C $(KERNEL_DIR) M=$(PWD) modules

test: test.c
	gcc $< -o [email protected]  -g

clean:
	rm -rf *.o *.ko *~ *.order *.symvers *.markers *.mod.c

테스트 스크립트
1  load_scull.sh
#!/bin/sh

/sbin/insmod scull.ko
mknod /dev/scull c 252 0

2  unload_scull.sh
#!/bin/sh

/sbin/rmmod scull.ko
rm /dev/scull -f

3  test.sh
#!/bin/sh
make clean
make 
make test
sudo ./unload_scull
sudo ./load_scull
sudo ./test.o

좋은 웹페이지 즐겨찾기