Android Dev./Kernel2013. 8. 6. 00:18

안드로이드 커널 모듈은 동적으로 장치 주번호/부번호가 부여되므로 아래 코드와 같이 자동으로 주번호/부번호를 부여받아 MKDEV()하는 코드를 써야 한다. 더 이상의 설명은 생략하며 질문은 받지 않는다. 인터넷에 좋은 설명들이 많으니 직접 찾을 것.



------------ Makefile START ------------

## PLEASE CONFIG HERE --- START ---
KERNEL_DIR= SET KERNEL DIRECTORY HERE
CROSS_TOOLCHAIN= SET TOOLCHAIN DIRECTORY HERE .... prebuilt/linux-x86/toolchain/arm-eabi-4.4.3/bin/arm-eabi-
## PLEASE CONFIG HERE --- E N D ---

obj-m := hello.o
PWD := $(shell pwd)
all:
    $(MAKE) ARCH=arm CROSS_COMPILE=$(CROSS_TOOLCHAIN) -C $(KERNEL_DIR) SUBDIRS=$(PWD) modules
clean:
    $(MAKE) -C $(KERNEL_DIR) SUBDIRS=$(PWD) clean

------------ Makefile E N D ------------



------------ HELLO.C START ------------

#include <linux/module.h>    /* Needed by all modules */
#include <linux/kernel.h>    /* Needed for KERN_INFO */
#include <linux/fs.h>
#include <linux/cdev.h>
#include <linux/device.h>

static dev_t g_firstdevice;
struct cdev g_hello_cdev;
struct class *g_p_hello_class;
struct device *g_p_hello_dev;

static int hello_open(void)
{
    return 0;
}

static int hello_read(void)
{
    return 0;
}

static int hello_write(void)
{
    return 0;
}

static int hello_ioctl(void)
{
    return 0;
}

static int hello_release(void)
{
    return 0;
}

struct file_operations hello_fops =
{
    .owner = THIS_MODULE,
    .open = hello_open,
    .read = hello_read,
    .write = hello_write,
    .unlocked_ioctl = hello_ioctl,
    .release = hello_release
};

static int __init hello_init(void)
{
    printk(KERN_INFO "Hello world\n");
    if (alloc_chrdev_region(&g_firstdevice, 0, 1, "hello") < 0)
    {
        printk (KERN_ERR "%s: unable to allocate device numbers\n", __FUNCTION__);
        return -ENODEV;
    }

    cdev_init(&(g_hello_cdev), &hello_fops);
    g_hello_cdev.owner = THIS_MODULE;
    kobject_set_name(&g_hello_cdev.kobj, "hello%d", 0);
    if (cdev_add(&(g_hello_cdev), MKDEV(MAJOR(g_firstdevice), 0), 1))
    {
        printk (KERN_ERR "cdev_add failure \n");
        return -ENODEV;
    }
    g_p_hello_class = class_create(THIS_MODULE, "hello");
    if (g_p_hello_class == NULL)
    {
        printk (KERN_ERR "failure in class_create\n");
        cdev_del(&g_hello_cdev);
        unregister_chrdev_region(g_firstdevice, 1);
    }
    g_p_hello_dev = device_create(g_p_hello_class, NULL, g_firstdevice, NULL, "hello");
    if (g_p_hello_dev == NULL)
    {
        printk (KERN_ERR "failure in device_create\n");
        class_destroy(g_p_hello_class);
        unregister_chrdev_region(g_firstdevice, 1);
        return -1;
    }
    return 0;
}

static void __exit hello_exit(void)
{
    printk(KERN_INFO "Goodbye world\n");
    device_unregister(g_p_hello_dev);
    class_destroy(g_p_hello_class);
    cdev_del(&g_hello_cdev);
    unregister_chrdev_region(g_firstdevice, 1);
}

module_init(hello_init);
module_exit(hello_exit);

MODULE_LICENSE("GPL");

------------ HELLO.C END ------------

Posted by young.h.rhie