Showing results for 
Search instead for 
Did you mean: 
Registered: ‎11-23-2017

Writing to DDR fails

Hi all,

In my application , it needs to allocate physical memory and copying data from one location to another, i wrote a kernel module and allocated memory region and accessed it via virtual address returned by ioremap_nocache(); and writing to virtual address results in kernel freeze , Linux Hangs stucks and reboot is required. does anyone know why is this so?

here is my kernel module code i wrote:

#include <linux/delay.h>
#include <linux/dmaengine.h>
#include <linux/init.h>
#include <linux/kthread.h>
#include <linux/module.h>
#include <linux/random.h>
#include <linux/slab.h>
#include <linux/wait.h>
#include <linux/version.h>
#include <linux/interrupt.h>
#include <linux/vmalloc.h>
#include <linux/mman.h>
#include <linux/types.h>
#include <linux/fs.h>
#include <linux/errno.h>
#include <linux/mm.h>
#include <linux/sched.h>
#include <linux/cdev.h>
#include <linux/kernel.h>
#include <asm/io.h>
#include <asm/uaccess.h>
#include <asm/cacheflush.h>

#define DEVICE_NAME   "dma_kernel"

#define CLASS_NAME    "axi_dma"

MODULE_DESCRIPTION("A simple Linux driver for the AXI DMA."); 

//static void __iomem *dma_virt_addr;
static void __iomem *virt_source_buf_address;
//static void __iomem *virt_destination_buf_address;
//static unsigned int* p;
//static volatile unsigned int* dma_virt_addr;

static int    majorNumber;                             
static struct class*  axidmaclass  = NULL;
static int     axi_dma_open(struct inode *, struct file *);
static int     axi_dma_release(struct inode *, struct file *);

static int axi_dma_open(struct inode *inodep, struct file *filep){
   printk(KERN_INFO "AXI DMA: Device has been opened time(s)\n");
   return 0;

static int axi_dma_release(struct inode *inodep, struct file *filep){
   printk(KERN_INFO "AXI DMA: Device successfully closed\n");
   return 0;
static struct file_operations axi_dma={


static int __init axi_dma_init(void){
// Try to dynamically allocate a major number for the device -- more difficult but worth it
   majorNumber = register_chrdev(0, DEVICE_NAME, &axi_dma);
   if (majorNumber<0){
      printk(KERN_ALERT "axidma failed to register a major number\n");
      return majorNumber;
   printk(KERN_INFO "axidma: registered correctly with major number %d\n", majorNumber);

   // Register the device class
   axidmaclass = class_create(THIS_MODULE, CLASS_NAME);
   if (IS_ERR(axidmaclass)){                // Check for error and clean up if there is
      unregister_chrdev(majorNumber, DEVICE_NAME);
      printk(KERN_ALERT "Failed to register device class\n");
      return PTR_ERR(axidmaclass);          // Correct way to return an error on a pointer
   printk(KERN_INFO "axidma: device class registered correctly\n");

//request memory region

printk("failed to request memory region\n");

   printk(KERN_INFO "AXI DMA Initialized");

	u32  *src_buffer;
	u32  *dest_buffer;
	u32  *p; 
	src_buffer = kmalloc(1024, GFP_KERNEL);
	dest_buffer = kzalloc(1024, GFP_KERNEL);
int i;

if (!src_buffer || !dest_buffer) {
		printk(KERN_ERR "Allocating memory failed\n");
		return -1;

		for (i = 0; i < 1024/4; i++)
		src_buffer[i] = i;

	virt_source_buf_address = ioremap_nocache(0x80001400, 256*1024);
        if (!virt_source_buf_address ) {
                printk("Could not map physical memory to virtual\n");
                return -1;
	printk("virt_source_buf_address: %08X\n", (unsigned int)virt_source_buf_address);
	p = virt_source_buf_address;

		for (i = 0; i < 1024/4; i++){
		__raw_writel(src_buffer[i], p++);
			printk("data \n%d\n",*p);

		p = virt_source_buf_address;
		for (i = 0; i < 1024/4; i++)
		dest_buffer[i] = __raw_readl(p++);

		for (i = 0; i < 1024/4; i++) {
		if (dest_buffer[i] != src_buffer[i]) { 
			printk("index = %d, src=%02X, dest = %02X\n", i, src_buffer[i], dest_buffer[i]);

return 0;


static void __exit axi_dma_exit(void){
	device_destroy(axidmaclass, MKDEV(majorNumber, 0));     // remove the device
   	class_unregister(axidmaclass);                          // unregister the device class
   	class_destroy(axidmaclass);                             // remove the device class
   	unregister_chrdev(majorNumber, DEVICE_NAME);             // unregister the major num
	release_mem_region(0x80001300 ,256*1024*256);
        printk(KERN_INFO "AXI DMA Exit\n");

and here is the result when i insert the module and it stuck the Linux as shown below:


0 Kudos
1 Reply
Registered: ‎08-05-2017

回复: Writing to DDR fails


Did you solve this problem?

I have the same situation.

0 Kudos