Messages in this thread | | | Subject | system calls for physical buffers allocation | Date | Wed, 04 Mar 1998 17:26:56 +0100 | From | Andrea Cisternino <> |
| |
Hi Everybody, Thanks for your work and excuse me for the lengthy message.
I'm trying to write a small set of new system calls for 2.0.33 as part of a project here at INFN. These calls will allow user-space applications to "malloc" in user space contiguous buffers of physical RAM originally obtained with the BIGPHYSAREA patch.
I've implemented three new system calls:
bpalloc() bpfree() bpgetphys()
All of them passed a minuscule set of tests (dont' crash the system, get executed, their results are meaningful, I can R/W to the area :-) but I'm far from being a MM expert so I would like to have your comments on some details.
** bpalloc() **
This is basically a stripped down version of do_mmap with the addition of a bigphysarea_alloc_pages() call near the beginning to actually get the memory. In the vma that I'm using to build the mappings I set the flags in the following way:
vma->vm_flags = (PROT_READ | PROT_WRITE) | mm->def_flags; vma->vm_flags |= (VM_SHARED| VM_MAYREAD | VM_MAYWRITE | VM_MAYSHARE);
The virtual address is obtained with:
virt_addr = get_unmapped_area (0, size_in_bytes);
Other settings in the vma are:
vma->vm_start = virt_addr; vma->vm_ops = NULL; vma->vm_inode = NULL; vma->vm_pte = 0;
The actual mapping is performed with (stripped code):
vma->vm_offset = phys_addr_from_bigphysalloc; remap_page_range (vma->vm_start, vma->vm_offset, size, vma-> vm_page_prot); insert_vm_struct (mm, vma); merge_segments (mm, vma->vm_start, vma->vm_end); mm->total_vm += size_in_bytes >> PAGE_SHIFT;
return virt_addr;
Comments and/or suggestions?
** bpfree() **
This is very simple:
asmlinkage void sys_bpfree(unsigned long addr) { range_t **range_ptr; if (addr == 0UL) return;
/* * Search the block in the used list. */ for (range_ptr = &used_list; *range_ptr != NULL; range_ptr = &(*range_ptr)->next) if ((*range_ptr)->virt == addr) break;
if (*range_ptr == NULL) return;
(void) do_munmap((*range_ptr)->virt, (*range_ptr)->size); bigphysarea_free_pages((*range_ptr)->base); }
Do I have to use the do_munmap() return code in some way?
** bpgetphys() **
This returns to the user the physical address of the memory buffer. This address could be used to set PCI hardware registers directly from user-space (I know that this can be dangerous but this could be a requirement for our particular application).
One last question: right now the real system calls are defined in this way:
asmlinkage unsigned long sys_bpalloc (unsigned int size) asmlinkage void sys_bpfree (unsigned long addr) asmlinkage unsigned long sys_bpgetphys (unsigned long addr)
These definitions shut up gcc during compilation but are they correct as regards the pointer<=>integer issue? In other words are there any types that would fit better (e.g. be "64 bit clean") without giving warnings? I'm sorry but I'm a little bit confused by long, int, caddr_t, void *, daddr_t, __kernel_caddr_t etc. :-)
TIA, Andrea. -- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+~~~~~~~~~~~~~~~~~~~~~~~~~~~ Andrea Cisternino (Tel: 39-50-880306)| APEmille Team INFN Pisa - Italy (Fax: 39-50-880317)| Debian GNU/Linux <URL:http://pcape1.pi.infn.it/~acister> | Climb and be happy !!!! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+~~~~~~~~~~~~~~~~~~~~~~~~~~~ PGP FP: 72 ED D4 1E DE 1E 92 9D 88 E9 C7 6A 32 33 32 1D ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.rutgers.edu
| |