// 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; // macro definition static ssize_t read_test (struct file * file, char * Buf, size_t count, loff_t * f_pos) has been initialized) { 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 "); // Critical resource access If (globalvar_count) { Spin_unlock (& spin ); Return-ebusy; } Globalvar_count ++; // release the selected lock 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-d1_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 ); } Then delete the device RM/dev/test-F in sequence. Uninstall the rmmode testmakeinsmod test module. omknod/dev/test C 254 0gcc-O test. c. /Test start another terminal and run test. The result will fail and the device is busy. |
|
|
|