📄 socket_test.c
字号:
#ifndef __KERNEL__# define __KERNEL__#endif#ifndef MODULE# define MODULE#endif#include <linux/config.h>#if defined(CONFIG_MODVERSIONS) && !defined(MODVERSIONS)# define MODVERSIONS#endif#ifdef MODVERSIONS# include <linux/modversions.h>#endif#include <linux/module.h>#include <linux/kernel.h>#include <linux/proc_fs.h>#include <linux/fcntl.h>#include <linux/errno.h>#include <asm/delay.h>#include <linux/fs.h>#include <asm/hardware.h>#include <asm/io.h>#include <asm/system.h>#include <linux/interrupt.h>#include <linux/devfs_fs_kernel.h>#include <asm/irq.h>#include <asm/uaccess.h>#include <linux/init.h>#include <linux/delay.h>#include <linux/poll.h>#include <linux/sched.h>#include <linux/ioport.h>#include <asm/arch-ks8695/platform.h>#include <linux/module.h>#include <linux/vermagic.h>#include <linux/compiler.h>MODULE_INFO(vermagic, VERMAGIC_STRING);#undef unixstruct module __this_module__attribute__((section(".gnu.linkonce.this_module"))) = { .name = __stringify(KBUILD_MODNAME), .init = init_module,#ifdef CONFIG_MODULE_UNLOAD .exit = cleanup_module,#endif};static const char __module_depends[]__attribute_used____attribute__((section(".modinfo"))) ="depends=";#define SOCKET_DEBUG( format, args... ) do \{ \ printk( "[%d: %s, %s] ", __LINE__, __FILE__, __FUNCTION__ ); \ printk( format, ##args ); \} while( 0 )#define SOCKET_MAJOR 208#define SOCKET_NAME "socket" typedef enum _IOCTL_CMD{ IOCTL_SET_SOCKET_FD = 0x7F, /*用户态向内核态 SET一个socket 描述字*/ IOCTL_TEST_OPTION = 0x80,} ioctl_cmd_enum;unsigned char mem_addr[ 1024 ] = "I am htgo, you are anssie.";wait_queue_head_t int_info_wait;static unsigned int poll_flag = 0;static ssize_t socket_test_read( struct file *filp, char *buf, size_t count, loff_t *f_pos );static ssize_t socket_test_write( struct file *filp,const char *buf, size_t count,loff_t *f_pos );static unsigned int socket_test_poll( struct file *filp,poll_table *wait );static int socket_test_mmap( struct file *file, struct vm_area_struct *vma );static int socket_test_ioctl( struct inode *inode, struct file *filp,unsigned int cmd, unsigned long param );static int socket_test_open( struct inode *inode,struct file *filp );static int socket_test_release( struct inode *inode, struct file *filp );static struct file_operations socket_fops = {owner: THIS_MODULE,read: socket_test_read,write: socket_test_write,poll: socket_test_poll,mmap: socket_test_mmap,ioctl: socket_test_ioctl,open: socket_test_open,release: socket_test_release};static ssize_t socket_test_read( struct file *filp, char *buf, size_t count, loff_t *f_pos ){ return 0;}static ssize_t socket_test_write( struct file *filp,const char *buf, size_t count,loff_t *f_pos ){ return 0;}static unsigned int socket_test_poll( struct file *filp,poll_table *wait ){ unsigned int mask = 0; poll_wait( filp, &int_info_wait, wait ); if( poll_flag ) { poll_flag = 0; mask |= ( 1 << poll_flag ); } return mask;}static struct semaphore sock_sem;static struct page *mem_vma_nopage( struct vm_area_struct *vma, unsigned long address, int write ){ struct page *page = NOPAGE_SIGBUS; unsigned long offset; void *pageptr = NULL; down( &sock_sem ); offset = ( address - vma->vm_start ) + ( ( vma )->vm_pgoff << PAGE_SHIFT ); if( offset < PAGE_SIZE ) { pageptr = (void *)mem_addr; printk( "offset < PAGE_SIZE\n" ); } else { printk( "go out\n" ); goto out; } page = virt_to_page( pageptr ); get_page( page );out: up( &sock_sem ); return page;} void mem_vma_open( struct vm_area_struct *vma ){ //MOD_INC_USE_COUNT;}void mem_vma_close( struct vm_area_struct *vma ){ //MOD_DEC_USE_COUNT;} struct vm_operations_struct mem_vm_ops = {open: mem_vma_open,close: mem_vma_close,nopage: mem_vma_nopage};static inline int noncached_address(unsigned long addr){ return addr >= __pa(high_memory);}static int socket_test_mmap( struct file *file, struct vm_area_struct *vma ){#if 0 if ( ( ( vma )->vm_pgoff << PAGE_SHIFT ) & ( PAGE_SIZE-1 ) ) { printk( "ENXIO\n" ); return -ENXIO; } vma->vm_ops = &mem_vm_ops; vma->vm_flags |= VM_RESERVED; vma->vm_private_data = NULL; mem_vma_open( vma );#endif unsigned long offset = ( unsigned long )( __pa( ( unsigned long)mem_addr ) ); //vma->vm_pgoff << PAGE_SHIFT; /* * Accessing memory above the top the kernel knows about or * through a file pointer that was marked O_SYNC will be * done non-cached. */ if (noncached_address(offset) || (file->f_flags & O_SYNC)) { vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); } /* Don't try to swap out physical pages */ vma->vm_flags |= VM_RESERVED; /* * Don't dump addresses that are not real memory to a core file. */ if (offset >= __pa(high_memory) || (file->f_flags & O_SYNC)) vma->vm_flags |= VM_IO; //if (remap_page_range(vma->vm_start, offset, vma->vm_end-vma->vm_start, if (remap_page_range( vma, vma->vm_start, offset, vma->vm_end-vma->vm_start, vma->vm_page_prot ) ) { return -EAGAIN; } return 0;}static int socket_test_ioctl( struct inode *inode, struct file *filp,unsigned int cmd, unsigned long param ){ switch( cmd ) { case IOCTL_SET_SOCKET_FD: poll_flag = *( ( unsigned long* )param ); printk( "poll_flag: %2x\n", poll_flag ); wake_up_interruptible( &int_info_wait ); break; default: printk( "mem_addr: %s\n", mem_addr ); break; } return 0;}static int socket_test_open( struct inode *inode,struct file *filp ){ return 0;}static int socket_test_release( struct inode *inode, struct file *filp ){ return 0;}int __init socket_init(void){ int result = 0; result = register_chrdev( SOCKET_MAJOR, SOCKET_NAME, &socket_fops ); if( 0 != result ) { SOCKET_DEBUG( "register_chrdev failed" ); return result; } memset( &int_info_wait, 0, sizeof( int_info_wait ) ); init_waitqueue_head( &int_info_wait ); //printk( "get_vbase_addr: %x\n", get_vbase_addr() ); sema_init ( &sock_sem, 1 ); return 0;}static void __exit socket_exit(void){ SOCKET_DEBUG( "exit\n" ); unregister_chrdev( SOCKET_MAJOR, SOCKET_NAME ); return;}module_init( socket_init );module_exit( socket_exit );MODULE_DESCRIPTION("Test socket from kernel");MODULE_AUTHOR( "htgo" );MODULE_LICENSE( "GPL" );
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -