mknod /dev/hello c major# minor#
명령어를 실행하면 inode가 생성되어 i_rdev에 number가 i_fop에 device_fops가 할당된다.
insmod hello.ko
rmmod hello
int register_chdev(unsigned int major, const * name, struct file_operation * fops);
// major# 회수
void unregister_chrdev(unsigned int major, const * name);
insmode init_module( ) register_chrdev
rmmode cleanup_module( ) unregister_chrdev
후엔 file operation에 해당하는 함수 정의
dev = open("/dev/device", O_WRONLY);
write(dev, &buf, 1);
close(dev);
#include <linux/module.h>
#include <linux/fs.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <asm/uaccess.h>
static char device_name[20];
static int result; // holds the return value from register_chrdev
static int major_number=0; // holds major number
int test_open(struct inode *inode, struct file *file){
printk("Open call for test device \n");
return 0;
}
int test_release(struct inode *inode, struct file *file) {
printk("Release call for Char Device \n");
return 0;
}
ssize_t test_read(struct file *file, char *buffer, size_t length, loff_t *offset) {
printk("Read Call for test device \n");
return 0;
}
ssize_t test_write(struct file *file, const char *buffer, size_t length, loff_t *offset) {
char val;
printk("Write Call for test device \n ");
return 0;
}
struct file_operations test_fops = { //mapping
open : test_open,// open
read : test_read, // read
write : test_write, // write
release : test_release,// release
};
int init_module(void) {
printk("TEST DEVICE DRIVER\n");
strcpy(device_name, "TEST_Device");
result= register_chrdev(major_number, device_name, &test_fops);
if(result<0) {
printk("device: can get major number");
return result;
}
if(major_number==0) major_number=result;
printk("major_number:%d\n",major_number);
return 0;
}
void cleanup_module(void) {
printk("Clean Up Module\n");
unregister_chrdev(major_number,device_name);
}
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("dummy module");
MODULE_AUTHOR("EMBEDDED");
#include <stdio.h>
#include <fcntl.h>
#include <errno.h>
static int fd;
int main(int argc, char **argv){
char buf[1];
if((fd=open("/dev/test",O_RDWR))<=0){
fprintf(stderr,"Open error: %s\n",strerror(errno));
return 0;
}
read(fd,buf,1);
write(fd,buf,1);
close(fd);
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/fs.h>
#include <linux/miscdevice.h>
#include <linux/mutex.h>
static int kdriver_open(struct inode * inode, struct file * file){
printk("kdriver_open, \n");
return 0;
}
static int kdriver_release(struct inode * inode, struct file * file){
printk("kdriver_release, \n");
return 0;
}
static ssize_t kdriver_read(struct file * file, char * buf, size_t length, loff_t * ofs){
printk("kdriver_read, \n");
return 0;
}
static ssize_t kdriver_write(struct file * file, const char * buf, size_t length, loff_t * ofs){
printk("kdriver_write, \n");
return 0;
}
static long kdriver_ioctl(struct file * file, unsigned int cmd, unsigned long arg){
printk("kdriver_ioctl, \n");
switch(cmd){
default:
return ENOTTY;
}
return 0;
}
static struct file_operations kdriver_fops = {
.owner = THIS_MODULE,
.open = kdriver_open,
.release = kdriver_release,
.read = kdriver_read,
.write = kdriver_write,
.unlocked_ioctl = kdriver_ioctl,
}
static struct miscdevice kdriver_driver = {
.minor = MISC_DYNAMIC_MINOR,
.name = "kdriver",
.fops =&kdriver_fops,
};
static int kdriver_init(void){
printk("kdriver_init, \n");
return misc_register(&kdriver_driver);
}
static void kdriver_exit(void){
printk("kdriver_exit, \n");
misc_deregister(&kdriver_driver);
}
module_init(kdriver_init);
module_exit(kdriver_exit);
MODULE_AUTHOR("Author of the kdriver to put it here.");
MODULE_DESCRIPTION("Description of the kdriver to put it here.");
MODULE_LICENSE("Dual BSD/GPL");
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <fcntl.h>
#define NODE_NAME "/dev/kdriver"
int main(int argc, char * argv[]) {
int fd;
fd = open(NODE_NAME, O_WRONLY);
if(fd < 0) {
printf("%s open error...\n", NODE_NAME);
return -1;
}
write(fd, NULL, 0);
ioctl(fd, 0, 0);
close(fd);
exit(0);
}