request_mem_region粗略讲解
来源:互联网 发布:美工练手 编辑:程序博客网 时间:2024/04/29 12:30
linux
下request_mem_region的粗略理解
文章来源
:
http
:
//gliethttp.cublog.cn
Linux
把基于I/O映射方式的I/O端口和基于内存映射方式的I/O端口资源统称为“I/O区域”(I/O Region)。I/O Region仍然是一种I/O资源,因此它仍然可以用resource结构类型来描述。
Linux
是以一种倒置的树形结构来管理每一类I/O资源(如:I/O端口、外设内存、DMA和IRQ)的。每一类I/O资源都对应有一颗倒置的资源树,树中的每一个节点都是一个resource结构,而树的根结点root则描述了该类资源的整个资源空间。
1
.
结构体
1
.
1
>
struct
resource iomem_resource
=
{
"PCI mem"
,
0x00000000
,
0xffffffff
,
IORESOURCE_MEM
};
1
.
2
>
struct
resource
{
const
char
*
name
;
unsigned
long
start
,
end
;
unsigned
long
flags
;
struct
resource
*
parent
,
*
sibling
,
*
child
;
};
2
.
调用函数
request_mem_region
(
S1D_PHYSICAL_REG_ADDR
,
S1D_PHYSICAL_REG_SIZE
,
"EpsonFB_RG"
)
#
define
request_mem_region
(
start
,
n
,
name
)
__request_region
(&
iomem_resource
,
(
start
),
(
n
),
(
name
))
__request_region
检查是否可以安全占用起始物理地址S1D_PHYSICAL_REG_ADDR之后的连续S1D_PHYSICAL_REG_SIZE字节大小空间
struct
resource
*
__request_region
(
struct
resource
*
parent
,
unsigned
long
start
,
unsigned
long
n
,
const
char
*
name
)
{
struct
resource
*
res
=
kmalloc
(
sizeof
(*
res
),
GFP_KERNEL
);
if
(
res
)
{
memset
(
res
,
0
,
sizeof
(*
res
));
res
->
name
=
name
;
res
->
start
=
start
;
res
->
end
=
start
+
n
-
1
;
res
->
flags
=
IORESOURCE_BUSY
;
write_lock
(&
resource_lock
);
for
(;;)
{
struct
resource
*
conflict
;
conflict
=
__request_resource
(
parent
,
res
);
//sibling parent
下的所有单元,检测申请部分是否存在交叠冲突
if
(!
conflict
)
//conflict=0;
申请成功,正常安置了[start,end]到相应位置
break
;
if
(
conflict
!=
parent
)
{
parent
=
conflict
;
if
(!(
conflict
->
flags
&
IORESOURCE_BUSY
))
continue
;
}
kfree
(
res
);
//
检测到了资源交叠冲突,kfree归还kmalloc申请的内存
res
=
NULL
;
break
;
}
write_unlock
(&
resource_lock
);
}
return
res
;
}
static
struct
resource
*
__request_resource
(
struct
resource
*
root
,
struct
resource
*
new
)
{
unsigned
long
start
=
new
->
start
;
unsigned
long
end
=
new
->
end
;
struct
resource
*
tmp
,
**
p
;
if
(
end
<
start
)
return
root
;
if
(
start
<
root
->
start
)
return
root
;
if
(
end
>
root
->
end
)
return
root
;
p
=
&
root
->
child
;
//root
下的第一个链表元素*p.[child链表是以I/O资源物理地址从低到高的顺序排列的]
for
(;;)
{
tmp
=
*
p
;
if
(!
tmp
||
tmp
->
start
>
end
)
{
new
->
sibling
=
tmp
;
*
p
=
new
;
//
可以从root->child=null开始我们的分析考虑,此时tmp=null,那么第一个申请将以!tmp条件满足而进入
//
这时root->child的值为new指针,new->sibling = tmp = null;当第二次申请发生时:如果tmp->start > end成立,
//
那么,root->child的值为new指针,new->sibling = tmp;这样就链接上了,空间分布图如:
//child=[start,end]-->[tmp->start,tmp->end](1);
如果条件tmp->start > end不成立,那么只能是!tmp条件进入
//
那么,root->child的值不变,tmp->sibling = new;new->sibling = tmp = null这样就链接上了,空间分布图如:
//child=[child->start,child->end]-->[start,end](2);
//
当第三次申请发生时:如果start在(2)中的[child->end,end]之间,那么tmp->end < start将成立,继而continue,
//
此时tmp = (2)中的[start,end],因为tmp->start < end,所以继续执行p = &tmp->slibing = null,
//
因为tmp->end > start,所以资源冲突,返回(2)中的[start,end]域
//
综上的两个边界值情况和一个中间值情况的分析,可以知道代码实现了一个从地地址到高地址的顺序链表
//
模型图:childe=[a,b]-->[c,d]-->[e,f],此时有一个[x,y]需要插入进去,tmp作为sibling指针游动
//tmp
指向child=[a,b],
//tmp
指向[a,b],当tmp->start>y时,插入后的链接图为:child=[x,y]-->[a,b]-->[c,d]-->[e,f]-->null;当tmp->end>=x时,冲突返回tmp
//tmp
指向[c,d],当tmp->start>y时,插入后的链接图为:child=[a,b]-->[x,y]-->[c,d]-->[e,f]-->null;当tmp->end>=x时,冲突返回tmp
//tmp
指向[e,f],当tmp->start>y时,插入后的链接图为:child=[a,b]-->[c,d]-->[x,y]-->[e,f]-->null;当tmp->end>=x时,冲突返回tmp
//tmp
指向null ,插入后的链接图为:child=[a,b]-->[c,d]-->[e,f]-->[x,y]-->null;
//
顺利的达到了检测冲突,顺序链接的目的
new
->
parent
=
root
;
return
NULL
;
}
p
=
&
tmp
->
sibling
;
if
(
tmp
->
end
<
start
)
continue
;
return
tmp
;
}
}
- request_mem_region粗略讲解
- linux下request_mem_region的粗略理解
- linux下request_mem_region的粗略理解
- linux下request_mem_region的粗略理解
- linux下request_mem_region的粗略理解
- request_mem_region 申请内存函数讲解
- request_mem_region 申请内存函数讲解
- 快速排序讲解(粗略)
- kmp算法粗略讲解
- 树状数组粗略讲解
- MYSQL的索引粗略讲解
- 关于PROTEL主要功能的粗略讲解
- LCS 最大公共序列算法粗略讲解
- 回文串(Manacher)算法粗略讲解
- 最长上升子序列LIS算法粗略讲解
- ioremap,request_mem_region
- request_mem_region,ioremap
- ioremap,request_mem_region
- MySQL表名不允许带-
- oracle实现存储过程的分页并用java代码调用存储过程
- 解决" 0X000000该内存不能为read" 的方法
- spring的定时执行(worker)
- Log4j中使用相对路径
- request_mem_region粗略讲解
- 带输出参数的存储过程调用
- 完全掌握Eclipse项目开发实战
- ASP.NET本质论
- 请教如何用WIN 7笔记本发射WIFI信号~
- 11.5.19关于T-SQL杂篇
- 高效程序员的45个习惯
- PHP - HTTP_REFERER
- MasterPage