简体   繁体   English

编写Linux内存驱动程序以将小写转换为大写

[英]Writing a Linux memory driver to convert lowercase to upper case

I was doing an assignment to build a memory driver which can convert lowercase to uppercase in Linux. 我正在分配一个内存驱动程序,可以在Linux中将小写字母转换为大写字母。 Linux will take the last byte through echo and cat. Linux将通过echo和cat获取最后一个字节。 It was due already. 已经到期了。 I tried several approaches but all didn't succeed. 我尝试了几种方法,但都没有成功。

I did char upper = 'A' + (upper - 'a') or ASCII - 32 if (ASCII is between a and z). 我做了char upper ='A'+(upper-'a')或ASCII-32 if(ASCII在a和z之间)。 I tried to put the statement in either memory write or read. 我试图将语句放入内存写入或读取。 Neither work. 都不起作用。

Here is the memory.c. 这是内存。c。 Can anyone let me know what mistake I have committed to? 谁能让我知道我犯了什么错误? I just make on change based on the sample code from my instructor. 我只是根据教练提供的示例代码进行更改。

/* Necessary includes for device drivers */
#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h> /* printk() */
#include <linux/slab.h> /* kmalloc() */
#include <linux/fs.h> /* everything... */
#include <linux/errno.h> /* error codes */
#include <linux/types.h> /* size_t */
#include <linux/proc_fs.h>
#include <linux/fcntl.h> /* O_ACCMODE */
#include <asm/system.h> /* cli(), *_flags */
#include <asm/uaccess.h> /* copy_from/to_user */


MODULE_LICENSE("Dual BSD/GPL");

/* Declaration of memory.c functions */
int memory_open(struct inode *inode, struct file *filp);
int memory_release(struct inode *inode, struct file *filp);
ssize_t memory_read(struct file *filp, char *buf, size_t count, loff_t *f_pos);
ssize_t memory_write(struct file *filp, char *buf, size_t count, loff_t *f_pos);
void memory_exit(void);
int memory_init(void);

/* Structure that declares the usual file */
/* access functions */
struct file_operations memory_fops =
{
  read: memory_read,
  write: memory_write,
  open: memory_open,
  release: memory_release
};

/* Declaration of the init and exit functions */
module_init(memory_init);
module_exit(memory_exit);

/* Global variables of the driver */
/* Major number */
int memory_major = 60;

/* Buffer to store data */
char *memory_buffer;



/* Memory Init Module */
int memory_init(void)
{
  int result;
  printk(KERN_ALERT "memory_init\n");

  /* Registering device */
  result = register_chrdev(memory_major, "memory", &memory_fops);
  if (result < 0) {
    printk(
      "<1>memory: cannot obtain major number %d\n", memory_major);
    return result;
  }

  /* Allocating memory for the buffer */
  memory_buffer = kmalloc(1, GFP_KERNEL);

  if(!memory_buffer)
  {
    memory_exit();
    return(-ENOMEM);
  }
  else
  {
    memset(memory_buffer, 0, 1);
    printk("<1>Inserting memory module\n");
    return 0;
  }
}



/* Memory Exit */
void memory_exit(void)
{

  printk("<1>Removing memory module\n");

  /* Freeing the major number */
  unregister_chrdev(memory_major, "memory");

  /* Freeing buffer memory */
  if (memory_buffer) {
    kfree(memory_buffer);
  }
}

/* Memory Open */
int memory_open(struct inode *inode, struct file *filp)
{
  printk(KERN_ALERT "memory_open\n");

  /* Success */
  return 0;
}

/* Memory Release */
int memory_release(struct inode *inode, struct file *filp)
{
  printk(KERN_ALERT "memory_release\n");

  /* Success */
  return 0;
}

/* Memory Read */
ssize_t memory_read(struct file *filp, char *buf,
                    size_t count, loff_t *f_pos)
{

  printk(KERN_ALERT "memory_read\n");
  /* Transfering data to user space */
  copy_to_user(buf,memory_buffer,1);  

  /* Changing reading position as best suits */
  if (*f_pos == 0)
  {
    *f_pos+=1;
    return 1;
  }
  else
  {
    return 0;
  }
}

/* Memory Write */
ssize_t memory_write( struct file *filp, char *buf,
                      size_t count, loff_t *f_pos)
{
  char *tmp;


  tmp=buf+count-1;
  copy_from_user(memory_buffer,tmp,1);
  char upper = 'A' + (upper - 'a'); // convert lower to upper case
  printk(KERN_ALERT "memory_write\n");

  return 1;
}

A few comments: 一些评论:

In your code for memory_write you are actually writing the new contents to memory before "calculating" the uppercase of the char. 在用于memory_write的代码中,实际上是在“计算”字符的大写之前将新内容写入内存。 I said "calculating" because you are attempting to calculate the uppercase of something, but that something is neither defined nor used, so the compiler is probably discarding the line, I'm talking about this line: 我说“计算”是因为您正在尝试计算某物的大写字母,但是没有定义或使用某物,因此编译器可能会丢弃该行,我在说这行:

char upper = 'A' + (upper - 'a'); // convert lower to upper case

You are defining the value of upper using the current value of upper if I'm understanding correctly, that's undefined. 如果我正确理解,则使用当前的upper值来定义upper的值,这是未定义的。

By looking at the code it seems like you should be trying to modify the value of *tmp (turn it to uppercase) before the call to copy_from_user. 通过查看代码,您似乎应该在调用copy_from_user之前尝试修改* tmp的值(将其变为大写)。

Last but not least, you are not taking into account the count, you are assuming that the user only wants to copy 1 character at the end of the block here, I'm not sure if that's what you want to do or not. 最后但并非最不重要的一点是,您没有考虑计数,而是假设用户只想在此处的块末尾复制1个字符,我不确定这是否是您想要的。

Briefly: 简要地:

  • You are not changing the value the user writes, that's why it is not doing anything 您没有更改用户编写的值,这就是为什么它没有做任何事情
  • You are only copying 1 character at the end of the block provided by the user 您仅在用户提供的块末尾复制1个字符
  • The code you are using to attempt to change the character to uppercase is wrong 您尝试将字符更改为大写的代码是错误的

To solve the uppercase part, and considering that you are intending to copy only 1 char and not the entire block, you could try something like this: 要解决大写部分,并考虑到您只打算复制1个char而不是整个块,可以尝试执行以下操作:

/* Memory Write */
ssize_t memory_write( struct file *filp, char *buf,
                      size_t count, loff_t *f_pos)
{
  char *tmp;


  tmp=buf+count-1;
  copy_from_user(memory_buffer,tmp,1);//write to memory

  char to_upper=memory_buffer[0]; //grab the char
  if (to_upper >= 97 && to_upper <= 122) // if the char in is the range a-z
  {
     to_upper = to_upper - 32;// convert to uppercase
     memory_buffer[0] = to_upper;
  }
  printk(KERN_ALERT "memory_write\n");

  return 1;
}

Hope it helps! 希望能帮助到你!

In memory_write... 在memory_write中...

copy_from_user(memory_buffer,tmp,1);
*memory_buffer = 'A' + (*memory_buffer - 'a');

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM