关键词不能为空

当前您在: 主页 > 英语 >

iomem—IO映射方式的IO端口和内存映射方式的IO端口

作者:高考题库网
来源:https://www.bjmy2z.cn/gaokao
2021-02-19 14:46
tags:

-

2021年2月19日发(作者:prada是什么意思)


iomem



I/O


映 射方式的


I/O


端口和内存映射方式的


I/O


端口





Linux


将基于

< br>I/O


映射方式的


I/O


端口和 基于内存映射方式的


I/O


端口资源统称为


I/O


区域


< br>(


I/O Region




I/O

< p>
Region


仍然是一种


I/O

< br>资源,因此它仍然可以用


resource


结构类型来描 述。下面我们就来看看


Linux


是如何管理

< br>I/O


Region


的。


< /p>


3



3



1 I/O Region


的分配



在函数


__request_resource()

的基础上,


Linux


实现了用于分配

I/O


区域的函数


__request_region()


,如下


:


1 struct resource * __request_region(struct resource *parent,


2






unsigned long start, unsigned long n, const char *name)


3




{


4




struct resource *res = kmalloc(sizeof(*res), GFP


_KERNE


L);



5





6




if (res) {


7




memset(res, 0, sizeof(*res));


8




res->name = name;


9




res->start = start;


10




res->end = start + n - 1;


11




res->


flags = IORE


SOURCE


_BUSY;


12





13




write_lock(&


resource_lock);


14





15




for (;;) {


16




struct resource *conflict;


17





18




conflict = __request_resource(parent, res);


19




if (!conflict)


20




break;


21


22




if (conflict != parent) {


23




parent = conflict;


24




if (!(conflict->


flags & IORESOURCE


_BUSY))


25




continue;


26




}


27





28




/* Uhhuh, that didn't w


ork out.. */


29




kfree(res);


30




res = NULL;


31




break;


32




}


33




w rite_unlock


(&resource_lock);


34




}


35




return res;


36




}


37


NOTE












首先, 调用


kmalloc


()函数在


SLA B


分配器缓存中分配一个


resource

结构。











然后,相应的根据参数来填充


resource


结构。注意!


flags


成员被初始化为


IORE


SOURCE


_BUSY












接下来,用一个


for


循环开始进行资源分 配,循环体的步骤如下:










l


首先,


调用


__request_resource()


函数进行资源 分配。


如果返回


NULL


< p>
说明分配成功,


因此就执行


break

< p>
语句推出


for


循环,返回所分配的


resource


结构的指针,函数成功地结束。










l < /p>


如果


__request_resource()


函数分配不成功,则进一步判断所返回的冲突资源节点是否就是父资源节点


pa rent


。如果不是,则将分配行为下降一个层次,即试图在当前冲突的资源节点中进行 分配(只有在冲突的资源节点没


有设置


IORE


SOURCE


_BUSY


的情况下才可以)

< p>
,于是让



parent


指针等于


conflict


,并在


co nflict->


flags&IORE


SOURCE


_BUSY



0


的情况 下执行


continue


语句继续


f or


循环。







l < /p>


否则如果相冲突的资源节点就是父节点


parent


,或者相冲突资源节点设置了


IORE


SOURCE


_BUSY



志位,

< br>则宣告分配失败。


于是调用


k


f ree


()


函数释放所分配的


res ource


结构,


并将


res


指针置为


NULL



最 后用


break


语句推出


for


循环。








最后, 返回所分配的


resource


结构的指针。

< br>






3



3



2 I/O Region


的释放










函数


__ release_region()


实现在一个父资源节点


pa rent


中释放给定范围的


I/O Region



实际上该函数的实


现思想与


__release_resource()


相类似。其源代码如下:



1 void __release_region(struct resource *parent,


2








unsigned long start, unsigned long n)


3




{


4




struct resource **p;


5




unsigned long end;


6





7




p = &parent->child;


8




end = start + n - 1;


9





10




for (;;) {


11




struct resource *res = *p;


12





13




if (!res)


14




break;


15




if (res->


start <= start && res->end >= end) {


16




if (!(res->


flags & IORE


SOURCE


_BUSY)) {


17




p = &res->child;


18




continue;


19




}


20




if (res->


start != start' 'res->end != end)


21




break;


22




*p = res->sibling;


23




kfree(res);


24




return;


25




}


26




p = &res->sibling;


27




}


28




printk(Trying to free nonexi


s


tent resource <


%08lx-%08lx>



29




, start, end);


30




}


31






类似地,该函数也是通过一个


for


循环来遍历父资源


parent



child


链表。为此,它让指针


res< /p>


指向当前


正被扫描的子资源节点,指针


p


指向前一个子资源节点的


sibling


成员变量,


p


的初始值为指向


par ent->child



For


循环< /p>


体的步骤如下:












res


指针指向当前被扫描的子资源节点(


res



*p













如果


res


指针 为


NULL


,说明已经扫描完整个


ch ild


链表,所以退出


for


循环。< /p>











如果


res


指针 不为


NULL


,则继续看看所指定的


I /O


区域范围是否完全包含在当前资源节点中,也即看



[start,start+n-1]


是否包含在

res->[start,end]


中。如果不属于,则让


p


指向当前资源节点的


sibling


成员,然后继续


for


循环。如果属于,则执行下列步骤:










l


先看看当前资源节点是否设置了


I ORESOURCE


_BUSY


标志位。如果没有设置该标志位 ,则说明该资


源节点下面可能还会有子节点,


因此将扫描过程下 降一个层次,


于是修改


p


指针,


使它指向


res->child


< p>
然后执行


continue


语句继续


for


循环。







l < /p>


如果设置了


IORESOURCE


_BU SY


标志位。则一定要确保当前资源节点就是所指定的


I/O< /p>


区域,然后


将当前资源节点从其父资源的


child


链表中去除。这可以通过让前一个兄弟资源节点的


s ibling


指针指向当前资源节点的


下一个兄弟资源节点来实 现(即让


*p=res->


sibling


,最后调用


k


free


()函数释放当前资源节点的


resource


结构。然后


函数就可以成功返回了。







3



3



3


检查指定的


I/O Region


是否已被占用










函数


__ check_region()


检查指定的


I/O Region


是否已被占用。其源代码如下:



1 int __check_region(struct resource *parent, unsigned long start, unsigned long n)


2




{


3




struct resource * res;


4





5




res = __request_region(parent, start, n, check-region);


6




if (!res)


7




return -E


BUSY;


8





9




release_resource(res);


10




kfree(res);


11




return 0;


12




}


13






该函数 的实现与


__check_resource()


的实现思想类 似。首先,它通过调用


__request_region()


函数试图在


父资源



parent


中分配指定的


I/O R egion


。如果分配不成功,将返回


NULL


,因此此时函数返回错误值-


E


BUSY


表示所


指定的


I/O Region


已被占用。如果


res


指针不为空则说明所指定的


I/O Region


没有被占用。于是调用


__release_resource()


函数将刚刚分配的资源释放掉

< p>
(实际上是将


res


结构从


parent




child


链表去除)



然后调用


kfree


()


函数释放


res


结构所占用的内存。


最后,


返回

< p>
0


值表示指定的


I/O Region


没有被占用。



中国网管论坛








3



4


管理


I/O


端口资源










我们都 知道,采用


I/O


映射方式的


X86< /p>


处理器为外设实现了一个单独的地址空间,也即



I/O


空间




I/O


S


pace


)或称 为



I/O


端口空间

< br>”


,其大小是


64KB



0x0000



0xffff




Linux


在其所支持的 所有平台上都实现了



I/O


端口空< /p>





这一概念。










由于


I/ O


空间非常小,因此即使外设总线有一个单独的


I/O


端口空间,


却也不是所有的外设都将其


I/O< /p>



口(指寄存器)映射到



I/O


端口空间



中。比如 ,大多数


P


CI


卡都通过内存映射方式 来将其


I/O


端口或外设内存映射到


C P


U



RAM


物理地址空间中。而老式的



ISA


卡 通常将其


I/O


端口映射到


I/O


端口空间中。










Linux


是基于

< br>“


I/O Region



这一 概念来实现对


I/O


端口资源(


I/O



mapped




Memory


mapped


)的管


理的。










3



4



1


资源根节点的定义










Lin ux



kernel/Resource.c

< br>文件中定义了全局变量


ioport_resource



iomem_resource


,来分别描述基



I/O


映射方式的整个


I /O


端口空间和基于内存映射方式的


I/O

内存资源空间


(包括


I/O


端口和 外设内存)



其定义如下:



1




struct resource ioport_resource =


2








{ P


CI IO, 0x0000, IO_SP


ACE


_LIMIT


, IORE


SOURCE


_IO };



3




struct resource iomem_resource =


4








{ P


CI mem, 0x00000000, 0xffffffff, IORESOURCE


_MEM };







其中,宏


IO_SP


ACE


_LIMIT


表示整个


I/O


空间的大小,对于


X86


平台而言,它是


0xffff


(定义在


include/asm-i386/ io.h


头文件中)


。显然,


I/O< /p>


内存空间的大小是


4GB



-


-


-


-


-


-


-


-



本文更新与2021-02-19 14:46,由作者提供,不代表本网站立场,转载请注明出处:https://www.bjmy2z.cn/gaokao/667991.html

iomem—IO映射方式的IO端口和内存映射方式的IO端口的相关文章

  • 余华爱情经典语录,余华爱情句子

    余华的经典语录——余华《第七天》40、我不怕死,一点都不怕,只怕再也不能看见你——余华《第七天》4可是我再也没遇到一个像福贵这样令我难忘的人了,对自己的经历如此清楚,

    语文
  • 心情低落的图片压抑,心情低落的图片发朋友圈

    心情压抑的图片(心太累没人理解的说说带图片)1、有时候很想找个人倾诉一下,却又不知从何说起,最终是什么也不说,只想快点睡过去,告诉自己,明天就好了。有时候,突然会觉得

    语文
  • 经典古训100句图片大全,古训名言警句

    古代经典励志名言100句译:好的药物味苦但对治病有利;忠言劝诫的话听起来不顺耳却对人的行为有利。3良言一句三冬暖,恶语伤人六月寒。喷泉的高度不会超过它的源头;一个人的事

    语文
  • 关于青春奋斗的名人名言鲁迅,关于青年奋斗的名言鲁迅

    鲁迅名言名句大全励志1、世上本没有路,走的人多了自然便成了路。下面是我整理的鲁迅先生的名言名句大全,希望对你有所帮助!当生存时,还是将遭践踏,将遭删刈,直至于死亡而

    语文
  • 三国群英单机版手游礼包码,三国群英手机单机版攻略

    三国群英传7五神兽洞有什么用那是多一个武将技能。青龙飞升召唤出东方的守护兽,神兽之一的青龙。玄武怒流召唤出北方的守护兽,神兽之一的玄武。白虎傲啸召唤出西方的守护兽,

    语文
  • 不收费的情感挽回专家电话,情感挽回免费咨询

    免费的情感挽回机构(揭秘情感挽回机构骗局)1、牛牛(化名)向上海市公安局金山分局报案,称自己为了挽回与女友的感情,被一家名为“实花教育咨询”的情感咨询机构诈骗4万余元。

    语文
iomem—IO映射方式的IO端口和内存映射方式的IO端口随机文章