If I know the physical memory of data, because it was placed there by a memory mapped peripheral, how do I access it in a kernel module? My first instinct is to make a pointer
int * addr;
and assign it
addr = 0x________;
then read it
printk(KERN_INFO "%d\n",*addr);
but trying this makes the module crash. What's the appropriate way to do this?
You need to set up a kernel virtual address mapping for the location e.g.
addr = ioremap_nocache(0x________, <size_in_bytes>);
Related
I want to unmap the memory mapped by my custom character driver, through an ioctl call. is there any kernel API for that??
From userspace app1, I will be accessing my bar memory in a loop. Through an ioctl call from another user app2, i need to remove the mapping so that access my aap1 will create an SIGBUS error.
io_remap_pfn_range(vma, vma->vm_start, paddr >> PAGE_SHIFT, size, vma->vm_page_prot);
I have a PCI based Device, more specifically based on tms320c6000 DSP, I am trying to communicate (reading some registers) with this device through the Jungo WinDriver. Surprisingly it sometimes work and sometimes doesn't, when it doesn't system hang and I have to restart the system.
this is the snipped code which I used to read EMIF Registers, for example.
WD_TRANSFER tt[9];
BZERO(tt);
for (unsigned i = 0; i < 9; i++) {
tt[i].cmdTrans = RM_DWORD;
tt[i].dwPort = mmr + (i * 4);
}
WD_MultiTransfer(hDevice, &tt, 9);
mmr came from WD_CardRegister function which gave information about the PCI BARs and their mapped address (mmr is non prefechtable mapped memory).
I would be very grateful if someone could give me some hint about what might cause this problem.
Thanks
I am answering my question in case the problem happened to someone else.
there are sequence of actions which should be taken before using this device.
Warm reset through HDCR Register (set WARMRESET bit).
then the EMIF registers should be initialised, these are the values I used.
struct emif emif_val = {
0x00052078, //GBLCTL;
0x73a28e01, //CE1 Flash/FPGA;
0xffffffd3, //CE0 SDRAM;
0x00000000, //Reserved;
0x22a28a22, //CE2 Daughtercard 32-bit async
0x22a28a42, //CE3 Daughtercard 32-bit sync
0x63115000, //SDRAM contral, 4 banks
0x0000081b, //SDRAM timing
0x001faf4d //SDRAM extended control
};
and then you are able to access all address space of the device without any problem.
and for more information this linux source code could be very helpful
all
My program maybe have a memory issue, so I try to find information about memory usage provided by various tools. In order to find the cause, I do simple experiments as well.
In release mode, I add the following code,
pChar = new char[((1<<30)/2)];
for(int i; i < ((1<<30)/2); i++)
{
pChar[i] = i % 256;
}
When the code is executed, the available physical memory in Windows task manager doesn't change. In my view, the compiler may remove the code to boost performance. I declare the variable as one global variable. It doesn't work. But in debug mode, the available physical memory in Windows task manager changes as expected. I can't understand that.
I have another question. Will the new operation allocate memory from virtual memory if the physical memory runs out. Or one exception will be thrown?
It's indeed quite possible that the compiler detects a "write-only" variable. Since it's non-volatile, the writes can be safely eliminated, and then there's no need for the OS to actually allocate RAM.
new just allocates address space, on modern systems. Physical RAM is allocated when needed. Typically this happens when the ctor runs, as it initializes the members. But in new char there's of course no ctor.
I am trying to find memory leaks in a very complicated legacy system that is written in C++/C on the Solaris operating system. the idea is to log every malloc and free and then postproccess the log.
i was able to write a stub malloc and free function that gets called correctly. the problem is that they dont do anyhing other than log. As a result the sytem crashes
My question is: is they a substitute malloc library that works on solaris that is can call from my stub malloc& free functions?
Why don't you just do an LD_PRELOAD of libumem and use UMEM_DEBUG? The manpage for umem_debug should give you more information.
Ideally, You should some memory profiling tool but in the absence of the same you can try to implement your own leak detector as you plan to.
You can just call malloc and free library versions through your wrapper.
Here is a scheme that you may try to implement:
Your wrapper function should implement a functionality wherein your wrapper for malloc stores the line number, file name, size requested & address being returned by malloc in a linked list.
How to get filename and line number?
Hint: Use __FILE__, __LINE__
The free wrapper should check the address being sent for freeing against the list and remove the entry from the linked list.
At the end of the program you should print contents of this linked list which gives you leaking memory size, file name and line number from where the buffer was allocated.
Update:
How do you map program malloc calls to own wrapper calls without infinite recurssion?
Through clever Use of Macros!
#define malloc(X) my_malloc( X, __FILE__, __LINE__, __FUNCTION__)
void* my_malloc(size_t size, const char *file, int line, const char *func)
{
void *p = malloc(size);
printf ("Allocated = %s, %i, %s, %p[%li]\n", file, line, func, p, size);
/*Link List functionality goes in here*/
return p;
}
In addition to libumem, I would recommend using Solaris Studio dbx which includes with RTC, a memory leak detector.
This is my first question here :).
I been trying for while now to map physical memory to virtual memory in vxWorks 6.8 with no success,
I'm trying to use "vmMap" function but somehow it keeps return with:
errno = 0x30065 S_taskLib_NAME_NOT_FOUND.
my code is:
int page_size=0;
PHYS_ADDR GPIO_BASE_VIRTUAL_ADDR = 0x40E00000;
VIRT_ADDR VIRTUAL_ADDR=0;
page_size =vmPageSizeGet();
if((VIRTUAL_ADDR = (VIRT_ADDR)memalign(page_size,page_size*2))==NULL)// allocate 2 pages
{
printf("error in memalign() errno = 0x%x\n",errnoGet());
}
if(vmMap(NULL,VIRTUAL_ADDR,GPIO_BASE_VIRTUAL_ADDR,(page_size*2))== ERROR )
{
printf("Error mapping memory errno = 0x%x%\n",errnoGet());
}
Any help will be very appreciate,
thanks,
Moshe.
I see you already solved this long ago, but thought I'd leave some bread crumbs for whoever else might stumble this way in the dim & distant future..
Unless you're doing RTPs there's a good chance your MMU isn't even translating addresses. I.e., if something appears at say, 0x7fc00400 in the physical address space, you could simply cast that value to a pointer and use it.
*((short *) 0x7fc00400) = foo; // write 16 bits!
And Yes, these days it is almost sacrilege to suggest (ab)using pointers this way, but I would point out that if you're doing vxworks kernel space code, you're practically on the bare metal anyway, so why not?