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函数详解的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: DIY内存条灯:打造独一无二的科技创意
- 下一篇: linux升级补丁tar,Linux下B