Memory and I/O access for Linux kernel development (IV)

Source: Internet
Author: User

Time: PM

Location: dormitory ..

"Mr. Wang, I won't talk much today, but I didn't finish talking about it yesterday. Otherwise, I won't be able to even get up." I urged.

As mentioned in the previous section, if the memory applied for by kmalloc () is to be mapped to the user space, you can use mem_map_reserve () to set it to retained. How to operate it? Here is a template:

 // Kernel module Loading Function  Int _ Init kmalloc_map_init ( Void ) {../Apply for the device number and add the cedv struct buffer = kmalloc (buf_size, gfp_kernel ); // Apply for Buffer    For (Page = pai_to_page (buffer); page <pai_to_page (buffer + buf_size); Page ++) {mem_map_reserve (PAGE ); // Property is retained }} // MMAP () function  Static   Int Kmalloc_map_mmap ( Struct File * filp, Struct Vm_area_struct * VMA ){ Unsigned   Long Page, Pos; Unsigned   Long Start = ( Unsigned   Long ) VMA-> start; Unsigned   Long Size = ( Unsigned   Long ) (VMA-> end-VMA-> Start); printk (kern_info ,"Mmaptest_mmap called \ n "); If (Size> buf_size) // The region to be mapped is too large.          Return -Einval; Pos = ( Unsigned   Long ) Buffer; While (Size> 0) // Map all pages in the buffer {Page = maid (( Void *) POS ); If (Remap_page_range (START, page, page_size, page_sharred )) Return -Eagain; Start + = page_size; POS + = page_size; size-= page_size ;} Return 0 ;}

In addition, generally, the IO memory needs to be nocache when mapped. In this case, set the nocache flag for VMA-> vm_page_prot. As follows:

 
Static IntXxx_nocache_mmap (StructFile * filp,StructVm_area_struct * VMA) {VMA-> vm_page_prot = pgprot_noncached (VMA-> vm_page_prot );// Assign the nocache flagVMA-> vm_pgoff = (u32) map_start> page_shift );If(Rempa_pfn_range (VMA, VMA-> vm_start, VMA-> vm_pgoff, VMA-> vm_end-vm_start, VMA-> vm_page_prot ));Return-Eaggin;Return0 ;}

This sectionCodePgprot_noncached () in is a macro, which actually disables the cache and write buffer of the relevant page. Another macro with a slight limit is:

# Define pgprot_writecombine (prot) _ pgprot (pgprot_val (prot) &-l_pte_cacheable); no write buffer is prohibited

Besides rempa_pfn_range (),ProgramThe nopage () function implementing VMA generally provides a more flexible memory ing path for the device. When a page is missing, nopage () is automatically called by the kernel ,. This is because when a page exception occurs, the system will go through the following process:

1) Find the VMA of the virtual address with missing pages. 2) If necessary, allocate the directory table and page table on the middle page.

3) if the physical page table corresponding to the page table item does not exist, call the nopage () method of this VMA and return the page descriptor of the physical page.

4) Fill in the address of the physical page to the page table.

After nopage is implemented, the user space can call the mremap () system to re-bind the address bound to the ing area. The following is a typical example of using nopage () in the device driver:

 Static   Int Xxx_mmap (Struct File * filp, Struct Vm_area_struct * VMA );{ Unsigned   Long Offset = VMA-> vm_pgoff <page_offset; If (Offset> = _ Pa (high_memory) | (filp-> flags & o_sync) VMA-> vm_flags | = vm_io; VMA-> vm_ops = & xxx_nopage_vm_ops; xxx_vma_open (VMA ); Return 0 ;} Struct Page * xxx_vma_nopage ( Struct Vm_area_struct * VMA, Unsigned   Long Address,Int * Type ){ Struct Page * pageptr; Unsigned   Long Offset = VMA-> vm_pgoff <page_shift; Unsigned   Long Physaddr = address-VMA-> vm_start + offset; // Physical memory     Unsigned   Long Pageframe = physaddr> page_shift; // Page frame number     If (! Pfn_valid (pageframe )) // The page frame number is valid.       Return Nopage_sigbus; pageptr = pfn_to_page (pageframe ); // Page frame number-> page Descriptor Get_page (pageptr ); // Get the page and add the page usage count     If (Type) * type = vm_fault_minor; Return Pageptr; // Return page Descriptor 
 
}

The above function maps the regular memory and returns a page descriptor that can be used to expand or reduce the memory area of the ing. It can be seen that a big difference between nopage () and remap_pfn_range () is remap_pfn.

_ Range () is generally used for device memory ing, while nopage () can also be used for Ram ing.

 

Mr. Wang, I watched this Section together with the previous one. I can take a break. If you take a look at it, you will not bother me. I will call you for dinner at night ..

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.