Anonymous
Почему dma_mapping_error возвращает true в моей программе?
Сообщение
Anonymous » 30 июн 2024, 20:26
Я написал драйвер ядра Linux, хочу протестировать API dma в ядре Linux, код:
Я получил: «Похоже, что ваше сообщение состоит в основном из кода; добавьте, пожалуйста, еще немного». подробности." когда я пишу этот вопрос, я пишу что-то бесполезное, чтобы избежать этого предупреждения (может ли кто-нибудь помочь в этой ситуации, мой вопрос прост, и все, что мне нужно, это вставить его в это место.).
Код: Выделить всё
#define DEVICE_NAME "mychardev"
#define BUFFER_SIZE 1024
static int major;
static char device_buffer[BUFFER_SIZE];
static struct cdev my_cdev;
static struct class *my_class;
static struct device *my_device;
static int my_open(struct inode *inode, struct file *file) {
return 0;
}
static int my_release(struct inode *inode, struct file *file) {
return 0;
}
static ssize_t my_read(struct file *file, char __user *buf, size_t count, loff_t *ppos) {
return count;
}
static ssize_t my_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos) {
return count;
}
static const struct file_operations fops = {
.owner = THIS_MODULE,
.open = my_open,
.release = my_release,
.read = my_read,
.write = my_write,
};
static int __init my_init(void) {
int err;
dev_t dev;
unsigned char *tbuffer = NULL;
dma_addr_t tbuffer_dma = 0;
err = alloc_chrdev_region(&dev, 0, 1, DEVICE_NAME);
if (err < 0) {
printk(KERN_ERR "mychardev: Failed to allocate major number\n");
return err;
}
major = MAJOR(dev);
cdev_init(&my_cdev, &fops);
my_cdev.owner = THIS_MODULE;
err = cdev_add(&my_cdev, dev, 1);
if (err < 0) {
unregister_chrdev_region(dev, 1);
printk(KERN_ERR "mychardev: Failed to add cdev\n");
return err;
}
my_class = class_create(THIS_MODULE, DEVICE_NAME);
if (IS_ERR(my_class)) {
cdev_del(&my_cdev);
unregister_chrdev_region(dev, 1);
return PTR_ERR(my_class);
}
my_device = device_create(my_class, NULL, dev, NULL, DEVICE_NAME);
if (IS_ERR(my_device)) {
class_destroy(my_class);
cdev_del(&my_cdev);
unregister_chrdev_region(dev, 1);
return PTR_ERR(my_device);
}
tbuffer = (unsigned char *)kmalloc(1024 * 32 * sizeof(unsigned char), GFP_KERNEL | DMA_TO_DEVICE);
if (!tbuffer) {
printk(KERN_INFO "malloc failed\n");
goto nomem;
}
printk(KERN_INFO "kmalloc success\n");
printk(KERN_INFO "before map: %llx\n", tbuffer_dma);
tbuffer_dma = dma_map_single(my_device, (void *)tbuffer, 64, DMA_TO_DEVICE);
if (dma_mapping_error(my_device, tbuffer_dma)) {
printk(KERN_INFO "dma map error\n");
}
memset(tbuffer, 0, 1024);
print_hex_dump(KERN_INFO, "data:", DUMP_PREFIX_OFFSET, 32, 1, tbuffer, 1024, false);
dma_sync_single_for_device(my_device, tbuffer_dma, 64, DMA_TO_DEVICE);
printk(KERN_INFO "dma sync for device success\n");
printk(KERN_INFO "dma addr is: %llx\n", tbuffer_dma);
dma_unmap_single(my_device, tbuffer_dma, 1024, DMA_TO_DEVICE);
kfree(tbuffer);
printk(KERN_INFO "mychardev: Loaded with major number %d\n", major);
return 0;
nomem:
class_destroy(my_class);
cdev_del(&my_cdev);
unregister_chrdev_region(dev, 1);
return -ENOMEM;
}
static void __exit my_exit(void) {
device_destroy(my_class, MKDEV(major, 0));
class_destroy(my_class);
cdev_del(&my_cdev);
unregister_chrdev_region(MKDEV(major, 0), 1);
printk(KERN_INFO "mychardev: Unloaded\n");
}
module_init(my_init);
module_exit(my_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Your Name");
MODULE_DESCRIPTION("A simple character device driver");
После того, как я собрал драйвер и вставил файл .ko в ядро с помощью команды insmod, я получил ошибку ниже:
Я плохо знаю о dma, почему это произошло?
Я хочу знать, почему dma_map_single не удалось. Спасибо большое.
Подробнее здесь:
https://stackoverflow.com/questions/786 ... my-program
1719768405
Anonymous
Я написал драйвер ядра Linux, хочу протестировать API dma в ядре Linux, код: Я получил: «Похоже, что ваше сообщение состоит в основном из кода; добавьте, пожалуйста, еще немного». подробности." когда я пишу этот вопрос, я пишу что-то бесполезное, чтобы избежать этого предупреждения (может ли кто-нибудь помочь в этой ситуации, мой вопрос прост, и все, что мне нужно, это вставить его в это место.). [code]#define DEVICE_NAME "mychardev" #define BUFFER_SIZE 1024 static int major; static char device_buffer[BUFFER_SIZE]; static struct cdev my_cdev; static struct class *my_class; static struct device *my_device; static int my_open(struct inode *inode, struct file *file) { return 0; } static int my_release(struct inode *inode, struct file *file) { return 0; } static ssize_t my_read(struct file *file, char __user *buf, size_t count, loff_t *ppos) { return count; } static ssize_t my_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos) { return count; } static const struct file_operations fops = { .owner = THIS_MODULE, .open = my_open, .release = my_release, .read = my_read, .write = my_write, }; static int __init my_init(void) { int err; dev_t dev; unsigned char *tbuffer = NULL; dma_addr_t tbuffer_dma = 0; err = alloc_chrdev_region(&dev, 0, 1, DEVICE_NAME); if (err < 0) { printk(KERN_ERR "mychardev: Failed to allocate major number\n"); return err; } major = MAJOR(dev); cdev_init(&my_cdev, &fops); my_cdev.owner = THIS_MODULE; err = cdev_add(&my_cdev, dev, 1); if (err < 0) { unregister_chrdev_region(dev, 1); printk(KERN_ERR "mychardev: Failed to add cdev\n"); return err; } my_class = class_create(THIS_MODULE, DEVICE_NAME); if (IS_ERR(my_class)) { cdev_del(&my_cdev); unregister_chrdev_region(dev, 1); return PTR_ERR(my_class); } my_device = device_create(my_class, NULL, dev, NULL, DEVICE_NAME); if (IS_ERR(my_device)) { class_destroy(my_class); cdev_del(&my_cdev); unregister_chrdev_region(dev, 1); return PTR_ERR(my_device); } tbuffer = (unsigned char *)kmalloc(1024 * 32 * sizeof(unsigned char), GFP_KERNEL | DMA_TO_DEVICE); if (!tbuffer) { printk(KERN_INFO "malloc failed\n"); goto nomem; } printk(KERN_INFO "kmalloc success\n"); printk(KERN_INFO "before map: %llx\n", tbuffer_dma); tbuffer_dma = dma_map_single(my_device, (void *)tbuffer, 64, DMA_TO_DEVICE); if (dma_mapping_error(my_device, tbuffer_dma)) { printk(KERN_INFO "dma map error\n"); } memset(tbuffer, 0, 1024); print_hex_dump(KERN_INFO, "data:", DUMP_PREFIX_OFFSET, 32, 1, tbuffer, 1024, false); dma_sync_single_for_device(my_device, tbuffer_dma, 64, DMA_TO_DEVICE); printk(KERN_INFO "dma sync for device success\n"); printk(KERN_INFO "dma addr is: %llx\n", tbuffer_dma); dma_unmap_single(my_device, tbuffer_dma, 1024, DMA_TO_DEVICE); kfree(tbuffer); printk(KERN_INFO "mychardev: Loaded with major number %d\n", major); return 0; nomem: class_destroy(my_class); cdev_del(&my_cdev); unregister_chrdev_region(dev, 1); return -ENOMEM; } static void __exit my_exit(void) { device_destroy(my_class, MKDEV(major, 0)); class_destroy(my_class); cdev_del(&my_cdev); unregister_chrdev_region(MKDEV(major, 0), 1); printk(KERN_INFO "mychardev: Unloaded\n"); } module_init(my_init); module_exit(my_exit); MODULE_LICENSE("GPL"); MODULE_AUTHOR("Your Name"); MODULE_DESCRIPTION("A simple character device driver"); [/code] После того, как я собрал драйвер и вставил файл .ko в ядро с помощью команды insmod, я получил ошибку ниже: [code]dma map error [/code] Я плохо знаю о dma, почему это произошло? Я хочу знать, почему dma_map_single не удалось. Спасибо большое. Подробнее здесь: [url]https://stackoverflow.com/questions/78689315/why-dma-mapping-error-return-true-in-my-program[/url]