我正在做一个分配来构建一个内存驱动程序,它可以在Linux中将小写转换为大写。 Linux将通过echo和cat获取最后一个字节。它已经到期了。我尝试了几种方法,但都没有成功。
我做了char upper ='A'+(upper - 'a')或ASCII - 32 if(ASCII在a和z之间)。我试图将语句写入内存写入或读取。都没有工作。
这是memory.c。任何人都可以让我知道我承诺的错误是什么?我只是根据教师的示例代码进行更改。
/* 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;
}
答案 0 :(得分:3)
一些评论:
在memory_write的代码中,实际上是在“计算”char的大写字母之前将新内容写入内存。我说“计算”是因为你试图计算某些东西的大写,但是既没有定义也没有使用,所以编译器可能放弃了这一行,我正在谈论这一行:
char upper = 'A' + (upper - 'a'); // convert lower to upper case
如果我正确理解,你使用upper的当前值来定义upper的值,这是未定义的。
通过查看代码,您似乎应该在调用copy_from_user之前尝试修改* tmp的值(将其转换为大写)。
最后但并非最不重要的是,你没有考虑到计数,你假设用户只想在块的末尾复制1个字符,我不确定这是你想要做的或者不
简言之:
要解决大写部分,并考虑到您只打算复制1个字符而不是整个块,您可以尝试这样的事情:
/* 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;
}
希望它有所帮助!
答案 1 :(得分:0)
在memory_write中......
copy_from_user(memory_buffer,tmp,1);
*memory_buffer = 'A' + (*memory_buffer - 'a');