Chinaunix首页 | 论坛 | 博客
  • 博客访问: 120641
  • 博文数量: 49
  • 博客积分: 91
  • 博客等级: 民兵
  • 技术积分: 269
  • 用 户 组: 普通用户
  • 注册时间: 2012-05-02 10:14
文章分类

全部博文(49)

文章存档

2012年(49)

我的朋友

分类:

2012-06-05 22:50:52

原文地址:linux内核驱动模块写文件 作者:chl00100

最近项目中遇到一个问题,需要在驱动ko文件中写文件记录log,网上google了半天,要么不能用,要么直接编译不通过,最后参考内核源码linux-2.6.38/drivers/staging/spectra/lld_emu.c才搞定,主要如下:

1.我内核版本为2.6.38,编译器gcc version 4.4.1 (Sourcery G++ Lite 2009q3-67);
2.使用网上说的sys_open编译没问题,加载时会提示unknown symbol错误,估计是没有EXPORT_SYMBOL,所以不能在ko文件中使用;
3.使用网上一个filp_open例子,里面还调用了ioctl相关,直接编译错误,去除相关错误后,又加载错误;
4.用cscope搜索调用filp_open相关地方,找到drivers/staging/spectra/lld_emu.c里面有一个int emu_write_mem_to_file(void),copy出来,几乎不用修改直接可以使用,源码如下:

点击(此处)折叠或打开

  1. #include <linux/kernel.h>
  2. #include <linux/init.h>
  3. #include <linux/module.h>
  4. #include <linux/syscalls.h>
  5. #include <linux/file.h>
  6. #include <linux/fs.h>
  7. #include <linux/fcntl.h>
  8. #include <asm/uaccess.h>
  9. #include <linux/stat.h>
  10. #include <asm/unistd.h>
  11. #include <linux/types.h>

  12. static int write_log_file(char *filename, char *data_w) {
  13.     mm_segment_t fs;
  14.     struct file *nef_filp = NULL;
  15.     struct inode *inode = NULL;
  16.     loff_t nef_size = 0;
  17.     loff_t tmp_file_offset;
  18.     ssize_t nwritten;
  19.     int rc = -EINVAL;
  20.     int str_len;

  21.     fs = get_fs();
  22.     set_fs(get_ds());

  23.     nef_filp = filp_open(filename, O_CREAT | O_RDWR, 0);
  24.     if (IS_ERR(nef_filp)) {
  25.         printk(KERN_ERR "filp_open error: "
  26.                "Unable to open nand emu file!\n");
  27.         return PTR_ERR(nef_filp);
  28.     }

  29.     if (nef_filp->f_path.dentry) {
  30.         inode = nef_filp->f_path.dentry->d_inode;
  31.     } else {
  32.         printk(KERN_ERR "Invalid " "nef_filp->f_path.dentry value!\n");
  33.         goto out;
  34.     }

  35.     nef_size = i_size_read(inode->i_mapping->host);
  36.     if (nef_size < 0) {
  37.         printk(KERN_ERR "Invalid "
  38.                "nand emu file size: 0x%llx\n", nef_size);
  39.         goto out;
  40.     } else {
  41.         printk(KERN_ERR "nand emu file size: ""%lld\n", nef_size);
  42.     }

  43.     str_len = strlen(data_w) + 1;
  44.     tmp_file_offset = nef_size;
  45.     nwritten = vfs_write(nef_filp,
  46.                  (char __user *)data_w,
  47.                  str_len, &tmp_file_offset);
  48.     if (nwritten < str_len) {
  49.         printk(KERN_ERR "%s, Line %d - "
  50.                "nand emu file partial write: "
  51.                "%d bytes\n", __FILE__, __LINE__, (int)nwritten);
  52.         goto out;
  53.     }
  54.     
  55.     rc = 0;

  56. out:
  57.     filp_close(nef_filp, current->files);
  58.     set_fs(fs);
  59.     return rc;
  60. }

在合适处调用如write_log_file("/root/kernel_reboot.txt", "rebooting...\n\n")即可。


阅读(439) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~