📄 5.html
字号:
* is 80. BE CAREFUL NOT TO OVERFLOW BUFFERS,
* ESPECIALLY IN THE KERNEL!!!
*/
Message_Ptr = Message;
/* Make sure that the module isn\'t removed while
* the file is open by incrementing the usage count
* (the number of opened references to the module, if
* it\'s not zero rmmod will fail)
*/
MOD_INC_USE_COUNT;
return SUCCESS;
}
/* This function is called when a process closes the
* device file. It doesn\'t have a return value in
* version 2.0.x because it can\'t fail (you must ALWAYS
* be able to close a device). In version 2.2.x it is
* allowed to fail - but we won\'t let it.
*/
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0)
static int device_release(struct inode *inode,
struct file *file)
#else
static void device_release(struct inode *inode,
struct file *file)
#endif
{
#ifdef DEBUG
printk (\"device_release(%p,%p)\\n\", inode, file);
#endif
/* We\'re now ready for our next caller */
Device_Open --;
/* Decrement the usage count, otherwise once you
* opened the file you\'ll never get rid of the module.
*/
MOD_DEC_USE_COUNT;
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0)
return 0;
#endif
}
/* This function is called whenever a process which
* have already opened the device file attempts to
* read from it. */
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0)
static ssize_t device_read(struct file *file,
char *buffer, /* The buffer to fill with data */
size_t length, /* The length of the buffer */
loff_t *offset) /* Our offset in the file */
#else
static int device_read(struct inode *inode,
struct file *file,
char *buffer, /* The buffer to fill with
* the data */
int length) /* The length of the buffer
* (mustn\'t write beyond that!) */
#endif
{
/* Number of bytes actually written to the buffer */
int bytes_read = 0;
/* If we\'re at the end of the message, return 0
* (which signifies end of file) */
if (*Message_Ptr == 0)
return 0;
/* Actually put the data into the buffer */
while (length && *Message_Ptr) {
/* Because the buffer is in the user data segment,
* not the kernel data segment, assignment wouldn\'t
* work. Instead, we have to use put_user which
* copies data from the kernel data segment to the
* user data segment. */
put_user(*(Message_Ptr++), buffer++);
length --;
bytes_read ++;
}
#ifdef DEBUG
printk (\"Read %d bytes, %d left\\n\",
bytes_read, length);
#endif
/* Read functions are supposed to return the number
* of bytes actually inserted into the buffer */
return bytes_read;
}
/* This function is called when somebody tries to write
* into our device file - unsupported in this example. */
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0)
static ssize_t device_write(struct file *file,
const char *buffer, /* The buffer */
size_t length, /* The length of the buffer */
loff_t *offset) /* Our offset in the file */
#else
static int device_write(struct inode *inode,
struct file *file,
const char *buffer,
int length)
#endif
{
return -EINVAL;
}
/* Module Declarations ***************************** */
/* The major device number for the device. This is
* global (well, static, which in this context is global
* within this file) because it has to be accessible
* both for registration and for release. */
static int Major;
/* This structure will hold the functions to be
* called when a process does something to the device
* we created. Since a pointer to this structure is
* kept in the devices table, it can\'t be local to
* init_module. NULL is for unimplemented functions. */
struct file_operations Fops = {
NULL, /* seek */
device_read,
device_write,
NULL, /* readdir */
NULL, /* select */
NULL, /* ioctl */
NULL, /* mmap */
device_open,
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0)
NULL, /* flush */
#endif
device_release /* a.k.a. close */
};
/* Initialize the module - Register the character device */
int init_module()
{
/* Register the character device (atleast try) */
Major = module_register_chrdev(0,
DEVICE_NAME,
&Fops);
/* Negative values signify an error */
if (Major < 0) {
printk (\"%s device failed with %d\\n\",
\"Sorry, registering the character\",
Major);
return Major;
}
printk (\"%s The major device number is %d.\\n\",
\"Registeration is a success.\",
Major);
printk (\"If you want to talk to the device driver,\\n\");
printk (\"you\'ll have to create a device file. \\n\");
printk (\"We suggest you use:\\n\");
printk (\"mknod <name> c %d <minor>\\n\", Major);
printk (\"You can try different minor numbers %s\",
\"and see what happens.\\n\");
return 0;
}
/* Cleanup - unregister the appropriate file from /proc */
void cleanup_module()
{
int ret;
/* Unregister the device */
ret = module_unregister_chrdev(Major, DEVICE_NAME);
/* If there\'s an error, report it */
if (ret < 0)
printk(\"Error in unregister_chrdev: %d\\n\", ret);
}</pre><hr><br><center><a href='4.html'>上一页 </a>||<a href='6.html'>下一页</a></center></div> </td> </tr> </table> <p> </p> </div> </td> </tr> </table> <br> <table border="0" width="75%"><tr><td align="right"><a href="/"><img src="/image2/logo_bottom.gif" border="0"></a></td></tr></table> <hr size="1" align="center" color="#eecccc"> <br> </div> </div> </td> </tr></table> <center><a href="http://ad.myrice.com/RealMedia/ads/click_nx.ads/goldnets.myrice.com/banner1@Bottom" target=_blanck ><script language=JavaScript><!---todayd = new Date();var seconds = todayd.getTime();document.write("<img src=\"http://ad.myrice.com/RealMedia/ads/adstream_nx.ads/goldnets.myrice.com/banner1@Bottom?dd=seconds\" border=0 width=468 height=60>");//--></script></a></center></body></html>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -