Subject: Re: how to allocate 9MB of memory in kernel ?

From: Misbah khan <[email-masked]>
Date: Thu, 24 Jul 2008 01:33:18 -0700 (PDT)

Hi all ...
 
I am uploading the source code which is doing the following :-

1. mapping cpld register using ioremap coping the data to circular buffer
and remapping it to user space .

2. It can also map kernel virtual dma memory to user space if compiled
conditionally .

following is the problem which i am facing ...

1. It is somitimes giving following kernel panic ....

nable to handle kernel NULL pointer dereference at virtual address 00000000
pgd = c0004000
[00000000] *pgd=00000000
Internal error: Oops: 17 [#1]
Modules linked in: fluke_driver tstamp sig_router mvci_spi mvci_sf_pcd
mvci_sci_unidir_s1 mvci_sci_diff mvci_sci_bidir_s
1 mvci_rtmd_s1 mvci_kwiso_s1 mvci_kw1281_s1 mvci_kh_s1 mvci_j1850
mvci_gm_sbc mvci_diagh_s1 g_ether mvci_dcl mvci_can1 f
pga_conf arcotg_udc adc_dac keypad(F) splc501_lcd(F) cpld
CPU: 0
PC is at cascade+0x64/0x8c
LR is at __init_begin+0x3fff8000/0x30
pc : [<c00484ac>]    lr : [<00000000>]    Tainted: GF
sp : c0293ea8  ip : 0040b000  fp : c0293ecc
r10: 8001d9f0  r9 : c0292000  r8 : 00000001
r7 : c0292000  r6 : 0000000c  r5 : c02fa048  r4 : 00000000
r3 : c02fa2f8  r2 : 0000261a  r1 : bf01ab70  r0 : c02fa2f8
Flags: Nzcv  IRQs off  FIQs on  Mode SVC_32  Segment kernel
Control: C5387F
Table: 8698C000  DAC: 00000017
Process swapper (pid: 0, stack limit = 0xc0292250)
Stack: (0xc0293ea8 to 0xc0294000)
3ea0:                   bf01ab70 c02fb440 0000000a 00000000 c02fa048
0000000a
3ec0: c0293efc c0293ed0 c0048810 c0048454 c0293eec c0293ee0 c002a30c
00000001
3ee0: c02f9e44 0000000a 00000002 00000001 c0293f1c c0293f00 c00442a0
c0048794
3f00: c0293f2c 0000001d c0294740 00000000 c0293f2c c0293f20 c00446d4
c0044254
3f20: c0293f4c c0293f30 c00217b0 c0044698 c0293f5c ffffffff 0000ffff
00000001
3f40: c0293fa4 c0293f50 c00209e4 c0021770 00000001 00000001 c0292000
00000000
3f60: c0022068 c0292000 c0298c44 c03121c0 8001da24 4107b364 8001d9f0
c0293fa4
3f80: c0293fa8 c0293f98 c0021d48 c002209c 60000013 ffffffff c0293fbc
c0293fa8
3fa0: c0021d48 c0022074 c02faae0 c02f292c c0293fcc c0293fc0 c00202e0
c0021d24
3fc0: c0293ff4 c0293fd0 c0008848 c00202b4 c00083c4 00000000 00000000
c02f29a8
3fe0: 00000000 00c5387d 00000000 c0293ff8 80008030 c00086e0 00000000
00000000
Backtrace:
[<c0048448>] (cascade+0x0/0x8c) from [<c0048810>]
(run_timer_softirq+0x88/0x1e8)
 r6 = 0000000A  r5 = C02FA048  r4 = 00000000
[<c0048788>] (run_timer_softirq+0x0/0x1e8) from [<c00442a0>]
(__do_softirq+0x58/0xc8)
 r8 = 00000001  r7 = 00000002  r6 = 0000000A  r5 = C02F9E44
 r4 = 00000001
[<c0044248>] (__do_softirq+0x0/0xc8) from [<c00446d4>] (irq_exit+0x48/0x5c)
 r6 = 00000000  r5 = C0294740  r4 = 0000001D
[<c004468c>] (irq_exit+0x0/0x5c) from [<c00217b0>] (asm_do_IRQ+0x4c/0x64)
[<c0021764>] (asm_do_IRQ+0x0/0x64) from [<c00209e4>] (__irq_svc+0x44/0x80)
 r6 = 00000001  r5 = 0000FFFF  r4 = FFFFFFFF
[<c0022068>] (default_idle+0x0/0x3c) from [<c0021d48>] (cpu_idle+0x30/0x5c)
[<c0021d18>] (cpu_idle+0x0/0x5c) from [<c00202e0>] (rest_init+0x38/0x40)
 r5 = C02F292C  r4 = C02FAAE0
[<c00202a8>] (rest_init+0x0/0x40) from [<c0008848>]
(start_kernel+0x174/0x1c0)
[<c00086d4>] (start_kernel+0x0/0x1c0) from [<80008030>] (0x80008030)
Code: e1530005 15822000 ebffffb6 e1a0e004 (e5944000)
 <0>Kernel panic - not syncing: Aiee, killing interrupt handler!

also when i run it on X86 PC i am able to get the data and no panic where in
on the board it is giving the above error ....

2. I can raed the data using the user application when i run it on X86 PC
where in i cant able to read the data when i run it on the board the data i
was getting was always '/0' filled buffer .

Here is the compilete code .............

/******************************************************************************
* McBSP_Driver.c
*
* Fluke Driver
*
* Description:
*
* Libraries Used:
*
*
* Unit Test Drivers (Binary):
*
*		<fix me >
*
*
* Special Compile Flags
*		Nil
*
* Revision History:
* 	(17/July/2008) Misbah
*    		Created the file
*
* Copyright (C)
*
******************************************************************************/

/******************************************************************************
*						Include Files
*****************************************************************************/

/* Standard linux files includes */
#include<linux/kernel.h>
//#include<linux/config.h>
#include<linux/ioctl.h>
#include<linux/types.h>
#include<linux/module.h>
#include<linux/fs.h>
#include<linux/delay.h>
#include<linux/init.h>
#include<linux/interrupt.h>
#include<linux/version.h>
#include<linux/wait.h>
#include<linux/poll.h>
#include<linux/timer.h>
#include<linux/irq.h>
#include<asm/uaccess.h>
#include<linux/time.h>
#include<asm/io.h>
#include<asm/bitops.h>
#include<linux/mm.h>
//#include<asm/mmzone.h>
#include<linux/bootmem.h>
#include <linux/dma-mapping.h>
#include <linux/vmalloc.h>
#include <asm/pgtable.h>
#include<asm/io.h>
#include<asm/bitops.h>
#include"fluke_driver.h"

static int McBSP_DriverOpen(struct inode *inode,struct file *file);
static int McBSP_DriverInit(void);
static int McBSP_DriverIoctl(struct inode *inode, struct file *file,\
					unsigned int cmd, unsigned long param);
static ssize_t McBSP_DriverWrite(struct file *file,
			const char __user *buf, size_t len,loff_t *offset);
static ssize_t McBSP_DriverRead(struct file *file,char __user *buf,size_t
len,
			loff_t *offset);
static int McBSP_DriverMmap(struct file *file,struct  vm_area_struct *vma);
static void MmapOpen(struct vm_area_struct *vma);
static void MmapClose(struct vm_area_struct *vma);
static void McBSP_DriverExit(void);
static int McBSP_DriverClose(struct inode *inode,struct file *file);
static int WriteBuf(void);
void timer_func(void);

static struct timer_list 		fluke_timer;
static dma_addr_t 				dma_addr;
static char						*buf_ptr;

static struct file_operations fluke_fops =
{
	.owner 		= THIS_MODULE,
	.open 		= McBSP_DriverOpen,
//	.read 		= McBSP_DriverRead,
	.ioctl 		= McBSP_DriverIoctl,
	.mmap		= McBSP_DriverMmap,
//	.write		= McBSP_DriverWrite,
	.release 	= McBSP_DriverClose,
};

/* File operation structure for mmap system call */
static struct vm_operations_struct mmap_op=
{
	.open		=	MmapOpen,
	.close		=	MmapClose,
};

static circularbuffer_S *buf_area = NULL;
static circularbuffer_index_S buf_index_area;
static int device_open_count	  = 0;
static int data_present_status    = 0;

void *ioremap_ptr;
static int phy_addr ;

/* static declaration of wait queue  */
static DECLARE_WAIT_QUEUE_HEAD(wait_queue);

static DECLARE_MUTEX(mutex);

module_init(McBSP_DriverInit);
module_exit(McBSP_DriverExit);

MODULE_AUTHOR("Misbah U K");
MODULE_LICENSE ("GPL");

#define SIMULATION
/****************************************************************************
*
* Description: This function will open fluke device
*
* Input:	File structure pointer and Inode structure pointer.
*			( passed by the kernel )
*
* output:	Returns 0 on Success.
*
***************************************************************************/
static int McBSP_DriverOpen(struct inode *inode,struct file *file)
{
	/* Reintialize file operation structure */
	file->f_op=&fluke_fops;

	printk(KERN_DEBUG" fluke driver open success \n");

	if (device_open_count == 0)
	{
		device_open_count = 1;

		/* Reset the read and write index*/
		buf_index_area.write_index=0;
		buf_index_area.read_index=-1;
		buf_index_area.count_index=0;

		#ifdef SIMULATION
		/* Initialize the Timer */
		init_timer(&fluke_timer);
		fluke_timer.expires = jiffies + (HZ*10);//Timer will Expire after 60 sec
		fluke_timer.data = 0;
		fluke_timer.function = (void *)timer_func;
		add_timer(&fluke_timer);
		#endif
	}

	return 0;
}

/******************************************************************************
 *
 * Description : Interrupt handler function.
 *
 * Input:		 NONE
 *
 * Output:		 NONE
 *

*****************************************************************************/
irqreturn_t DataAcqIntHandler(int irq,void *dev_id, struct pt_regs *regs)
{
	printk(KERN_ALERT" In Interrupt Handler\n");
	/* Data present status is set to wake up the read call */
	data_present_status=1;

	/* Wake up the blocked Select call */
	wake_up_interruptible(&wait_queue);

	#ifndef SIMULATION
	/* Clear the interrupt in the interrupt pending registor */
	cpi->ic_scprrh |=DATA_ACQ_INT_CLEAR;
	#endif

	return IRQ_HANDLED;

}/* End of PpsIntrHandler() */

#ifdef SIMULATION
void timer_func(void)
{

	printk(KERN_ALERT" In the timer function \n");
	/* Data present status is set to wake up the read call */
	data_present_status=1;

	/* Wake up the blocked Read call */
	wake_up_interruptible(&wait_queue);

}

#endif

/***************************************************************************
*
* Description: Register the device and perform Initialization.
*
* Input:		NIL
*
* Output:		Returns 0 on Success and -1 on failure
*
**************************************************************************/
static int __init McBSP_DriverInit(void)
{
	unsigned int virt_addr = 0;
	int mem = 0;

	//buf_area = vmalloc(sizeof(circularbuffer_S));
	//if(!buf_area)
	//{
	//	printk(KERN_ALERT"vmalloc failed \n");
	//	return -1;
	//}

#if 0
	/*
	* Allocate memory for the circular buffer in the DMA coherent area
	* and algin it in the Cache
	*/
	mem = L1_CACHE_ALIGN(sizeof(circularbuffer_S));

	buf_ptr = (char *)dma_alloc_coherent(NULL, mem, &dma_addr,GFP_KERNEL);
	printk(KERN_INFO" buf_ptr = 0x%x \n",(int )buf_ptr);
	if(NULL == buf_ptr )
	{
		printk(KERN_ALERT" Allocation of Memory failure ");
		return -1;
	}

	buf_area = (circularbuffer_S *)(((unsigned int )buf_ptr + PAGE_SIZE - 1) \
			& PAGE_MASK);

	printk(KERN_INFO" buf_area = 0x%x \n",(int )buf_area);

	if(NULL == buf_area)
	{
		printk(KERN_ALERT" Circular buffer memory not allocated \n");
		return -1;
	}

	/* Marking the Pages as reserved */
	for (virt_addr = (unsigned int)buf_area; \
	virt_addr < (unsigned int )buf_area + sizeof(circularbuffer_S);\
	virt_addr += PAGE_SIZE)
	{
		/* Set the pages as reserved */
		SetPageReserved(virt_to_page(virt_addr));
		//mem_map_reserve(virt_to_page(virt_addr));
	}

	phy_addr = virt_to_phys(buf_ptr);
	printk(KERN_INFO"Allocated Memory for Circular Buffer at physical
0x0%x\n",phy_addr);

#else

	buf_area = ioremap(0xB2000000,0x4000); //(0xB2000000,0x4000);
//(7700000,900000);
	if(!buf_area)
	{
		printk(KERN_ALERT"ioremap failed \n");
		return -1;
	}

	printk(" Ioremap mapped to virtual 0x0%x \n",buf_area);
	*((unsigned int *)buf_area) = 0xa5a5a5a5;
	printk(" Ioremap data  0x0%x \n",*((unsigned int *)buf_area + 0));

#endif

	/* Device major number is registered to set the driver entry point */
	if(register_chrdev(MAJOR_NO,MODULE_NAME, &fluke_fops)==0)
	{
		printk(KERN_DEBUG" Fluke driver registeration success \n");

	}
	else
	{
		printk(KERN_ALERT" Fluke driver registeration failed \n");
		return -1;
	}

	/*
	 * Register Data Acq interrupt request with specified irq and install the
	 * handler
	 */
	 if(request_irq(DATA_ACQ_INT,(void *)DataAcqIntHandler, SA_INTERRUPT,
	 						MODULE_NAME, NULL)==0)
	{
		printk(KERN_DEBUG" Data Acq interrupt request returns success \n");
	}
	else
	{
		printk(KERN_DEBUG" Data Acq interrupt request failed \n");
		unregister_chrdev(MAJOR_NO,MODULE_NAME);
		return -1;

	}

	/* Reset the read and write index*/
	buf_index_area.write_index=0;
	buf_index_area.read_index=0;
	buf_index_area.count_index=0;

	return 0;

}

/***************************************************************************
*
* Description: Input/Output entry point for driver.
*
* Input:		Inode pointer, File pointer, command and parameter.
*
* Output:		Returns 0 on success and -1 on failure.
*
**************************************************************************/

static int McBSP_DriverIoctl(struct inode *inode, struct file *file,\
									unsigned int cmd, unsigned long param)
{
	int i;
	daq_t daq_param;

	printk(KERN_DEBUG"In ioctl command \n");

	switch(cmd)
	{
		case START_ACQ_DATA:

			if(copy_from_user(&daq_param,(void *)param,sizeof(daq_param)))
			{

				return -1;
			}

			/* For Simulation we are writing the data */
			if(WriteBuf() < 0)
			{
				printk(" Writing to the memory failure \n");
				return -1;
			}

			/* Wait for the Interrupt to occur */
			wait_event_interruptible( wait_queue, data_present_status !=0);

			printk("Read Index before read %d\n",buf_index_area.read_index);
			data_present_status=0;

			buf_index_area.read_index++;
			buf_index_area.read_index%=NO_FRAMES;

			if(buf_index_area.read_index ==((buf_index_area.write_index +1) %
NO_FRAMES))
			//if(buf_index_area.read_index == buf_index_area.write_index )
			{
				printk("Read failure because read and write index are same\n");
				return -1;
			}

			/* Decrement the count index to indicate the data availibility */
			down(&mutex);
			buf_index_area.count_index--;
			up(&mutex);

			/* copy the circular buffer read index */
			daq_param.circular_index = buf_index_area.read_index;

			/*for(i = 0;i < SIZE_FRAME; i++)
			{
				printk("%c",buf_area->fluke[buf_index_area.read_index].buffer[i]);
			}
			*/
			/* Configure ADC unit for No of samples and period */
			/* < To Dod > */
			#ifdef SIMULATION
			/* Reinitialize the timer and run it again */
			init_timer(&fluke_timer);
			fluke_timer.function=(void *)timer_func;
			fluke_timer.data=0;
			fluke_timer.expires=jiffies + (HZ*10);
			del_timer(&fluke_timer);
			printk(KERN_DEBUG"Timer reinitialize in ioctl \n");
			add_timer(&fluke_timer);

			#endif
			printk("Read Index after read %d\n",buf_index_area.read_index);
			if(copy_to_user((void *)param,&daq_param,sizeof(daq_param)))
			{

				return -1;
			}

			break;
		default:
			return(0);
	}
	return (0);
}

/******************************************************************************
* Description: This function writes data to the device.
*
* Inputs:  NONE
*
* Outputs: Returns No of bytes copied or -1 on failure.
******************************************************************************/
static ssize_t McBSP_DriverWrite(struct file *file,
			const char __user *buf, size_t len,loff_t *offset)
{

	int i,write_index;
	write_index = buf_index_area.write_index;
	if(buf_index_area.read_index ==((buf_index_area.write_index +1) %
NO_FRAMES))
	//if(buf_index_area.read_index == buf_index_area.write_index )
	{
		printk(KERN_ALERT"Not able to write\n");
		return -1;
	}
	printk(KERN_INFO" Before Write index = %d\n",buf_index_area.write_index);
	for(i=0;i<len;i++)
	{
		buf_area->fluke[write_index].buffer[i]=buf[i];
		//memset(buf_area->fluke[write_index].buffer,'A',SIZE_FRAME);
		//for(i = 0;i < SIZE_FRAME; i++)
		//{
		//	printk("%c",buf_area->fluke[write_index].buffer[i]);
		//}
		//printk(" %c",buf_area->fluke[write_index].buffer[i]);
	}
	for(i = 0;i < SIZE_FRAME; i++)
	{
		printk("%c",buf_area->fluke[write_index].buffer[i]);
	}
	//len = copy_from_user(buf_area->fluke[write_index].buffer,buf,len);

	//memcpy_fromio(ioremap_ptr,buf_area->fluke[write_index].buffer,4);

	buf_index_area.count_index++;
	buf_index_area.write_index++;
	buf_index_area.write_index%=3;

	printk(KERN_INFO" After Write index = %d\n",buf_index_area.write_index);

	return len;

}

/******************************************************************************
* Description: This function writes data to the circular buffer.
*
* Inputs:  NONE
*
* Outputs: Returns No of bytes copied or -1 on failure.
******************************************************************************/
static int WriteBuf(void)
{
	int i;

	printk(" write Index is %d \n",buf_index_area.write_index);
	if(buf_index_area.read_index ==((buf_index_area.write_index +1) %
NO_FRAMES))
	//if(buf_index_area.read_index == buf_index_area.write_index )
	{
		printk(KERN_ALERT"Not able to write\n");
		return -1;
	}

	memset(buf_area->fluke[buf_index_area.write_index].buffer,'A',SIZE_FRAME);

	/*for(i = 0;i < SIZE_FRAME; i++)
	{
		printk("%c",buf_index_area.fluke[buf_index_area.write_index].buffer[i]);
	}
	*/
	buf_index_area.count_index++;
	buf_index_area.write_index++;
	buf_index_area.write_index%=3;
	printk(" write Index incremented to %d \n",buf_index_area.write_index);

	return 0;
}

/******************************************************************************
* Description: This function reads data from the shared mmap area.
*
* Inputs:  file structuer,data buffer pointer and length of data.
*
* Outputs: Return no of bytes read or -1 on failure.
*
******************************************************************************/
static ssize_t McBSP_DriverRead(struct file *file,char __user *buf,size_t
len,
			loff_t *offset)
{

	int temp_read_index,i;
	printk(KERN_INFO"Entering %s\n",__FUNCTION__);

	/* Wait till timer Expires */
	wait_event_interruptible( wait_queue, data_present_status !=0);

	data_present_status=0;

	buf_index_area.read_index++;
	buf_index_area.read_index%=NO_FRAMES;

	/* Decrement the count index to indicate the data availibility */
	down(&mutex);
	buf_index_area.count_index--;
	up(&mutex);

	temp_read_index = buf_index_area.read_index;

	printk(KERN_INFO"Exting %s\n",__FUNCTION__);

	printk(KERN_INFO"count_index=%d\n",buf_index_area.count_index);
	printk(KERN_INFO"read_index=%d\n",buf_index_area.read_index);
	/*for(i = 0 ;i < SIZE_FRAME ; i++)
	{
		printk("%c",buf_area->fluke[temp_read_index].buffer[i]);
	}
	*/
	return((temp_read_index));
}

/*****************************************************************************
* Description:This function is used to map the memory area to user
application.
*				There is a circular buffer which is created in the driver.
*			   This region is mmaped to the user application by this function.
*			   This fuction sets the permissions for that area accordingly.
*
* Inputs:file pointer, virtual memory area structure.
*
* Outputs: Returns 0 on success or -1 on failure.
*******************************************************************************/
static int McBSP_DriverMmap(struct file *file,struct  vm_area_struct *vma)
{

	unsigned long start = vma->vm_start;
	unsigned long size = vma->vm_end - vma->vm_start; //0x900000;
	unsigned long phy_add = virt_to_phys(buf_ptr); //0x7700000;
	int ret = 0;

	/* Make the mmaped area noncacheable */
	vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);

	/* Set the Flags to give permissions to Mmaped area */
	vma->vm_flags |=VM_RESERVED;
	vma->vm_flags |=VM_READ;
	vma->vm_flags |=VM_WRITE;
	vma->vm_flags |=VM_IO;
	//vma->vm_flags |=VM_SHARED;
	//vma->vm_flags |=VM_LOCKED;

	printk(KERN_DEBUG"In mmap function\n");

	/* Mmap the kernel buffer to user space */
	if(remap_pfn_range(vma,start,(phy_add >>
PAGE_SHIFT),size,vma->vm_page_prot))
	//if(remap_pfn_range(vma,start,vma->vm_pgoff,size,vma->vm_page_prot))
	{
		printk(KERN_ALERT"remap_pfn_range failed\n");
		goto mmap_exit;

   	}

   	printk(KERN_ALERT"phy addr 0x%08X mmapped to virt addr 0x%08X, size =
0x%08X\n",
		(unsigned int)phy_add, (unsigned int)start, (unsigned int)size);

	/* Initialize the file operation structure of Mmaped area */
	vma->vm_ops=&mmap_op;

	/* Open the Mmaped area */
	MmapOpen(vma);

	mmap_exit:
	   	return ret;
}

/******************************************************************************
* Description: This function opens mmaped area for the device.
*
* Inputs:  Virtual memory area structure.
*
* Outputs: none
******************************************************************************/
static void MmapOpen(struct vm_area_struct *vma)
{
	printk("Mmaped are is opened \n");

	printk("Virtual= %lx, Physical=%lx \n",vma->vm_start,
		(vma->vm_pgoff << PAGE_SHIFT));
	return;
}

/******************************************************************************
* Description: This function closes mmaped area for the device
*
* Inputs: Virtual Memory structure.
*
* Outputs: Return CASHEL_SUCCESS after closing the device.
******************************************************************************/
static void MmapClose(struct vm_area_struct *vma)
{
	printk(KERN_DEBUG"Mmaped are is closed\n ");
	return;
}

/******************************************************************************
*
* Description	: Unregisters the driver and makes the resources free.
*
* Input		: NIL
*
* Output		: NIL
*
*****************************************************************************/
static void __exit McBSP_DriverExit(void)
{
	unsigned int virt_addr;

#if 0
	/* Clear or Free the pages which are reserverd */
	for (virt_addr=(unsigned int)buf_area; virt_addr < (unsigned int)buf_area
										+ sizeof(circularbuffer_S);
	virt_addr += PAGE_SIZE)
	{
		// clear all pages
		ClearPageReserved(virt_to_page(virt_addr));
	}

	/* Free the mmaped buffer area */
	dma_free_coherent(NULL,L1_CACHE_ALIGN(sizeof(circularbuffer_S)),
												buf_ptr,dma_addr);
#else

	iounmap(buf_area);

#endif

	/* Unregister the device */
	if(unregister_chrdev(MAJOR_NO , MODULE_NAME)==0)
		printk(KERN_DEBUG" device cleanup success\n");
	else
		printk(KERN_ALERT" device cleanup failed \n");

	/* Free IRQ */
	free_irq(DATA_ACQ_INT,NULL);

	//if(buf_area)
	//	vfree(buf_area);

}

/******************************************************************************
* Description: This function closes the device
*
* Inputs:  Inode structure pointer, File structure pointer
*
* Outputs: Return 0 on success and -1 on failure.
******************************************************************************/
static int McBSP_DriverClose(struct inode *inode,struct file *file)
{
	device_open_count--;
	if(device_open_count == 0)
	{
		/* Delete the timer */
		del_timer(&fluke_timer);
	}

	printk(KERN_INFO" device closed %d\n",device_open_count);
	return 0;
}

/******************************************************************************
 *						 File Ends

*****************************************************************************/

#define MODULE_NAME						"fluke_driver"
#define MAJOR_NO							 333
#define NO_FRAMES							 3
#define SIZE_FRAME							 1024*5//(1024*1024*1)/* 3MB */
#define DATA_ACQ_INT						 23 /* To Do <for testing only > */
#define DATA_ACQ_INT_CLEAR					 1 /* To Do <for testing only > */

#define MAGIC_NUM      			'D'

#define START_ACQ_DATA   		_IOWR(MAGIC_NUM, 0,unsigned long)

/* Frame */
typedef struct
{
	char buffer[SIZE_FRAME];

}frame_S;

/* Circular Buffer Structured */
/* Mmaped area Structure */
typedef struct
{

	frame_S  fluke[NO_FRAMES];

}circularbuffer_S;

typedef struct
{
	unsigned int count_index;
	unsigned int read_index;
	unsigned int write_index;
}circularbuffer_index_S;

typedef struct
{
	int test_period_ms;		/*????? send to driver*/
	int req_no_sample;		/*send to driver*/
	int acq_no_of_sample;  /* return by driver*/
	int circular_index;    /* return by driver*/
	int sampling_rate_hz;  /*send to driver*/

}daq_t;

/******************************************************************************
 *						 File Ends

*****************************************************************************/

/******************************************************************************
* McBSP_appl.c
*
* Fluke Driver
*
* Description:
*
* Libraries Used:
*
*
* Unit Test Drivers (Binary):
*
*		<fix me >
*
*
* Special Compile Flags
*		Nil
*
* Revision History:
* 	(17/July/2008) Misbah
*    		Created the file
*
* Copyright (C)
*
******************************************************************************/

/******************************************************************************
*						Include Files
*****************************************************************************/
/* Standard linux files includes */
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>
#include <sys/types.h>
#include <unistd.h>
#include <errno.h>
#include <sys/stat.h>
#include <signal.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <sys/ioctl.h>
#include "fluke_driver.h"

#define FLUKE_DRIVER		"/dev/fluke"

int main (int argc ,char *argv[])
{
	circularbuffer_S *mmap_ptr;
	int fd = -1,i;
	int size_mmap = sizeof(circularbuffer_S);
	int read_index = -1,ret = -1 ;
	FILE *fp1,*fp2,*fp3;
	char buf[1024];
	char *mmap_data;
	daq_t daq_param;

	/* Initialize the config param */
	daq_param.test_period_ms = 60*1000 ;
	daq_param.acq_no_of_sample = 0;
	daq_param.req_no_sample =0;
	daq_param.sampling_rate_hz = 0;

	mmap_data = (char *)malloc(sizeof(circularbuffer_S));

	/* creat files for frames */
	fp1 = fopen("frame1.txt","w");
	fp2 = fopen("frame2.txt","w");
	fp3 = fopen("frame3.txt","w");

	/* Open the device file */
	fd = open(FLUKE_DRIVER , O_RDWR);
	if (fd == -1)
	{
		printf(" Error in opening fluke device \n");
		return -1;
	}

	/* map the kernel memory to user space */
	mmap_ptr = mmap(NULL,size_mmap,PROT_READ|PROT_WRITE,MAP_SHARED,fd,0);
	printf(" Virtual addr of the pointer is 0x%x \n",(unsigned int)mmap_ptr);

	if(mmap_ptr == NULL )
	{
		printf(" mapped ptr returns NULL from driver n");
		return -1;
	}

	while(1)
	{
		/* Write to driver for testing only */
		memset(buf,'Z',sizeof(buf));
		printf(" Writing to driver \n");
		//write(fd,buf,sizeof(buf));

		/* Block on read to get the circular buffer read index */
		//read_index = read(fd, buf , 1024);
		//printf(" Here is the read for you %s\n",buf);
		if (ioctl(fd , START_ACQ_DATA ,&daq_param) < 0)
		{
			printf(" ioctl failed \n");
			return -1 ;
		}

		read_index = daq_param.circular_index;

		printf(" read index from application %d \n",read_index);

		/* Print the data read */
		//for(i = 0;i <= 1024 ; i++)
			printf(" %s \n",mmap_ptr->fluke[read_index].buffer);

		/* Write the data read fron the driver to the file */
		if(read_index >= 0)
		{
			ret = (SIZE_FRAME) ;

			memcpy(mmap_data, \
				mmap_ptr->fluke[read_index].buffer,SIZE_FRAME);

			if(read_index == 0)
				fwrite(mmap_ptr->fluke[read_index].buffer ,SIZE_FRAME , 1 ,fp1);
			else if(read_index == 1)
				fwrite(mmap_ptr->fluke[read_index].buffer ,SIZE_FRAME , 1 ,fp2);
			else if(read_index == 2)
				fwrite(mmap_ptr->fluke[read_index].buffer ,SIZE_FRAME , 1 ,fp3);
			else
			{
				printf("Not able to write to file as read_index returns %d
\n",read_index );
				return -1;
			}

		}

	}

	if(mmap_data)
		free(mmap_data);
	fclose(fp1);
	fclose(fp2);
	fclose(fp3);

	return 0;
}

/******************************************************************************
 *						 File Ends

*****************************************************************************/

please help me to resolve this issue .......

Thanks in advance ...

---- Misbah <><

Misbah khan wrote:
> 
> 
> If you SDRAM is you main memory, you need vmalloc and remap_vmalloc_range.
> If the SDRAM is not your main memory but some I/O attached buffer, you
> need
> ioremap/of_iomap and remap_pfn_range.
> 
> My SDRAM is the main memory of which 9MB i have to allocate in the driver. 
> 
> If i allocate 9BM using vmalloc and remap to user space how should it
> address to the 9MB 
> SDRAM contigues address which i need to map for user access ? 
> 
> 
> Arnd Bergmann wrote:
>> 
>> On Tuesday 22 July 2008, Misbah khan wrote:
>>> First of all let me thank you for your valuable suggessions ...
>>> 
>>> 1. I wanted to allocate 9MB in kernel and wanted that memory to be
>>> mapped to
>>> the physically continews SDRAM memory. but till now i could not found a
>>> way
>>> to do so ???
>>> 
>>> 2. So i thought to use ioremap to map SDRAM and make it accessible to
>>> user
>>> using mmap technique but there is only one doubt and that is will it be
>>> secure and stable and whether it is a right way of doing ???
>> 
>> As I have told you a few times now, you *either* allocate the memory *or*
>> ioremap it, NOT BOTH!!!
>> 
>> If you SDRAM is you main memory, you need vmalloc and
>> remap_vmalloc_range.
>> If the SDRAM is not your main memory but some I/O attached buffer, you
>> need
>> ioremap/of_iomap and remap_pfn_range.
>> 
>> 	Arnd <><
>> _______________________________________________
>> Linuxppc-embedded mailing list
>> [email-masked]
>> https://ozlabs.org/mailman/listinfo/linuxppc-embedded
>> 
>> 
> 
> 

-- 
View this message in context: http://www.nabble.com/how-to-allocate-9MB-of-memory-in-kernel---tp18503022p18627544.html
Sent from the linuxppc-embedded mailing list archive at Nabble.com.