首页 > 编程知识 正文

linux内核编译安装,调用linux内核函数

时间:2023-05-03 18:34:11 阅读:18572 作者:3092

操作系统: Ubuntu 10.04http://www.Sina.com/http://www.Sina.com /

void * http://www.Sina.com/(unsigned long phys _ addr,unsigned long size,unsigned long flags )。

参数:1,:映射的第一个IO地址;ioremap:要映射的空间大小;__ioremap:要映射的IO空间权限标志;

功能: http://www.Sina.com/http://www.Sina.com/http://www.Sina.com /

实现:确定要映射的IO地址空间。 http://www.Sina.com/http://www.Sina.com/http://www.Sina.com /不允许用户将IO地址空间映射到正在使用的RAM。 最后申请虚拟机VM_Area

含义:

例如,isa和pci设备、fb、硬件跳线或物理连接方法决定了硬件上的内存反映在哪个cpu的物理地址中。phys_addr这正是__ioremap的意义所在。 应该注意的是,物理存储器已经“存在”,不需要向该地址提供alloc page。

为了让软件访问I/O内存,必须为设备分配虚拟地址。 这就是ioremap的工作。 此函数专用于为I/O内存空间分配虚拟地址(空间)。 不执行任何直接映射的I/O地址ioremap。 (在uClinux上是这样实现的吗? )

有了http://www.Sina.com/和http://www.Sina.com/,无论设备是否直接映射到虚拟地址空间,都可以访问任何I/O内存空间。 但是,不能直接使用这些地址。 使用名为readb的函数。

根据计算机平台和使用的总线,I/O内存可能通过页面表访问,也可能不是。 通过页面表访问的是统一地址(PowerPC ),否则为独立地址(Intel )。 如果访问是通过页面表进行的,则内核必须首先安排物理地址,以便设备驱动程序可以看到。 这通常意味着在进行输入输出之前必须调用ioremap。 如果访问不需要页表,则I/O内存空间类似于I/O端口,可以使用适当格式的函数读写。 3358 www.Sina.com/http://www.Sina.com/http://www.Sina.com/3358 www.Sina.com.Sina.com o内存在硬件级别的寻址方式与常规RAM相同,但建议在需要额外注意时不要使用常规指针,如I/o寄存器和常规内存中所述。 相反,使用“包装”函数访问I/O内存在所有平台上是安全的,但如果可以直接对指针指向的内存区域执行操作,则进行了优化

在X86体系下,CPU的物理地址和PCI总线地址共享一个空间。 linux内核将3G-4G虚拟地址固定映射到物理地址0-1G处。 但是,如果外围设备的地址大于1G,例如,一个PCI卡被分配给大于1G的地址,则必须调用ioremap以重新建立其物理地址(总线地址)到虚拟地址的映射此映射过程在ioremap.c文件的__ioremap函数中首先检查将来映射的物理地址。 这意味着不能重新映射640K-1M地址。 由于历史原因,图形卡上保留了物理地址为640k到1M的空间。 普通的ram地址也无法重新映射。 然后,当调用get_vm_area获取可用的虚拟地址并基于与该虚拟地址映射的物理地址修改页面表时,内核可以使用该虚拟地址访问映射的物理地址

size

偏移:物理空间(I/O设备

上的一块物理内存)的起始地址
size:   物理空间的大小

给一段物理地址(起始地址offset)建立页表(地址映射)
--------------------------------------------------
static inline void __iomem * ioremap(unsigned long offset, unsigned long size)
{   
    return __ioremap(offset, size, 0);
}    



    Remap an arbitrary physical address space into the kernel virtual address space. Needed when the kernel wants to access high addresses directly.
--------------------------------------------------
void __iomem * __ioremap(unsigned long phys_addr, unsigned long size, unsigned long flags){
    void __iomem * addr;
    struct vm_struct * area;
    unsigned long offset, last_addr;
    last_addr = phys_addr + size - 1;
    if (!size || last_addr < phys_addr)
        return NULL;
    if (phys_addr >= ISA_START_ADDRESS && last_addr < ISA_END_ADDRESS)
        return (void __iomem *) phys_to_virt(phys_addr);

如果需要映射的空间的起始地址phys_addr为于ZONE_NORMAL区,通过virt_to_page()进行映射
|------------------------------------------------------------------------------|
|   if (phys_addr <= virt_to_phys(high_memory - 1))                            |
|    {                                                                         | 
|       char *t_addr, *t_end;                                                  |
|       struct page *page;                                                     |
|       t_addr = __va(phys_addr);                                              |
|       t_end = t_addr + (size - 1);                                           |
|       for(page = virt_to_page(t_addr); page <= virt_to_page(t_end); page++) -|
|           if(!PageReserved(page))                                            |
|               return NULL;                                                   |
|   }                                                                          |
|------------------------------------------------------------------------------|
    offset = phys_addr & ~PAGE_MASK;
    phys_addr &= PAGE_MASK;
    size = PAGE_ALIGN(last_addr+1) - phys_addr;

通过“非连续存储器区”进行映射
get_vm_area()创建类型为vm_struct的新描述符
get_vm_area()首先调用kmalloc()为新描述符获得一个存储区;然后扫描类型为struct vm_struct的描述符表,查找一个可用线性地址空间(至少包含size+4096个地址)。
|----------------------------------------------------------|
|   area = get_vm_area(size, VM_IOREMAP | (flags << 20)); -|
|   if (!area)                                             |
|       return NULL;                                       |
|----------------------------------------------------------|



3,参考文件
1,http://wenku.baidu.com/link?url=uM3vDOg6SgUNegieKZ8yFHQ0cO8CsUs9TcSJuBxx4dHoDoP3XYpWkEXrCzXd2mRgOIFQHV-ZZZbnk8dPgoE4qcZzjLZYeXXOImI1B8VsT4C

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。