日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > linux >内容正文

linux

linux64位ioremap函数,linux操作系统中的ioremap函数详解

發布時間:2024/2/28 linux 37 豆豆
生活随笔 收集整理的這篇文章主要介紹了 linux64位ioremap函数,linux操作系统中的ioremap函数详解 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

在編寫驅動程序的過程中,我們總免不了要使用ioremap函數來將我們的硬件的地址映射到系統的虛擬地址空間。

ioramp函數原型:

#define ioremap(cookie,size) __ioremap(cookie,size,0,1)

這是一個宏來實現的,當然要進入__ioremap去看看究竟。

void __iomem *

__ioremap(unsigned long phys_addr, size_t size, unsigned long

flags,

unsigned long align)

{

void * addr;

struct vm_struct * area;//管理虛擬頁面所使用的結構體

unsigned long offset, last_addr;

last_addr = phys_addr + size - 1;

if (!size || last_addr 《 phys_addr)

return NULL;

offset = phys_addr & ~PAGE_MASK; //取得偏移量

phys_addr &= PAGE_MASK; //得到頁面的基地址

size = PAGE_ALIGN(last_addr + 1) - phys_addr;

//取得所需要的尺寸。注意是按照對齊來算的

area = get_vm_area(size, VM_IOREMAP);//通過get_vm_area來獲得虛擬內存

if (!area)

return NULL;

addr = area-》addr;

if (remap_area_pages((unsigned long) addr, phys_addr, size, flags))

{

vfree(addr);

return NULL;

}

return (void __iomem *) (offset + (char *)addr);

}

遇到了get_vm_area函數,我們goto Defination去看看。

struct vm_struct *get_vm_area(unsigned long size, unsigned long

flags)

{

return __get_vm_area(size, flags, VMALLOC_START, VMALLOC_END);

}

繼續

struct vm_struct *__get_vm_area(unsigned long size, unsigned long

flags,

unsigned long start, unsigned long end)

{

struct vm_struct **p, *tmp, *area;

unsigned long align = 1;

unsigned long addr;

if (flags & VM_IOREMAP) {

int bit = fls(size); //獲得最高位為1所在的位置,0x00000600返回10

if (bit 》 IOREMAP_MAX_ORDER) //如果分配超過最大尺寸,按照最大尺寸處理

bit = IOREMAP_MAX_ORDER;

else if (bit 《 PAGE_SHIFT)

bit = PAGE_SHIFT; //以頁為單位進行分配,最小單位是頁

align = 1ul 《 bit;//以頁來對齊

}

addr = ALIGN(start, align);

area = kmalloc(sizeof(*area), GFP_KERNEL);//分配一個空間來保存這些信息的結構體

if (unlikely(!area))

return NULL;

size += PAGE_SIZE;//中間空了一頁,目的是安全穩定

if (unlikely(!size)) {

kfree (area);

return NULL;

}

write_lock(&vmlist_lock);

for (p = &vmlist; (tmp = *p) != NULL ;p =

&tmp-》next) {

if ((unsigned long)tmp-》addr 《 addr) {

if((unsigned long)tmp-》addr + tmp-》size 》= addr)

addr = ALIGN(tmp-》size +

(unsigned long)tmp-》addr, align);//找空閑的虛擬地址

continue;

}

if ((size + addr) 《 addr)

goto out;

總結

以上是生活随笔為你收集整理的linux64位ioremap函数,linux操作系统中的ioremap函数详解的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。