Вопросы команде платформы

Разработка модулей ядра Linux: задача File operations

Разработка модулей ядра Linux: задача File operations

by Кямран Шахаев -
Number of replies: 3

Здравствуйте!
Никак не могу понять, где у меня ошибка. На локальном ПК у меня все работает и в моем понимании в задаче реализовано то, что требуется. Можете мне помочь?

#include <linux/cdev.h>
#include <linux/fs.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/string.h>
#include <linux/uaccess.h>

#define MYDEV_NAME "solution_node"

static dev_t first;
static unsigned int count = 1;
static int my_major = 240, my_minor = 0;
static struct cdev* my_cdev;
static char* global_kbuf;

static size_t open_count = 0;
static size_t write_count = 0;

static int solution_node_open(struct inode* sol_inode, struct file* sol_file)
{
  printk(KERN_INFO "kernel_mooc solution_node_open");
  ++open_count;
  return 0;
}

static int solution_node_release(struct inode* sol_inode, struct file* sol_file)
{
  printk(KERN_INFO "kernel_mooc solution_node_release");
  return 0;
}

static ssize_t solution_node_read(struct file* sol_file, char __user* buf, size_t buf_size, loff_t* ppos)
{
  char kbuf[256];
  size_t kbuf_size = 0;
  size_t copy_size = 0;
 
  printk(KERN_INFO "kernel_mooc solution_node_read");
 
  kbuf[0] = '\0';
  sprintf(kbuf, "%lu %lu\n", open_count, write_count);
  kbuf_size = strlen(kbuf);
  printk(KERN_INFO "kernel_mooc kbuf = %s, kbuf_size = %lu", kbuf, kbuf_size);
 
  copy_size = copy_to_user(buf, kbuf, kbuf_size);
  printk(KERN_INFO "kernel_mooc copy_size = %lu", copy_size);

  return kbuf_size - copy_size;
}

static ssize_t solution_node_write(struct file* sol_file, const char __user* buf, size_t buf_size, loff_t* ppos)
{
  int nbytes = 0;

  printk(KERN_INFO "kernel_mooc solution_node_write");
 
  nbytes = buf_size - copy_from_user(global_kbuf + *ppos, buf, buf_size);
  *ppos += nbytes;

  write_count += nbytes;
  return nbytes;
}

static const struct file_operations mycdev_fops =
{
  .owner = THIS_MODULE,
  .open = solution_node_open,
  .release = solution_node_release,
  .read = solution_node_read,
  .write = solution_node_write
};

static int __init custom_init(void)
{
  printk(KERN_INFO "kernel_mooc init_module kyamran");

  global_kbuf = kmalloc(10 * PAGE_SIZE, GFP_KERNEL);
 
  first = MKDEV(my_major, my_minor);
  register_chrdev_region(first, count, MYDEV_NAME);

  my_cdev = cdev_alloc();
  if (!my_cdev)
  {
    printk(KERN_ERR "kernel_mooc cdev_alloc");
  }

  cdev_init(my_cdev, &mycdev_fops);
  cdev_add(my_cdev, first, count);

  return 0;
}

static void __exit custom_exit(void)
{
  printk(KERN_INFO "kernel_mooc cleanup_module kyamran");

  if (my_cdev)
  {
    cdev_del(my_cdev);
  }

  unregister_chrdev_region(first, count);

  kfree(global_kbuf);
}

module_init(custom_init);
module_exit(custom_exit);

MODULE_LICENSE("GPL");

In reply to Кямран Шахаев

Re: Разработка модулей ядра Linux: задача File operations

by Кямран Шахаев -
Нашел ошибку. В моем понимании, все то, что передается из памяти ядра в память пользовательского процесса НЕ должно лежать на стеке. В моем случае массив char kbuf[256] лежит на стеке, оттуда и ошибка.
In reply to Кямран Шахаев

Re: Разработка модулей ядра Linux: задача File operations

by Валерия Допира -
Здравствуйте.
Здорово, что получилось разобраться! Да, пользовательский стек используется только во время работы процесса в пользовательском режиме. Соотвтетсвенно стек ядра является частью пространства ядра, он недоступен для пользовательских процессов. Когда пользовательский процесс, например, вызывает какой-нибудь syscall, ОС переключается в режим ядра. Во время вызова syscall используется стек ядра запущенного процесса.
Подробнее вы можете почитать в документации или тут

Успехов в обучении.
In reply to Валерия Допира

Re: Разработка модулей ядра Linux: задача File operations

by Кямран Шахаев -
Спасибо за разъяснение!