//hello.c#define __NO_VERSION__ #include <linux/module.h> #include <linux/config.h> #include <linux/version.h> #include <asm/uaccess.h> #include <linux/init.h> #include <linux/module.h> #include <linux/kernel.h> #include <linux/fs.h> #include <linux/sched.h> #include <linux/mm.h> #include <asm/page.h> #include <linux/poll.h> #include <linux/kdev_t.h> #include <asm/semaphore.h> #include <linux/slab.h> #include <linux/delay.h> #include <asm/uaccess.h> #include <asm/irq.h> #include <linux/interrupt.h> #include <linux/spinlock.h> unsigned int test_major = 0; static int global_var=0; static int globalvar_count = 0; char *mystr="wodeshen" ; static struct semaphore sem; static spinlock_t spin = SPIN_LOCK_UNLOCKED; //宏定義 已經初始化static ssize_t read_test(struct file *file,char *buf,size_t count,loff_t *f_pos) { int left; printk(KERN_INFO "read_test/n"); if (verify_area(VERIFY_WRITE,buf,count) == -EFAULT ) return -EFAULT; if (down_interruptible(&sem)) { return - ERESTARTSYS; } printk("copy_to_user======2=======/n"); copy_to_user(buf, mystr, strlen(mystr)); /* for(left = count ; left > 0 ; left--) { __put_user('1',buf); buf++; } */ up(&sem); //return sizeof(int); return strlen(mystr); } static ssize_t write_test(struct file *file, const char *buf, size_t count, loff_t *f_pos) { if (down_interruptible(&sem)) { return - ERESTARTSYS; } if (copy_from_user(&global_var, buf, sizeof(int))) { up(&sem); return - EFAULT; } up(&sem); printk(KERN_INFO "write_test/n"); return sizeof(int); } static int open_test(struct inode *inode,struct file *file ) { spin_lock(&spin); printk("globalvar open/n"); //臨界資源訪問 if (globalvar_count) { spin_unlock(&spin); return - EBUSY; } globalvar_count++;//釋放自選鎖 spin_unlock(&spin); printk(KERN_INFO "open_test/n"); MOD_INC_USE_COUNT; return 0; } static int release_test(struct inode *inode,struct file *file ) { printk(KERN_INFO "release_test/n"); MOD_DEC_USE_COUNT; globalvar_count--; return 0; } struct file_operations test_fops = { read:read_test, write:write_test, open: open_test, release:release_test }; int init_module(void) { int result; result = register_chrdev(0, "test", &test_fops); init_MUTEX(&sem); if (result < 0) { printk(KERN_INFO "test: can't get major number/n"); return result; } if (test_major == 0) test_major = result; /* dynamic */ return 0; } void cleanup_module(void) { unregister_chrdev(test_major, "test"); } MODULE_LICENSE("GPL"); MODULE_AUTHOR("BECKHAM"); //Makefile CC=gcc MODCFLAGS:=-Wall -DMODULE -D__KERNEL__ -DLINUX -I /usr/src/linux-2.4.20-8/include test.o:hello.c $(CC) $(MODCFLAGS) -c hello.c //test.c #include <stdio.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> main() { int testdev; int i; int j; char *buf=malloc(150); testdev = open("/dev/test",O_RDWR); if ( testdev == -1 ) { perror(open); printf("Cann't open file /n"); exit(0); } j=read(testdev,buf,10); strcat(buf,"/0"); printf("%d===%s/n",j,buf); while(1); close(testdev); } 然後順序執行先刪除裝置rm /dev/test -f 卸載模組 rmmode testmakeinsmod test.omknod /dev/test c 254 0gcc -o test test.c./test再開啟一個終端,運行test,結果將失敗,顯示裝置處於忙的狀態 |
|
|
|