1. C code:
# Include <Linux/module. h>
# Include <Linux/types. h>
# Include <Linux/fs. h>
# Include <Linux/errno. h>
# Include <Linux/mm. h>
# Include <Linux/sched. h>
# Include <Linux/init. h>
# Include <Linux/cdev. h>
# Include <ASM/IO. h>
# Include <ASM/system. h>
# Include <ASM/uaccess. h>
# Define globalmem_size 0x1000
# Define mem_clear 0x01
# Define globalmem_major 254
Static globalmem_major = globalmem_major;
Struct globalmem_dev
{
Struct cdev;
U8 mem [globalmem_size];
Struct semaphore SEM;
};
Struct globalmem_dev * globalmem_devp;
Int globalmem_open (struct inode * inode, struct file * filp)
{
Filp-> private_data = globalmem_devp;
Return 0;
}
Int globalmem_release (struct inode * inode, struct file * filp)
{
Return 0;
}
Static ssize_t globalmem_read (struct file * filp, char _ User * Buf, size_t count, loff_t * PPOs)
{
U32 P = * PPOs;
Int ret = 0;
Struct globalmem_dev * Dev = filp-> private_data;
If (P> = globalmem_size ){
Return count? -Enxio: 0;
}
If (count> globalmem_size-p ){
Count = globalmem_size-P;
}
If (down_interruptible (& Dev-> SEM )){
Return-erestartsys;
}
If (copy_to_user (BUF, (void *) (Dev-> mem + p), count )){
Ret =-efault;
} Else {
* PPOs + = count;
Ret = count;
Printk (kern_info "read % d byte (s) from % d/N", Count, P );
}
Up (& Dev-> SEM );
Return ret;
}
Static ssize_t globalmem_write (struct file * filp, const char _ User * Buf, size_t count, loff_t * PPOs)
{
U32 P = * PPOs;
Int ret = 0;
Struct globalmem_dev * Dev = filp-> private_data;
If (P> = globalmem_size ){
Return count? -Enxio: 0;
}
If (down_interruptible (& Dev-> SEM )){
Return-erestartsys;
}
If (count> globalmem_size-p ){
Count = globalmem_size-P;
}
If (copy_from_user (Dev-> mem + P, Buf, count )){
Ret =-efault;
} Else {
* PPOs + = count;
Ret = count;
Printk (kern_info "writtem % d byte (s) from % d/N", Count, P );
}
Up (& Dev-> SEM );
Return ret;
}
Static loff_t globalmem_llseek (struct file * filp, loff_t offset, int orig)
{
Loff_t ret;
Switch (orig)
{
Case 0:
If (offset <0 ){
Ret =-einval;
Break;
}
If (u32) Offset> globalmem_size ){
Ret-filp-> f_pos;
Break;
}
Filp-> f_pos = (u32) offset;
Ret = filp-> f_pos;
Break;
Case 1:
If (filp-> f_pos + offset)> globalmem_size ){
Ret =-einval;
Break;
}
If (filp-> f_pos + offset) <0 ){
Ret =-einval;
Break;
}
Filp-> f_pos + = offset;
Ret = filp-> f_pos;
Break;
Default:
Ret =-einval;
}
Return ret;
}
Static int globalmem_ioctl (struct inode * inodep, struct file * filp, u32 cmd, u32 Arg)
{
Struct globalmem_dev * Dev = filp-> private_data;
Switch (CMD)
{
Case mem_clear:
If (down_interruptible (& Dev-> SEM )){
Return-erestartsys;
}
Memset (Dev-> MEM, 0, globalmem_size );
Up (& Dev-> SEM );
Printk (kern_info "globalmem is set to zero/N ");
Break;
Default:
Return-einval;
}
Return 0;
}
Static const struct file_operations globalmem_fops =
{
. Owner = this_module,
. Llseek = globalmem_llseek,
. Read = globalmem_read,
. Write = globalmem_write,
. IOCTL = globalmem_ioctl,
. Open = globalmem_open,
. Release = globalmem_release,
};
Static void globalmem_setup_cdev (struct globalmem_dev * Dev, int index)
{
Int err, devno = mkdev (globalmem_major, index );
Cdev_init (& Dev-> cdev, & globalmem_fops );
Dev-> cdev. Owner = this_module;
Dev-> cdev. Ops = & globalmem_fops;
Err = cdev_add (& Dev-> cdev, devno, 1 );
If (ERR ){
Printk (kern_notice "error % d adding globalmem % d/N", err, index );
}
}
Int globalmem_init (void)
{
Int result;
Dev_t devno = mkdev (globalmem_major, 0 );
If (globalmem_major ){
Result = register_chrdev_region (devno, 1, "globalmem ");
} Else {
Result = alloc_chrdev_region (& devno, 0, 1, "globalmem ");
Globalmem_major = major (devno );
}
If (result <0 ){
Return result;
}
Globalmem_devp = kmalloc (sizeof (struct globalmem_dev), gfp_kernel );
If (! Globalmem_devp ){
Result =-enomem;
Goto fail_malloc;
}
Memset (globalmem_devp, 0, sizeof (struct globalmem_dev ));
Globalmem_setup_cdev (globalmem_devp, 0 );
Init_mutex (& globalmem_devp-> SEM );
Return 0;
Fail_malloc: unregister_chrdev_region (devno, 1 );
Return result;
}
Void globalmem_exit (void)
{
Cdev_del (& globalmem_devp-> cdev );
Kfree (globalmem_devp );
Unregister_chrdev_region (mkdev (globalmem_major, 0), 1 );
}
Module_author ("Alex Xia ");
Module_license ("dual BSD/GPL ");
Module_param (globalmem_major, Int, s_irugo );
Module_init (globalmem_init );
Module_exit (globalmem_exit );
2. Run. Sh
#! /Bin/sh
Make-C/lib/modules/2.6.31-22-generic/build/M = $ (PWD) Modules
3. Clean. Sh
#! /Bin/sh
RM *. Mod. C *. O *. Ko *. Mar *. sym *. ord *