디바이스 드라이버를 설치해도 /dev 폴더에 장치가 생기지 않네요???

ivyapink의 이미지

안녕하세요..
리눅스 초보인데요...
임베디르 리눅스 공부중입니다.
SDK 상태로 받은 소스에 디바이스 드라이버가 이미 작성되어 있습니다.
컴파일하면 .ko 파일도 생성이 되고요..
타겟 보드에 올려서 insmod 명령으로 설치하면, 설치는 되는 것 같습니다.
lsmod 명령으로 확인해보면 방금 설치한 드라이버가 표시됩니다.
그런데, /dev 폴더에 해당하는 장치가 생기지 않네요.
이 폴더에 장치 이름이 생겨야, open() 명령으로 가져다 사용할 수 있는게 아닌가요?

몇일 동안 여기 저기 뒤져봐도 알 수가 없어서 질문 드립니다.

드라이버 소스는 아래와 같습니다.

#define GPIO_USE_NAME "ftgpio_function"
 
static dev_t dev_num;
static struct cdev gpio_cdev;
static struct class *gpio_class = NULL;
static u32 open_cnt = 0;
static DECLARE_MUTEX(drv_sem);
 
//============================================
//      file operations
//============================================
static int gpio_open(struct inode *inode, struct file *filp)
{
    int ret = 0;
 
    down(&drv_sem);
    if (!open_cnt) {
        open_cnt++;
    } else {
        printk("request gpio functions fail\n");
        ret = -EINVAL;
    }
    up(&drv_sem);
    return ret;
}
 
static int gpio_release(struct inode *inode, struct file *filp)
{
    int ret = 0;
 
    down(&drv_sem);
    open_cnt--;
    up(&drv_sem);
 
    return ret;
}
 
static int gpio_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg)
{
    int ret = 0;
 
    if (_IOC_TYPE(cmd) != GPIO_IOC_MAGIC)
        return -ENOTTY;
    if (_IOC_NR(cmd) > GPIO_IOC_MAXNR)
        return -ENOTTY;
    if (_IOC_DIR(cmd) & _IOC_READ)
        ret = !access_ok(VERIFY_WRITE, (void __user *)arg, _IOC_SIZE(cmd));
    else if (_IOC_DIR(cmd) & _IOC_WRITE)
        ret = !access_ok(VERIFY_READ, (void __user *)arg, _IOC_SIZE(cmd));
    if (ret)
        return -EFAULT;
 
    switch (cmd) {
    case 1:
        break;
 
    case 2:
        break;
 
    case 3:
        break;
 
    default:
        break;
    }
    return ret;
}
 
struct file_operations gpio_fops = {
    .owner = THIS_MODULE,
    .open = gpio_open,
    .release = gpio_release,
    .ioctl = gpio_ioctl,
};
 
static int __init ftgpio_function_init(void)
{
    int ret = 0;
    ret = alloc_chrdev_region(&dev_num, 0, 1, GPIO_USE_NAME);
    if (unlikely(ret < 0)) {
        printk(KERN_ERR "%s:alloc_chrdev_region failed\n", __func__);
        goto err1;
    }
    cdev_init(&gpio_cdev, &gpio_fops);
    gpio_cdev.owner = THIS_MODULE;
    gpio_cdev.ops = &gpio_fops;
    ret = cdev_add(&gpio_cdev, dev_num, 1);
    if (unlikely(ret < 0)) {
        printk(KERN_ERR "%s:cdev_add failed\n", __func__);
        goto err3;
    }
    gpio_class = class_create(THIS_MODULE, GPIO_USE_NAME);
    if (IS_ERR(gpio_class)) {
        printk(KERN_ERR "%s:class_create failed\n", __func__);
        goto err2;
    }
    device_create(gpio_class, NULL, gpio_cdev.dev, NULL, GPIO_USE_NAME);
 
    printk(KERN_NOTICE "\nFTGPIO Functions Driver registered success\n");
  err1:
    return ret;
  err2:
    cdev_del(&gpio_cdev);
  err3:
    unregister_chrdev_region(dev_num, 1);
    return ret;
}
 
static void __exit ftgpio_function_exit(void)
{
    unregister_chrdev_region(dev_num, 1);
    cdev_del(&gpio_cdev);
    device_destroy(gpio_class, dev_num);
    class_destroy(gpio_class);
}
 
module_init(ftgpio_function_init);
module_exit(ftgpio_function_exit);
MODULE_AUTHOR("Test Corp.");
MODULE_DESCRIPTION("GPIO Function Driver");
MODULE_LICENSE("GPL");
goforit의 이미지

#1: /proc/devices 살펴서 만든 드라이버의 major 값을 가지고 오세요.
alloc_chrdev_region 사용했으니, dynamically 하게 major 값을 할당합니다.

#2: Device 노드를 만드세요. 예를 들면:
$ mknod /dev/mymod 250 (1번에서 찾은 값) 0

ivyapink의 이미지

goforit 님...
멋진 댓글 감사합니다.
님이 말씀하신대로 하니, 장치가 생기고, 또 가져다 사용하는 것도 가능하네요.
단, 캐릭터 디바이스라서
# mknod /dev/mynod c 253 0 으로 처리하였습니다.
몇 일 동안 고생한 문제를 단번에 해결하였습니다.
다시 한 번 감사드립니다.

그런데요,,,,,
이렇게 major 값을 자동으로 할당 받을 때, 장치까지 자동으로 생성하는 방법은 없나요?
항상 이렇게 수동으로 장치를 만들어줘야 하는 건가요?

Prentice의 이미지

udev에 대해 한번 알아보세요. (embedded면 mdev?)

ivyapink의 이미지

Embedded 입니다.
mdev에 대해서 공부하고 적용한 후 결과를 알려드리겠습니다.

감사합니다.

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • You can use Textile markup to format text.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.