/* Necessary includes for device drivers http://www.freesoftwaremagazine.com/articles/drivers_linux?page=0%2C1 */
#include <linux init.h>
//#include <linux config.h> no more since 2.6.19 deprecated
#include <linux module.h>
#include <linux kernel.h> /* printk() */
#include <linux slab.h> /* kmalloc() */
#include <linux fs.h> /* everything... */
#include <linux errno.h> /* error codes */
#include <linux types.h> /* size_t */
#include <linux proc_fs.h>
#include <linux fcntl.h> /* O_ACCMODE */
#include <asm system.h> /* cli(), *_flags */
#include <asm uaccess.h> /* copy_from/to_user */
MODULE_LICENSE("Dual BSD/GPL");
/* Declaration of memory.c functions */
int memory_open(struct inode *inode, struct file *filp);
int memory_release(struct inode *inode, struct file *filp);
ssize_t memory_read(struct file *filp, char *buf, size_t count, loff_t *f_pos);
ssize_t memory_write(struct file *filp, char *buf, size_t count, loff_t *f_pos);
void memory_exit(void);
int memory_init(void);
/* Structure that declares the usual file */
/* access functions */
struct file_operations memory_fops = {
read: memory_read,
write: memory_write,
open: memory_open,
release: memory_release
};
/* Declaration of the init and exit functions */
module_init(memory_init);
module_exit(memory_exit);
/* Global variables of the driver */
/* Major number */
int memory_major = 60;
/* Buffer to store data */
char *memory_buffer;
int memory_init(void) {
int result;
/* Registering device */
result = register_chrdev(memory_major, "memory", &memory_fops);
if (result < 0) {
printk(
"<1>memory: cannot obtain major number %d\n", memory_major);
return result;
}
/* Allocating memory for the buffer */
memory_buffer = kmalloc(1, GFP_KERNEL);
if (!memory_buffer) {
result = -ENOMEM;
goto fail;
}
memset(memory_buffer, 0, 1);
printk("<1>Inserting memory module\n");
return 0;
fail:
memory_exit();
return result;
}
void memory_exit(void) {
/* Freeing the major number */
unregister_chrdev(memory_major, "memory");
/* Freeing buffer memory */
if (memory_buffer) {
kfree(memory_buffer);
}
printk("<1>Removing memory module\n");
}
int memory_open(struct inode *inode, struct file *filp) {
/* Success */
return 0;
}
int memory_release(struct inode *inode, struct file *filp) {
/* Success */
return 0;
}
ssize_t memory_read(struct file *filp, char *buf,
size_t count, loff_t *f_pos) {
/* Transfering data to user space */
copy_to_user(buf,memory_buffer,1);
/* Changing reading position as best suits */
if (*f_pos == 0) {
*f_pos+=1;
return 1;
} else {
return 0;
}
}
ssize_t memory_write( struct file *filp, char *buf,
size_t count, loff_t *f_pos) {
char *tmp;
tmp=buf+count-1;
copy_from_user(memory_buffer,tmp,1);
return 1;
}
///----Makefile
obj-m = hello.o memory.o
KVERSION = $(shell uname -r)
all:
make -C /lib/modules/$(KVERSION)/build M=$(PWD) modules
clean:
make -C /lib/modules/$(KVERSION)/build M=$(PWD) clean
///----Testing after make
$sudo nsmod memory.ko
$sudo rmmod memory.ko
$ dmesg | less
[223447.209899] Inserting memory module
[223629.779878] Removing memory module
[223663.099549] Loading hello module...
# mknod /dev/memory c 60 0 (make device using system call see http://www.kernel.org/doc/man-pages/online/pages/man2/mknod.2.html
In the above,
c
means that a
char
device is to be created,
60
is the
major number
and
0
is the
minor number
.
)
Insert character into the device
#
chmod 666 /dev/memory
#insmod memory.ko
#echo -n ABC > /dev/memory
#cat /dev/memory
C
Note: .ko kernel object,.so /usr/lib (library), .ro (module plugin gedit)
.o for object then link gcc -o test test.c
Questions:
Q. Can you explain me what is device files and how do I access or see device files? Why UNIX / Linux has device files?
A. Under Linux and UNIX each and every hardware device treated as a file. A device file allows to accesses hardware devices so that end users do not need to get technical details about hardware.
In short, a device file (also called as a special file) is an interface for a device driver that appears in a file system as if it were an ordinary file. This allows software to interact with the device driver using standard input/output system calls, which simplifies many tasks.
Device file two types
There are two types of device files based upon how data written to them and read from them is processed by the operating system and hardware:
- Character special files or Character devices
- Block special files or Block devices
Understanding Character special files or Character devices
- Talks to devices in a character by character (1 byte at a time)
- Examples: Virtual terminals, terminals and serial modems etc
Understanding Block special files or Block devices
- Talks to devices 1 block at a time ( 1 block = 512 bytes to 32KB)
- Examples: Hard disk, DVD/CD ROM, and memory regions etc
Why use device files?
Device file allows transparent communication between user space applications and computer hardware.
What is a Zombie process?
http://en.wikipedia.org/wiki/Zombie_process On
Unix and
Unix-like computer
operating systems, a
zombie process or
defunct process is a
process that has
completed execution but still has an entry in the
process table. This entry is still needed to allow the parent process to read its child's
exit status. The term
zombie process derives from the common definition of
zombie — an
undead person. In the term's metaphor, the child process has "
died" but has not yet been "
reaped". Also, unlike normal processes, the
kill
command has no effect on a zombie process.
How do I kill zombie process?
You cannot kill zombies, as they are already dead. But if you have too many zombies then kill parent process or restart service.
You can kill zombie process using PID obtained from any one of the above command. For example kill zombie process having PID 4104:
# kill -9 4104
create zombie.c
#include <stdlib.h&g
#include <sys types.h&g
#include <unistd.h&g
int main ()
{
pid_t child_pid;
child_pid = fork (); // system call to create a new process referred to as the child process
if (child_pid > 0) {
sleep (60);
}
else {
exit (0); // parent exist make child becomes zombie if the parent crashes makes it becomes
} // orphan process will waste resources but zombie is no harm except running out PID
return 0;
}
gcc zombie.c -o zombie
./zombie
after 1 minute
ps -ax
1815 ? Sl 0:00 /usr/bin/python /usr/bin/bzr-notify
6314 pts/1 S+ 0:00 ./zombie
6315 pts/1 Z+ 0:00 [zombie]
The child process is marked as
, and its status code is Z, for zombie.
When the program exits, the child process is inherited by init. This process should cleans up the zombie proces automatically.
Zombie vs. Orphan process
http://en.wikipedia.org/wiki/Zombie_process
On
Unix and
Unix-like computer
operating systems, a
zombie process or
defunct process is a
process that has
completed execution but still has an entry in the
process table. This entry is still needed to allow the parent process to read its child's
exit status. The term
zombie process derives from the common definition of
zombie — an
undead person. In the term's metaphor, the child process has "
died" but has not yet been "
reaped". Also, unlike normal processes, the
kill
command has no effect on a zombie process.
A zombie process is not the same as an
orphan process.
An orphan process is a process that is still executing, but whose
parent has died. They do not become zombie processes; instead, they are
adopted by
init
(process ID 1), which
wait
s on its children.